マクロツイーター

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

TeX芸人実力判定問題、その3(解答編)

脆弱・頑強の説明が済んだところで、改めて芸人問題の正解の話。*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 を参照してみてほしい。

*1:「もう脆弱性なんて怖くない」のシリーズは元々この問題の解説として書き始めたのだが、脆弱・頑強の説明を含めようとしたら予想外に大きな分量になり、「問題の解説」として相応しくなくなったので、今の形に書き直した。