(前回の続き)
\def\withthreeargsexpanded#1#2#3#4{%
\expandafter\def\expandafter\xx@arg@ii\expandafter{\expandafter{#2}}%
\expandafter\def\expandafter\xx@arg@iii\expandafter{\expandafter{#3}}%
\expandafter\def\expandafter\xx@arg@iv\expandafter{\expandafter{#4}}%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter#1%
\expandafter\expandafter\expandafter\xx@arg@ii
\expandafter\xx@arg@iii
\xx@arg@iv}\newtoks\xx@arg@II
\newtoks\xx@arg@III
\newtoks\xx@arg@IV
\def\withthreeargsexpandedii#1#2#3#4{%
\xx@arg@II\expandafter{#2}%
\xx@arg@III\expandafter{#3}%
\xx@arg@IV\expandafter{#4}%
\edef\xx@final{\noexpand#1{\the\xx@arg@II}{\the\xx@arg@III}{\the\xx@arg@IV}}%
\xx@final}\newtoks\xx@arg@II
\newtoks\xx@arg@III
\newtoks\xx@arg@IV
\def\xx@assign@toks#1#2{#1\expandafter{#2}}
\def\withthreeargsexpandedii#1#2#3#4{%
\xx@assign@toks\xx@arg@II{#2}%
\xx@assign@toks\xx@arg@III{#3}%
\xx@assign@toks\xx@arg@IV{#4}%
\edef\xx@final{\noexpand#1{\the\xx@arg@II}{\the\xx@arg@III}{\the\xx@arg@IV}}%
\xx@final}\usepackage{multiexpand}
\def\withthreeargsexpanded#1#2#3#4{%
\def\xx@i{#2}\def\xx@ii{#3}\def\xx@iii{#4}%
\MultiExpandAfter{4}#1%
\MultiExpandAfter{4}{%
\MultiExpandAfter{4}\xx@i
\MultiExpandAfter{4}}%
\MultiExpandAfter{4}{%
\MultiExpandAfter{2}\xx@ii
\MultiExpandAfter{2}}%
\MultiExpandAfter{2}{\xx@iii}%
}- 参考:multiexpand パッケージ(CTAN)
で、ZRさんの“模範解答”は?
私が一番無難だと思ってるのは次のコード。
\def\withthreeargsexpanded#1#2#3#4{%
\edef\xx@next{\noexpand#1{\unexpanded\expandafter{#2}}%
{\unexpanded\expandafter{#3}}{\unexpanded\expandafter{#4}}}%
\xx@next
}この中に出現する
\unexpanded\expandafter{XXX}は、(\edef 中において)「トークン列 XXX を一度だけ展開したもの」を表している。etoolbox パッケージを利用すると、この部分を \expandonce{XXX} と書くことができる。これを使うと、次のような非常に直接的で解りやすいコードが書ける。
\usepackage{etoolbox}
\def\withthreeargsexpanded#1#2#3#4{%
\edef\xx@next{\noexpand#1{\expandonce{#2}}{\expandonce{#3}}{\expandonce{#4}}}%
\xx@next
}もし、「e-TeX 拡張を使わない」という条件であるならば、次のようにする。hak7a3 さんの 2 番目の解答と同じようにトークン列レジスタを利用するが、新たに \newtoks で確保するのでなくてスクラッチを利用している。
\def\withthreeargsexpanded#1#2#3#4{%
\begingroup
\toks0\expandafter{#2}\toks2\expandafter{#3}\toks4\expandafter{#4}%
\xdef\xx@next{\noexpand#1{\the\toks0}{\the\toks2}{\the\toks4}}%
\endgroup
\xx@next
}番外1
これが一番簡単!!
\usepackage{expl3}
\ExplSyntaxOn
\cs_set_eq:NN \withthreeargsexpanded \exp_args:Nooo
\ExplSyntaxOff番外2

発展課題
これで、件の問題の解説を終えることにする。「展開」に関する問題としては非常に基礎的なものであったので、“TeX な人”の中には、「こんな問題は簡単すぎて考える気すら起きない」という人もいたであろう。そういうわけで、発展課題として、例の制約を加えたものを出題しておこう。
完全展開可能にしてみよう。
そう、ソレである。要件を正確に述べると以下のようになる。
\CSを任意の制御綴とする。また、〈A〉、〈B〉、〈C〉を任意のトークン列とし、各々を一回展開したトークン列を〈A′〉、〈B′〉、〈C′〉とする。この時、\withthreeargsexpanded\CS{〈A〉}{〈B〉}{〈C〉}
を何回か展開した結果が
\CS{〈A′〉}{〈B′〉}{〈C′〉}
となる。
この問題が解けた人は、自分を「展開芸人」と称しても差し支えないであろう。