\expandafterは展開の順序を制御するTeXのプリミティブ。このプリミティブの用法と使用例について紹介する。
説明や例の多くを下記の参考文献から引用している。
\expandafterは,2つ以上のトークンを従える。
\expandafter〈token1〉〈token2〉〈token3〉 ... 〈tokenN〉TeXは\expandafterを読み込んだ後, 後置されている〈token1〉を読み込むが、 これを展開せずに保存した後、〈token2〉を読み込み展開する。 〈token2〉の展開が終われば,〈token1〉をその前に置く。
\expandafterは2つ目のトークン〈token2〉が何かによって少しずつ異なる動きをする。
\expandafter〈token1〉\macro [〈arguments〉]
先ず\macroを展開する。 マクロに引数〈arguments〉がある場合にはそれらも読み込んでから展開する。 展開が終われば、\macroを展開したトークン列〈expanded_macro〉の前に保存したトークン〈token1〉を置く。
〈token1〉〈some_tokens_from_\macro〉マクロは一段階しか展開しないことに注意。マクロの中にマクロがあってもそれはそのままになる。
プリミティブはそれ以上展開できないので、結局のところ\expandafterは何の役にも立たない。 ただし、いくつか例外があるので以下で紹介する。
\expandafter〈token1〉\expandafter〈token3〉〈token4〉
もう一つの\expandafterはその次のトークン〈token3〉を保存し、 〈token4〉を展開する。 この展開が終われば、まず保存していた〈token3〉を頭につけて、 さらに〈token1〉をそのさらに頭に付ける。
〈token1〉〈token3〉〈some_tokens_from_token4〉
そして、〈token1〉からまた展開を始めることになる。
\expandafter〈token1〉\csname〈some_tokens〉\endcsname
\csnameから\endcsnameまで読み込み、これらに挟まれるトークンリストからなるコントロールシーケンスが作られる。例えば 〈some_tokens〉=hogeならば、
〈token1〉\hogeが残る。
\expandafter〈token1〉\the〈register〉
\theに続く〈register〉も読み込み、レジスタ値に展開し、 その前に〈token1〉を置く。
〈token1〉〈some_tokens_from_register〉
\def\xx [#1]{The argument is #1.}
\def\yy{[ABC]}
として,
\xx\yyを実行するとエラーになる。
! Use of \xx doesn't match its definition. \lt;*\gt; \xx\yyなぜならば,\xxの引数として与えられている\yyは展開されずに読み込まれるから。 \yyを展開したあとで読み込みたければ,\expandafterを用いればよい。
\expandafter\xx\yy次に,マクロがもう一段深い場合にはどうなるだろうか。
\def\zz{\yy}
のように\zzが定義されているとき,
\expandafter\xx\zzはうまく働くだろうか。この場合もエラーとなる。
! Use of \xx doesn't match its definition. \zz ->\yyなぜならば,\zzは\yyには展開されるが,展開がそこで終わってしまうから。 最後まで展開させるには,\edefを用いると良い。
\edef\zz{\yy}
今度はうまくいく。
\expandafter\xx\zz
3つのマクロ\a, \b, \cがあるとする。 この3つのマクロを
\a \b \cの順に並べて,逆順に展開したいとする。つまり、\cを展開し,次に\bを展開し,最後に\aを展開したいとする。
表現が短くするために
\let\ex = \expandafterとしておく。
上記の展開を実現するには
\ex_1 \ex_2 \ex_3 \a \ex_4 \b \cとするとよい。\exの添え字は便宜上付けているだけで実際には\exに等しいとする。
これを実行すると,まず\ex_1が実行され,\ex_2が保存される。 そして実行が\ex_3に移る。
\ex_3は次の\aを保存し,\ex_4を実行する。
\ex_4は\bを保存し,\cを展開する。 これでまずは\cが展開された。
逆に戻って,保存していた\bを\cを展開したものの前に置く。 さらに保存していた\aを\bの前に置く。さらに保存していた\ex_2を\aの前に置く。
保存していたものをすべてはき出したので,\ex_2を実行する。
\ex_2は次の\aを保存して,\bを読み込み展開する。\bの展開が終わればその前に\aを置く。そして最後に\aを展開して終了する。
\ex_1 \ex_2 \ex_3 \a \ex_4 \b \c →\ex_2 \a \b 〈tokens_from_\c〉 →\a 〈tokens_from_\b〉 〈tokens_from_\c〉 →〈tokens_from_\a〉 〈tokens_from_\b〉 〈tokens_from_\c〉
コントロール・シーケンスには\から始まりカテゴリコード12の文字(英小文字,英大文字)しかつかえないことになっているが,\csname, \endcsnameを用いれば,数字入りのコントロールシーケンスを作成することも可能になる。例えば
\csname a?a-4\endcsnameは \a?a-4 というコントロールシーケンスを表している。 数字やクエスチョンマークまで加えることが出来る。
このコントロールシーケンスを定義するには,
\expandafter\def\csname a?a-4\endcsname{Peculiar control sequence.}
とすればよい。\expandafterは\defを保存して,\csname ... \endcsnameを先に実行し,コントロールシーケンスを生成した後,その前に\defを配置する。
ここで作った特殊なコントロールシーケンスを使うときには,\csnameを使って,
\expandafter\show\csname a?a-4\endcsnameのように書けばよい。