latex 编译链简介
【摘 要】 在 LaTex 中,文章内容、参考文献文件、宏包文件、格式文件是相互分开的。编译过程需要将这些文件拼接起来,形成最终的 pdf 文件。此过程不是一步到位的,而是涉及到一个编译链条:将前一步编译的结果输送到下一步继续编译。
1 Latex 中的各种文件
latex 中的常见文件有如下类型(指参与编译的源文件):
- .tex:tex 文件是最常见的 latex 文件,也是平时编写文章主要文件
- .cls:cls 文件是 latex 的格式文件,规定了 tex 源文件的排版格局,称为类文件(class),一般使用
\documentclass{}
导入 - .sty:sty 文件是一种宏包文件(package),一般使用
\usepackage{}
导入 - .bst:bst 文件是参考文献的排版格式文件,一般使用
\bibliographystyle{}
导入 - .bib:存储参考文献数据的库文件,一般使用
\bibliography{}
导入文中使用到的文献 - 其他文件: 图片、多媒体等其他资源文件
其中 bib 文件一般如下:
1 | @article{XXX, |
2 一个示例
假设在当前目录下有下列文件:main.tex
、A.cls
、B.sty
、C.bst
、D.bib
。
1 | %main.tex 文件 |
3 编译过程
类似上例附带参考文献的源文件,整个编译需要完成四步:
【符号说明】:(xe/pdf)latex
表示可以使用 latex
, pdflatex
或 xelatex
等工具进行编译。
第一步 (xe/pdf)latex main.tex
:
生成 main.aux
、main.log
和 main.pdf
文件。其中 aux
是引用标记记录文件,用于再次编译时生成参考文献和超链接。此时的 pdf
文件中不包含参考文献,文中的引用表现为 [?]
。
第二步 bibtex main.aux
生成 main.bbl
和 main.blg
文件。其中 blg
为 bibtex 处理过程记录文件,bbl
文件为文中使用的参考文献数据。
第三步 (xe/pdf)latex main.tex
更新了 main.aux
、main.log
和 main.pdf
文件。此时的 pdf
文件的末尾有了参考文献列表,但是正文中的引用仍然表现为 [?]
。
第四步 (xe/pdf)latex main.tex
,更新了 main.aux
、main.log
和 main.pdf
文件。并生成最终的 pdf
文件,此时正文中的引用表现为经标记好的引用方式,如 [1]
、[2]
… 等。
上述编译链看起来非常复杂,因此有人开发了一个工具,可以将上述计算流程整合为一个过程,这就是 latexmk
。
4 PDFLaTeX 和 XeLaTeX 的区别
PDFLaTeX
编译模式与 XeLaTeX
区别如下:
- PDFLaTeX 使用的是 TeX 的标准字体,所以生成 PDF 时,会将所有的非 TeX 标准字体进行替换,其生成的 PDF 文件默认嵌入所有字体;
- 使用 XeLaTeX 编译,如果论文中有很多图片或者其他元素没有嵌入字体的话,生成的 PDF 文件也会有些字体没有嵌入。 XeLaTeX 对应的 XeTeX 字体的支持更好,允许用户使用操作系统字体来代替 TeX 的标准字体,而且对非拉丁字体的支持更好。
- PDFLaTeX 进行编译的速度比 XeLaTeX 快。
5 latexmk 使用常识
已经有人将上述编译过程整合在了一个命令行程序中,那就是 latexmk
。
5.1 基本命令格式
latexmk
的通用格式为
1 | latexmk [options] [file] |
其中 file
可以直接写文件名, 如果直接写 foo
的话, latexmk
会按照 foo.tex
来处理. 有一些符号在文件名中是不能用的: $
, %
, \
,`(这个东西不能放在代码块里……), &
这个符号不能作为文件名的开头, 还有一些控制字符也不可以, 不过我估计没人会闲的用控制字符来做 .tex
的文件名…
5.2 常用命令行选项
(1) -auxdir=FOO
或者 -aux-directory=FOO
设置存放辅助文件的文件夹, 可惜此选项只对 MacOS 的 MiKTeX
版本起作用, linux 的 TeX Live
无法使用。
(2)-bibtex
当源文件需要用 .bbl
文件作为参考文献的时候, 运行 bibtex
或者 biber
来更新 .bbl
文件. 这个选项可以将配置文件 .latexmkrc
中的 $bibtex_use
的值设置为 2
来实现.
(3) -bibtex-
从不运行 bibtex
或者 biber
. 同时将 .bbl
文件看做珍贵的 ( 原文为 precious ), 也就是在执行清理命令的时候不会删除 .bbl
文件。如果我们接受到的文件中只有 .bbl
而没有 .bib
的时候会启用此选项。这个选项可以将 .latexmkrc
中的 $bibtex_use
的值设置为 0
来实现.
(4) bibtex-cond
如果源文件中存在 .bib
文件, 则运行 bibtex
或 biber
来重写 .bbl
文件, 如果没有 .bib
文件, 则不运行 bibtex
或 biber
, 这个选项也会将 .bbl
文件看做珍贵的. 这个选项可以将.latexmkrc
中的 $bibtex_use
的值设置为 1
来实现.
(5) -command
列出 latexmk
在处理文件时可以使用的命令, 然后退出.
(6) -c
清理所有由 latex
, bibtex
, 以及 biber
生成的可再生的文件, 除了 .dvi
, postscript
, 和 .pdf
文件. 会删除的文件有 .log
, .aux
, latexmk
创建的数据文件, 还有 @generated_exts
中指定扩展名的文件, 同时还有 $clean_ext
指定的文件.
(7) -C
清理 -c
选项中的所有文件, 以及 .pdf
, .dvi
, postscript
文件, 以及 $clean_full_ext
指定的文件.
(8) -cd
在进行处理之前切换到有源程序的文件夹, 并将所有的文件生成在这个文件夹里. 举例: 如果你的文件夹结构为 parent/subfolder/main.tex
, 你在 parent
文件夹下, 命令行执行
1 | latexmk -cd -xelatex subfolder/main |
会进入 subfolder
文件夹进行编译, 并将辅助文件和输出文件生成在 subfolder
文件夹下. 这里注意路径的分隔符要使用 /
, 哪怕是 Windows
.
(9) -f
和 -interaction=nonstopmode
强制执行 latexmk
哪怕遇到了 error
. 一般情况下, 当 latexmk
遇到了 latex
或者其他程序在 接下来的运行中 无法处理的问题的时候, 将不会给出处理结果。
接下来的运行 指的是 如果没有 error
出现, 运行其他程序或者重新运行latex
的时候会编译完成 ( 这段其实我没看懂, 原文是 “Further processing” means the running of other Programs or the rerunning of latex (etc) that would be done if no errors had occurred. ) 额外地, 如果你想让 latex
程序遇到 error
之后不出现给用户处理 error
的暂停 , 你需要使用一些可以传递给程序的选项, 比如 -interaction=nonstopmode
。 举例: 当文档里有一个严重的错误, 比如没有定义的命令。此时使用 -f
的命令行为:
1 | latexmk -f -xelatex main |
此时在遇到错误时,依旧会暂停来等待用户处理。而使用 -interaction=nonstopmode
的话:
1 | latexmk -interction=nonstopmode -xelatex main |
此时,latexmk
会一气呵成运行到最后, 哪怕没有文件输出。
(10) -g
强制完整地运行一遍 latexmk
, 哪怕在 latexmk
觉得源文件自从上次编译之后没有改动
(11) -jobname=STRING
把输出文件中的文件名设置为 STRING
, 而不是源文件名, 注意 STRING
中不能带空格。 允许使用占位符 %A
, 比如
1 | latexmk -xelatex -jobname=%A-xelatex main |
此时输出文件名就变成了 main-xelatex.***
。
(12) -outdir=FOO
或者 -output-directory=FOO
设置存放所有输出文件的文件夹。
(13)编译和预览控制
-pdflatex
: 使用pdflatex
作为编译器, 该编译器会关闭.dvi
和.ps
文件的生成。-xelatex
: 使用xelatex
作为编译器, 该编译器会关闭.dvi
和.ps
文件的生成。-pdf
: 使用pdflatex
编译时,输出.pdf
文件。-pvc
: 是否运行预览。编译中文文档时会使用xelatex
编译器,此时不生成.dvi
和.ps
文件, 所以会直接预览.pdf
文件。
(14) -r <rcfile>
人工指定配置文件,按照 <rcfile>
中的内容执行 latexmk
。 但需注意调用顺序, latexmk
总是会先调用标准初始的 .latexmkrc
文件, 在不存在初始 .latexmkrc
文件时,再去调用 <rcfile>
。但如果 <rcfile>
中指定了一个初始 .latexmkrc
文件, 那么此指定会在标准的初始 .latexmkrc
文件之前运行。
5.3 .latexmkmc
配置文件
latexmk
可以通过配置文件来设置一些默认选项,标准的初始文件位置为 ~/.latexmkrc
变量采用如下格式设置:
- 设置一个值为 字符串型 的变量,如:
$bibtex='bibtex %O %B';
- 设置一个值为 数值型 的变量,如:
$preview_mode=1;
- 设置一个值为 数组型 的变量,如:
@default_files=('paper', 'paper1');
- 用如下语句来给数组变量追加值,如:
push @default_files, 'paper2';
可以注意到:简单变量的名字的开头都是 $
, 而数组变量的名字的开头是 @
, 每个语句都以分号 ;
结尾。 字符串应该用 单引号 括起来, 不建议使用双引号。
5.4 占位符的使用
可以使用一些占位符来辅助设置 latexmk
中的一些命令参数, 例如: 如果想让 latexmk
将 elatex
用作编译器命令, 并且想让其使用 --shell-escape
等选项, 可以写为:
latex='elatex --shell-escape %O %S';
其中,两个前面带 %
的符号就被称为 占位符, 在实际运行命令之前,这些占位符会被替换为实际值. 因此 %S
会被替换为源文件名, %O
会被替换为将作用在此命令上的各种选项,下面列出可用的占位符:
%A
: 主.tex
文件的文件名。 不同于%R
,%A
不会被设置别名(jobname) 而受影响;%B
: 最近命令中的基础名 (base name)。 比如一个document.ps
文件从一个document.dvi
转化得到, 那么这个文件名就是document
%D
: 终点 (destination) 文件名。 比如一个.ps
文件由一个.dvi
文件转化得到, 那么终点文件名就是这个.ps
文件。名%O
: 例子中提到的选项。%P
: 如果变量$pre_tex_code
不空, 那么%P
会被替换为$pre_tex_code
中\input{SOURCE}
后面的内容, 其中SOURCE
是资源文件 (source file) 的名字。 这让 TeX 代码可以在资源文件被读入之前就传给*latex
引擎。 如果$pre_tex_code
为空, 那么%P
和%S
等价。%R
: 根文件名, 这是主.tex
文件的基础名, 但是这个值可以被-jobname
选项或者$jobname
变量改变。%S
: 源文件名。 比如当转化一个.dvi
文件到.ps
的时候,.dvi
的文件名就是源文件名。%T
: The name of the primary.tex
file。%U
: 如果变量$pre_tex_code
不空, 那么这个值就被传递给%U
, 如果为空, 那么它被替换为一个空字符 (null string)。%Y
: 辅助文件所在的文件夹名。 如果文件夹名不是以合法符号结束, 那么就会被添加一个文件夹分隔符/
。 注意: 如果设置了$out_dir
却没设置$aux_dir
, 那么latexmk
就把$aux_dir
设置为$out_dir
。%Z
: 输出文件夹名。 如果$out_dir
不空, 且没以合法符号结束, 那么就会被添加一个文件夹分隔符/
。
如果有什么原因你要使用一个 %
字符, 还不是上面标出的情况, 那么用 %%
.
注意: 在文件名传递的过程中会被适当地自动添加引号, 所以不需要自行添加引号, 即使文件名中有空格。 如果你的 TeX 文件名中有空格, 那么一些过老版本的 TeX 程序可能不会很好地处理它们。如果 latexmk
的引号不能正确地工作, 你也可以将它关闭, 在变量 $quote_filenames
的设置中。