マクロツイーター

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

「文字間トークン自動挿入機能」の話

以前に述べた「フォントにない文字を別のフォントで補う」の処理のように、「LaTeX の命令(TeX の制御綴)を表に出さずに独自の処理を割り込ませる」目的のために XeTeX エンジンが用意しているのが「文字間トークン自動挿入機能」である。(この機能自体の解説は XeTeX エンジンのマニュアル((texdoc xetex-reference コマンドを実行すれば表示される。))にあるのでここでは行わない。)さらに言うと、先述のような目的を果たす手段はこれしかないといっても構わないと思う。勿論、「文字をアクティブにする(カテゴリコードを 13 に変更)」という手段もあるが、これは他のパッケージとの共存が難しいため一般に避けられている。

「文字間トークン自動挿入機能」は言語固有の正確な組版を実現するために実際に使われている。例えば、Polyglossia(XeLaTeX 用の多言語パッケージ)のフランス語オプションでは、所謂 double punctuation (〈?〉〈:〉等の直前に微小な空きを要求する文末句読点)の処理にこの「自動挿入機能」が利用されている(Babel ではアクティブ文字を用いていた)。同様に、CJK 言語のためのパッケージ(xeCJK、zhspacing、xetex.ko 等;拙作の zxjatype は xeCJK を土台にしている)はどれも「自動挿入機能」を CJK 言語での句読点周りの空白を調節するのに用いている。先に述べた事情もあって、「自動挿入機能」は CJK 言語の組版に不可欠な重要な機能なのである。

ところで、「別のフォントで補う」のコードは実験的なものであり、「自動挿入機能」に関するパラメタ(\XeTeXcharclass\XeTeXinterchartoks)について「グローバル」な代入を行っている。従って、このコードはほかの「自動挿入機能」を用いるパッケージとは共存できないことは明らかである。これは、例えば 8 ビット TeX で「割込処理を行うのにカテゴリコードのグローバルな設定を行う」ようなパッケージが互いに衝突するのと同じである。実は、困ったことに、先述したような(実験的でない)パッケージはどれも、「自動挿入機能」のパラメタのグローバルな設定に頼っている。このことの帰結は、例えば、韓国語用の xetex.ko と中国語用の xeCJK と Polyglossia フランス語オプションは、どれも互いに共存できないということになる。これは「多言語環境の実現」を期待する者にとっては致命的なものである。では、何故そういう一見不完全な実装になっているかについては、単純な理由がある。XeLaTeX 上で「共存できる形で自動挿入機能の設定を行うための枠組」がそもそも存在していないからである。
従って、この問題を解決して、XeLaTeX 上で「多言語対応可能」な形で「日本語対応」を実現しようとすると、「共存できる枠組」が構築される必要がある。これには 2 つの問題が絡んでいる。

  • 技術的問題: 「自動挿入機能」の仕組では、2 種類の設定を同時に「有効にする」ことは原理的にできないため、共存の方法は「設定を切り替える」ことになるであろう(例えば、中国語の段落では xeCJK を「有効」にし、韓国語の段落では xetex.ko を「有効」にする、等)。そうすると、「切替」の時に、関係する文字の「文字クラス」を変更する必要があり、今の例のように CJK 文字が絡む場合はその数は数万に及ぶ。数万回の代入が言語の切替の度に発生するのはいかにも効率が悪いが、実はもっと大きな問題があり、言語の切替をローカルに行われた場合、エンジンのメモリ設定によっては、メモリ不足のエラーに陥ってしまう(実際に W32TeX では、ローカルで「文字クラス」の代入を繰り返すと約 2500 個の時点で capacity overflow になった)。この問題を本質的に回避できる実装法は私は知らない。

  • 事務的問題: 仮に「共存できる方法」があったとしても、「自動挿入機能」を利用するパッケージがそれに従わなければ実際の問題解決には至らない。パッケージ開発者の間でそのような「紳士協定」がある状態に移行するのは至難の業と思われる。先述のカテゴリコードの問題の場合、Babel では「文字のアクティブ化」を制御する機構を持っていて、各言語オプションの実装者(Babel 本体の開発者とは異なる場合が多い)がその機構に従っている限り、異なる言語間で異なる「アクティブ化状態」を安全に切り替えられるようになっている。Babel の中での話なので、Babel が当該の機構を持っていることが比較的理解され易いのだと思う。

  • 本気で解決しようと思うなら、まず XeTeX の ML で問題を提起するところから始めないといけないけど、悩ましいな……。

    実のところ、「XeTeX で日本語する件」を扱うに際して、「新たに日本語用に『自動挿入機能』利用のパッケージを作る」のではなく「既存の中国語用の xeCJK パッケージの改造で済ませる」方針を採った理由の一つもこの点であったりする。あと、xeCJK が「XeTeX の CJK サポートの事実上標準」と見られる可能性が高そうだから、そこに乗っかった方が、他のパッケージとの共存・連携の点でも有利かなという考えもある。