我该如何让Org-mode在Evince中打开PDF文件?

35

在Org-mode中,当我尝试打开PDF文件链接时,没有任何反应。另外,当我执行C-c C-e d进行导出为LaTeX并处理成PDF并打开时,PDF已生成但未打开。我如何使Org-mode在Evince中打开PDF文件?

我正在使用GNU Emacs 23.3.1 中的 Org-mode 7.6 和 Ubuntu 11.10 中的 Evince 3.2.1。

3个回答

23
M-x customize-variable [RET] org-file-apps [RET]
如果组织使用您的系统默认设置,则需要编辑您的"./mailcap"文件。 尝试添加这行:
application/pdf; /usr/bin/evince %s

在我的.emacs中是否有一行代码可以添加,而不必使用“M-x customize-variable [RET] org-file-apps [RET]”? - N.N.
根据 find-variableorg-file-apps 包括 ("\\.pdf\\'" . default) - N.N.
你可以在.emacs文件中添加(setq org-file-apps...)这样的内容,但我不明白为什么你不根据自己的需求设置变量。如果你尝试使用F1 v org-file-apps命令,第一个例子是这个:Example: ("pdf" . "evince %s") to open PDFs with evince.所以请查看帮助文件并尝试将其设置为evince。 - certainly
1
你使用 customize-variable 并添加 evince %s 来打开 PDF 的解决方案是可行的。但我认为 customize-variable 会使 .emacs 文件变得混乱,因此我提供了一种不需要使用 customize-variable 的解决方案,请参考我的回答:https://dev59.com/-moy5IYBdhLWcg3wA5WC#8836108。 - N.N.

12

另一个可能适用于此的结构是使用eval-after-load而不是add-hook。它只会在启动时设置值一次,你不必担心条目是否被添加或删除(除非您经常重新加载org)。

再加上setcdr,您可以避免删除列表中的元素,然后重新添加元素,添加if,您将确保添加或更改该值。 if仅针对默认情况下不在列表中的值需要使用,以确保您不会在某个地方出现冲突。

(eval-after-load "org"
  '(progn
     ;; .txt files aren't in the list initially, but in case that changes
     ;; in a future version of org, use if to avoid errors
     (if (assoc "\\.txt\\'" org-file-apps)
         (setcdr (assoc "\\.txt\\'" org-file-apps) "notepad.exe %s")
       (add-to-list 'org-file-apps '("\\.txt\\'" . "notepad.exe %s") t))
     ;; Change .pdf association directly within the alist
     (setcdr (assoc "\\.pdf\\'" org-file-apps) "evince %s")))

澄清编辑

eval-after-load 只有在调用 (require 'org) 时才会评估代码块。如果已经加载了 org,它将立即评估(我错误地认为它会在每个库加载时运行,但它似乎只是第一次)。add-hookeval-after-load 的区别在此处解释

由于 org-file-apps 是一个 defcustom,如果在加载 org 之前设置值,则不会更改这些值;如果你从头开始构建列表(包括默认值,如第二个较丑的解决方案),则可以在 init.el 中使用 setq 并且一切都可以工作。这也意味着它不会覆盖您的更改。

(if (assoc 添加到 PDF 条目中不会有任何损害,它只是确保如果从默认的 org-file-apps 中删除 PDF,它仍将被添加。唯一不会失败的解决方案是第二个方案。其他所有方案都假设该条目以某种形式存在。


我有时在一个会话中多次为缓冲区加载 org-mode。这会影响该解决方案吗?还是只有当我使用“org-reload”时才会影响它?此外,我能否添加(if(assoc)结构以使其对未来的 pdf 文件具有兼容性? - N.N.
@N.N在编辑中添加了一些细节,应该可以回答那个问题。 - Jonathan Leech-Pepin
感谢您的详细说明。这个解决方案到目前为止是最优雅的。 - N.N.

11

你可以使用类似于https://dev59.com/YW865IYBdhLWcg3wHK7u#3985552的结构,但要将其适应于PDF文件和Evince。你想要做的是修改列表org-file-apps。这可以通过在.emacs文件中添加以下内容来完成:

;; PDFs visited in Org-mode are opened in Evince (and not in the default choice) https://dev59.com/-moy5IYBdhLWcg3wA5WC#8836108
(add-hook 'org-mode-hook
      '(lambda ()
         (delete '("\\.pdf\\'" . default) org-file-apps)
         (add-to-list 'org-file-apps '("\\.pdf\\'" . "evince %s"))))
这将删除PDF文件的默认设置,并改为在Evince中打开它们(并保留org-file-apps中包含的所有其他内容)。我对elisp还很陌生,所以不确定这个解决方案是否牢固,但它对我有效,并且似乎比下面的解决方案更优雅。
另一个选择是查找默认值并将所有内容设置为它们,但将PDF文件的值更改为不同的值,这种方法看起来更加繁琐。
;; PDFs visited in Org-mode are opened in Evince (and other file extensions are handled according to the defaults)
(add-hook 'org-mode-hook
      '(lambda ()
         (setq org-file-apps
           '((auto-mode . emacs)
             ("\\.mm\\'" . default)
             ("\\.x?html?\\'" . default)
             ("\\.pdf\\'" . "evince %s")))))

当然,我已经编辑了解决方案,因为每次调用org-mode时append都会添加条目,这会使变量泛滥。也许我可以使用add-to-list来做一些更优雅的事情。 - N.N.
@当然,我添加了一些更加优雅的东西。 - N.N.
你的解决方案看起来应该可以胜任!我对elisp一无所知,所以很高兴在Emacs中有自定义系统,但它并非没有缺陷。我希望将来会有更先进的工具来组织和跟踪emacs的偏好设置,并提供更直观的界面。有一些项目指向这个方向,但据我所知,还没有真正方便的东西。 - certainly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接