「pLaTeXからLuaLaTeXへの移行」に関するクイズ


TeX界隈(のごく一部)では「(u)pLaTeXからLuaLaTeXへの移行は容易であるか」という議論があるようです。議論の内容についてはともかくとして、このテーマについて、クイズをチョット出題してみます。“(u)pLaTeXからLuaLaTeXへの移行に自信ニキ”な人は挑戦してみてください。

問題

以下に掲げるpLaTeX文書のプレアンブルを、LuaLaTeXにおいてほぼ“同等”な出力が得られるものに改修して下さい。

\documentclass[dvipdfmx,a4paper]{jsarticle}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
%% ブックマーク
\usepackage[hidelinks,pdfusetitle]{hyperref}
\usepackage{pxjahyper}
%% 和文フォント
\usepackage[deluxe]{otf}
\usepackage[unicode,yu-win10]{pxchfon}
%% 画像
\usepackage[dvipdfmx]{graphicx}
\usepackage{tikz,scsnowman}
%% タイトル
\title{ゆきだるま{\ajSnowman}は素敵}
\author{幸せな{\LaTeX}}

\begin{document}
% (以降文書本体)

模範解答

\documentclass[a4paper]{ltjsarticle}
\usepackage[no-math]{fontspec}
%% ブックマーク
\usepackage[unicode,hidelinks,pdfusetitle]{hyperref}
%% 和文フォント
\usepackage[deluxe,yu-win10]{luatexja-preset}
%% 画像
\usepackage{graphicx}
\usepackage{tikz,scsnowman}
%% タイトル
\title{ゆきだるま☃は素敵}
\author{幸せな{\LaTeX}}

\begin{document}
% (以降文書本体)

ただし、これは\ajSnowmanなどの「japanese-otfパッケージの外字入力命令」を使わずに直接“☃”などのUnicode文字を書く方針をとった場合です。文字入力命令を使いたい場合はluatexja-otfパッケージが追加になります。

\documentclass[a4paper]{ltjsarticle}
\usepackage[no-math]{fontspec}
%% ブックマーク
\usepackage[unicode,hidelinks,pdfusetitle]{hyperref}
%% 和文フォント
\usepackage[deluxe,yu-win10]{luatexja-preset}
\usepackage{luatexja-otf}
%% 画像
\usepackage{graphicx}
\usepackage{tikz,scsnowman}
%% タイトル
\title{ゆきだるま{\ajSnowman}は素敵}
\author{幸せな{\LaTeX}}

\begin{document}
% (以降文書本体)

解説

念のため:ファイルの文字コード

問題のファイルはWindows上のpLaTeX文書です(pxchfonでyu-win10が指定されているので)。この状況では、今でもまだシフトJISが使われることが多いと思います。LuaLaTeXではファイルの文字コードはUTF-8しか使えないことに注意しましょう。

※もし \usepackage[utf8]{inputenc} が使われている場合は、それは削除します。

文書クラス

改修前
\documentclass[dvipdfmx,a4paper]{jsarticle}

これは知っていると思います。jsarticleクラスは(u)pLaTeX専用であり、LuaLaTeXでは代わりにltjsarticleクラスを使います。

※その他のjs~の文書クラスも同様で、LuaLaTeXでは対応するltjs~という名前のクラスを代わりに使います。
※ltjs~クラスではluatexjaパッケージが内部で読み込まれるので、LuaTeX-jaの日本語処理機能が使えるようになります。

クラスオプションのdvipdfmxはグローバルの「ドライバ指定オプション」で、dvipdfmxの使用を指定するものです。LuaLaTeXはPDFファイルを直接出力するエンジンであり、当然dvipdfmxは使わないので、dvipdfmxは削除します。

※現在では、PDF出力のエンジンに対するドライバ指定オプション(luatexなど)は指定しないのが原則です。

その他のクラスオプション(a4paperなど)はそのまま通用します。

