如何设置 texi2dvi 与 synctex 和错误处理?

如何设置 texi2dvi 与 synctex 和错误处理?

我想要设置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.texshell,通过以下方式打开 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 bytexi2dvi`。

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")))

这并没有提供我原先计划的方便的错误处理,但是它需要的黑客攻击要少得多,而且运行良好。

相关内容