脆弱・頑強の説明が済んだところで、改めて芸人問題の正解の話。*1
LaTeX(ToL)で、以下の要件を満たす命令
\makecounterprinter
を実装せよ。
\makecounterprinter\制御綴A\制御綴B
は\制御綴A
を以下のようなカウンタ値出力命令として定義する。\制御綴B{<整数>}
は引数の整数を「ある特定の形式」(例えばナベアツ)で出力する命令であると仮定する。ただし、引数は 10 進表記で与えなければならない。\制御綴A{<LaTeXカウンタ名>}
は当該のカウンタの現在の値を\制御綴B
の定める形式で出力する。\制御綴B
は脆弱(fragile)であるかも知れない。
といっても、もうほとんど正解は「もう脆弱性なんて怖くない(3)」の記事に出てしまっている。\nabeazz
から \NabeAzzLike
を作るためのコードが
\def\NabeAzzLike#1{% \expandafter\protect\expandafter\nabeazz\expandafter{\number\csname c@#1\endcsname}}
であり、ということは、この問題の \makecounterprinter
について、
\makecounterprinter\NabeAzzLike\nabeazz
が先のコードに展開されればよい。なので、以下のものが正解となる。
\def\makecounterprinter#1#2{% \def#1##1{% \expandafter\protect\expandafter#2\expandafter{\number\csname c@##1\endcsname}}
おまけ: OTF パッケージの \ajLabel
ちなみに、この問題と似たコードが実際に使われている例として、OTF パッケージの \ajLabel
命令がある。これは、OTF パッケージが提供する「装飾付数字」(丸付など)でカウンタ出力をするためのものである。例えば、enumi が 42 の時に、\ajLabel\ajMaru{enumi}
とすると、〈㊷〉(丸付42)が出力される。\ajMaru
等の文字出力命令は脆弱であるが、それでも \ajLabel
は頑強になるように実装されている。すなわち、以下のような形への展開((ここまでの変換を展開だけで行う必要があることに注意。そのため、\ajLabel
マクロの定義はかなり技巧的になっている。))を行っている。
\ajLabel\ajMaru{enumi} → \protect\ajMaru{42} \ajLabel\ajMaru*{enumi} → \protect\ajMaru*{42}
興味のある人は ajmacros.sty を参照してみてほしい。