我一直在尝试使用 shell escape 和 tikz externalize(例如参见这里),但我有两个问题:
- 当 tikz 图片因某些错误而失败时,如果编译是在图片的先前版本上进行的,则编译不会停止(相反,编译的最后一张图片将永远使用)。这非常烦人,因为我可能认为已经应用了更改……但实际上并非如此。
- 这些错误毫无帮助:如果图片在第一次编译时编译失败,我只会看到一个一般错误
l.13 \end{tikzpicture}
,否则如上所述,它甚至不会停止编译,而只会打印system returned with code 256
。与没有外部化时获得的错误进行比较:! Package pgf Error: No shape named
C' 是已知的。
有没有什么解决办法:
- 总是停止如果 shell 转义失败,则进行编译
- 显示有意义的错误
平均能量损失
编译以pdflatex -shell-escape file.tex
查看问题 2。要查看错误 1,请注释最后一行,进行编译,取消注释最后一行,然后重新编译。
\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}
编辑(问题 2 已解决,问题 1 仍然存在)
感谢 David Carlisle,我意识到问题 2 可以通过查看.log
错误消息中给出的文件(这有点长)或直接转到下一个错误(使用“Enter”,或者在 emacs 中使用已启用 shell-escape,可以使用C-c backtick
)。Ulrike Fischer 还建议删除命令batchmode
中的/tikz/external/system call
。事实上,如果我使用:
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error -jobname "\image" "\texsource"}}
错误现在直接写入控制台,谢谢!所以问题 2 解决了!
但是,这些答案都不能解决问题 1:即使删除了批处理模式,它们仍然会生成有效的 pdf:(Output written on file.pdf
第一次编译时出现错误,错误现在写入日志中,但如果不阅读整个日志可能很难看到。此外,它在第二次编译后就消失了):
以下是完整记录:
$ 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.
如您所见,当发生错误时,它会在日志中显示错误,但不会停止编译(此错误在大型文档中可能很难看到,或者如果您直接从 emacs 编译,只会显示“未发生错误”)。更糟糕的是,如果您编译两次,则错误会从日志文件中完全消失,而是显示过时的图片!这真的很烦人,因为人们可能会认为拼写错误已得到修复,但实际上并非如此。
编辑
按照评论中的建议删除后-halt-on-error
,第一次编译时会失败(如预期的那样)。但如果我再次重新编译,它只会说,===== Image 'file-figure0' is up-to-date. ======
而我预计它会再次失败。我猜 tikz 会更新 md5,而不管编译是否成功...我不确定是否有解决方法,或者这是否是一个错误。
答案1
因此我将把讨论放在这里的评论中(感谢 David 和 Ulrike):
基本上,显示的错误是“在文件中查找FILE-figureX.log
错误”。一种解决方案是读取该文件,或按“Enter”转到下一个错误:下一个错误实际上是编译错误。如果您使用 emacs,请确保在文件中添加:
% Local Variables:
% TeX-command-extra-options: "-shell-escape"
% End:
启用 shell-escape,使用 重新加载M-x revert-buffer
,并在编译后使用快捷方式C-c backtick
转到下一个错误。
第三种解决方案(我更喜欢这个解决方案,因为第一次编译失败时它也会失败)是添加:
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -jobname "\image" "\texsource"}}
这将直接在屏幕上显示错误。
不幸的是,这些解决方案都不能完全解决问题 1。这是我报告的 tikz 问题这里。