我想要设置texi2dvi
(带有错误处理、用于正向和反向同步的 synctex 以及 Okular 作为查看器)来编译.tex
文档(在带有 Emacs 24 的 Ubuntu 12.04 下)。
(如果这很重要)这是我的常规 LaTeX/AUCTeX 设置.emacs
(如果您在这里发现无意义的内容,请随意评论):
;; basics
(add-to-list 'load-path "/usr/share/emacs23/site-lisp"); path to tex-site.el
(require 'tex-site); enable AUCTeX
(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t); preview in .tex file
(setq TeX-auto-save t); enable parsing buffers on save
(setq TeX-parse-self t); enable parsing buffers on load
(setq TeX-save-query nil); autosave before compiling (=> do not ask for saving)
(setq TeX-PDF-mode t); use pdflatex by default
(setq TeX-clean-confirm nil); don't ask for confirmation on cleaning via M-x TeX-clean
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode); turn on latex math mode
(add-hook 'LaTeX-mode-hook 'turn-on-auto-fill); turn on auto-fill mode
(setq-default TeX-master nil); for master/slave projects
;; start (first) emacs session in server mode (required for backward search from
;; .pdf to .tex)
;; see http://stackoverflow.com/questions/6397323/how-to-avoid-the-message-of-server-start-while-opening-another-emacs-session
(require 'server)
(or (server-running-p)
(server-start))
如果出现错误,应显示 TeX Help 缓冲区,指出错误。如果错误得到解决并.tex
再次编译文件,则缓冲区应消失。对于后者,我们需要以下函数:
;; for closing the help buffer after all errors are resolved
;; see http://stackoverflow.com/questions/9249458/latex-emacs-automatically-open-tex-help-buffer-on-error-and-close-it-after-c
(defun demolish-tex-help ()
(interactive)
(if (get-buffer "*TeX Help*")
(progn
(if (get-buffer-window (get-buffer "*TeX Help*"))
(delete-window (get-buffer-window (get-buffer "*TeX Help*")))
)
(kill-buffer "*TeX Help*")
)
)
)
以下函数是主要问题(如下所述)。它应该texi2dvi
以这样一种方式调用,以使 synctex 可以工作(用于与 Okular 进行向前和向后同步),并且错误应该显示在 TeX 帮助缓冲区中。
;; texi2dvi -- define nice function with error handling
;; see http://stackoverflow.com/questions/11565998/elisp-texi2dvi-how-to-call-texi2dvi-from-emacs/11587555#11587555
(defun mytexi2dvi ()
(interactive)
(let ((TeX-save-query nil)
(TeX-process-asynchronous nil)
(master-file (expand-file-name (TeX-master-file t)))); append .tex
(TeX-save-document ""); save document
;; run texi2dvi on master
(TeX-run-TeX "texi2dvi"; name
(TeX-command-expand
"texi2dvi -p %s"; command; TODO: errors are not caught ...
(lambda (ext-ignored nondir)
(TeX-master-file t nondir)))
master-file)
;; error handling
(if (plist-get TeX-error-report-switches (intern master-file))
(TeX-next-error t)
(progn
(demolish-tex-help); that's the function that closes the TeX Help buffer when there is no error anymore (see above)
(minibuffer-message "texi2dvi: done."))
)
)
)
为了使其mytexi2dvi
在 上可用C-c C-c
,我使用:
;; Compiling .tex files
;; adapted from http://stackoverflow.com/questions/9454839/how-to-add-a-function-latexmk-variant-to-tex-command-list-in-auctex
(add-hook 'LaTeX-mode-hook
(lambda ()
;; texi2dvi
(add-to-list 'TeX-command-list
'("texi2dvi" "(mytexi2dvi)" TeX-run-function nil t :help "Run texi2dvi") t)
;; default
(setq TeX-command-default "latexmk")))
最后,Okular 设置如下:
;; set default pdf viewer
;; see http://tex.stackexchange.com/questions/29813/setup-synctex-with-emacs
;; Additionally, do: Okular -> Settings -> Editor -> change to Emacs client
(defun Okular-make-url () (concat
"file://"
(expand-file-name (funcall file (TeX-output-extension) t)
(file-name-directory (TeX-master-file)))
"#src:"
(TeX-current-line)
(expand-file-name (TeX-master-directory))
"./"
(TeX-current-file-name-master-relative)))
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-to-list 'TeX-expand-list
'("%u" Okular-make-url))))
(setq TeX-view-program-list
'(("Okular" "okular --unique %u")))
(setq TeX-view-program-selection '((output-pdf "Okular") (output-dvi "Okular"))); use okular for displaying .pdf and .dvi
有趣的是,以下是有效的:
设定于~/.profile
:
PDFLATEX="pdflatex --shell-escape -synctex=1 -file-line-error"
export PDFLATEX
然后我可以调用texi2dvi -p foo.tex
shell,通过以下方式打开 OkularC-c C-v
并获得前向和后向同步,因此这是从 shell 进行的。
然而,在 Emacs 内部,它却无法工作。问题如下:
1)C-c C-c
编译了文档,但未.synctex.gz
写入,因此 synctex(用于向后同步)不起作用。如果我texi2dvi -p %s
用替换,这个问题仍然存在"PDFLATEX='pdflatex --shell-escape -synctex=1 -file-line-error' texi2dvi -p %s"
。
2)C-c C-l
我收到`No process for this document.'' instead of the output generated by
texi2dvi`。
3) 如果发生错误,则不会显示 TeX 帮助缓冲区,因此无法捕获/检测到错误。
4)C-c C-v
在正确的位置打开 Okular,因此前向同步可以正常工作;后向同步(开启Shift + left mouse
)则无法正常工作(如上所述)
总的来说,我认为我尝试的是一个最低限度的设置,可以有效地使用 LaTeX。由于我只找到了一些信息,而且这些信息在网上也相当分散,我想知道其他人是如何使用 LaTeX/AUCTeX/Emacs 的?有没有更有效的方法?上面的设置对我来说似乎很不错,你只需要点击C-c C-c
(即使在项目的子文件内),主.tex
文件就会被编译(根据需要多次),如果出现错误,你可以直接看到发生了什么。如果没有“如果错误已解决则关闭帮助缓冲区”,我总是会搞不清楚我是否真的解决了错误,这就是为什么我觉得这个很有用。
答案1
我可以让它工作的方法是(简单地)texi2dvi
直接调用(无需设置我自己的函数):
;; Compiling .tex files
(add-hook 'LaTeX-mode-hook
(lambda ()
;; texi2dvi
(add-to-list 'TeX-command-list
'("texi2dvi" "PDFLATEX='pdflatex --shell-escape -synctex=1 -file-line-error' texi2dvi -p %t" TeX-run-command nil t :help "Run texi2dvi") t)
;; make
(add-to-list 'TeX-command-list
'("make" "make" TeX-run-command nil t :help "Run make") t)
;; default
(setq TeX-command-default "texi2dvi")))
这并没有提供我原先计划的方便的错误处理,但是它需要的黑客攻击要少得多,而且运行良好。