如何选择引擎/格式

「LaTeX 引擎该选哪一个?」——这是一份先给结论的决策指南,供你在 pdfLaTeX、XeLaTeX、LuaLaTeX、upLaTeX 四者之间犹豫时使用。简短的回答是:西文用 pdflatex,需要系统字体或 Unicode 就用 xelatexlualatex,日文用 uplatexlualatex。但这四者并非同等的四个选项:它们跑的都是同一个 LaTeX 格式,不同的只是底下的引擎。下文将依次讨论 XeLaTeX 与 LuaLaTeX 的正面对比、为什么日文的答案会不同,以及切换引擎时真正会坏掉的东西。

按用途给出的最短答案

对绝大多数人来说,这四行就够了。下面这些名字是 引擎(真正运行的程序)× 格式(LaTeX 这套命令体系) 的组合,以你实际敲下的命令名给出。拿不定主意时,先服从投稿目标或模板的指定;只有在没有任何指定时,才轮到下面这些分支。

  • 西文(英语及欧洲各语言),最稳妥的路pdfLaTeXpdflatex)。LaTeX 的事实标准,资料与先例最多——也是唯一能用上全部微观排版功能的引擎。
  • 想直接使用操作系统的字体、混排多种语言、配置尽量轻XeLaTeXxelatex)。有了 fontspec,一句 \setmainfont{...} 就够了。
  • 在此之上还想用程序控制排版/押注未来LuaLaTeXlualatex)。可以用 Lua 深入排版过程,内核中与引擎相关的新功能也往往先落在这里(例如 ltnews34 里的 LuaTeX 回调条目)。
  • 日文upLaTeXuplatex)是稳定的主流,LuaLaTeX + luatexja 是 Unicode 原生的现代路线。这里不推荐 XeLaTeX,理由见下文。jlreq 文档类在前两者上都能工作。

XeLaTeX 与 LuaLaTeX,该选哪个

这两者在「都支持 Unicode 与系统字体」这一点上完全一致,所以最让人犹豫。一句话就能定夺:想把手上这份文档轻快地做完,就用 XeLaTeX;这是一份要长期养大的文档,就用 LuaLaTeX。 二者之差不是功能表上的胜负,而是你付出的成本种类不同:XeLaTeX 在配置与等待上便宜,LuaLaTeX 在长远与可扩展性上便宜。请带着这个视角读下面的表。

比较之点XeLaTeXLuaLaTeX
fontspec可用;可以直接把操作系统的字体名交给它,逐个试名字很快可用;字体解析由 luaotfload 负责,指定写法更为严格
microtype只有字符凸出。 字体伸缩、词间距调整、字距调整(letterspacing)都不起作用凸出与字体伸缩兼有,letterspacing 也有效,西文成品接近 pdfLaTeX
speed居中;启动与排版都比 LuaLaTeX 轻最慢;在大型文档上可能耗时数倍于 pdfLaTeX
programmability只有 TeX 宏;没有伸进引擎内部的入口内嵌 Lua;\directlua 与回调让你能介入排版过程本身
output-route先经过中间的 .xdv,再由内置的 xdvipdfmx 转成 PDF直接写出 PDF,没有中间文件
japanese不是可行的选择;jlreq 根本不接受 XeLaTeX通过 luatexja 可以正经排版;jlreq 也以 lualatex 选项支持
pstricks能工作,因为其路径经过类 DVI 阶段;若已有 PSTricks 资产,选它基本上不能工作;PSTricks 图需要移植
development维护稳定,但新功能的重心不在这里内核中与引擎相关的新增功能往往先落在这里

从这张表可以划出一条实务界线。选 XeLaTeX 的场合:想用名字指定本机字体并立刻开始排版;主要目的是多语言混排,且对西文微观排版没有强烈追求;手上还带着既有的 PSTricks 图;以及重编译足够频繁、等待时间能被明显感知。选 LuaLaTeX 的场合:想把西文成品打磨到底(需要 microtype 的字体伸缩);日文要以 Unicode 处理;想给排版本身编程,比如读取外部数据来生成表格;以及这份文档要维护数年之久。另外请注意,在日文场景中,XeLaTeX 根本不进入这道二选一。

日文该选哪个引擎,以及答案为何不同

日文只在 uplatexlualatex 之间二选一,XeLaTeX 出局。 英语圈的文章通常止步于「要 Unicode 与系统字体,就用 XeLaTeX 或 LuaLaTeX」,但这个等式在日文里不成立。原因是日文排版所要求的,远不止「能输出 Unicode 字符」:禁则处理、和文与西文之间的四分空、竖排、注音假名,以及和文专用的字体度量(JFM)。这需要一个实现了这一切的层,而这样的层只存在于 pTeX 系引擎 与 LuaTeX 上的 luatexja

