ドキュメント訂正・PTEX_IN_FILTER

今日帰宅して,昨夜公開した OldSlav のドキュメントを眺めていたら,ロシア語の т がぼろぼろ脱落していて慌てた。литературалиераура となっていてマヌケなんである。OldSlav のとんでもないバグだとまずは考えた。今回 \russiantext 命令を結構いじっている。しかし,旧バージョンに戻して組版しても再現する。ドキュメント旧版を確認するときちんと出力されている。頭が煮詰まって来た。

なんで小文字の т だけが抜けるのか。うまく出ている原稿とダメな原稿を落ち着いてよく比べてようやく原因が判った。ダメ版ではいつものサボリ根性から T2A のキリル文字を簡単にマークアップするために \def\cyrt{\fontencoding{T2A}\selectfont} というマクロを書いていた。バカみたいなバグである。\cyrt は T2A 小文字の т の出力命令と同じ名前であって,これをつぶしていたわけである。フォント切替えなのでエラーとならず,見過ごしてしまった。

教訓は,サボルな,ではなくて,マクロの名前はよく考えよ。特定の文字の問題はマクロ名の重複を疑え。よく見るとほかにもいただけない瑕疵があり,類似見直しをした。ドキュメントを訂正して差し替えた。

* * *

奥村先生の TeX サイトで土村さんの ptetex3 の後継,ptexlive が出ていることを今ごろ知った。もう着いて行けてません。それなら OldSlav の改造は ptexlive でやったほうが皆のためだったかも知れない。まあ,そのうち時間が取れれば ptexlive 対応にも取り組みたいと思う。

また,ptetex3,ptexlive とも — ptexenc ライブラリによる入力では —,環境変数 PTEX_IN_FILTER として原稿ファイルの出口ルーチンを登録できるということも知るところとなった。ptexenc では互換性を重視して JISX-0208 に定義されているキリル文字,ギリシア文字を和文として扱う仕様になっており,ロシア語・ギリシア語の UTF-8 テキストを欧文として処理したいユーザーには少し物足りないところは否めない。旧 pTeX でロシア文字を JIS コードで入力していた人にはまったく影響がないのでそういう選択をしたということのようである。それでも,文字を ^^十六進形式にすれば,欧文として扱うとのことを土村さんから教えていただいた。そしてその変換を行うフィルタを PTEX_IN_FILTER に登録すればよい,という話であった。

Utf82TeX を改造して試したら,たしかにばっちりロシア語が出た。でも ^^十六進形式にするのは,大げさなプログラムは不要で,次のような Perl コードですんでしまう。

#!/usr/bin/perl
# -*- coding: utf-8; mode: cperl; -*-
# Cyrillic and Greek to ^^HEX format
binmode(STDOUT,":utf8");
while (<STDIN>) {
    utf8::decode($_);
    foreach my $chr (split(//, $_)) {
        if ((($chr ge "\x{0400}") && ($chr le "\x{04ff}")) || # Cyrillic
            (($chr ge "\x{0370}") && ($chr le "\x{03ff}")) || # Greek
            (($chr ge "\x{1f00}") && ($chr le "\x{1fff}"))) { # Greek Ext
            utf8::encode($chr); # UTF-8 encode
            foreach my $bchr (split(//, $chr)) {
                print(sprintf("^^%x", ord($bchr)));
            }
        } else {
            print($chr);
        }
    }
}

※ 2010.7.31 付記
上記フィルタには,もともと binmod(STDIN, ":utf8"); があったが,utf8::decode 関数をその入力に対して発行すると,latin1 のみからなるテキスト断片では「二重デコード」されてテキストが壊れるという問題があることが判明した。奥村先生の TeX Forum で鋭い方のご指摘があったので,問題訂正をした。

UTF-8 で書いた TeX ファイルをこれ(myfilter.pl とでもしておこう)で前処理すれば,キリル文字とギリシア文字(拡張領域含む)だけが ^^十六進形式に変換される。ただし,PTEX_IN_FILTER を通すと,あらゆるマクロファイルをこれに掛けるためか,LaTeX コンパイルが眼に見えて遅くなる。面倒でも,次のようなスクリプト(u8platex とでもしておこう)を書いてドライブしたほうが高速である。u8platex hoge とすると hoge.pdf までができる。もちろん,これは UNIX, Mac OS X 用である。

#!/bin/sh
# u8platex command
BN=`basename $1 .tex`
myfilter.pl < $BN.tex > $BN.utf
eplatex --kanji=utf8 $BN.utf && dvipdfmx $BN.dvi && rm -f $BN.utf