У меня возник вопрос, очень похожий на этот пост (\includegraphics{\input{|команда оболочки}}), на который, к сожалению, так и не было дано реального ответа.
Цель состоит в том, чтобы создать команду, которая вызывает скрипт python для создания графика, который затем вставляется в LaTeX. То, что я пробовал до сих пор, это следующее:
main.tex:
\newcommand\pytexplot[1]{
\immediate\write18{python pytexplot.py #1}
\input{shellout}
}
\begin{document}
\includegraphic{\pytexplot{plot1}}
\includegraphic{\pytexplot{plot2}}
\end{document}
pytexplot.py — это скрипт Python, который создает различные графики в зависимости от предоставленного параметра и сохраняет файл shellout.tex, содержащий имя и местоположение изображения сгенерированного графика.
Сообщаемая таким образом ошибка представляет собой неопределенную управляющую последовательность (всего более 100), поэтому, боюсь, это не поможет.
Пока что я решил, что это связано с макрорасширениями, и пробовал вставлять их \expandafter
в разные позиции, но безрезультатно.
EDIT: второе предложение Wipet, похоже, работает, но оно включает один и тот же сюжет дважды. Кроме того, я не знаю, как объединить его с командой оболочки
Может ли кто-нибудь мне помочь в этом вопросе?
решение1
Если файл shellout.tex
содержит только одну строку с именем сгенерированного файла, то
\usepackage{catchfile}
\newcommand{\includeplot}[2][]{%
\immediate\write18{python pytexplot.py #2}%
\CatchFileDef\plotpath{shellout.tex}{\endlinechar=-1 }%
\includegraphics[#1]{\plotpath}%
}
в преамбуле, с
\includeplot{plot1}
в документе или
\includeplot[<options for \includegraphics>]{plot1}
должен сделать то, что вам нужно.
решение2
Если у вас есть команда оболочки, которая создает plot1
файл shellout.tex
, то вы можете просто изменить эту команду оболочки, чтобы она создавала
\includegraphics{plot1}
вместо простого plot1
в shelloupt.tex
файле. И вы можете просто использовать
\input shellout
Но если вы настаиваете на идее, что ваша команда оболочки создает только plot1
ваш shellout.tex
файл, то код немного усложняется:
{\everyeof={\noexpand}\xdef\filecontent{\csname @@input\endcsname shellout }}
\def\tmp#1 {\def\filecontent{#1}}\expandafter\tmp\filecontent
\expandafter\includegraphics\expandafter{\filecontent}
Редактировать:Вопрос был отредактирован, реакция на это изменение приведена ниже.
Вы можете определить
\def\pytexplot#1{%
\immediate\write18{python pytexplot.py #1}%
{\endlinechar=-1\everyeof={\noexpand}\xdef\filecontent{\csname @@input\endcsname shellout }}%
\includegraphics\filecontents
}
и вы можете использовать только
\pytexplot{plot1}
\pytexplot{plot2}
Если вам явно нужно написать \includegraphics{\pytexplot{...}}
в вашем документе, то вам нужно переопределить, \includegraphics
как \pytexplot
выше и \def\pytexplot#1{#1}
. Но если вы используете команду \includegraphics
для других нужд, то это не так просто. Вам нужно реализовать больше интеллекта в вашем\includegraphics
переопределении.
Комментарии:
В
\tmp
моем первом коде удаляется пространство, сгенерированное\endlinechar
. Но\endlinechar=-1
локальная настройка (предложенная jfbu) кажется лучше, поэтому я использую ее во втором коде.\includegraphics{out1}
IMHO самое простое решение — сгенерировать\includegraphics{out2}
с помощью Python и определить:\def\pytexplot#1{\immediate\write18{python pytexplot.py #1}\input shellout }
решение3
[перемещено из комментария]
Просто чтобы предоставить дополнительный контекст к уже данным ответам:
В общем случае нельзя надеяться перейти к какой-либо команде LaTeX, ожидая в качестве аргумента что-то вроде имени файла или макроса; в лучшем случае (и не всегда) команда будет иметь тип, который пытается расширить свой аргумент, и как только этот аргументнерасширяемыйвещи, весьма вероятно, что команда не будет работать.
В случае \includegraphics
вы можете использовать его с \temp
аргументом, если \temp
расширяется до допустимого имени файла. Но если \temp
необходимо сделать определения или содержит \write
операцию, вы обречены (независимо от того, сколько \expandafter
вы попытаетесь возиться с)