这一点从文档类那边也能得到印证。遵循 JIS X 4051 的日文排版类 jlreq 以选项接收引擎,而 jlreq.cls 所接受的引擎恰好只有三个:platexuplatexlualatexxelatex 不在其中。 这并非说 XeLaTeX 下无法处理日文——zxjatype 之类的宏包是存在的。但主要的日文文档类与积累下来的资料都集中在上述三者,期刊或院校提供的日文模板也基本不出这个范围。实务上的结论是:只要文档含日文,就不要把 XeLaTeX 当作首选。

那么 uplatexlualatex 该选哪个?自然的界线是:已有既存资产就用 uplatex,全新且要长期使用就用 lualatex uplatex 快,日文排版规则已经非常成熟,学会与出版社发放的文档类大多以它为前提。但它的输出必定是 DVI,因而要走经 dvipdfmx 的两段流程,字体也按传统方式配置。lualatex + luatexja 可以直接使用 Unicode 与系统字体,luatexja-fontspec 允许以名字指定和文字体,但排版时间会明显变长。另外,指定和文字体用的不是裸的 fontspec

决定取舍的几条轴

当快速答案不适用,或者你想知道为什么时,我们逐条来看这些轴。它们大多最终都归结为:该引擎如何处理字体与字符编码

字体。 pdfTeX 使用 TeX 传统的字体模型,即 TFM(TeX Font Metric)加 Type1/PK 字体。它无法直接指向操作系统里安装的字体。XeTeX 与 LuaTeX 在这里分歧最为明显——二者都能直接使用系统上已有的 TrueType / OpenType 字体,通过 fontspec 宏包以 \setmainfont{Times New Roman} 这样的名字指定。反过来说,fontspec 需要 XeTeX 或 LuaTeX,在 pdfLaTeX 下无法工作。

输入编码。 XeTeX 与 LuaTeX 内部是 Unicode 原生的,直接接受 UTF-8 源文件。pdfTeX 自 2018 年的 LaTeX 发行版起也以 UTF-8 为默认输入编码,不再需要写 \usepackage[utf8]{inputenc}——但它在内部仍然映射到 8 位字体编码(如 T1),因此哪些字符能出取决于你的 fontenc 与字体,无法随手键入任意 Unicode 或中日韩字符。若想轻松键入多语言文字与符号,XeTeX / LuaTeX 更占优势。

宏包兼容性。 这是实务中最常被忽视的陷阱。有些宏包是特定引擎专用的。fontspecunicode-math 只用于 XeTeX / LuaTeX。反过来,pstricks 在走 DVI 路径的 pdfLaTeX 与 XeLaTeX 下可用,但在 LuaLaTeX 下原则上不可用。不兼容也会朝反方向发生:照老教程写出的源码,未必能在新引擎上编译。铁律是:首先确认你的模板或投稿方的文档类要求哪个引擎。

速度。 差异真实存在,而且能被感知。次序是 pdfTeX 最快,XeTeX 居中,LuaTeX 最慢——但差距出现在与排版量成正比的部分,而不是启动阶段。在接近空白的单页文档上,三者几乎难分伯仲;到了几百页的规模,LuaLaTeX 要花上 pdfLaTeX 数倍的时间(实测数据见 LuaTeX 那一页)。写稿期间的重编译动辄成百上千次,这个差距会累积起来。反过来说,十几页的论文完全不必为此操心。

微观排版(microtype)。 能切实提升西文观感的,是 microtype字符凸出(protrusion)字体伸缩(expansion)。这里的引擎差异很大,而且 microtype 自己的 README 就写得明明白白:凸出在 pdfTeX、LuaTeX、XeTeX 三者上都有效,但字体伸缩只在 pdfTeX 与 LuaTeX 上有效,XeTeX 无效。此外,词间距与额外字距的调整仅限 pdfTeX,禁用连字与字距调整(letterspacing)则需要 pdfTeX 或 LuaTeX。若把西文成品的精致度放在首位,pdfLaTeX,其次 LuaLaTeX 是稳妥的选择。

图形与可编程性。 PNG、JPEG、PDF 的导入,在各引擎上都能用 graphicx\includegraphics 以基本相同的写法完成(pdfLaTeX 会自动转换 EPS)。真正拉开差距的是 LuaTeX 特有的 Lua 控制:你可以在排版的各个阶段挂钩,或读取外部数据来生成表格——这些用宏很难写。它与包含 fontspecunicode-math 的现代宏包体系也相处融洽,这正是「面向未来更稳」的依据。

