LaTeX フォーマット(pLaTeX / LuaLaTeX / XeLaTeX)

pdflatex とは何かと訊かれたら、正確な答えは「プログラムの名前」ではありません。pdfTeX というエンジンを、LaTeX というフォーマットを積んだ状態で起動したもの です。pdflatexlualatexplatex とコマンド名が並ぶと別々のソフトウェアに見えますが、実際には エンジン(実行されるプログラム)× フォーマット(先にコンパイルしておいたマクロ群) という二つの軸の組み合わせにすぎません。この軸が見えると、.fmt ファイルとは何か、なぜ latex を実行すると PDF ではなく DVI が出るのか、そして LaTeX3 は結局どうなったのかまで、まとめて説明がつきます。

エンジンとフォーマットの違い

エンジンは実行ファイル、フォーマットはデータです。 エンジンは .tex を読んで組版する実行ファイルそのもので、texpdftexxetexluahbtexeuptex などがあります。フォーマットは \documentclass\section といったマクロを大量に集め、あらかじめ展開して一つのダンプ(.fmt ファイル)に固めたもの。起動時にエンジンがその .fmt を一瞬で読み込むので、実行のたびに何万行ものマクロを定義し直さずに済みます。

したがって 「LaTeX」はフォーマットの名前であって、エンジンの名前ではありません。 同じ LaTeX フォーマットを違うエンジンの上で走らせることができ、あなたが打つコマンド名がその エンジン+フォーマットの組 を指定しています。この対応表は推測に頼る必要がなく、TeX Live のなかに fmtutil.cnf という一枚の設定ファイルとして実在します。書式は「フォーマット名/エンジン名/ハイフネーションパターン/引数」の 4 列で、TeX Live 2024 版には 54 行——つまり 54 通りの組み合わせが登録されています。

terminal
$ grep -E '^(tex|latex|pdflatex|lualatex|xelatex|uplatex|amstex|pdfcsplain) ' \
      $(kpsewhich fmtutil.cnf)

# format      engine     hyphenation                 arguments
tex           tex        -                           tex.ini
latex         pdftex     language.dat                *latex.ini
pdflatex      pdftex     language.dat                *pdflatex.ini
xelatex       xetex      language.dat                -etex xelatex.ini
lualatex      luahbtex   language.dat,language.dat.lua lualatex.ini
uplatex       euptex     language.dat                *uplatex.ini
amstex        pdftex     -                           *amstex.ini
pdfcsplain    luatex     -                           csplain.ini
pdfcsplain    pdftex     -                           csplain-utf8.ini
pdfcsplain    xetex      -                           csplain.ini

この表から二つのことが読み取れます。第一に、同じフォーマット名が複数のエンジンに現れうる こと——pdfcsplainluatexpdftexxetex の三つの行を持ちます。フォーマットとエンジンが直交していることの、これ以上ない証拠です。第二に、引数の先頭に付く *。これは e-TeX 拡張を有効にしてダンプせよという指示で、ファイル自身の冒頭コメントが「-etex オプションと本質的に等価」と説明しています。latex の行には * があり、Knuth の tex の行には無い——現代の LaTeX が e-TeX 前提であることが、この一文字に凝縮されています。

.fmt ファイルの中身は何か

エンジンの内部状態をまるごと保存したメモリのダンプです。 ソースコードでもテキストでもありません。マクロの定義、カテゴリコード、ハイフネーションパターン、数式フォントの割り当て——latex.ltx を最後まで読み終えた時点でエンジンの記憶にあるものが、そのままバイナリとして書き出されています。TeX Live 2024 の latex.fmt はおよそ 8.2 MB。この 8.2 MB を読み直す時間と、latex.ltx を毎回解釈し直す時間の差が、LaTeX の起動が一瞬で済む理由です。

