LaTeX 命令行编译
整理一下关于 pdflatex,xelatex 和
latexmk 的基本使用和配置。
这部分的中文资料其实比较少,因为大部分资料都在关注 LaTeX
应该怎么写,而不是怎么用命令去编译, 本文参考:
- LaTeX技巧912:使用latexmk自动编译LaTeX
- 在终端中编译 LaTeX
- latexmk 的学习
- Latex 编译和编写方案配置 — latexmk + latexworkshop
- Using Latexmk
pdflatex & xelatex
基本使用
这里只考虑 pdflatex 和 xelatex
的命令行基本用法,对于含有中文的文档只考虑使用 xelatex
编译。
最基本的用法如下,使用 pdflatex 和 xelatex
编译指定的源文件,源文件的.tex后缀名可以省略。
1
2pdflatex [options] main.tex
xelatex [options] main.tex
在源文件之前可以添加若干的选项,选项形如-<option1>、-<option2>=<string>,具体选项见下文,注意必须在源文件之前,不允许出现在源文件之后。
默认情况下,编译成功后输出文件<filename>.pdf,还会产生很多各种后缀的杂项文件(例如<filename>.log),
它们存放的位置是执行命令的目录,而不是源文件所在的目录,可以使用下面的选项更改所有文件生成的位置。
注意:
- 源文件的文件名不要含有
\斜杠,对于路径分隔符只支持使用/ - 如果遇到错误可能会输出
?并等待输入,可以输入Q或X回车退出(不区分大小写),或者直接ctrl+z退出。不同的退出方式有一些区别,但是不用管这些,因为编译报错内容的可读性实在太低了(和C++模板报错有得一拼),直接退出算了。
常见选项
pdflatex 和 xelatex
命令的帮助信息列出了许多常见选项 1
2pdflatex -help
xelatex -help
以下是对一些公共的主要选项的解释。
首先是关于编译过程如何处理交互和错误的:
-interaction=STRING:(常用)设置交互模式,用于控制编译过程中如何输出信息和处理错误,方便调试。STRING包括以下几种模式:errorstopmode: (默认)遇到错误时停止编译,等待用户输入或干预。batchmode: 不在命令行中输出任何有关编译的信息,遇到错误时也不提示或等待用户输入,直接继续编译。nonstopmode: 遇到错误时不会暂停编译,继续执行,直到最后显示出来错误的位置与内容。scrollmode: 在屏幕上输出编译信息, 遇到错误会跳过, 但是会在找不到文件时停止编译并等待用户输入。
-file-line-error/-no-file-line-error:(常用)控制是否启用file:line:error样式的错误消息。启用此选项后,错误消息中会包含文件名和行号,方便快速定位错误。-halt-on-error:(似乎不常用)遇到第一个错误时立即停止编译。使用这个选项时,当文档中出现任何错误,编译会中断,帮助更快定位问题。
然后是一些特殊需求的选项:
-synctex=NUMBER:(常用)是否启用 SyncTeX,用于将源文件与生成的 PDF 文件进行同步和双向跳转。NUMBER控制同步信息的详细程度:默认0代表关闭,1代表开启,2代表开启并且更详细。这个选项对使用 LaTeX 编辑器(如 TeXShop 或 TeXworks)进行实时预览时非常有用,具体实现基于xxx.syntex.gz文件,在清理时需要保留。-output-directory=DIR:(常用)将所有生成的文件输出到指定的目录DIR中(包括PDF文件),默认情况下会输出到当前目录中,这个选项可以避免生成的辅助文件(如.log、.aux文件)混杂在源文件目录中,有助于管理输出文件。-jobname=STRING:将编译任务的名称设置为STRING,这会影响生成的输出文件的名称。默认情况下,输出文件名与输入的.tex文件名一致,可以通过此选项更改输出文件名。-shell-escape/-no-shell-escape:启用或禁用\write18命令,它允许 LaTeX 执行外部的 shell 命令(如调用图形转换程序)。-shell-restricted是一种更安全的方式,只允许执行预定义的受限命令。启用 shell escape 可能带来安全风险,因此默认情况下是禁用的。但是
注意:
- 对于
-output-directory=DIR选项的路径,如果是相对路径,那么相对的是执行命令时的目录,而不是源文件所在位置。编译器没有自动创建目录的能力,因此需要手动保证DIR目录已经存在。(latexmk类似选项的行为却不相同,见下文) - 对于
-shell-escape选项,某些宏包(例如minted)在正常使用时需要启用此选项,pdflatex插入eps图片时可能也需要开启这个选项(测试发现,Windows上需要开启,否则编译报错,但是Linux上不需要)。
多次编译
对于复杂情况下的LaTeX文件编译,由于存在交叉引用和文献引用,仅仅执行一遍编译是不够的,需要进行多次编译,并且对于参考文献,还需要在其中搭配
bibtex 或 biber
编译,例如下面的示例源文件main.tex:
1 | % main.tex |
执行如下的多次编译 1
2
3
4pdflatex main.tex
bibtex main.aux
pdflatex main.tex
pdflatex main.tex
大致解释一下每次编译的行为:
- 第一次
pdflatex将\cite的的参数 (也就是使用到的 .bib 文件中的 key) 信息写入了main.aux文件 bibtex读取哪些 key 被用到了, 然后根据这些 key 生成main.bbl文件- 第二次
pdflatex读取main.bbl文件, 将\cite引用的正确的序号写进main.aux - 第三次
pdflatex读取main.aux文件, 在输出文件中使用正确的\cite编号
latexmk
介绍
除了手动执行多次编译,还有一种值得介绍的自动化工具:latexmk,它会自动探测并执行多次编译。
可以将其理解为针对 LaTeX 定制的 make,它基于 Perl
实现,另一种类似的处理多次编译的工具是 MikTex 的
textify。
最近还有一些人试图模仿
latexmk开发新工具,例如基于Python实现的PyTeXMK,因为基于Perl实现的latexmk从各个方面来看都有点过时了。
基本使用
latexmk 支持如下命令行选项来指定编译引擎:
-pdf:(常见)当使用pdflatex的时候确保输出 PDF 文件(否则会生成dvi文件,很奇怪)-xelatex:(常见)指定使用xelatex并生成 PDF 文件,关闭 DVI/PS 模式-lualatex:(常见)指定使用lualatex并生成 PDF 文件,关闭 DVI/PS 模式
最基本的用法如下 1
2
3latexmk -pdf main.tex
latexmk -xelatex main.tex
latexmk -lualatex main.tex
latexmk 提供如下清理命令
1 | latexmk -c main.tex |
这个命令会自动清理所有相关的杂项文件,前者会保留pdf等输出文件,后者则会将pdf文件也删除,源文件有时也可以缺省,会自动检测。
使用-pv选项可以实现在 PDF 阅读器中进行预览,例如
1
latexmk -pdf -pv main.tex
使用-pvc选项可以在预览的同时开始持续更新,即程序会在终端中会保持等待状态,一旦检测到文件改动,就会自动进行编译。
1
latexmk -pdf -pvc main.tex
可以使用下面的命令检查latexmk执行具体指令时的具体行为(受到配置文件影响后的实际行为)
1
latexmk -commands
常见选项
使用latexmk -help可以查看到支持的选项,有很多细节上的选项不用管,下面只列出值得注意的选项:(对选项的解析同时支持-和--开头)
-auxidr=,-aux-directory=DIR:指定辅助文件的存放位置,例如采用./.aux作为杂项文件的存放位置,目录不存在时可以自动创建,相对目录是相对于执行命令时所在的目录,而不是源文件所在目录。-outdir=DIR,-output-directory=DIR:指定输出位置:主要是pdf文件,也包括.syntex.gz文件-cd:执行命令之前,切换到源文件所在的目录(在自动化脚本中可以调整实际命令执行的位置,这里也可以进行设置)-r:指定latexmk读取的配置文件
此外,latexmk还会将一些选项直接传递给pdflatex等编译命令,
例如最常见的-synctex=1,-interaction=nonstopmode,-shell-escape等。
配置文件
latexmk 除了通过命令行参数设置具体的编译选项,也支持通过配置脚本设置,它会在如下位置寻找配置文件:
- 当前LaTeX主文件所在目录,
.latexmkrc或latexmkrc均可。 - 任何其他位置,执行
latexmk时由-r参数指定。 - 个人家目录,
$HOME/.latexmkrc,也支持$HOME/.config/latexmk/latexmkrc。 - 系统目录,如
/usr/local/lib/latexmk/LatexMk,视系统设置而定。
注意:
- 配置文件的语法类似Perl,因为
latexmk本身就是基于 Perl 实现的。(现在谁还用 Perl 啊,看不懂的过时语言) - 和
make不同,即使没有配置文件,latexmk也可以自动执行得很好。
有几份配置文件可以参考:
在配置文件中有两个值经常被设置:
$pdf_mode用于设置pdf生成模式,支持的值包括:(默认为0,参考配置文件都设置为5)0:代表不生成 pdf1:代表使用$pdfltex选项的命令2:代表使用$ps2pdf选项的命令3:代表使用$dvipdf选项的命令4:代表使用$lualatex选项的命令5:代表使用$xelatex选项的命令
$bibtex_use用于设置 bibtex 或 biber 的使用规则,支持的值包括:(默认为1,普遍都设置为1.5)0: 不使用 bibtex 或 biber; 清空的时候不会清空 .bbl 文件1: 只有 bib 文件存在才使用 bibtex 或 biber;清空的时候不会清空 .bbl 文件1.5: 只有 bib 文件存在才使用 bibtex 或 biber;当 bib 文件存在时会清空 bbl,否则不会清空2: 有必要更新bbl文件时,运行 bibtex 或 biber,无需测试 bib 文件存在与否;清空删除 bbl
Overleaf 等在线平台的编译方式是基于 latexmk
的,允许选择不同的编译命令(pdflatex,xelatex,lualatex),Overleaf
使用的配置文件看起来很复杂, 但是可以用如下测试项目将其导出
1
2
3
4
5
6
7
8\documentclass[a4paper]{article}
\usepackage[margin=1cm]{geometry}
\usepackage{verbatim,shellesc}
\ShellEscape{cp /usr/local/share/latexmk/LatexMk ./LatexMk}
\begin{document}
\section*{Listing the \texttt{LatexMk} file}
\verbatiminput{./LatexMk}
\end{document}
最终选择没有使用.latexmkrc,直接使用latexmk命令加上一些选项就足够了,而且在没搞懂的情况下,盲目进行任何配置都可能导致编译错误。
LaTeX 的编译真的是天坑,系统平台差异,版本差异就不说了,各种编译器之间的差异,各种缓存文件没清理干净就容易报错,如果编译时其它程序在占用 PDF 也会报错,而且输出信息乱七八糟,一大堆问题,却没多少有效信息,比C++的编译系统都混乱得多。
