我有一份包含大量图表的大型文档。对于图表,我使用 matlab,然后使用 matlab2tikz 将图表转换为 tikz(之后进行一些修改),对于大多数其他图表,我更喜欢 Inkscape 及其 pdf_tex 导出。对于 tikz 和 Inkscape,如果图表中确实发生了变化,我都希望自动重新生成图表。我有两个自定义命令,\includetikz 和 \includesvg。一切都运行良好,直到我不得不将 tikz 图表从 pdflatex 更改为 lualatex。我有一些图表,我无法进一步减少数据,而且我无法使用 pdflatex 排版这些图表(也增加了内存设置)。使用 lualatex 效果很好。现在的问题是,lualatex 的 \includetikz 命令会以某种方式干扰我的 \includesvg 命令。
我有以下 MWE:
\documentclass[11pt,a4paper,english]{scrbook}
\usepackage{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\RequirePackage{luatex85}
% inkscape
\usepackage{import}
\newcommand{\executeiffilenewer}[3]{%
\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
{\pdffilemoddate{#2}}>0%
{#3}\fi%
}
\newcommand{\includesvg}[2]{%
\immediate\write18{if not exist #1.svg_external/ (mkdir "#1.svg_external/")}%
\executeiffilenewer{#1#2.svg}{#1.svg_external/#2.pdf}{%
\immediate\write18{"C:/Program Files (x86)/Inkscape/inkscape.exe" -z -C --file=#1#2.svg --export-pdf=#1.svg_external/#2.pdf --export-latex}}%
\import{#1.svg_external/}{#2.pdf_tex}%
}
\usepackage{filemod}
\newlength{\figheight}
\newlength{\figwidth}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{pgfplots}
\usepgfplotslibrary{external}
\pgfplotsset{compat=1.14}
\tikzexternalize % activate externalization
\tikzset{external/system call={lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"}}
\tikzset{external/figure list=true}
\tikzset{external/up to date check=simple}
\newcommand{\tikzcustomremake}[2]{\tikzset{external/remake next}}
\newcommand{\includetikz}[2]{%
\tikzsetnextfilename{#1.tikz_external/#2}%
\filemodCmp{#1#2.tikz}{#1.tikz_external/#2.pdf}%
{\tikzcustomremake{#1}{#2}}{}%
\input{#1#2.tikz}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\figwidth=5cm
\figheight=5cm
\includetikz{fig/ch1/}{plot2}
%\footnotesize\includesvg{fig/ch1/}{inkscape1}
\end{document}
不幸的是,Inkscape 命令包含它的绝对路径,因此您可能需要更改它。plot2.tikz 的代码如下:
\begin{tikzpicture}
\begin{axis}[%
width=\figwidth,
height=\figheight,
xmin=0,xmax=10,
xlabel=\pgfactualjobname,
ymin=-1,ymax=5,
axis background/.style={fill=white}
]
\addplot [color=red,solid,forget plot]
table[row sep=crcr]{%
0 0\\
10 1\\
};
\end{axis}
\end{tikzpicture}%
文件 inkscape1.svg 可以是任何 svg,例如:https://de.wikipedia.org/wiki/LaTeX#/media/File:LaTeX_logo.svg
我现在的问题是:如果我按原样运行代码,一切都会正常工作。svg 被注释掉,生成的 pdf 仅包含图。之后,再次删除 \includesvg 命令的注释,一切正常。生成了 pdf_tex,pdf 中有两个图。但是,如果我在 tikz 文件中进行一些更改,例如必须重新生成图,lualatex 就会失败。
日志文件对我没有任何帮助。在主文档的日志文件中,错误部分如下:
Writing 'fig/ch1/.tikz_external/plot2' to 'diss01lua.figlist'.
\openout3 = `diss01lua.auxlock'.
===== 'mode=convert with system call': Invoking 'lualatex -shell-escape -halt-o
n-error -interaction=batchmode -jobname "fig/ch1/.tikz_external/plot2" "\def\ti
kzexternalrealjob{diss01lua}\input{diss01lua}"' ========
runsystem(lualatex -shell-escape -halt-on-error -interaction=batchmode -jobname
"fig/ch1/.tikz_external/plot2" "\def\tikzexternalrealjob{diss01lua}\input{diss
01lua}")...executed.
\openout3 = `diss01lua.auxlock'.
! Package tikz Error: Sorry, the system call 'lualatex -shell-escape -halt-on-e
rror -interaction=batchmode -jobname "fig/ch1/.tikz_external/plot2" "\def\tikze
xternalrealjob{diss01lua}\input{diss01lua}"' did NOT result in a usable output
file 'fig/ch1/.tikz_external/plot2' (expected one of .pdf:.jpg:.jpeg:.png:). Pl
ease verify that you have enabled system calls. For pdflatex, this is 'pdflatex
-shell-escape'. Sometimes it is also named 'write 18' or something like that.
Or maybe the command simply failed? Error messages can be found in 'fig/ch1/.ti
kz_external/plot2.log'. If you continue now, I'll try to typeset the picture.
See the tikz package documentation for explanation.
Type H <return> for immediate help.
...
l.16 \end{tikzpicture}
%
This error message was generated by an \errmessage
command, so I can't give any explicit help.
Pretend that you're Hercule Poirot: Examine all clues,
and deduce the truth by order and method.
plot2 日志文件的最后几行是:
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <10.95> on input line 15.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <8> on input line 15.
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <6> on input line 15.
[1
{C:/ProgramData/MiKTeX/2.9/pdftex/config/pdftex.map}])
if not exist fig/ch1/.svg_external/ (mkdir "fig/ch1/.svg_external/")
! Undefined control sequence.
\executeiffilenewer #1#2#3->\ifnum \pdfstrcmp
{\pdffilemoddate {#1}}{\pdffil...
l.51 \footnotesize\includesvg{fig/ch1/}{inkscape1}
Here is how much of LuaTeX's memory you used:
25909 strings out of 494568
100000,953878 words of node,token memory allocated
1158 words of node memory still in use:
4 hlist, 1 rule, 7 disc, 1 local_par, 1 dir, 23 glue, 4 kern, 2 penalty, 85 g
lyph, 7 attribute, 47 glue_spec, 7 attribute_list, 1 if_stack nodes
avail lists: 2:739,3:212,4:5,5:13,7:182,8:2,9:78,10:1
29028 multiletter control sequences out of 65536+200000
27 fonts using 1573183 bytes
65i,11n,111p,8876b,1869s stack positions out of 5000i,500n,10000p,200000b,50000s
! ==> Fatal error occurred, no output PDF file produced!
我发现有趣的是,lualatex 以某种方式看到了 inkscape 的东西,我不明白。
我在这里上传了完整的日志文件,希望它们有帮助:http://www.uni-ulm.de/~pqa62/tex/
有人知道该如何修复此行为吗?我真的很喜欢我进行外部化和自动重建的方式,尤其是因为在我的包含命令的完整实现中涵盖了一些更高级的内容,而且在我不得不切换到 lualatex 之前一切都正常。
编辑:
我做了更多测试,发现自定义命令\executeiffilenewer
显然是问题所在,这也是错误发生的原因。不知何故,lualatex(它应该只排版 tikz-plot)也会查看以下\includesvg
命令并尝试执行它。在这里,它不知道这个自定义命令,因为它没有在其调用中定义。如果我\includesvg
像这样修改命令:
\newcommand{\includesvg}[2]{%
\immediate\write18{"C:/Program Files (x86)/Inkscape/inkscape.exe" -z -C --file=#1#2.svg --export-pdf=#1.svg_external/#2.pdf --export-latex}%
\import{#1.svg_external/}{#2.pdf_tex}%
}
我不再收到错误。问题是,它总是执行 Inkscape。而且,我仍然不明白为什么 lualatex 在 tikz-plot 完成后不停止。
答案1
如果您更改-interaction=batchmode
为并向文档-interaction=scrollmode
添加一些错误或\show
命令,则可以看到 luatex 运行编译了整个 tex 文件。并且它在此过程中扩展了命令 - 它能够在 \includetikz 中找到图片,因此自然也必须在 \includesvg 中查找。这意味着 luatex 不知道的命令可能会导致问题。
\pdfstrcmp
在 luatex 中没有定义。您可以加载 pdftexcmds 包来获取实现https://tex.stackexchange.com/a/158612/2388。注意:我没有检查 pdftexcmds 是否已经适应 luatex 0.95/1.0,但在我的精简示例中它似乎可以工作。
\documentclass[11pt,a4paper,english]{scrbook}
\usepackage{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{ifluatex}
\ifluatex
\RequirePackage{luatex85}
\usepackage{pdftexcmds}
\makeatletter
\let\pdfstrcmp\pdf@strcmp
\let\pdffilemoddate\pdf@filemoddate
\makeatother
\fi
\newcommand{\includesvg}{\pdfstrcmp{1}{2}}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize % activate externalization
\tikzset{external/system call={lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"}}
\tikzset{external/force remake}
\newcommand{\includetikz}{%
\begin{tikzpicture}
\draw[red](0,0)--(1,1);
\end{tikzpicture}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
blub
\includesvg
\includetikz
\end{document}