マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

完全展開可能なナベアツ

「TeX でナベアツ」問題については、これまでに Web 上にいくつか回答が公開されている。その多くは完全な正解であるが、それは何れも「脆弱(fragile)」である。すなわち、

\edef\result{\NabeAzz{40}}
\result

のように一回 \edef で「展開」した後で実行するということはできない。そこで、「完全展開可能」なナベアツを実装しようというのが今回の出題の趣旨である。

以下の仕様を満たすマクロ \NabeAzzX を実装せよ。

  • \NabeAzzX{<n>} を完全に展開すると、1 から n までの整数について、その 10 進表記の数字列を空白トークンで区切ったものに展開される。ただし、3 の倍数または 10 進表記に数字 3 を含む整数については、{\AhoFont <整数>} という形になる。
  • ここで、制御綴 \AhoFont は展開不能であると仮定する。
  • 例えば、\edef\result{\NabeAzzX{40}} を実行すると、\result は以下のトークン列に展開されるマクロになる。
    1 2 {\AhoFont 3} 4 5 {\AhoFont 6} 7 8 {\AhoFont 9} 10 11 {\AhoFont 12} {\AhoFont 13} 14 {\AhoFont 15} 16 17 {\AhoFont 18} 19 20 {\AhoFont 21} 22 {\AhoFont 23} {\AhoFont 24} 25 26 {\AhoFont 27} 28 29 {\AhoFont 30} {\AhoFont 31} {\AhoFont 32} {\AhoFont 33} {\AhoFont 34} {\AhoFont 35} {\AhoFont 36} {\AhoFont 37} {\AhoFont 38} {\AhoFont 39} 40
    

ここでトーク\AhoFont はもちろん「アホなフォントに切り替える命令」を想定している。plain TeX の場合、例えば、「\font\AhoFont=cmfi10 scaled \magstep2」のように定義されたトークン \AhoFont は展開不能だから問題の前提に適っている。これに対して、LaTeX のフォント命令は TeX の(展開可能な)マクロとして実現されるので、問題の前提に合致するフォント切替命令 \AhoFont を用意するのは難しい。ただし、問題の仕様を満たす \NabeAzzXLaTeX *1で実装した場合、LaTeX の「protect(保護)」の機構を利用して次のようなことができるはずである。

  • フォント切替命令 \AhoFont を protect された命令として定義する:*2
    \DeclareRobustCommand*\AhoFont{\usefont{OT1}{cmfr}{m}{it}\Large}
  • \typeout{\NabeAzzX{40}} を実行すると、問題文中で述べた「1 2 {\AhoFont 3} ... 40」が端末に表示される。((なお、\edef で試したい場合は、代わりに \protected@edef という内部命令を用いる必要がある:\protected@edef\result{\NabeAzzX{40}}))
  • (ただし、\AhoFont の定義をどうするかは問題の一部ではないので、例えば「\AhoFont\relax に等置(\let)されていると思っても良い。)

    なお補足であるが、命令(マクロ)を「脆弱」でなくす(「頑強(robust)」にする)のに、必ずしも「完全展開可能」にしなくてもよく、例えば先に述べた LaTeX の protect を使うと、(LaTeX 上では)頑強になる。*3じゃあ何故に完全展開可能性を求めるかというと…もちろんそれが挑戦的で面白いからである。でも、まだ「普通のナベアツ」を終えていない人はさっさとそちらを済ませてからにしよう。

    *1:じゃなくて「TeX on LaTeX」ですね…。

    *2:次行の定義を実際に使う場合は type1cm パッケージを読み込むこと。

    *3:というか、そもそもナベアツが頑強性が求められる合理的な理由がどこにもない。