I would like to set up texi2dvi (with error-handling, synctex for forward and backward syncronization, and Okular as viewer) to compile .tex documents (under Ubuntu 12.04 with Emacs 24).

(In case this matters) here is my general LaTeX/AUCTeX setup in .emacs (feel free to comment if you see nonsense here already):

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

In case of an error, the TeX Help buffer should be displayed, indicating the error. If the error is resolved and the .tex file compiled again, the buffer should disappear. For the latter, we need the following function:

;; 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 ()
  (if (get-buffer "*TeX Help*")
        (if (get-buffer-window (get-buffer "*TeX Help*"))
            (delete-window (get-buffer-window (get-buffer "*TeX Help*")))
        (kill-buffer "*TeX Help*")

The following function is the main problem (as mentioned below). It should call texi2dvi in such a way that synctex works (for forward and backward syncronization with Okular) and errors should be displayed in the TeX Help buffer.

;; 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 ()
  (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
          "texi2dvi -p %s"; command; TODO: errors are not caught ...
          (lambda (ext-ignored nondir)
            (TeX-master-file t nondir)))
    ;; error handling
    (if (plist-get TeX-error-report-switches (intern master-file))
        (TeX-next-error t)
        (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."))

For making mytexi2dvi available on C-c C-c, I use:

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

Finally, Okular is set up like this:

;; 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
               (expand-file-name (funcall file (TeX-output-extension) t)
                         (file-name-directory (TeX-master-file)))
               (expand-file-name (TeX-master-directory))
(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

Interestingly, the following works:

Set in ~/.profile:

PDFLATEX="pdflatex --shell-escape -synctex=1 -file-line-error"
export PDFLATEX 

I can then call texi2dvi -p foo.tex in the shell, open Okular via C-c C-v and get forward and backward sync, so this is working from the shell.

However, from within Emacs, it's not working. Here are the problems:

1) C-c C-c compiles the document, but not .synctex.gz is written, so synctex (for backward sync) is not working. This problem remains if I replace texi2dvi -p %s by "PDFLATEX='pdflatex --shell-escape -synctex=1 -file-line-error' texi2dvi -p %s".

2) On C-c C-l I receive `No process for this document.'' instead of the output generated bytexi2dvi`.

3) In case of an error, no TeX Help buffer is shown, so errors are not caught/detected.

4) C-c C-v opens Okular at the correct spot, so forward sync is working; backward sync (on Shift + left mouse) is not working (as stated above)

Overall, I would consider what I try as a minimal setup to efficiently work with LaTeX. Since I only found some information and even this quite scattered on the web, I am wondering how others work with LaTeX/AUCTeX/Emacs? Is there a more efficient way? The setup above seemed pretty nice to me, you just have to hit C-c C-c (even inside sub-files of a project), the master .tex file is compiled (as many times as necessary), and in case of an error, you directly see what happened. Without the "close-help-buffer-if-error-is-resolved" I always get confused if I actually solved the error, that's why I find this useful.


The way I could get it to work is by (simply) calling texi2dvi directly (without setting up my own function):

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

This does not provide a convenient error-handling as I originally planned to have, but it requires much less hacking and works fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.