我刚刚偶然发现了这一点,因此我将以问答形式发布此信息:
我决定尝试 tikz-external,而我所拥有的只是序言中的这些:
\usetikzlibrary{external}
\tikzexternalize[prefix=img/] %activate
... 我运行的初始测试没有问题。但是,我不喜欢test-figure0
包给出的默认名称;我想对图像使用类似这样的名称:
\tikzsetnextfilename{\jobname-mypic}
但是,当我输入这些后,LaTeX 就开始生成文件,最后崩溃了?我甚至觉得第二次运行好像提前结束了——但是,通过 write18 对外部调用命令的定时响应:是否阻塞?确认 shell 转义调用应该被阻塞(因此它应该等到产生的对 latex 的“外部化”调用完成,无论成功与否)。
因此我进行了一些调试,通过更改 shell 命令中的某些内容(通过删除batchmode
和添加一些睡眠来增加详细程度):
\tikzset{external/system call={pdflatex \tikzexternalcheckshellescape -halt-on-error
% -interaction=batchmode -jobname "\image" "\texsource"} % default; batchmode=quiet!
-jobname "\image" "\texsource" ; echo "After pdflatex!" ; sleep 2 ; echo "After sleep!"},
external/optimize=false, % because of https://tex.stackexchange.com/questions/170291/tikz-wont-let-me-externalize-and-halts-on-error/172017#172017
}
...最终会产生如下日志:
...
(./img/mypic.tikz
% ... runs here...
% (then this - from img/test-mypic.log):
! Package tikz Error: Sorry, image externalization failed: the resulting image
was EMPTY. I tried to externalize 'img/test-mypic', but it seems there is no such image in the document!?
l.526 \end{document}
! ==> Fatal error occurred, no output PDF file produced!
Transcript written on img/test-mypic.log.
After pdflatex!
After sleep!
% (then this from test.log):
! Package tikz Error: Sorry, the system call ... did NOT result in a usable output file ...
...
...这意味着特别是对 pdflatex 的“内部”外部化调用失败了 - 但是该文件中根本没有明显的错误?(并且同一个文件在没有自定义名称的情况下也可以很好地外部化)。
那么可能存在什么问题呢?
答案1
该\jobname
命令始终包含当前编译步骤作业名称。因此,您的代码将向下递归并发生更改,\jobname
而这并不是您想要的。
该external
库提供了以下命令:
\tikzexternalrealjob
这正是你想要的(主 TeX 文件作业名)。所以你想要的是:
\tikzsetnextfilename{\tikzexternalrealjob-mypic}
而且它应该可以正常工作。
答案2
问题确实是这样的:
\tikzsetnextfilename{\jobname-mypic}
... 或者更确切地说,使用\jobname
那里...通过把这个:
\edef\tmsg{IZCK tikzexternal@getnextfilename: pgf@tempa '\pgf@tempa', }%
\typeout{\tmsg} %
\def\tikzexternal@getnextfilename
在的末尾texlive/2011/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex
;我可以在日志中看到这一点:
$ grep -r IZCK .
...
./test.log:IZCK tikzexternal@getnextfilename: pgf@tempa 'img/test-mypic',
./img/test-mypic.log:IZCK tikzexternal@getnextfilename: pgf@tempa 'img/img/test-mypic-mypic',
显然,问题在于第二次外部化调用中,\jobname
被外部化库修改,因此变化递归到\tikzsetnextfilename
。
所以,我想也许我可以使用主文件名来代替\jobname
- 但事实证明这并不简单:如果使用 -jobname 调用 pdflatex,则宏将检索源文件的真实名称
最后,我决定创建一个辅助文件mjob.id
,在第一次运行时,我将主文件存储\jobname
为\mjobname
。随后的递归调用将从\mjobname
文件中读取此名称;并将其应用于\tikzsetnextfilename
:
\IfFileExists{mjob.id}{%true-branch
}{%false-branch
% NB: \immediate goes everywhere!
\newwrite\mjobfile
\immediate\openout\mjobfile=mjob.id
\immediate\write\mjobfile{\noexpand\gdef\noexpand\mjobname{\jobname}}
\immediate\closeout\mjobfile
}
\input{mjob.id}
...
\tikzsetnextfilename{\mjobname-mypic} %
最后,这似乎停止了名称的递归,以及外部化调用结束时的崩溃 - 并根据要求创建所有文件。