※念のため:これはltjsarticleが「jsarticleと高い互換性をもつように特別に設計された」クラスだからです。互換のない別のクラスに変えるのであれば、当然、クラスオプションの指定も見直す必要があります。

改修後
\documentclass[a4paper]{ltjsarticle}

欧文フォント設定

改修前
\usepackage[T1]{fontenc}
\usepackage{lmodern}

欧文フォントとして、Latin ModernをT1エンコーディングで用いています。LuaLaTeXでは当然Unicodeフォントを用いるべきですから、fontspecパッケージを読み込みます。

\usepackage{fontspec}

fontspecでは既定で(Unicodeの)Latin Modernフォントが使われるので、明示的な欧文フォント指定(setmainfontなど)は不要です。

数式フォント設定

改修前の設定では、数式フォントのパッケージ(newtxmathなど)の読込がないので、既定のComputer Modernが使われることになります。

LuaLaTeXを使う場合は数式フォントの設定の方針には、次の3つがあります。

  1. fontspecの既定動作: 数式英字フォント(\mathrm\mathsfなど)がテキスト用のフォント(\setmainfontなどで指定したもの)と同じに変更される。なので$\mathrm{höğé}$とかが通るようになる。それ以外は(仕様上は)変わらない。
  2. fontspecにno-mathを指定: この場合、数式関連の設定は何も変更されない。なので数式部分は従来通り(和文を除き)全てASCII文字で書くことになる。
  3. unicode-mathパッケージを使用する: LaTeXの数式機能が完全にUnicode対応になる(Unicode数式フォントの使用が前提になる)。なので$\mathrm{höğé}$$h+o×g⊕e$も可能になる。

このうち、1は「中途半端にUnicodeになるので数式記号パッケージとの併用でトラブルが起こりやすい」というデメリットがあり、また日本語使用者にとってはメリットが少ないため、避けた方がよいでしょう。3の「数式処理を完全にUnicode前提にする」というのは魅力的ではありますが、数式機能の使い方全体を見直す必要があり学習コストが高いので、「とにかく(u)pLaTeXから移行したい」というケースでは向いていません。従って、ここでは最も無難な2を選択することにします。つまり、fontspecにno-mathオプションを追加します。

改修後
\usepackage[no-math]{fontspec}

これで、数式の設定はpLaTeXのときと何も変わらないことになりました。

hyperref

改修前
\usepackage[hidelinks,pdfusetitle]{hyperref}
\usepackage{pxjahyper}

hyperrefで指定するPDFの文書情報(ブックマークなど)に含まれる非ASCII文字を正常に処理したい場合、(u)pLaTeXではpxjahyperパッケージを併用するのが(最近では1)一般的です。LuaLaTeXの場合は、hyperrefにunicodeオプションを指定する必要があります。

改修後
\usepackage[unicode,hidelinks,pdfusetitle]{hyperref}

unicodeの代わりにunicode=truepdfencoding=unicodeと書いても等価です。
※hyperrefはドライバ依存性をもつパッケージですが、前述の通り、LuaLaTeXではドライバ指定は省略するのでした。

和文フォント設定

改修前
\usepackage[deluxe]{otf}
\usepackage[unicode,yu-win10]{pxchfon}

和文フォントについては、「Windows 10付属の游フォントを多ウェイトで使う」という指定になっています。

LuaLaTeX+LuaTeX-jaの下では、luatexja-fontspecパッケージの機能を利用すれば和文フォントが極めて自由に設定できます(参考)。従ってこれが和文フォント設定に対する一般的な解決法となります。

\usepackage{luatexja-fontspec}
\setmainjfont{YuMincho-Regular}[% 游明朝
  FontFace={l}{n}{YuMincho-Light}, % 細字
  BoldFont=YuMincho-Demibold       % 太字
]
\setsansjfont{YuGothic-Medium}[% 游ゴシック
  BoldFont=YuGothic-Bold % 太字
]

