
Ich habe folgenden Befehl definiert:
\newcommand{\formatcommand}[1]{
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
Das funktioniert einwandfrei:
\formatcommand{}
\formatcommand{ }
Wenn Sie jedoch den obigen Befehl innerhalb von verwenden \write18
,
\immediate\write18{\formatcommand{}}
die \def
s scheinen nicht erweitert zu werden, da ich bekomme \def is not an executable...
, was bedeutet, dass \write18
der Textkörper \formatcommand{}
ohne Erweiterung an die Befehlszeile gesendet wurde. Wie kann das behoben werden?
MWE
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write18{\formatcommand{}}
\end{document}
Antwort1
Wenn TeX den Inhalt eines \write
Befehls schreibt, expandiert es das gesamte Material ähnlich wie bei einer \edef
Definition, d. h. alle erweiterbaren Befehle werden expandiert, es findet jedoch keine Ausführung statt. Makrodefinitionen (oder andere Zuweisungen) sind nicht erweiterbar, daher \def
verbleiben die s im Eingabestrom, wenn sie als Shell-Befehle geschrieben werden.
Die Lösung besteht darin, einen vollständig erweiterbaren Test für eine leere Tokenliste zu verwenden, wie das folgende \ifempty
Makro:
\makeatletter
\newcommand\ifempty[1]{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\newcommand{\formatcommand}[1]{
echo "\ifempty{#1}{empty}{not empty}"
}
Antwort2
Im Allgemeinen empfehle ich die Lösung von siracusa, aber wenn Sie LuaTeX verwenden, gibt es einen anderen Trick, den Sie verwenden können, wenn Ihr Problem nicht erweiterbar geschrieben werden kann:
LuaTeX verfügt über Grundelemente \immediateassignment
, \immediateassigned
die erweiterbare s ermöglichen \def
:
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\immediateassignment\def\temp{#1}
\immediateassignment\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write255{\formatcommand{}}
\end{document}
(Ich habe es \write18
durch ersetzt \write255
, um den Befehl auf dem Terminal anzuzeigen, da Shell-Escape in LuaTeX anders funktioniert und die Ausführung des Befehls daher größere Änderungen erfordert hätte.)
Mit \immediateassigned
können Sie alle Zuweisungen in einem Block erweiterbar machen:
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\immediateassigned{%
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
}%
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write255{\formatcommand{}}
\end{document}