排版这件事,平时不痛不痒,真到了要交三十页毕业论文、或者投一份格式要求苛刻的期刊稿件时,才会发现 Word 那套“所见即所得”的思路有多让人抓狂:插图一挪位置就跑,公式编号手动改到怀疑人生,参考文献格式换一本期刊就得重排一遍,目录页码刷半天刷不出来。LaTeX 就是冲着这些场景来的,它本质是一套论文排版工具,你用纯文本写内容、打标记,剩下的字体、行距、编号、交叉引用、参考文献格式交给一套排版引擎自动算。它不神秘,也不是学术圈的门槛,只是一个把“排版”和“写作”彻底拆开的工具。
这篇东西我按自己带师弟师妹的流程来写:先讲清楚 LaTeX 到底在干什么、编译链是怎么跑起来的,再给出一套 Windows 下从头到尾的安装教程,然后是编辑器配置、语法最小可用集、论文模板怎么改,最后是我这几年攒下来的报错速查表。安装教程部分我以 TeX Live 完整版为主线,它是目前兼容性最稳、坑最少的一条路;使用教程部分不会把宏包文档抄一遍,只讲你写论文真正会用到的那二三十个命令。完全没碰过命令行的本科生能照着走完,用过一阵子的人也能在里面翻到几条能省时间的配置。
1. 先搞懂 LaTeX 到底在做什么
1.1 内容和排版分离,这才是核心
Word 的思路是“你看到什么就是什么”,你敲字的时候顺手调格式,格式和内容搅在一起。写三页的文档没问题,写三千页的文档就完蛋。LaTeX 的思路反过来:你只负责写内容并打上语义标记,比如“这里是二级标题”“这里是一张图片”“这里要引用文献 3”,具体二级标题该用多大字号、图片该浮到哪里、文献 3 该显示成 [3] 还是 (Zhang et al., 2023),全由样式文件决定。
这个差别带来的最大好处不是“好看”,而是一致性可以被机器保证。你论文里有一百三十处交叉引用,改动了章节顺序之后,编号会自动重算;你有一百二十条参考文献,换一个期刊模板,全文引用格式一次性重排,你一个字母都不用动。我在实际使用中发现,真正让人回不去 Word 的,就是这一点。
还有一个隐性优势:.tex文件是纯文本。这意味着你可以用 Git 做版本管理,可以 diff 出“这次改了什么”,可以多人协作时靠合并工具解决冲突。相比之下,.docx是压缩包里的二进制 XML,冲突了基本只能靠人力肉眼比对。
1.2 一次编译到底发生了多少次“搬运”
很多人第一次用 LaTeX 会困惑:为什么目录是空的?为什么引用显示成???为什么非要编译两遍?答案在编译链里。
一次完整的编译通常涉及四个程序接力:
| 程序 | 作用 | 产物 |
|---|---|---|
xelatex(或pdflatex) | 读取.tex,生成排版结果 | .pdf、.aux |
bibtex或biber | 读取.aux里的引用需求,去.bib数据库取数据 | .bbl |
xelatex第二遍 | 读.bbl把参考文献排进去 | 更新的.aux |
xelatex第三遍 | 读取上一遍写入的页码、编号,填进目录和引用 | 最终.pdf |
.aux这个中间文件是关键,它相当于排版引擎留给自己的便签本:目录里每个章节在第几页、每个\label对应什么编号,全都写在这。所以目录空、引用问号、公式编号乱,九成情况是编译次数不够,不是代码写错了。理解了这一层,后面排查问题会轻松很多。
顺带说一句latexmk。它是个自动化脚本,会根据.aux的依赖关系自动判断该跑几遍、要不要跑 bibtex。用上它之后你只需要按一次编译键,这也是下面编辑器配置里我强烈推荐用它做默认工具的原因。
1.3 什么情况该上 LaTeX,什么情况别硬上
不是所有文档都值得用 LaTeX。我个人的判断标准是三条:
- 数学公式密度高:一篇文档里超过二十个公式,或者需要多行对齐、矩阵、分段函数,LaTeX 的收益立刻拉开差距。
- 格式要求由外部规定:期刊、学位论文有模板,你不想跟格式要求较劲,那就用模板。
- 文档规模大且结构复杂:章节多、图表多、交叉引用多、参考文献多,涉及反复修改。
反过来,如果是给同事发的一份周报、一份产品需求文档、一张带排版的简历,用 LaTeX 就是自找麻烦,Word 或者在线文档二十分钟搞定的事,没必要配置环境。我见过有人为了做一份两页的社团通知折腾一下午 TeX 环境,这个性价比实在不高。
2. 安装方案选型:三条主流路线怎么挑
2.1 三个发行版的能力对比
所谓“安装 LaTeX”,准确说法是安装一个 TeX 发行版。发行版 = 排版引擎 + 几万个宏包 + 字体 + 辅助工具打包在一起。主流选择有三个:
| 发行版 | 平台 | 安装体积 | 更新策略 | 适合谁 |
|---|---|---|---|---|
| TeX Live | Windows / Linux / macOS | 完整版约 7–8 GB | 年度版本,可在线更新宏包 | 首选,兼容性最好,模板作者一般都拿它测 |
| MiKTeX | Windows / macOS / Linux | 初始约 200 MB | 用到哪个宏包下载哪个 | 硬盘紧张、或者只做轻量文档 |
| MacTeX | macOS | 约 6 GB | 本质是 TeX Live 的 Mac 封装 | Mac 用户,装了就等于装了 TeX Live |
我给你一个不太“官方”但很实在的建议:只要是正儿八经写论文,直接 TeX Live 完整版。MiKTeX 的按需下载听起来很香,但它的代价是编译过程中可能突然弹窗或卡住去下宏包,网络不好的时候编译速度会被拖得很难受;更麻烦的是,很多学位论文模板依赖一些冷门宏包,第一次编译满载下载,报错信息还容易被下载日志淹没。
2.2 关于“latex 下载”这件事,先把来源搞清楚
搜索引擎里搜“latex 下载”,排在前面的往往是一些第三方站的“绿色版”“精简版”“免安装便携版”。我的建议很明确:只从发行版官方渠道下载。原因有三个:
第一,TeX 系统里有大量可执行文件,从不明来源拿来的安装包,你没法确认里面有没有被塞进别的东西。
第二,精简版通常砍掉了字体和文档,你后面遇到File 'xxx.sty' not found之类的报错,原因就是被砍掉了,你还要花时间补回来。
第三,这些版本更新频率低,宏包版本老,遇到新模板直接编译不过。
下载的时候注意一件事:用镜像站。官方主站的下载速度在某些时段会非常慢,国内几个高校和镜像站点都有完整同步,用镜像下载能把几个小时压到十几分钟。安装器里也内置了镜像选择,安装中途可以切换。
2.3 先把磁盘和时间的预算算清楚
在动手之前,先把这两个数字看清楚,免得装到一半发现空间不够:
- 磁盘:完整安装约 7–8 GB,加上后续更新和临时文件,建议预留 15 GB 以上。装在机械硬盘上编译大文档会明显慢,有条件放固态。
- 时间:网络顺畅的情况下,完整安装 20–40 分钟;网络一般的话,一两个小时也正常。这个过程可以干别的事,但别关电脑。
还有一个容易被忽略的点:安装路径不要带中文和空格。像D:\我的论文\texlive或者D:\Program Files\texlive这种,某些宏包在处理文件路径时会出问题,报错信息还很难懂。用D:\texlive\2024这种干净路径,能避开一大类莫名其妙的故障。
3. Windows 下 TeX Live 安装完整实操
3.1 下载安装器与镜像选择
打开 TeX Live 官方页面,下载install-tl-windows.exe。这个 exe 其实是个引导器,运行后会先连网下载真正的安装程序。双击之后会出现两个选项:
- Simple / 简易安装:一键装完整版,几乎不需要做选择。
- Advanced / 高级安装:可以自定义组件、路径、镜像。
我一般选高级安装,理由有三个:能改安装路径(默认路径难记)、能选镜像(决定下载速度)、能关掉一些用不上的语言包(省空间)。安装器界面左侧有一个Directories区块,把TEXDIR改成你准备好的干净路径,比如D:\texlive\2024。
镜像选择在安装器界面上部有个下拉框,一般会自动测速。如果自动选中的那个下载速度很慢(进度条半小时不动),手动换一个。判断标准很简单:看剩余时间估计,如果超过三个小时就换。
3.2 安装选项逐项拆解
进入高级安装之后,会看到一堆组件勾选框,容易让人懵。按我的习惯,这样处理:
Scheme(安装方案):选full,也就是完整安装。不要选basic或者medium,理由前面说过。Language collections:Chinese、Chinese/Japanese/Korean这两个可以留着,中间有中文排版要用的东西。TeXworks editor:可以留着,装完先拿它验证环境能不能跑通,后面换 VS Code。Install TeX Live documentation:这个会多占一两个 GB,如果你习惯本地查文档就留着,主要靠在线查的话可以取消。Create symlinks之类的选项在 Windows 上一般不需要动。
参数确认之后点安装,剩下的就是等。安装过程中有一个细节值得注意:关闭杀毒软件的实时扫描,或者把安装目录加进白名单。TeX Live 会在短时间内释放几十万个小文件,实时扫描会把这个过程拖得非常慢,我遇到过装了两小时才装完一半的情况,加白名单之后 25 分钟结束。
注意:安装过程中不要中途强退。TeX Live 的安装不是原子操作,中断之后目录可能处于半成品状态,重新安装时容易因为残留文件报错。真需要中断,先把整个安装目录删干净再重来。
3.3 装完必须做的三项验证
安装器跑完最后一步会打印一行提示,告诉你哪些环境变量已经设置好。很多人到这里就直接开编辑器了,结果一堆“命令找不到”的报错。我建议先做三项验证,命令行里敲:
xelatex --version bibtex --version latexmk --version三行都能打印出版本号,说明 PATH 配好了。如果提示“不是内部或外部命令”,有两个可能:一是安装时没勾选创建环境变量;二是你当前开着命令行窗口,而 PATH 是在窗口打开之后才修改的,需要关掉重开。老版本的 Windows 需要重新登录一次才能生效。
第二项验证:写一个最小文档,编译一次。新建test.tex:
\documentclass{article} \begin{document} Hello, \LaTeX. \end{document}在命令行里cd到文件所在目录,执行:
xelatex test.tex同目录下应该出现test.pdf。这一步跑通,说明引擎可用。
第三项验证:tlmgr能连上镜像。执行tlmgr update --self,如果能正常列出更新信息,说明后续可以自己维护宏包。这一步很多人跳过,等到半年后模板需要新宏包时才发现更新不了,还得重新排查。
4. 编辑器怎么选,怎么配
4.1 编辑器对比:别在选型上纠结太久
TeX Live 自带的 TeXworks 能用,但功能比较基础。真正写论文,我建议从下面几个里挑:
| 编辑器 | 优势 | 短板 | 推荐度 |
|---|---|---|---|
| VS Code + LaTeX Workshop | 生态好、配置可控、能和其他语言共用 | 需要手写一段 JSON 配置 | 最推荐 |
| TeXstudio | 开箱即用,菜单里能改的东西多 | 界面偏老,大项目偶尔卡 | 新手友好 |
| TeXworks | 装了就有,零配置 | 功能单薄,没有正向反向搜索 | 应急 |
| 在线平台 | 不装环境,多人协作方便 | 依赖网络,大文件编译慢 | 临时救急 |
| Vim / Emacs | 键盘流效率天花板 | 学习曲线陡 | 老手自便 |
如果你已经装了 VS Code 并且常用,那就别折腾了,直接配 LaTeX Workshop,一劳永逸。如果完全没接触过 VS Code,TeXstudio 的菜单式配置更省心。
4.2 VS Code + LaTeX Workshop 配置逐行说明
先装两个东西:VS Code 本体,以及扩展市场里的LaTeX Workshop。装完之后打开设置,切到 JSON 模式(快捷键Ctrl+Shift+P,输入Open Settings (JSON)),把下面这段贴进去:
{ "latex-workshop.latex.recipes": [ { "name": "xelatex -> bibtex -> xelatex*2", "tools": ["xelatex", "bibtex", "xelatex", "xelatex"] }, { "name": "latexmk (xelatex)", "tools": ["latexmk-xe"] } ], "latex-workshop.latex.tools": [ { "name": "xelatex", "command": "xelatex", "args": [ "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "%DOC%" ] }, { "name": "bibtex", "command": "bibtex", "args": ["%DOCFILE%"] }, { "name": "latexmk-xe", "command": "latexmk", "args": [ "-xelatex", "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "%DOC%" ] } ], "latex-workshop.latex.autoClean.run": "onBuilt", "latex-workshop.latex.clean.fileTypes": [ "*.aux", "*.bbl", "*.blg", "*.idx", "*.ind", "*.lof", "*.lot", "*.out", "*.toc", "*.acn", "*.acr", "*.alg", "*.glg", "*.glo", "*.gls", "*.fls", "*.log", "*.fdb_latexmk", "*.snm", "*.nav" ], "latex-workshop.view.pdf.viewer": "tab", "latex-workshop.latex.autoBuild.run": "onFileChange" }逐项解释一下为什么这么写,不然你以后改了配置出问题不知道怎么回退:
recipes是编译方案的组合。第一个方案面向中文论文,走xelatex编译、bibtex处理文献、再补两遍xelatex填目录和引用。第二个方案用latexmk一次性搞定,适合追求速度的日常编译。
tools里每一项对应一条可执行命令。-synctex=1是关键参数,它让 PDF 和源码之间建立坐标映射,你才能在 PDF 上点一下跳回源码、在源码里跳回 PDF 对应位置。-interaction=nonstopmode保证遇到错误不弹交互提示,否则无人值守编译会永久卡住。-file-line-error让报错信息带上文件名和行号,排查效率翻倍。
autoClean.run: onBuilt表示每次编译成功后自动清理中间文件。这个设置很有必要,否则一个论文目录里会堆几十个.aux、.bbl、.log,用 Git 提交的时候一片红。但要注意,如果你要提交给期刊的源码包,临时关掉这个设置,因为有些期刊要求你连.bbl一起提交。这是个真事,我帮人改模板时见过有人把所有中间文件清干净了,结果对方编辑说缺少编译产物。
view.pdf.viewer: tab让 PDF 在 VS Code 里的标签页中预览,边写边看,不用切窗口。
4.3 中文排版为什么必须用 xelatex
这是个高频困惑点:为什么别人给的命令是pdflatex,我配的却是xelatex?
简单类比:pdflatex是个老式打字机,它只认早期的字体格式,处理中文需要走一堆转换流程;xelatex是新一代引擎,可以直接调用系统里装好的字体文件。你写中文论文,只要在导言区加一句:
\usepackage{ctex}ctex宏包会自动帮你配置好中文字体、中文标点、章节标题的“第几章”字样、以及中英文间距。注意一个细节:用ctex宏包时,编译必须走 xelatex,用 pdflatex 会直接报字体找不到。
如果你需要指定具体字体,比如学校要求正文用宋体、标题用黑体:
\usepackage[UTF8]{ctex} \setCJKmainfont{SimSun} \setCJKsansfont{SimHei} \setCJKmonofont{FangSong}字体名必须是系统里真实存在的名字。查字体名的办法是在系统的字体设置里找,或者直接把字体文件拷到项目目录里,用Path=和Extension=参数指定文件名,这样换电脑也不会因为缺字体而编译失败。
4.4 正向搜索和反向搜索,用一次就离不开
SyncTeX 是我认为最被低估的功能。配置好之后:
- 正向搜索:在源码里把光标放到某一段,按
Ctrl+Alt+J,PDF 会跳到对应位置。 - 反向搜索:在 PDF 预览里按住
Ctrl点击某处,源码会跳到对应行。
写长论文时,你经常需要“这段落排出来是什么样”“这一页的表格源码在哪”,有这两个功能,来回确认格式的时间能省掉一大半。如果你用的是外部 PDF 阅读器(比如 SumatraPDF),需要在 VS Code 设置里把查看器改成external,并在 SumatraPDF 里配置反向搜索的命令行参数,稍微麻烦一点,但阅读体验更顺。
5. LaTeX 语法:写论文真正用得上的那一部分
5.1 最小文档结构与导言区
任何一个.tex文件,骨架都是三段:
\documentclass[12pt, a4paper]{article} % 文档类 \usepackage{graphicx} % 导言区:加载宏包 \usepackage{amsmath} \begin{document} % 正文区开始 正文内容写在这里。 \end{document}\documentclass里的选项决定全局参数,12pt是正文字号,a4paper是纸张。article适合短论文,report适合有章节的长文档,book是书,学位论文一般直接用学校提供的自定义文档类,比如\documentclass{xxxuniversitythesis}。
导言区里\usepackage的顺序有时会有影响。经验规则是:先加载基础宏包,再加载自定义宏包。如果两个宏包都要重定义同一个命令,后加载的会覆盖前面的,报错信息通常是Command \xxx already defined,这时用\usepackage{宏包名}换成带选项的版本,或者用\let手动让位。
5.2 换行、分段、间距:这几个符号别再搞混
搜“latex 换行符怎么打”的人特别多,因为这里的坑确实多。我把这几个命令的区别整理成一张表:
| 写法 | 效果 | 使用场景 |
|---|---|---|
| 空一行 | 开始新段落,段首自动缩进 | 正文分段,最常用 |
\\ | 强制换行,不产生新段落 | 诗歌、地址、表格单元格内 |
\newline | 强制换行,与\\基本相同 | 语义更清楚时用 |
\linebreak | 在当前位置断行,并把整行拉伸到满宽 | 极少用 |
\par | 显式开始新段落,等同于空一行 | 宏定义内部常用 |
\newpage | 强制换页 | 章节之间手动画分页 |
\noindent | 取消本段首行缩进 | 摘要、特殊段落 |
~ | 不断行空格 | 防止“图 1”被拆到两行 |
最容易犯的两个错误:一是拿\\当分段用,结果段首缩进和段间距全不对,而且后面如果接\section之类的命令会直接报错There's no line here to end;二是在\paragraph之类的短标题里塞\\,同样会翻车。
还有两个和中文相关的细节:ctex已经帮你处理了中英文之间自动加空隙,所以不要手动敲空格;中文标点不用转义,但英文环境下的%、&、_、#、$这些符号必须转义成\%、\&、\_、\#、\$。我曾经帮人看一个报错,就是参考文献标题里有个50%,%把后半行全注释掉了,编译看起来成功但内容少了一半,找了一小时。
5.3 数学公式与符号速查
这是 LaTeX 最不可替代的部分。行内公式用$...$,独立成行的用equation环境:
行内公式 $E = mc^2$ 夹在文字里。 \begin{equation} \label{eq:main} f(x) = \int_{-\infty}^{\infty} \hat{f}(\xi)\, e^{2\pi i \xi x} \, d\xi \end{equation} 公式 \eqref{eq:main} 说明了……多行对齐用align环境,&标记对齐位置,\\换行:
\begin{align} a &= b + c \\ &= d + e + f \end{align}常用符号我列一张能覆盖九成写作场景的表:
| 需求 | 写法 | 显示效果 |
|---|---|---|
| 上下标 | x^2,a_i | x², aᵢ |
| 多字符上下标 | x^{10},a_{ij} | x¹⁰, aⱼ |
| 分数 | \frac{a}{b} | a/b 竖排 |
| 根号 | \sqrt{x},\sqrt[3]{x} | √x, ∛x |
| 求和 | \sum_{i=1}^{n} | Σ |
| 积分 | \int_0^1,\iint | ∫, ∬ |
| 希腊字母 | \alpha\beta\Gamma | α β Γ |
| 关系符 | \leq\geq\neq\approx | ≤ ≥ ≠ ≈ |
| 集合 | \in\subset\cup\cap | ∈ ⊂ ∪ ∩ |
| 箭头 | \to\Rightarrow\leftrightarrow | → ⇒ ↔ |
| 花体 | \mathcal{L} | 𝓛 |
| 向量 | \vec{v},\mathbf{v} | v⃗,v |
| 极限 | \lim_{x \to 0} | lim |
| 矩阵 | \begin{matrix} ... \end{matrix} | 矩阵 |
几个容易踩的点:求和、积分的上下限在行内模式下默认放在右侧而不是上下方,想强制放在上下方用\limits;公式里想插入正常文字用\text{其中},不要直接敲中文;\label必须放在公式环境内部,放在外面引用不到。
5.4 插图:位置乱跑是正常的,别跟它较劲
LaTeX 里插图用的是浮动体(figure),意思是“这张图排在这附近就行”。很多人第一次看到图片跑到下一页会抓狂,其实这是设计行为。基本写法:
\begin{figure}[htbp] \centering \includegraphics[width=0.8\textwidth]{figures/result.png} \caption{实验结果对比} \label{fig:result} \end{figure} 如图 \ref{fig:result} 所示,……[htbp]是位置偏好:here(当前位置)、top(页顶)、bottom(页底)、page(单独一页)。LaTeX 会按这个顺序尝试,但最终由排版算法决定。
实操里我总结了几条经验:
第一,先别急着用[H]。强制固定位置需要float宏包,用了之后确实不动了,但代价是页面底部可能出现大片空白,甚至图片被推到章节末尾。除非学校格式明确要求,否则先接受默认浮动。
第二,图片尺寸用相对宽度。width=0.8\textwidth表示正文宽度的 80%,这样换纸张、换模板都不用改。用绝对长度(比如width=10cm)在双栏模板里很容易溢出。
第三,\caption放在\includegraphics之后。这决定图注显示在图下方。如果放前面,图注会跑到图上面。表格正好相反,\caption要放在表格内容之前。
第四,图片文件不要用中文名。某些引擎处理中文文件名会报Cannot determine size of graphic,改成fig1.png立刻好。
第五,一张图包含多个子图时用subcaption宏包,能生成 (a)(b)(c) 子标签和统一的总标题,比手动拼图省事得多。
5.5 表格与自动换行:这一块最容易翻车
表格是 LaTeX 里最让人头疼的部分,也是搜“latex 表格自动换行”的人最多的原因。基础写法:
\begin{table}[htbp] \centering \caption{参数配置} \label{tab:params} \begin{tabular}{lcc} \hline 参数 & 取值 & 说明 \\ \hline 学习率 & 0.001 & 初始值 \\ 批大小 & 32 & 受显存限制 \\ \hline \end{tabular} \end{table}{lcc}里的字母是每列的对齐方式:l左对齐、c居中、r右对齐。列之间可以用|加竖线,但学术排版一般不推荐竖线。
核心问题来了:普通tabular的单元格不会自动换行。内容长了会直接冲出页面。三种解决办法:
方案一,用p{宽度}指定列宽,超长内容自动折行:
\begin{tabular}{p{3cm}p{6cm}}方案二,用tabularx宏包,让某一列自动分配剩余宽度:
\usepackage{tabularx} \begin{tabularx}{\textwidth}{lX} 参数 & 一段很长的说明文字,会自动换行并撑满剩余宽度 \\ \end{tabularx}X列是最省心的做法,它会自动计算剩余空间并等分,适合“一列短标签 + 一列长描述”的常见结构。
方案三,单元格内部手动断行,用makecell宏包:
\usepackage{makecell} \makecell{第一行\\第二行}如果表格特别宽,横向放不下,可以用sidewaystable环境把它旋转 90 度,或者干脆把表格拆成两张。另外提醒一句:表格列数很多时,先在纸上画出结构再敲代码,比在编辑器里反复试要快得多,这是我踩了无数次坑之后的习惯。
5.6 参考文献:一次配置,终身受益
手写参考文献是浪费时间的行为。正确做法是维护一个.bib文件,每条文献一个条目:
@article{zhang2023deep, author = {Zhang, San and Li, Si}, title = {A Deep Model for Something}, journal = {Journal of Examples}, year = {2023}, volume = {12}, number = {3}, pages = {45--67} }正文里用\cite{zhang2023deep}引用,编译时由bibtex去取数据并按样式文件格式化。样式由\bibliographystyle{...}指定,常见的比如plain(数字编号)、ieeetr(IEEE 风格)、apalike(作者年份制)。
这里有一个大坑必须提前说:\bibliographystyle和biblatex不能混用。前者是老一代方案,配合bibtex;后者是新一代方案,配合biber。你要是抄了别人的.bib文件又抄了另一套模板,很容易出现“引用了但没进文献表”或者“文献表里有多余条目”。判断方法很简单:看模板的.tex文件里是\usepackage{biblatex}还是\bibliographystyle,然后照着它的方案走,不要自己换。
还有一个细节:bibtex对大小写敏感度、特殊字符的处理比较死板。文献标题里的大写字母(比如专有名词)容易被自动转成小写,这时候用花括号把它包起来:{DNA},这样就能保留原样。
6. 拿到论文模板之后该怎么做
6.1 先做三件事,别急着填内容
很多人拿到模板第一件事就是把内容往里灌,结果写到一半发现模板解压错了、编译不过、宏包冲突,返工成本极高。我建议的顺序是:
第一,先编译一份空模板。什么内容都不加,直接编译。能出 PDF 说明环境和模板是匹配的。这一步如果失败,问题一定在环境,不在你写的代码。
第二,只改标题、作者、摘要三处,再编译一次。这一步是验证你改动的位置对不对,尤其是摘要、关键词这类容易被模板用特殊环境包裹的部分。
第三,写两页正文,包含一个章节、一个公式、一张图、一张表、一条引用,再编译。这一步是压力测试,能提前暴露八成问题。
6.2 模板目录结构怎么读
一个标准的学位论文模板,目录大致长这样:
thesis/ main.tex 主文件,包含文档类声明和 \input chapters/ ch1-intro.tex 第一章 ch2-related.tex 第二章 figures/ 图片 refs.bib 文献数据库 setup/ 样式定义、封面、声明页 Makefile 或 build.sh 编译脚本主文件main.tex通常用\input{chapters/ch1-intro}把各章拼进来。注意\input后面不要加.tex后缀,加了有些模板会报错。
看模板时重点盯三个地方:导言区加载了哪些宏包、文档类是什么、有没有自定义命令。自定义命令通常是学校要求的特殊格式,比如\schoolname{}、\keywords{},照着示例填就行,别自己造。
6.3 提交前必须过一遍的检查清单
论文最终提交,我每次都按这张单子过:
| 检查项 | 具体做法 |
|---|---|
| 目录页码正确 | 重新编译三遍,确认目录里的页码和正文一致 |
| 交叉引用无问号 | 全文搜索??,找到就是引用没编译进去 |
| 图片清晰度 | 别用截屏图片,矢量图优先,位图至少 300 dpi |
| 参考文献齐全 | 对照正文引用列表,逐条核对是否有遗漏或多出 |
| 字体嵌入 | 提交 PDF 前确认字体已嵌入,否则对方打开可能乱码 |
| 空白页 | 检查有没有因浮动体被推挤产生的空白页 |
| 文件清单 | 期刊要求提交源码时,确认.bbl、图片、宏包是否齐全 |
最后一项特别容易被忽略。有些期刊的投稿系统要求上传源码压缩包,你在本地编译能过,是因为你电脑上装着完整宏包;对方的系统可能只装了基础宏包,这就需要你把自定义的.sty文件和图片一起打包,必要时连字体文件也带上。
7. 报错排查:这些坑我都替你踩过
7.1 高频报错速查表
LaTeX 的报错信息出了名的不友好,经常报错行号和真实位置差好几行。下面这张表是我这几年积累下来的高频问题:
| 报错信息 | 真实原因 | 解决办法 |
|---|---|---|
File 'xxx.sty' not found | 宏包没装 | tlmgr install 宏包名,或换个镜像重装 |
Undefined control sequence | 命令拼错或宏包没加载 | 检查拼写,确认对应宏包在导言区 |
Missing $ inserted | 数学符号写在了文本模式 | 用$...$包起来,或给_^加转义 |
Runaway argument? | 括号没配对,常见于{}少一个 | 从报错行往上找未闭合的括号 |
There's no line here to end | 在段落开头或标题里用了\\ | 删掉或改用空一行分段 |
Too many }'s | 多了一个右括号 | 常见于\end{}和\begin{}环境名不匹配 |
Citation 'xxx' undefined | 文献没编译进去 | 跑 bibtex 再编译两遍 |
Reference 'xxx' undefined | 交叉引用没编译进去 | 再多编译一遍 |
Overfull \hbox | 某行太宽,内容溢出 | 是警告不是错误,检查长公式或长单词 |
| 中文变成方框 | 字体没配好 | 用 xelatex 编译,检查ctex和字体设置 |
7.2 读日志文件的正确姿势
报错刷了一屏,怎么找关键?我的做法是:
先看第一个!开头的行,后面第一个l.数字就是报错位置。很多人从下往上找,找到的是连锁反应产生的后续错误,真实原因在最上面。
然后打开.log文件,搜索!,从第一个开始看。日志里Overfull \hbox和Underfull \hbox是警告,不影响生成 PDF,初学阶段可以先忽略。
如果日志信息看不懂,用-file-line-error参数(前面配置里已经加了),报错会变成文件名:行号: 错误信息的格式,定位速度快很多。
还有一个实用技巧:二分法定位。把文档后半部分整体注释掉,编译;能过,说明问题在后半部分,再把后半部分二分,两三轮就能锁定到具体段落。这个方法听起来笨,但比盯着报错信息猜要靠谱得多。
7.3 几个反直觉的经验
第一个经验:宏包加载顺序会引发玄学问题。我遇到过一次,hyperref加载在cleveref之后,结果所有交叉引用都失效,两个宏包单独用都正常,换顺序就对了。所以遇到“查不出原因”的问题,先试试调整宏包加载顺序。
第二个经验:编译缓存也会出问题。有时候代码明明改对了,PDF 还是旧的样子,这时候删掉所有中间文件重新编译(VS Code 里有个Clean up auxiliary files的命令,或者手动删.aux.bbl.toc),往往立刻正常。
第三个经验:别在毕业论文里边写边更新宏包。写一半的时候手痒跑了tlmgr update --all,结果某个宏包更新后和模板不兼容,前功尽弃。要更新,等提交完再更新。
第四个经验:Git 提交时加.gitignore。把.aux.log.toc.out.bbl这些中间产物排除掉,仓库会干净很多,也不会有无意义的合并冲突。但如前所述,正式提交给期刊的源码包不在这个规则里。
最后再分享一个小技巧:如果你需要大量重复的表格结构,与其一行行敲,不如写一个简单的 Python 脚本读取 CSV 生成 LaTeX 代码。我用这个办法把一个四十行的数据表从半小时的手工活压缩到十秒,而且在数据更新时直接重新生成就行,不会因为手改漏掉单元格。这个脚本二十行代码就够,值得花十分钟写一次。
我在带人写论文的过程中最深的体会是:LaTeX 真正卡住新手的从来不是语法,而是环境。语法部分翻半小时文档就能上手,环境问题却能耗掉一整个晚上。所以按上面这套流程先把引擎、编辑器、编译链三样东西固定下来,之后再遇到任何问题,你至少能确定“环境是好的,问题在我写的代码里”,排查范围一下就缩小了一半。