zxjatype で「花園明朝B」をフォールバックに使うと上手くいかないという報告をもらった。調べてみると、次のような場合にエラーになるようだ。(^^^^4e01
は XeTeX の「拡張 TeX エスケープ形式」で U+4E01 の文字を書いたのと同値になる。数字が 5 桁の場合は ^^^^^20001
と ^
も 5 つにする。)
% XeLaTeX 文書; 文字コードは UTF-8 \documentclass{article} \usepackage[AutoFallBack=true]{zxjatype} \setjamainfont{HanaMinA}% 明朝→花園明朝A % 明朝フォールバック→花園明朝B(色を付けた) \setCJKfallbackfamilyfont{rm}[Color=00993300]{HanaMinB} \begin{document} ^^^^4e01^^^^4e02^^^^4e03 ^^^^^20001^^^^^20002^^^^^20003 \end{document}
! Missing \endcsname inserted. <to be read again> \__int_eval_end: l.7 ^^^^4e01^^^^4e02^^^^4e03 ^^^^^20001 ^^^^^20002^^^^^20003 ?
アレなのは何か
ただ、この場合も、^^^^^20001
の前の空白を消すと全て(フォールバック処理も含めて)正常に出力される。だから zxjatype の独自の処理*1もフォールバック処理も関係なさそうだ。
さらに調べてみた結果、このエラーは以下の状況で起こることが解った:
CheckSingle=true
(文字ウィドウ抑止)にしている。(このオプションの既定値は xeCJK では偽であるが、zxjatype では真にしている。)- BMP 外の文字を含んだテキストを入力している。
例えば、次のようなソースでエラーを再現できる。
% XeLaTeX 文書; 文字コードは UTF-8 \documentclass{article} \usepackage[CheckSingle=true]{xeCJK} \setCJKmainfont{HanaMinA} \begin{document} % エラー! ^^^^4e01^^^^4e02^^^^4e03 ^^^^^2000b \end{document}
(ただどういうテキストでエラーになるかの詳細は不明で、例えば上の例で空白の前が 2 文字だとエラーにならない。)
BMP 内と外で異なる挙動を示すことは、TeX 言語上の仕様では本来ないはずである。そうなると XeTeX の動作自体が怪しい。*2さらに調べてみると、「BMP 外の文字トークンに対する \meaning
の動作に不具合があることが判明した。(環境は Windows 上の TeX Live 2013。)
% plain XeTeX document \def\inspect#1{\expandafter\inspectA\meaning#1XY\relax#1} \def\inspectA#1 #2 #3#4#5\relax#6{\number`#3:\number`#4:#5:\number`#6} \message{\inspect ^^^^4e01} \message{\inspect ^^^^^20001} \bye
これを実行すると次のように端末に出力される。
19969:88:Y:19969 55360:56321:XY:131073
〈あ
〉のような文字トークンに \meaning
を適用すると、「the letter あ
」のような \the
-文字列が得られる。この中の〈あ
〉は当然元の文字トークンと同じ符号位置を持っているはずだが、元の文字が BMP 外の場合、ここが「サロゲートペアの符号位置のトークン 2 つ」に分裂してしまっているようである。
回避策
先述の \meaning
の問題は CheckSingle
(文字ウィドウ抑止)の処理の中で発生する。だから、取りあえずこれを無効にすると回避できる。zxjatype の場合は noCJKchecksingle
というオプションを指定する。
% XeLaTeX 文書; 文字コードは UTF-8 \documentclass{article} \usepackage[AutoFallBack=true,noCJKchecksingle]{zxjatype} \setjamainfont{HanaMinA} \setCJKfallbackfamilyfont{rm}[Color=00993300]{HanaMinB} \begin{document} ^^^^4e01^^^^4e02^^^^4e03 ^^^^^20001^^^^^20002^^^^^20003 \end{document}