\write18 の \def を展開する

\write18 の \def を展開する

次のコマンドを定義しました:

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

関連情報