ここに、エンジンとフォーマットの関係が ファイルシステムの形で見えている 場所があります。.fmt は「フォーマット名」ではなく エンジン名のディレクトリ に置かれるのです。TeX Live 2024 の texmf-var/web2c/ の下には tex/pdftex/xetex/luahbtex/euptex/ といったディレクトリが並び、それぞれの中にそのエンジンでダンプされたフォーマットが入っています。tex/tex.fmt は plain TeX、pdftex/latex.fmt は LaTeX、euptex/uplatex.fmt は upLaTeX——同じ .fmt という拡張子でも、どのエンジンで作ったかによって別物です。

terminal
# Formats are filed by ENGINE, not by format name.
$ ls /usr/local/texlive/2024/texmf-var/web2c/
aleph  euptex  hitex  luahbtex  luajittex  luatex  metafont  pdftex  tex  xetex

$ ls /usr/local/texlive/2024/texmf-var/web2c/euptex/
eptex.fmt  euptex.fmt  platex.fmt  ptex.fmt  uplatex.fmt  ...

# Ask kpathsea which .fmt a given engine would load.
$ kpsewhich -engine pdftex latex.fmt
/usr/local/texlive/2024/texmf-var/web2c/pdftex/latex.fmt

$ ls -l $(kpsewhich -engine pdftex latex.fmt)
-rw-r--r--  1 root  wheel  8221690 May  4  2024 .../pdftex/latex.fmt

フォーマットを作る側の仕組みも単純です。エンジンを -ini 付きで起動すると、.fmt を読まない「初期化モード」になります。その状態で latex.ltx のようなソースを読ませ、最後にプリミティブ \dump を実行すると、そのときの内部状態が .fmt として書き出されます。かつて別の実行ファイルだった initex は、この -ini 起動の別名にすぎず、いまでは tex へのシンボリックリンクとして残っているだけです。

フォーマットを作り直す — fmtutil

.fmt を作り直すコマンドが fmtutil です。fmtutil.cnf を読み、そこに書かれたエンジンと引数でフォーマットを一つずつダンプし直します。通常は配布物の更新時に自動で走るので手で叩く機会は多くありませんが、カーネルやハイフネーションパターンを差し替えたのに反映されない ときは、たいていフォーマットが古いままです。よく使う形は fmtutil-sys --all(全部作り直す)と fmtutil-sys --byfmt latex(一つだけ)の二つです。

terminal
# Rebuild one format (writes into the system tree; needs write permission).
$ fmtutil-sys --byfmt latex

# Rebuild every format listed in fmtutil.cnf.
$ fmtutil-sys --all

# Rebuild only the formats that use a given engine.
$ fmtutil-sys --byengine luahbtex

# Personal tree instead of the system tree (no root needed).
$ fmtutil-user --byfmt pdflatex

# Where did the format end up, and when was it built?
$ kpsewhich -engine pdftex latex.fmt

-sys-user の違いは、書き込み先が システムのツリー(TEXMFSYSVAR)か、利用者ごとのツリー(TEXMFVAR)か です。管理者権限がある環境なら -sys を使うのが素直で、共有マシンで自分の分だけ差し替えたいときに -user を選びます。ただし混在させると「直したはずなのに直っていない」の温床になるので、プロジェクトでは片方に統一しておくのが安全です。なお fmtutil.cnf そのものはディストリビューションの管理下にあり、ファイル冒頭のコメントが「このファイルを手で編集しても更新時に失われる」と明記しています。恒久的に変えたい場合は fmtutil-sys --enablefmt などの用意された手順を使います。

LaTeX2e — いま動いているフォーマットの正体

今日「LaTeX」と言えば、ほぼ例外なく LaTeX2e を指します。レスリー・ランポートが作った LaTeX マクロの現行版で、1994 年に登場し、いまは LaTeX Project が保守しています。「2e」は先行する LaTeX 2.09 からの「小改訂」を意味し、当時は長く計画されていた LaTeX3 への中間段階のつもりでした。手元のフォーマットが何なのかは自分で確かめられます——カーネル latex.ltx\def\fmtname{LaTeX2e} と名乗り、TeX Live 2024 同梱版では \fmtversion2023-11-01\patch@level1 です。

