使用 \tikzsetnextfilename 时崩溃?

使用 \tikzsetnextfilename 时崩溃?

我刚刚偶然发现了这一点,因此我将以问答形式发布此信息:

我决定尝试 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} % 

最后,这似乎停止了名称的递归,以及外部化调用结束时的崩溃 - 并根据要求创建所有文件。

相关内容