※luatexja-fontspecを読みこんだ時点で、既に多ウェイトの指定が可能なことに注意しましょう。つまり「多ウェイトにするためのotf+deluxe」はluatexja-fontspecで代用できます2

改修前の設定ではpxchfonの「プリセット指定」のyu-win10を利用していますが、LuaTeX-jaでも「プリセット指定」を提供するluatexja-presetパッケージが存在します。pxchfonと同様に、yu-win10で「Windows 10付属の游フォント」用の設定ができるので、こちらを利用することにしましょう。

改修後
\usepackage[deluxe,yu-win10]{luatexja-preset}

※自分でフォント設定を書かずにluatexja-presetに任せるわけなので、deluxeを渡す必要があります3。その他、otfパッケージのjis2004boldについても、代わりにluatexja-presetに渡すことができます。

もうチョットotfパッケージの話

実は、改修前のプレアンブルでは、otfパッケージは「多ウェイトにする」以外の役割ももっています。

改修前
\title{ゆきだるま{\ajSnowman}は素敵}

つまり、JIS外字4の“☃”(U+2603)の出力のために\ajSnowmanを使っています。もしかすると、他にも\ajMaru{1}(①;U+2460)や\UTF{9DD7}(鷗)を文章中で使っているかもしれません。

このような「JIS外字のためのotfパッケージの命令」をLuaLaTeXで使いたい場合は、luatexja-otfパッケージを利用することになります。

改修後
\usepackage{luatexja-otf}
%......
\title{ゆきだるま{\ajSnowman}は素敵}

しかし、“☃”も“①”も“鷗”もUnicodeにある文字なので、UTF-8の文書ソースでは直接入力ができて、またその方がソースの可読性が高くて好ましいかもしれません。そう考えるなら、luatexja-otfの読込は不要で、当該の命令を文字そのもので置き換えることになります。

改修後
\title{ゆきだるま☃は素敵}

これまで見てきたように、otfパッケージは多くの目的をもつパッケージであるため、「LuaLaTeXでのotfパッケージの代わりは何か」を考える場合は、otfを何のために使っているかの見極めが必要です。以下に整理してみましょう。

  • UnisodeにあるJIS外字を使いたい → Unicode文字を直接入力する
  • \ajMaru\UTFなどの文字入力命令を使いたい → luatexja-otf
  • UnicodeにないAdobe-Japan1の文字を使いたい → luatexja-otf
  • 多ウェイトにしたい/漢字字体切替をしたい → luatexja-fontspecで必要な和文フォント設定を記述する
    • 和文フォント設定を簡単に行いたい → luatexja-presetのプリセット設定を利用する

その他諸々

改修前
\usepackage[dvipdfmx]{graphicx}
\usepackage{tikz,scsnowman}

これらはドライバ依存のパッケージです5。既に述べた通りで、LuaLaTeXではドライバ指定を省きます。

改修後
\usepackage{graphicx}
\usepackage{tikz,scsnowman}

以上、ここまでに述べた改修を全部まとめたのが先に示した模範解答になります。

まとめ

ワタシハ LuaLaTeXへの移行 チョット デキル


  1. pxjahyperが普及する前は、dvipdfmxのpdf:tounicodespecial命令を直接書き込むというハックがよく行われていました。 

  2. ただし、細字を選択する高水準命令の\ltseriesはluatexja-fontspecでは提供されないので、\fontseries{l}\selectfontと低水準命令を使う必要があります。これは極太の\ebseriesについても同様です。もちろん、自分でマクロを定義してもかまいません。 

  3. deluxeがないと単ウェイトの設定になります。なお、deluxeオプションを付けた場合は、otf+deluxeの場合と同様に、\ltseries\ebseries\mgfamilyの高水準命令が提供されます。 

  4. 「JIS外字」とはJIS X 0208にない文字のことを指します。(“☃”はJIS X 0213には入っています。) 

  5. ちなみに、この例では既にグローバルオプションにドライバ指定dvipdfmxがあるため、graphicxのdvipdfmxは冗長です。