This is a follow up to How do I bind latexmk to one key in Emacs and have it show errors if there are any.
I\'m using a function in Emacs to compile LaTeX documents
There is a problem with how latexmk is being invoked. It is invoked with no arguments and so it tries to compile all tex files in the directory including the newly created vc.tex
. This of course causes problems because vc.tex
can't be compiled and so you get an error every time.
Starting from the function you have it is fairly easy to fix using TeX-command-expand
like:
(defun run-latexmk ()
(interactive)
(let ((TeX-save-query nil)
(TeX-process-asynchronous nil)
(master-file (TeX-master-file)))
(TeX-save-document "")
(TeX-run-TeX "latexmk"
(TeX-command-expand "latexmk %t" 'TeX-master-file)
master-file)
(if (plist-get TeX-error-report-switches (intern master-file))
(TeX-next-error t)
(minibuffer-message "latexmk done"))))
EDIT: In order to fix the problem with the "TeX Live 2011" buffer, you have to use the other answer as well.
I have had this problem long ago, and I looked into it. It's due to the way AUCTeX parses the output trying to determine what file the error is in. When TeX starts reading a file it outputs (/path/to/the/file
and when it finishes reading the file it prints )
. There are numerous ways in which AUCTeX can misunderstand. The first "file" that it reads is TeX Live 2011, and then for whatever reason it thinks more files have closed than opened and you end up back in TeX Live 2011.
In the short example that you gave, the problem is that the output contains
(./auctex-bug2.texsh: ./vc: No such file or directory
and it doesn't recognize this as a new file since (I presume) it contains a :
. Of course it would be the wrong file anyway, but that's neither here nor there. I can get the correct behaviour by adding a space to the *... output*
buffer in the appropriate spot before running TeX-next-error
(this isn't possible using your C-0
since it calls TeX-next-error
automatically, but can be done when running "manually" via C-c C-c latexmk RET C-c C-l
).
However, since I doubt this example is your actual problem you will need to find out what it actually is.
For me one common problem was AUCTeX incorrectly pasting together "overfull box" lines. You can read the the email where I figured this out as well as a fix (which is in the latest AUCTeX from CVS, but not in the latest release 11.86).
I recently had the same problem and decided to dig into it again. This time it was because of a line
Package hyperref Message: Driver (autodetected): hpdftex.
in which it didn't recognize (autodetected
as a file, but it did think that the )
marked the end of a file. Anyway, I overwrote TeX-parse-error
to colorize the output buffer which helped greatly in tracking it down. How to fix it will of course depend on what the problem is.
Below is what I used to colorize the output. Just evaluate the function definition and then run LaTeX as normal.
(defun TeX-parse-error (old)
"Goto next error. Pop to OLD buffer if no more errors are found."
(let ((regexp
(concat
;; TeX error
"^\\(!\\|\\(.*?\\):[0-9]+:\\) \\|"
;; New file
"(\\(\"[^\"]*?\"\\|/*\
\\(?:\\.+[^()\r\n{} \\/]*\\|[^()\r\n{} .\\/]+\
\\(?: [^()\r\n{} .\\/]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)\
\\(?:[\\/]+\\(?:\\.+[^()\r\n{} \\/]*\\|[^()\r\n{} .\\/]+\
\\(?: [^()\r\n{} .\\/]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)?\\)*\\)\
)*\\(?: \\|\r?$\\)\\|"
;; End of file
"\\()\\))*\\|"
;; Hook to change line numbers
" !\\(?:offset(\\([---0-9]+\\))\\|"
;; Hook to change file name
"name(\\([^)]+\\))\\)\\|"
;; LaTeX bad box
"^\\(\\(?:Overfull\\|Underfull\\|Tight\\|Loose\\)\
\\\\.*?[0-9]+--[0-9]+\\)\\|"
;; LaTeX warning
"^\\(LaTeX [A-Za-z]*\\|Package [A-Za-z]+ \\)Warning:.*")))
(while
(cond
((null
(re-search-forward regexp nil t))
;; No more errors.
(message "No more errors.")
(beep)
(TeX-pop-to-buffer old)
nil)
;; TeX error
((match-beginning 1)
(when (match-beginning 2)
(unless TeX-error-file
(push nil TeX-error-file)
(push nil TeX-error-offset))
(unless (car TeX-error-offset)
(rplaca TeX-error-file (TeX-match-buffer 2))))
(if (looking-at "Preview ")
t
(TeX-error)
nil))
;; LaTeX bad box
((match-beginning 7)
(if TeX-debug-bad-boxes
(progn
(TeX-warning (TeX-match-buffer 7))
nil)
(re-search-forward "\r?\n\
\\(?:.\\{79\\}\r?\n\
\\)*.*\r?$")
t))
;; LaTeX warning
((match-beginning 8)
(if TeX-debug-warnings
(progn
(TeX-warning (TeX-match-buffer 8))
nil)
t))
;; New file -- Push on stack
((match-beginning 3)
(overlay-put
(make-overlay (match-beginning 3) (match-end 3))
'face 'font-lock-type-face)
(let ((file (TeX-match-buffer 3))
(end (match-end 3)))
;; Strip quotation marks and remove newlines if necessary
(when (or (eq (string-to-char file) ?\")
(string-match "\n" file))
(setq file
(mapconcat 'identity (split-string file "[\"\n]+") "")))
(push file TeX-error-file)
(push nil TeX-error-offset)
(goto-char end))
t)
;; End of file -- Pop from stack
((match-beginning 4)
(overlay-put
(make-overlay (match-beginning 4) (match-end 4))
'face 'font-lock-warning-face)
(when (> (length TeX-error-file) 1)
(pop TeX-error-file)
(pop TeX-error-offset))
(goto-char (match-end 4))
t)
;; Hook to change line numbers
((match-beginning 5)
(setq TeX-error-offset
(list (string-to-number (TeX-match-buffer 5))))
t)
;; Hook to change file name
((match-beginning 6)
(setq TeX-error-file
(list (TeX-match-buffer 6)))
t)))))
EDIT:
As for you second example, that's a tough one because like TeX reads to the end of the file and closes it before it gives the error. So technically when the error comes you aren't in any file, but that's just only because TeX doesn't understand where the real error occured.
Anyway, here is an exceedingly dirty way to work around the problem. What it does is attempts to reconstruct what file should be the "default" based on the name of the output buffer *file-name output*
. This is simply masking the problem, but will probably work at least 80% of the time if your documents consist of a single file. When it doesn't work it will be confusing--perhaps even more than now. :-)
(defadvice TeX-parse-reset (after make-master-file-default () activate)
(push (concat (substring (buffer-name) 1 (- (length (buffer-name)) 8)) "." TeX-default-extension) TeX-error-file)
(push nil TeX-error-offset))