マクロツイーター

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

きょうの pTeX (1): \kansuji、\kansujichar

  • \kansuji<整数> :[展開可能] 整数を(一〇方式の)漢数字表記の和文文字トークン列に変換する。
  • \kansujichar<整数> :[整数パラメタ;読書可] 整数(0〜9)に対応する漢数字の(内部)漢字コード。

TeX 言語には「整数を文字列に変換する」ためのプリミティブとして、\number\romannumeral の 2 つがある。pTeX 拡張をもつエンジンではこれらに加えて、整数値を漢数字表記に変換するための \kansuji というプリミティブが用意されている。使い方は \number と全く同じで、引数には「TeX で整数として解釈されるトークン列」を何でもとることができる。

% 数字列の整数
\message{\kansuji2016年}%==>二〇一六年
\meesage{\kansuji '6789}%==>五五89
% 数字列を終結する空白は吸収される
\message{\kansuji4 2}%==>四2
% 内部値の整数
\message{\kansuji\active}%==>一三
% 内部値の寸法値は整数に変換される
\message{\kansuji\maxdimen}%==>一〇七三七四一八二三 

0〜9 の各数字に対応する“漢数字”がどの文字かは可変であり、\kansujichar というプリミティブで設定できる。

\kansujichar1=`え \kansujichar2=`び \kansujichar3=`す
\kansujichar4=`の \kansujichar5=`わ \kansujichar6=`ら
\kansujichar7=`い \kansujichar8=`が \kansujichar9=`お
\message{\kansuji56}%==>わら

なお、“漢数字による表記”には、「二千十六」のように日本語での読み下しを漢字で表す「十字方式」と「二〇一六」のように算用数字と同じ様式で表す「一〇方式」の 2 つが通用されているが、\kansuji が対応しているのは「一〇方式」の方である。

ところで、この \kansuji の適用結果の文字列は、要するに \number の結果の数字列に対して単純な一対一の文字変換を施したものに過ぎない。普通の TeX 言語者であれば、この \kansuji\kansujichar と同等の機能*1をもつマクロを構築することは容易であろう。すると一見、これらのプリミティブの存在意義は低いようにみえる。(実際、過去に一度廃止が検討されたことがあるらしい。)ところが実はこれらのプリミティブはもう一つの重要な用途があり、それがこれから説明する「\kansuji トリック」である。

\kansuji トリック

\kansuji トリック」とは、次の要望を字手実現するための技法である。

整数値をその符号値をもつ和文文字トークンに変換したい。

つまり、(内部漢字コードが Unicode である upTeX を前提とすると)例えば "2603 という数値が与えられた時に、符号位置がこの値である文字である〈☃〉の和文文字トークンを作り出したい、ということである。

某フォーラムを見ている人であれば、ごく最近に似た話題が出ていたことを覚えているだろう。

そこでは、XeTeX や LuaTeX について「整数値をその符号値をもつ文字トークンに変換したい」という要望があり、それに対して「\Uchar プリミティブ」「\lowercase トリック」という 2 つの解決法が示されている。((いや、前田さんの示した「TeX エスケープ(^^ab)の文字列を作って \scantokens する」も入れると 3 つか……。))このうち、XeTeX・LuaTeX 専用である \UcharpTeX 系エンジンでは明らかに使えない。残りの「\lowercase トリック」はどうかというと、残念ながらこれも今の問題については適用しない。何故かというと、pTeX 系では文字トークンが“欧文”と“和文”に明確に分かれていて、\lowercase が影響するのは欧文文字に限られるからである(\lccode も欧文文字にしか設定できない)。従って、和文トークンについては別の手段を考えないといけないわけである。

そして、その解決手段となるのが \kansuji プリミティブである。恐らく、「\kansuji を使えばできる」というヒントさえあれば、多くの TeX 言語者にとってその方法を思いつくのは容易であろう。

% これで \SNOWMAN の一回展開が"☃"になる
\kansujichar1="2603 \edef\SNOWMAN{\kansuji1}

……実にあっけないが、これが「\kansuji トリック」である。

実は、「\lowercase トリックの和文版を考えよ」という問題は、当ブログでも過去に「パズル」として“出題”されている。

そこでは以下のようなマクロを定義することが求められている。

% \getjchartoken \制御綴{<整数ch>}
% 内部漢字コードの値が ch の和文文字トークンに展開されるマクロ
% として \制御綴 を(ローカルに)定義する。

TeX 言語学習者は改めてこれに挑戦してみるといいであろう。

\kansuji トリックしたいとき

「指定のコードの和文トークンを得る」ことが必要になる場面は、(先の記事でも少し触れられているが)\write の引数や \csname の中身で“直接書けない和文文字”を使いたい場合である。

例えば upLaTeX 用のパッケージを作製していて、そこで \☃ という制御綴のマクロを定義したくなったとしよう。もちろん、普通は、パッケージのファイルの文字コードUTF-8 にして

\def\☃{...}

と書けば済む。ところが諸々の事情でファイルの中身を全て ASCII 文字にする必要があったとしよう。この場合は「\kansuji トリック」の使用が必須となる。

\begingroup \kansujichar1="2603
\expandafter\gdef\csname\kansuji1\endcsname{...}
\endgroup

以上、長い話になったが、\kansuji\kansujichar の両プリミティブに充分な存在意義があることが明らかになったと思う。

*1:インタフェースは異なるかもしれない。