I've been trying to use shell escape and tikz externalize (see for instance here), but I have two issues:
- when the tikz picture fails with some errors, the compilation does not stops if it compiled on a previous version of the picture (instead the last picture that compile will be used forever). This is very annoying as I may think that a change was applied... while in fact it is not.
- the errors are highly non-helpful: if the picture fails to compile at the first compilation, I see only a generic error
l.13 \end{tikzpicture}, otherwise as explained above it does not even stop the compilation and only printssystem returned with code 256. Compare with the error obtained without externalization:! Package pgf Error: No shape namedC' is known.`
Is there any solution to:
- always stop compilation if a shell escape fails
- displays a meaningful error
MWE
Compile with pdflatex -shell-escape file.tex to see the problem 2. To see error 1, comment the last line, compile, uncomment the last line, and recompile.
\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\begin{document}
\begin{tikzpicture}
\node (A) {A};
\node (B) at (1,1) {B};
%% If you want to see problem 1, you can compile once with this line first, then comment it back.
% \node (C) at (1,0) {C};
%% otherwise, this line should produce an error
\draw (A) -- (C);
\end{tikzpicture}
\end{document}
EDIT (problem 2 solved, problem 1 remains)
Thanks to David Carlisle, I realized that the issue 2 can be solved by either looking at the .log file given above in the error message (it's a bit long to do), or just go to the next error (with "Enter", or in emacs with shell-escape enabled, it can be done using C-c backtick). Ulrike Fischer also proposed to remove the batchmode in the /tikz/external/system call command. And indeed, if I use:
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -jobname "\image" "\texsource"}}
the error is now written directly to the console, thanks! So problem 2 is solved!
However, none of these answers solve the issue 1: even after removing the batchmode, they still produce a valid pdf: Output written on file.pdf (the error is now written in the log the first time it is compiled with an error, but may be hard to see without reading the whole log. Moreover, it disappears after the second compilation):
Here is a whole transcript:
$ cat file.tex
\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -jobname "\image" "\texsource"}}
\begin{document}
\begin{tikzpicture}
\node (A) {A};
\node (B) at (1,1) {D};
%% If you want to see problem 1, you can compile once with this line first, then comment it back.
\node (C) at (1,0) {C};
%% otherwise, this line should produce an error
\draw (A) -- (C);
\end{tikzpicture}
\end{document}
$ pdflatex -shell-escape file.tex
[...]
Output written on file-figure0.pdf (1 page, 9822 bytes).
[...]
Output written on file.pdf (1 page, 10695 bytes).
Transcript written on file.log.
$ cat file.tex ## see the commented line
\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -jobname "\image" "\texsource"}}
\begin{document}
\begin{tikzpicture}
\node (A) {A};
\node (B) at (1,1) {D};
%% If you want to see problem 1, you can compile once with this line first, then comment it back.
%\node (C) at (1,0) {C};
%% otherwise, this line should produce an error
\draw (A) -- (C);
\end{tikzpicture}
\end{document}
$ pdflatex -shell-escape file.tex
[...]
! Package pgf Error: No shape named `C' is known.
[...]
system returned with code 256
[...]
Output written on file.pdf (1 page, 10695 bytes).
Transcript written on file.log.
^__ See that even if the file contains an error, it does compile until the end. One needs to carefully inspect the log to see that an error occured. And even worse, if we compile a second time, it compiles fine without any error! See:
$ pdflatex -shell-escape file.tex
[...]
===== Image 'file-figure0' is up-to-date. ======
[...]
Output written on file.pdf (1 page, 10695 bytes).
Transcript written on file.log.
as you can see, when an error occurs, it displays an error in the log but does not stop the compilation (this error can be hard to see in large documents, or if you compile from emacs directly that will just say "no errors occured"). Even worse, if you compile twice, then the error is completely gone from the log file, and the outdated picture is showed instead! This is really annoying as one may think that the typo is fixed while in fact it is not.
EDIT
After removing -halt-on-error as suggested in comments, it fails (as expected) the first time I compile. But if I recompile another time, it just says ===== Image 'file-figure0' is up-to-date. ====== while I would expect it to fail again. I guess that tikz updates the md5 irrespective of the success of the compilation... I'm not sure if there is a workaround or if it is a bug.
(C)is not defined. – daleif Feb 08 '22 at 10:12Cbeing not defined. If I compile with externalize, the error is useless or not even blocking the compilation. My question is therefore "how to display a meaningful error and/or block the compilation in case of an error" – tobiasBora Feb 08 '22 at 10:18just get a generic error l.13 \end{tikzpicture" but that is the last line of a multi-line error message. If I run the posted code without shell-escape I get this multi-line error message – David Carlisle Feb 08 '22 at 10:34(C)is not defined? So far, it just says "the compilation failed, not sure why, maybe you forgot-shell-escape?" Also, this error will not even appear if you compile once without any error and add the error on a second compilation. – tobiasBora Feb 08 '22 at 10:36bb912-figure0and if I look inbb912-figure0.logit says! Package pgf Error: No shape named \C' is known.` which seems clear enough. – David Carlisle Feb 08 '22 at 10:39bb912-figure0.log, thanks for pointing that. Maybe it's an indication that it would be clearer to write this log file directly on the output directly? ^^ And indeed, if I press "Enter" the error appears (thanks for pointing that, usually I quit right after the first error), in emacs I can typeC-c backtickto go to the next errors and it seems to work. Thanks! But the issue 1 is still there, is there any method to solve this one? – tobiasBora Feb 08 '22 at 10:47/tikz/external/system call, – Ulrike Fischer Feb 08 '22 at 10:52-halt-on-error. – Ulrike Fischer Feb 08 '22 at 11:42.md5before checking if the compilation succeeds or not, so even if it fails it thinks that it worked... – tobiasBora Feb 08 '22 at 11:53