マクロツイーター

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

XeTeX のバージョンを判定してナントカしたい話

つまり、「バージョンが 0.85 以上だったらアレをする」みたいなことをやりたい。どうすればよいか。

XeTeX のバージョンの形式

XeTeX を起動すると次のようなバージョン表示が出てくる。

This is XeTeX, Version 3.14159265-2.6-0.99992 (TeX Live 2015/W32TeX) (preloaded
format=xetex)
 restricted \write18 enabled.

この中で「XeTeX のバージョン」に相当するのは「0.99992」である。このように(少なくとも最近の)XeTeX ではバージョン番号は単純な実数値となっている。*1 *2

TeX 言語のコードにおいては次の拡張プリミティブでバージョン番号を取得できる。

  • \XeTeXversion :[整数パラメタ;読取専用] “XeTeX のバージョン”の整数部分の値。(0.99992 ならば 0。)
  • \XeTeXrevision :[展開可能]“XeTeX のバージョン”の整数部分より後に続く文字列。(0.99992 ならば “.99992”。*3

つまり、次のトークン列を完全展開すればバージョン番号の文字列が得られることになる。

\the\XeTeXversion\XeTeXrevision

バージョンの値の大小を比較する

バージョン番号の取得の方法が判ったので、次は比較の方法を考えよう。もちろん等値比較だけでなく大小比較(「バージョンが〜以上なら」など)もできる必要がある。整数値の比較であれば \ifnum を使うだけなので簡単であるが、残念ながら、バージョン番号は実数値である。どうすればよいだろうか。

実数値の大小比較を行うための定番の方法は「pt などの単位を付けて寸法値扱いにして \ifdim で比較する」ことである。例えば、\realValue が実数値(の十進表記)に展開されるマクロであるとして、その実数値が 3.14 よりも大であることを判定するには次のようにすればよい。

% \realValue が 3.14 より大ならば
\ifdim \realValue pt > 3.14pt ...

以上の事項を合わせると、例えば「XeTeX のバージョンが 0.99992 より大ならば」という判定をするには以下のように書けばよい。

% バージョンが 0.99992 より大ならば
\ifdim \the\XeTeXversion\XeTeXrevision pt > 0.99992pt ...

一件落着……。

……ではない。実はこの方法は重大な欠陥がある。これは次のようなコードを実行してみればわかる。(対話モード)

*\ifdim 0.99993pt > 0.99992pt \message{OK}\else\message{NG}\fi
NG

なんと“0.99993 > 0.99992”という不等式が偽になってしまっている! 何故かというと……そう、

精度が足りない。

TeX の寸法値の精度は 1/65536 pt であるが、これは 0.00001pt(= 1/100000 pt)より大きい。なので小数 5 桁目については有効範囲には完全には収まらない。これにより“0.99992pt”は“0.99991pt”よりは大きいが、“0.99993pt”とは同じ値と見なされる、という現象が起こっているのである。従って、この「定番の方法」は“XeTeX のバージョン番号が細かすぎる”ために使えない、ということになる。

ではどうすればよいかというと、簡便な方法としては、バージョン番号を“文字列として”比較すればよい。少なくとも、バージョン番号の整数部が 1 桁である間は、実数値の大小は文字列として比較をした場合の大小と一致するからである。幸い、XeTeX には文字列比較を行うプリミティブ \strcmp がある(これは pdfTeX 拡張の \pdfstrcmp と等価である)ので、これを使えばバージョン番号の比較が簡単に実装できる。

% バージョンが 0.99992 より大ならば
\ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99992}>0 ...

ちなみに、「0.99992 以上」の判定については、「0.99992 より小」の逆条件とすることもできるが、次のようにも書ける。

% バージョンが 0.99992 以上ならば
\ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99992}>-1 ...

*1:ちなみに「XeTeX のバージョン番号は 1 に収束するのか?(しない)」という話は 2010 年の某集いの某氏の発表のネタとして使用済である。

*2:過去にはバージョン表示が「0.9999.3」のようになっていた時もある(これは 0.99992 よりも古い)が、この場合は「0.9999」までを“XeTeX のバージョン”と見なすことにする。

*3:先述の「0.9999.3」の場合は“.9999”となる。