カーネルはいま 年に 2 回ほどの定期リリース で更新されます。「では最新版は何か」を数字で覚えても意味がありません——半年で古くなるからです。代わりに、自分の環境で latex.ltx\fmtversion を見る習慣をつけてください。それが、いま実際にダンプされているカーネルの日付です。次のリリースを先取りして試したい人のために、TeX Live は 開発版フォーマット も並べて用意しています。fmtutil.cnf には latex-devpdflatex-devxelatex-devlualatex-devuplatex-dev の行があり、pdflatex-dev main.tex のように打てば次期カーネルで組めます。本番の原稿には使わず、クラスやパッケージの互換性検査に使うものです。

LaTeX3 は結局どうなったのか — expl3 という答え

LaTeX3 という「フォーマット」は、ついに出ませんでした。 出たのは、LaTeX3 のプログラミング言語のほうです。expl3(L3 programming layer)と呼ばれるその層は、独立した新カーネルとしてではなく、LaTeX2e の内側に取り込まれる形で 実現しました。したがって「LaTeX3 に移行すべきか」という問いには答えがありません。移行先が無いのではなく、すでに使っている からです。

その転機は記録に残っています。LaTeX News 31(2020 年 2 月 2 日)は、expl3 が「この 10 年で実験的なものから広く安定したものへ移った」と述べ、そのリリースで カーネルがフォーマットの構築時に expl3 の大部分を先読みするよう調整した と報告しました。狙いは速度です。fontspec を読む XeLaTeX / LuaLaTeX の文書では Unicode データの読み込みが重く、それを毎回やらずに済ませるためでした。

いまや expl3 はフォーマットの一部です。カーネル latex.ltx を読むとその処理が見えます——expl3 が既にあれば Skipping: expl3 code already part of the format と告げて先へ進み、無ければ \input expl3.ltx で読み込み、expl3.ltx そのものが見つからなければ \errmessage{LaTeX requires expl3} で止まります。expl3 はもはや任意のパッケージではなく、LaTeX2e の必須部品 だということです。文書やパッケージ側での \RequirePackage{expl3} は、古いフォーマットを使う人のためになお推奨されていますが、新しいフォーマットでは実質的に何もしません。expl3 の文法そのもの——\ExplSyntaxOn\cs_new:Npnl3kernel の型付き変数——は専用のページが扱います。

LaTeX 以外のフォーマット

LaTeX はもっとも広く使われるフォーマットですが、唯一のものではありません。fmtutil.cnf に並ぶ 54 行のうち LaTeX 系はごく一部で、残りは別のマクロ体系です。ここで amstex に触れておく価値があります。実行ファイルとしての amstexpdftex へのシンボリックリンクにすぎず、fmtutil.cnfamstex pdftex - *amstex.ini という行が、pdfTeX エンジンに AMS-TeX のマクロを積んだフォーマットを指定しています。AMS-TeX はアメリカ数学会が plain TeX の上に作った数学組版用のマクロ集で、LaTeX を使う人にとっては amsmath パッケージに事実上置き換わりました。新しい文書を AMS-TeX で書き始める理由はほぼありません。

フォーマットダンプするエンジン何であるか
textexクヌースの plain TeX。e-TeX 拡張を持たない唯一のフォーマット
latexpdftexLaTeX2e。DVI モードの pdfTeX で走り、.dvi を出力する
pdflatexpdftex同じ LaTeX2e を PDF 直接出力で。欧文の事実上の既定
xelatexxetexLaTeX2e を XeTeX の上に。システムフォントと Unicode
lualatexluahbtexLaTeX2e を LuaHBTeX の上に。Lua と HarfBuzz が使える
platex / uplatexeuptex日本語組版向けの LaTeX2e。DVI を出し dvipdfmx で PDF に
amstexpdftexAMS-TeX。plain TeX 上の数学用マクロ。LaTeX では amsmath に置き換わった
cont-enpdftex / xetexConTeXt(MkII)。LaTeX とは別系統の総合フォーマット。二つのエンジンに登録がある
csplainpdftexチェコ語・スロヴァキア語向けの plain TeX 派生。-etex を明示して作られる