把四个选项并列的比较表

下面按决策轴把四个主要选项并列;第一列是你实际敲下的命令名,microtype 一栏则把凸出与伸缩分开标注。请把这张表当作指南而非判决——pdfLaTeX 配上 \usepackage[T1]{fontenc} 和合适的西文字体宏包,同样能把许多欧洲语言排得很漂亮,而在 XeLaTeX 下凸出依然有效。与其读作「能/不能」的二值,不如读作投入与精致度之间的权衡

命令Unicode / 系统字体microtype速度主要用途
pdflatex不支持(TFM/Type1;可输入 UTF-8 但映射到 8 位)凸出 可 / 伸缩 可最快西文默认;兼容面最广
xelatex支持(用 fontspec 直接使用 OpenType)凸出 可 / 伸缩 不可居中轻松处理多语言与 OpenType
lualatex支持(fontspec 之外还有 Lua 控制)凸出 可 / 伸缩 可最慢面向现代与长期;日文用 luatexja
uplatex日文经 JFM(DVI 路径);可输入 UTF-8仅限西文部分日文论文;稳定的默认

用一个小的试验文件来决定

动笔之前,请用一页的试验文件把候选引擎都跑一遍。 在学位论文或投稿稿件中途更换引擎,字体、图形、参考文献、断行位置会一起变动,让人分不清究竟是什么导致了崩坏。要看的不只是「能不能通过」。还要看日志中的警告、PDF 里的字体嵌入、图形的处理方式,以及协作者能否复现同样的步骤——这四点。

terminal
# Western candidates: same source, three engines.
$ pdflatex engine-test.tex
$ xelatex  engine-test.tex
$ lualatex engine-test.tex

# Japanese candidate: upLaTeX writes DVI, dvipdfmx makes the PDF.
$ uplatex   engine-test.tex
$ dvipdfmx  engine-test.dvi

# Then compare what actually came out.
$ pdffonts engine-test.pdf     # are all fonts embedded?
$ grep -i warning engine-test.log
  • 若有投稿方的模板,就用那份模板来试。 空文件能通过,并不能证明提交用的配置也能通过。
  • 放进一张图、一条独立公式、一条参考文献。 试验若不是正式稿件的缩影,就没有意义。
  • 同时确认文献与索引工具。 用 BibTeX 还是 Biber、用 mendex 还是 upmendex,都会改变 latexmk 的配置。只定下引擎还不够:这一环对不上,构建照样通不过。
  • 决定之后,把引擎写进 .latexmkrc 或 README,以免日后有人随手用别的引擎编译。
  • 把 PDF 对照着看。 若断行位置或字体不同,就把选择该引擎的理由留在项目里。

更换引擎时会坏掉的东西

同一份源码,换了引擎结果也会不同。人们实际最常踩到的是以下四颗雷。

字体与编码的配置会变。 pdfLaTeX 的常备写法 \usepackage[utf8]{inputenc}\usepackage[T1]{fontenc},在 XeLaTeX / LuaLaTeX 下并不需要,通常也不写(这些引擎内部就是 Unicode)。取而代之的是 fontspec\setmainfont。若把 pdfLaTeX 的导言区原封不动搬过去,可能会产生警告或与字体相关的错误。

latex
% For pdfLaTeX (traditional; both lines are optional on current LaTeX)
%   \usepackage[utf8]{inputenc}
%   \usepackage[T1]{fontenc}

% For XeLaTeX / LuaLaTeX: name an OS or TeX font instead
\usepackage{fontspec}
\setmainfont{TeX Gyre Termes}

microtype 的作用方式会变。 同样一句 \usepackage{microtype},在不同引擎上实际生效的功能并不相同——在 XeLaTeX 下,字体伸缩干脆是关闭的。因此在 pdfLaTeX 上调好的版式一旦迁移,行长与断行位置就会略有偏移。在数十页的文档上,总页数增减一页并不稀奇。

可用的宏包会换一批。 有些宏包到了目标引擎上就不再工作,另一些则头一次可用。用 PSTricks 画的图搬到 LuaLaTeX 上无法运行(pstricks 不受支持);反过来,fontspecunicode-math 在 pdfLaTeX 下用不了。期刊与出版社的模板通常预设了特定的引擎,所以先照它办才稳妥。

在日文场景中,和文字体的配置会整体改变。 upLaTeX(pTeX 系)与 LuaLaTeX + luatexja 在和文字体的指定写法与嵌入方式上都是两回事。请把日文文档的迁移痛感估得比西文更高。具体的命令对应关系汇总在「编译命令」那一页。