0

I have a huge document with lots of figures. For plots, I use matlab and convert the plot to tikz using matlab2tikz (and do some modifications afterwards), for most other figures, I prefer Inkscape and its pdf_tex export. For both, tikz and Inkscape I like to have the figures automatically regenerated if something did change within the figure. I have two custom commands for that, \includetikz and \includesvg. Everything worked really well until I had to change from pdflatex to lualatex for the tikz-figures. I have some plots where I cannot reduce the data any further and I did not manage to typeset these figures with pdflatex (also with increased memory settings). With lualatex this worked quite well. The problem now is, the \includetikz command with lualatex somehow interferes with my \includesvg command.

I have the following 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}

Unfortunately, the Inkscape-command contains it absolute path, so you might want to change it. the code for plot2.tikz is the following:

\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}%

the file inkscape1.svg can be any svg, vor example: https://de.wikipedia.org/wiki/LaTeX#/media/File:LaTeX_logo.svg

my problem now: If I run the code as it is, everything works fine. The svg is commented out and the resulting pdf only contains the plot. Afterwards, removing the comment of the \includesvg-command again everything works fine. The pdf_tex is generated and in the pdf there are both figures. However, if I do some changes in the tikz-file, such that the figure has to be regenerated, lualatex fails.

The logfiles are not of any help for me. In the logfile for the main document, the error part is the following:

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.

in the last lines of the logfile for plot2 are:

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!

what I find is interesting is, that lualatex somehow sees the inkscape-stuff, which I don't understand.

I uploaded the full logfiles here, if they are on any help: http://www.uni-ulm.de/~pqa62/tex/

does anybody have an idea and know how to fix this behaviour? I really liked the way how I did the externalization and automatic rebuild, especially since in the full realization of my include commands some more advanced stuff is covered and also since everything worked until I had to switch to lualatex.

edit:

I did some more tests and I found out, the custom command \executeiffilenewer is apparently the the problem, why the error occures. Somehow, lualatex (which is supposed to typeset the tikz-plot only) looks into the following \includesvg command as well and tries to execute it. Here, it does not know this custom command because it is not defined within its call. If I modify the \includesvg command like this:

\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}%
}

I don't get an error anymore. The problem is, it always executes Inkscape. And still, I don't understand why lualatex does not stop after the tikz-plot is done.

  • I forgot to mention, to get the externalization run with lualatex in the first place, I had to generate the file pgfsys-luatex.def according to here: sourceforge.net/p/pgf/bugs/384/#de31 – bene Jan 29 '17 at 22:29
  • I'm having problems getting your MWE to run, so here's a guess: try \usepackage{shellesc}, this fixes some problem in luatex handling external files or something like that (i forgot the exact reason, but i need it in order to get tikz-externalize work with lualatex). Considering your MWE: i suggest you strip down it further. This a) makes it easier for us to try it out (currently i have to set up extra directories, somehow using hidden directories introduces problems) and b) could help you on finding the error. Get rid of the fancy stuff, boil it down to the essentials! – pschulz Feb 1 '17 at 8:43
  • I stripped down your MWE and got \pdfstrcmp undefined. This is also in your logfiles, so this is your issue, currently at least. What is this command? I don't know it, maybe it's not in lualatex? – pschulz Feb 1 '17 at 8:57
  • I did try to strip down my MWE (my original commands for the inclusion of tikz/svg are a lot bigger), but I did not want to remove the file handling into subfolders. This is one essential thing for me. Regarding the \pdfstrcmp, I use this command inside my custom \executeiffilenewer for a string comparison. Apparently it was introduced in pdflatex 1.30.0 : tug.org/pipermail/pdftex/2005-August/005913.html – bene Feb 1 '17 at 12:01
  • Yep, i misread your question. I thought you changed you main engine to lualatex, too. – pschulz Feb 1 '17 at 12:32
1
+50

If you change -interaction=batchmode to -interaction=scrollmode and add some errors or \show commands to your document you can see that the luatex run compiles the whole tex file. And it expands commands during this -- it is able to find the picture inside \includetikz, so naturally it also has to look inside \includesvg. This means that commands not known to luatex can lead to problems.

\pdfstrcmp is not defined in luatex. You can load the pdftexcmds package to get an implementation https://tex.stackexchange.com/a/158612/2388. Attention: I didn't check if pdftexcmds has been adapted to luatex 0.95/1.0, but in my stripped down example it seemed to work.

\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}
  • That's interessting. I thought that for the externalization in tikz, for each figure it is basically a new run of pdflatex only for the part between \begin{tikzpicture} and \end{tikzpicture}. If I understand it correctly, what you are saying is that with the externalization using lualatex, lualatex runs throug the whole code again and strips the individual figures. Is that right? – bene Feb 1 '17 at 12:06
  • Your MWE does work when I use it. However, if I try to insert it in to the bigger example of my question it does not. Somehow the compilation does not end. But based on your response, I found a workaround which does what I want. I wrap the definition of my custom \includesvg command in \ifluatex\else ... \fi. I don't know is it's the best idea but it works for me. – bene Feb 1 '17 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.