pLaTeX / upLaTeX — 日本語のための LaTeX フォーマット

pLaTeX と upLaTeX は、日本語組版用のエンジンに LaTeX フォーマットを載せたものです。 縦書き、ルビ、和文の行組版といった日本語固有の処理は、アスキーが拡張した pTeX 系のエンジン が担当します。TeX Live 2024 の fmtutil.cnf を見ると、platexuplatexeuptex エンジン の行に登録されており、フォーマット側の初期化ファイル(*platex.ini*uplatex.ini)で振る舞いを分けていることが分かります。両者の違いは実行ファイルではなく フォーマットの文字の扱い にあり、platex は従来の pTeX 互換の挙動を保ち、uplatex は内部 Unicode を前提にします。新規の日本語文書なら uplatex が標準的な選択です。

この系統は 必ず DVI を出力し、日本語を含む DVI を dvipdfmx で PDF に変換する二段構えです(uplatex file.tex のあとに dvipdfmx file.dvi)。索引には upmendex を組み合わせます。クラスファイルは奥村晴彦氏の jsarticlejsbook(pLaTeX 用)と ujarticle などの Unicode 版、そして JIS X 4051 に沿った比較的新しい jlreq がよく使われます。エンジン内部の詳細——JFM、禁則処理、縦組みの実装——は「pTeX ファミリー」のページが扱います。

どのコマンドがどの組み合わせなのか

同じ LaTeX フォーマットでも、コマンド名が背後のエンジン、出力形式、フォントの扱いを決めます。下の表は コマンド名を起点に左から右へ 読んでください。実務上いちばん効くのは右端の列で、fontspec が使えるかどうかがそのままエンジンの選択に直結します。

コマンドエンジン出力Unicode / システムフォント
latexpdfTeX(DVI モード)DVI — 別ツールで変換が要る不可(inputenc などが要る)
pdflatexpdfTeXPDF を直接不可(inputenc などが要る)
platexe-upTeX(pLaTeX 互換の設定)DVI → dvipdfmx和文は従来のフォント設定で
uplatexe-upTeXDVI → dvipdfmx内部 Unicode。和文フォントは従来方式
lualatexLuaHBTeXPDF を直接可 — fontspec / luatexja
xelatexXeTeXPDF(内部で xdvipdfmx を経由)可 — fontspec
terminal
# Engines that write PDF finish in one step.
$ pdflatex main.tex      # -> main.pdf
$ lualatex main.tex      # -> main.pdf
$ xelatex  main.tex      # -> main.pdf

# DVI-based routes add a conversion step.
$ latex    main.tex      # -> main.dvi   (pdfTeX in DVI mode)
$ uplatex  main.tex      # -> main.dvi   (Japanese)
$ dvipdfmx main.dvi      # -> main.pdf

ログの 1 行目を読む — 組み合わせを固定する

ログの 1 行目には、エンジンとフォーマットの両方が書いてあります。 This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=latex) を分解すると、前半がエンジンとそのバージョン、(preloaded format=...) が読み込まれたフォーマットです。This is LuaHBTeX ...This is XeTeX ...This is e-upTeX ... も同じ読み方をします。共同作業で「同じコマンドなのに出力が違う」となったとき、この 1 行を突き合わせるだけで、エディタの設定の問題か TeX Live の年次やフォーマットの違いかが即座に切り分けられます。

そして、いったん組み合わせが決まったら プロジェクトに書き留めて固定します。 学位論文なら、扉・目次・図表・参考文献まで通ったところで、コマンドを README か .latexmkrc に書いておきます。途中で lualatex から uplatex に移すと、フォント選択・和文の扱い・PDF 生成の経路・参考文献処理までが一度に変わります。どうしても切り替えるなら、本原稿に戻る前に小さな試験ファイルで全機能を確かめてください。どのエンジンを選ぶかの判断材料——速度、パッケージの互換性、日本語の事情——は「エンジンの選び方」のページにまとめてあります。