マクロツイーター

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

TeX芸人実力判定問題、その4

これが解けたら TeX 芸人 3 級相当。

plain TeX において、以下の仕様を満たすマクロ \numtohex を実装せよ。

  • \numtohex{<整数>} を実行すると、\result が「引数の整数を『2 桁の大文字 16 進数』((printf の書式で著すと %02X。))で表記した文字列(トークン列)」に展開されるマクロに定義される。
  • 引数の整数は 0〜255 の範囲にあることを仮定する。数字表記および内部値(レジスタ等)の何れで与えられる可能性もある。(異常入力時の動作は何も規定しない。)
  • 結果に含まれるトークンのカテゴリコードは 11 または 12 でないといけない。
  • \result の定義は局所的(\global でない)でないといけない。
  • plain TeX を破壊してはいけない。*1
  • コードの定義は、plain TeX の既定の設定で「\catcode`\@=11 」を実行した直後の状態((つまり、カテゴリコードの設定は LaTeX\makeatletter の状態と同じ。))で行われるものとする。\numtohex マクロの使用は、plain TeX の既定の設定((カテゴリコードの設定は LaTeX\makeatother の状態と同じ。))で行われるものとする。

ただし、実装のコードに含まれるトークンの総数が 50 個以下でなければならない。本体の \numtohex 以外の補助のマクロ等の定義を行った場合はその記述に用いたトークンも含めて数える。

plain TeX を前提にしているのは「LaTeX でしか定義されてないものの使用を防ぐため」であって、特に plain 特有の設定や機能を用いることは想定していない(しても構わないが)。だから LaTeX(ToL)との違いを気にする必要は生じないと思う。

トークンの個数に関する補足事項。

  • トークンの数え方は TeX の規則に従う。空白トークンも数えるが、コメントや行頭空白等のトークンにならない部分は数えない。
  • マクロパラメタの〈#〉(カテゴリコード 6)は単一のトークンである。つまり、〈#1〉は 2 トークン、〈##2〉は 3 トークンと数える。
  • 実装コードの途中でカテゴリコードの設定が変わる場合でも、とにかく実際にそのコードを実行したときに行われるトークン化に従う。例えば、
    {\catcode`\?11 \gdef\@x#1{\a?}}\@x \a?% example
    というテキストを実行すると、「{」「\catcode」「`」「\?」「1」「1」「」「\gdef」「\@x」「#」「1」「{」「\a?」「}」「}」「\@x」「\a」「?」とトークン化される(18 個)。

実装コードの使用例。

% plain TeX 文書
\catcode`\@=11
《ここに 50 トークン以内の実装コードが入る》
\catcode`\@=12
\numtohex{042}\show\result %==>2A
\numtohex{`\\}\show\result %==>5C
\count0=3 \numtohex{\count0}\show\result %==>03
\bye

*1:つまり、実装コードを実行した後 plain TeX が正常稼動しなくなることがあってはならない。要するに、plain TeX で定義済の制御綴に対する再定義をしなければよいわけである。