第一个文档:源文件结构与编译流程
环境装好后,很多同学的下一个动作是复制一段网上的模板开始改,改到报错再全网搜索。这种「先抄后懂」的路径低效且容易积累困惑。本文从一份十行的最小文档讲起,说清源文件的三大区域、编译命令的分工、辅助文件的作用,以及为什么生成一份带目录和文献的 PDF 往往要编译好几遍。理解这些机制后,你面对「第二次编译结果才正确」这类现象时就不会慌张。
一、源文件的三大区域
一份 LaTeX 源文件的骨架非常简单,所有复杂文档都是在这个骨架上逐步加内容。弄清区域划分是排错的第一步——「导言区误用正文命令」是最常见的新手错误之一。
\documentclass{ctexart} % 导言区:声明文档类与宏包
\usepackage{graphicx} % 导言区:加载宏包
\title{我的第一份文档}
\author{张三}
\date{\today}
\begin{document} % 正文区起点
\maketitle
你好,LaTeX!
\end{document} % 正文区终点(其后内容被忽略)
三个区域的分工必须分清:导言区位于文档类声明与正文起点之间,只放全局声明(文档类、宏包、标题信息、自定义命令),绝不能出现正文内容;正文区放实际文字与结构;正文结束命令之后的所有内容会被编译器彻底忽略,可以用来存废弃草稿。每次编译报错时,先确认出错的命令处在哪个区域,往往一眼就能看出问题。比如「在导言区写了正文文字」这类错误,日志会直接指出位置,但不懂区域划分的同学会对着报错发呆很久。
骨架要背下来其实只需记住一个画面:文档类声明打头,宏包与设置跟在后面,正文夹在开始与结束命令之间。所有复杂文档都是这个画面加内容而已,后面章节的示例全都遵循它。把这段十行示例存成空白模板文件,以后每篇新文档都从它复制开始,相当于给全书所有后续章节准备了一张安全网。
注意上例中行首的百分号:它之后到行尾都是注释,编译器会跳过。写文档时勤用注释分隔段落与记录修改原因,日后改版会轻松很多——这一点与编程完全一致。注释还有一个用途:临时禁用某段内容做对比测试,比删除再重敲安全得多。
新手在三大区域上栽的跟头有固定三类:把 \section 之类的结构命令写进导言区(引擎直接拒绝);在导言区写正文句子(报错位置指向导言区末尾,新手却在正文里找问题);把宏包加载命令写到 \begin{document} 之后(命令生效位置错误,行为完全不可预期)。报错时先问自己「这条命令现在站在哪个区域」,八成能立刻定位。这个习惯一旦养成,读任何模板源码都会顺畅很多。
二、编译命令的分工
源文件到 PDF 之间隔着「编译」这一步,而编译不止一种命令。理解它们的分工,才知道什么时候需要手动跑好几遍,什么时候可以一条命令搞定。第一次接触时建议每种命令都亲手敲一遍,建立直觉后再交给自动化工具。命令行的反馈比编辑器按钮更完整,你能看到每一步生成了什么文件。
| 命令 | 作用 | 何时需要 |
|---|---|---|
| xelatex(或 pdflatex) | 主编译,生成 PDF 与辅助文件 | 每次必跑 |
| bibtex / biber | 处理文献数据库,生成文献列表中间结果 | 用了文献时需要 |
| makeindex | 生成索引 | 手动做索引时需要 |
| latexmk | 自动按依赖决定调用顺序与遍数 | 强烈推荐日常使用 |
新手常问:为什么不一次编译完?因为各命令之间有数据依赖,主编译要等文献处理的结果才能填充引用,而这个依赖关系引擎自己最清楚。latexmk 的价值正在于此:它读取辅助文件判断依赖,自动按正确顺序调用对应命令,并决定跑几遍,日常写作几乎只需要它一条命令。
这四种命令的调用方式都在命令行完成,但编辑器通常提供一键编译(背后多半就是调用 latexmk)。如果你看到编辑器编译一次就停而 PDF 引用仍是问号,多半是它只调了主编译而没有处理文献——这时候切到命令行手动跑一遍最可靠。
三、为什么必须编译多遍
答案藏在「辅助文件」机制里。LaTeX 的目录、交叉引用、页码引用不是一次成型的:第一遍编译时,引擎扫描全文,把章节标题写进目录文件、把引用编号写进辅助文件,而此时正文里的引用位置还来不及读取这些数据,于是输出问号;第二遍编译读入辅助文件后,目录与引用才全部正确。文献处理还要额外插入一步:先由专门命令把文献数据库排版成列表,再交给主编译装配。
latexmk -xelatex main.tex
如果手动操作,带文献的文档标准顺序是四遍:主编译、文献处理、再两遍主编译。用 latexmk 则一条命令自动判断依赖并重复编译。它还会把编译日志摘要打印出来,配合本站正则表达式一章的方法可以快速抽取其中的警告行。一个判断技巧:如果某次改动后引用变成问号,先别怀疑源码,多半只是少跑了一遍。
为什么第二遍主编译也要跑两遍?因为文献列表插入后正文页码会变化,页码变化又影响目录与交叉引用的页码,需要再来一遍才能完全收敛。理解这个「连锁刷新」过程后,你会信任工具而不是猜测它——这就是为什么推荐让自动编译工具接管整件事,人只负责改源码。
四、辅助文件与干净交付
每编译一次,目录里就会多出若干辅助文件。它们是中间产物,删掉后重新编译会再生,不影响源文件安全。认识这些后缀还有一个好处:看别人的项目目录时,你能立刻判断它上次是用什么工具链编译的,排查协作问题时的沟通成本随之降低。
| 后缀 | 内容 | 可否删除 |
|---|---|---|
| .aux | 交叉引用与计数器记录 | 可删 |
| .toc | 目录条目 | 可删 |
| .log | 编译日志,排错依据 | 调试时保留 |
| .out | 超链接书签数据 | 可删 |
| .fdb_latexmk | 工具状态记录 | 可删 |
交作业或投稿时一般只交 PDF;开源项目则把这些中间文件加入忽略列表,只保留源码与图片资源。养成「源文件即唯一真相」的意识,远比手动清理文件夹重要——任何在辅助文件上做的手工修改,都会被下一次编译覆盖。日志文件是例外:遇到疑难排错时,把当时的 .log 留存下来对照,是定位问题的第一手材料。
判断哪些文件该提交、哪些该忽略,有一条简单规则:能由源文件重新生成的都是中间产物。只有源码、图片、文献数据库属于需要长期保存的资产。把这条规则落实成项目目录的固定结构,几年后回来打开也不会乱;给新项目建目录时顺手加上忽略清单,是成本最低的好习惯。
五、编译实战与常见迷宫
用前面的最小文档做一次完整观察。第一遍编译后 PDF 已生成;此时若在正文加一条对未定义标签的引用,你会得到问号与一条警告。补上目标标签再编译第二遍,引用变为正确编号;目录同理。若此时增删了文献,则文献列表的更新又要触发一轮。这个「改动—编译—确认」的循环节奏,就是长文档写作的基本节拍。
| 现象 | 日志关键词 | 修法 |
|---|---|---|
| 引用是问号 | 未定义引用警告 | 完整编译两遍 |
| 目录条目缺失 | 目录文件过期 | 再编译一遍 |
| 页码大幅跳动 | 无报错 | 浮动稳定后多编译一遍 |
| 文献列表不更新 | 文献命令未执行 | 按四遍顺序编译 |
常见的「迷宫」有两种:一是反复点编译按钮却发现问号依旧——其实只要文件存在改动未刷新的依赖,就需要完整跑一遍;二是删掉辅助文件后怀疑模板损坏,其实辅助文件本就是可再生的。排错的通用方法论见「编译排错」一章的十条清单。
还有一个新手必经的困惑:改了一个字母,编译却花了很久。这是引擎在重新处理依赖的全量刷新,属于正常现象。养成「改一段、编一次、看日志」的节奏,比一次性写完十页再编译要踏实得多——后者一旦报错,你根本不知道是哪一处引入的问题。
学到这里,建议做一个练习:把最小文档存为文件,分别用引擎命令与自动编译工具各编译一次,对比生成的 PDF 与目录中的文件变化。这个十分钟的练习会让你对整个工具链产生具体的掌控感。把练习结论和踩过的坑记进自己的知识库(见本站Obsidian 指南),数月后翻看会发现自己早已跨过入门门槛。若想把编译流程与写作计划串成固定工作流,本站的论文写作指南里有对应的章节安排建议。下一节处理中文这个绕不开的话题——它是新手上路后第一个大面积翻车的环节,我们会把引擎、宏集与字体三层关系一次拆清。
