экстернализация tikz с использованием lualatex в сочетании с автоматическим импортом inkscape

экстернализация tikz с использованием lualatex в сочетании с автоматическим импортом inkscape

У меня есть огромный документ с большим количеством фигур. Для графиков я использую Matlab и конвертирую график в Tikz с помощью Matlab2tikz (и делаю некоторые изменения впоследствии), для большинства других фигур я предпочитаю Inkscape и его экспорт в pdf_tex. Для обоих, Tikz и Inkscape, мне нравится, чтобы фигуры автоматически регенерировались, если что-то изменилось в фигуре. У меня есть две пользовательские команды для этого, \includetikz и \includesvg. Все работало очень хорошо, пока мне не пришлось перейти с pdflatex на lualatex для фигур tikz. У меня есть некоторые графики, где я не могу больше уменьшать данные, и мне не удалось набрать эти фигуры с помощью pdflatex (также с увеличенными настройками памяти). С lualatex это работало довольно хорошо. Проблема теперь в том, что команда \includetikz с lualatex каким-то образом мешает моей команде \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-Stuff, чего я не понимаю.

Я загрузил сюда полные файлы журналов, если они вам помогут:http://www.uni-ulm.de/~pqa62/tex/

есть ли у кого-нибудь идея и знает, как исправить это поведение? Мне очень понравилось, как я сделал экстернализацию и автоматическую пересборку, особенно потому, что в полной реализации моих команд include охвачены некоторые более продвинутые вещи, а также потому, что все работало, пока мне не пришлось переключиться на 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}

Связанный контент