
次のコマンドを定義しました:
\newcommand{\formatcommand}[1]{
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
これは正しく動作します:
\formatcommand{}
\formatcommand{ }
ただし、上記のコマンドを内部で使用する場合\write18
、
\immediate\write18{\formatcommand{}}
が\def
展開されていないようです。 が返されます。つまり、の本体がコマンド ラインに展開されずに送信された\def is not an executable...
ということです。どうすればこれを修正できますか?\write18
\formatcommand{}
ムウェ
\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}
答え1
TeX がコマンドの内容を書き込むとき\write
、定義の場合と同様にすべての内容が展開されます。\edef
つまり、展開可能なコマンドはすべて展開されますが、実行は行われません。マクロ定義 (またはその他の割り当て) は展開できないため、\def
シェル コマンドとして書き込まれると、コマンドは入力ストリームに残ります。
\ifempty
解決策は、次のマクロのように、空のトークン リストに対して完全に展開可能なテストを使用することです。
\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}"
}
答え2
一般的には、siracusa'a ソリューションをお勧めしますが、LuaTeX を使用する場合は、問題を拡張可能な方法で記述できない場合に使用できる別のトリックがあります。
LuaTeX には、拡張可能な を可能にするプリミティブ\immediateassignment
と\immediateassigned
があります\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}
( shell-escape の動作が LuaTeX では異なるため、コマンドをターミナルに表示するために\write18
を に置き換えました。そのため、コマンドを実行するには、より大きな変更が必要になります。)\write255
を使用すると\immediateassigned
、ブロック内のすべての割り当てを展開可能にすることができます。
\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}