マクロツイーター

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

LuaLaTeX で fontspec する件について

正確にいうとなかなか fontspec してくれない件。

LuaLaTeX の前に XeLaTeX の話。奥底の解説では、XeLaTeX で「Unicode する」為に必要なパッケージを一度に読み込むには xltxtra パッケージを用いるとしていた。現在でもそれ自体は変わらないが、「本当に必要なもの」に関しては、fontspec を読み込むだけで一緒に取りこまれる様になっている:例えば xunicode パッケージ、EU1 エンコーディング等である(さらに、etex や fixltx2e も該当する)。必須ではない追加機能(例えば XeTeX のロゴ等)は xltxtra 自体が提供している。従って、そういう「余分の」機能が不要であれば、xltxtra だけ読み込む代わりに fontspec だけ読み込むのでも構わない。

[sample.tex]


% 文字コードUTF-8
\documentclass[a4paper]{article}
\usepackage{fontspec} % fontspec だけ読み込む
% Ligatures=TeX で〈---〉等の入力方法が有効になる
\setmainfont[Ligatures=TeX]{TeX Gyre Termes}
\begin{document}
% キリル文字LaTeX アクセント命令を付した例<<Дв\'ажды дв\'а --- чет\'ыре.>>
\end{document}

そして、実は、LuaLaTeX でもこの全く同じソースが通用する。すなわち、LuaLaTeX で「Unicode する」方法は、XeLaTeX の場合と同じように fontspec の機能を用いることとなる。注意すべき点は以下の通り:

  • xltxtra、xunicode パッケージは XeLaTeX 専用なので LuaLaTeX では使えない。必ず fontspec「だけ」を読み込むことになる。(ただし、最新の fontspec は LuaLaTeX の場合も内部で「強引に」xunicode を読み込んでいるようである。)
  • --- → — (em-dash)〉等の「リガチャを利用した特殊文字入力」を有効にするためには、fontspec の属性として「Ligatures=TeX」の指定が必要である。古い形式の「Mapping=tex-text」は XeLaTeX でしか機能しない。

    (なお、Ligatures は本来は OpenType のリガチャ指定の制御を行う属性である。実際、LuaLaTeX では OpenType のリガチャ処理を拡張する形で TeX のリガチャを扱っているように思われる。一方、XeLaTeX では TECKit というテキスト変換機構を利用している。

上の例では、フォント指定を「TeX Gyre Termes」のように「フォント(ファミリ)名」で行っているが、LuaLaTeXでこの方式を利用するには、予め mkluatexfontdb というコマンドを実行して使用可能フォントのデータベースを作成する必要がある。(これは LuaTeX 側で用意された Lua スクリプトである。何でも自前で行うのが LuaTeX 流 ;-) )というわけで TeX Live 2010 で早速実行してみた。


C>mkluatexfontdb

luaotfload | Updating the font names database:
luaotfload | Font names database not found, generating new one.
This can take several minutes; please be patient.
#(…上と同じメッセージが 8781 回表示されて…)
luaotfload | Updating the font names database:C:\texlive\2010\bin\win32\runscrip
t.tlu:596: .../2010/texmf-dist/tex/luatex/lualibs/lualibs-file.lua:75: stack ove
rflow

何いぃぃー!??

気を取り直して、今度は W32TeX で実行してみる。


C>mkluatexfontdb

luaotfload | Updating the font names database:
luaotfload | Scanning TEXMF fonts...
luaotfload | Scanning OS fonts...
luaotfload | 700 fonts in the database
luaotfload | saved font names database in c:/usr/local/share/texmf/tex/luatex/lu
aotfload/names/otfl-names.lua

こちらは上手くいったようだ…。というわけで早速先の例を組版してみる。


lualatex sample.tex

XeLaTeX と同一の結果が得られた。これで LuaLaTeX が XeLaTeX と同様に Unicode 入出力を行えることが判る。

ただ、出力をよく見るとアクセントの位置(特に \'ы)が微妙におかしいことに気付く。現状の LuaLaTeX/XeLaTeX の処理では、アクセント命令(\')は Unicode 上で扱われる。\'ы の場合、Unicode に合成済文字がない(キリル文字についてはほとんど合成済文字がない)ので結合文字を付した列 〈ы 0301〉 に置き換えられる。従って、後は OpenType フォントがこれを正しく出力するための情報(合成済グリフやアンカー等)を持っているかに依存する(のだと思う)のだが、残念ながら「TeX Gyre Termes」は持っていないようだ(元々 TeX Gyre はキリル文字には強くない)。

というわけで、フォントを Doulos SIL に変えることにする。sample.tex の中の「{TeX Gyre Termes}」を「{Doulos SIL}」に変更して再びコンパイルする。


! LuaTeX error .../share/texmf/tex/luatex/luaotfload/otfl-font-nms.lua:108: att
empt to index field 'names' (a nil value).

\scan_stop:
l.5 \setmainfont[Ligatures=TeX]{Doulos SIL}

?

何だとおぉぉーーー!!?

原因を調べてみると、mkluatexfontdb で生成されたファイル c:/usr/local/share/texmf/tex/luatex/luaotfload/names/otfl-names.lua の中に、names テーブルが欠如しているものがあった。つまり、正常な場合、例えば「IPAex明朝」のエントリは


{
["familyname"]="IPAexMincho",
["filename"]={ "ipaexm.ttf", false },
["fontname"]="IPAexMincho",
["fullname"]="IPAexMincho",
["names"]={
["family"]="IPAexMincho",
["fullname"]="IPAexMincho",
["psname"]="IPAexMincho",
["subfamily"]="Regular",
},
["size"]={},
["slant"]=0,
["weight"]=400,
["width"]=5,
},

となっているところ、1 つだけ、["names"]={ ... } の部分が抜けているエントリが存在したのである。これは恐らくフォント自体の問題と推測される。そこで、取り敢えずそのエントリを手動で削除した。そしてもう一度コンパイルを試みると、今度は成功した。

アクセントも正しい位置に置かれている。