3

I am using the following function to run latexmk on my latex-file in emacs:

(defun my-run-latex ()
  (interactive)
  (if (buffer-modified-p)
      (progn  
        (setq TeX-save-query nil) 
        (TeX-save-document (TeX-master-file))
        (TeX-command "Latexmk" 'TeX-master-file -1))
    (TeX-view)))

(Taken from https://stackoverflow.com/a/14699078/406686).

Suppose I have a simple document (test.tex) with some errors in it like:

\documentclass{article}

\begin{document}
\error1
\error2
\end{document}

Now if I press for example Space and then Backspace (or doing any change and undo it) and then run my-run-latex latexmk runs and says that all targets are up to date. The problem is that then I loose the error list, so TeX-next-error will not have any effect.

I guess the problem could be solved by replacing (buffer-modified-p) by something which prevents to run latexmk in this case (best by the same test latexmk does to check if the file changed since the last run). Any idea how to do this?

Community
  • 1
  • 1
student
  • 1,636
  • 3
  • 29
  • 53
  • I use [this](http://lists.gnu.org/archive/html/auctex/2012-10/msg00031.html) to run `latexmk` on a file, whit this `TeX-next-error` will work as expected. – giordano Aug 09 '13 at 07:09
  • Can you just make a tex file with some errors, run latexmk and then run it again without changing anything. What output do you get after the second run and does jump do next error work **after** the second run? – student Aug 09 '13 at 08:33
  • Ah, ok, now I understand. To force `latexmk` to process a document you should add the `-g` option, see the [manual](http://users.phys.psu.edu/~collins/software/latexmk-jcc/latexmk-437.txt). – giordano Aug 09 '13 at 09:35
  • @giordano Thanks, I know that. However I don't think to force latexmk to compile if nothing changed. It would be better to replace the (buffer-modified-p) check in my script by something better or find an other way to keep the error log alive... – student Aug 09 '13 at 10:17
  • You could computed the [hash](http://www.gnu.org/software/emacs/manual/html_node/elisp/Checksum_002fHash.html) of the current buffer and compare to the previously computed hash, if it's changed then run `latexmk`, do nothing otherwise. – giordano Aug 09 '13 at 10:40

1 Answers1

1

latexmk uses hashing to determine whether a file was changed. The hash algorithm used is md5, it isn't completely secure but this isn't really important in this respect. So you can use a hash-based test instead of (buffer-modified-p). The following code should work:

(setq current-buffer-hash nil)
(make-variable-buffer-local 'current-buffer-hash)
(defun my-run-latex ()
  (interactive)
  (if (equal current-buffer-hash
         (setq current-buffer-hash (secure-hash 'md5 (current-buffer))))
      (TeX-view)
    (setq TeX-save-query nil)
    (TeX-save-document (TeX-master-file))
    (TeX-command "Latexmk" 'TeX-master-file -1)))

As pointed out by @student, the function secure-hash was introduced in Emacs 24.2. For previous versions one can use (md5 (current-buffer)).

giordano
  • 8,087
  • 3
  • 23
  • 48
  • Thanks. But it seems not to work. Does it work on your system? I guess that the order of `(TeX-view)` and `(progn ...)` should be swapped since `(TeX-view)` should be executed if the hashes are the same i.e. if nothing changed... However doing this also didn't work. Then I just replaced `(TeX-view)` and `(progn ...)` with two message calls which also didn`t work. Perhaps you see where the error is and can fix it... – student Aug 12 '13 at 18:45
  • About the order of the then and else branches you are right: if the hashes are equal then run `TeX-view`, else execute `latexmk`. The problem was `eq`, just replace with `equal`. Now it should really work. – giordano Aug 12 '13 at 19:23
  • 1
    For future readers: This works very well for emacs24 but the function `secure-hash` seems to be pretty new. For older versions using `(md5 (current-buffer))` instead of `(secure-hash 'md5 (current-buffer))` seems to work. – student Sep 08 '13 at 13:07