从上一篇续下来,这篇专门记录 VSCode 里处理 BUAA LaTeX 毕设模板的参考文献环节。用这个模板写论文的同学应该都有体会:正文里的 \cite{} 敲起来并不难,难的是参考文献列表为什么有时候出不来、有时候编号全是问号、有时候编译能过但引用格式跟学校要求差一截。我也是从手动维护参考文献列表的坑里爬出来的,这篇就把我在 VSCode 里把参考文献这套链路理顺的过程拆开讲,包括工具链配置、.bib 文件维护、引用补全技巧以及 undefined citation 这种高频报错的排查思路。如果你正在用 VSCode 写含参考文献的 LaTeX 论文,这篇可以直接当操作手册用。
1. 先说清楚参考文献在 LaTeX 里要跑几趟,否则你永远在瞎试
很多人一上来就问“为什么我点了一次编译,正文里的引用位置没有东西”。根源往往不是模板问题,而是对 LaTeX 参考文献编译链路没有概念。LaTeX 不像 Word 那样打开文档就能在末尾看到现成的引用列表,它需要一套“选人—整理通讯录—回填信息”的多轮过程。
1.1 第一次编译:先让正文里的引用占个位
当你第一次用 pdflatex 或 xelatex 编译主文档时,LaTeX 实际上不会去读 .bib 文件。它只做一件事:扫描正文中的 \cite{key},把用到的引用 key 写进 .aux 辅助文件,并在正文里先留下一个占位符。如果你只用这一次编译,正文里那些 [?] 是正常的,参考文献列表也通常是空白的,因为 LaTeX 引擎根本还没有去找你的文献数据源。
这也是新手最常见的误解:以为编译一次就等于所有东西都齐了。我开始也是这么踩坑的,后来才理解 .aux 文件里那些 \citation{...} 行就是“参会名单”。
1.2 中间程序:BibTeX 靠名单去 .bib 里查资料
第二步需要调用 BibTeX 或 biber 这类后端程序。它会读取上一步产生的 .aux 文件,根据 \citation 里记录的 key,去你指定的 .bib 数据库里捞取对应的条目,并按照参考文献样式生成 .bbl 文件。
.bbl 文件才是真正会被 LaTeX 排进正文末尾的内容。你可以把它理解成“BibTeX 已经根据学校模板排好版的一份参考文献草稿”。我做了一个比较粗糙的类比:第一次编译是收集参会嘉宾名单,BibTeX 是拿着名单去通讯录补齐每个人的完整信息,最终再编成座位表。没有这一步,正文中只用一句 \bibliography{ref} 是不可能凭空变出文献列表的。
1.3 第二次第三次编译:才能把编号回填正确
生成 .bbl 后,还需要再次编译主文档,让 LaTeX 去读 .bbl 的内容,并把参考文献的编号真正确认下来。如果参考文献样式需要双向引索(例如正文引用编号和文献列表中的编号一一对应),通常需要再编译一次才能把引用关系稳定下来。所以完整的顺序是:latex -> bibtex -> latex -> latex。这也解释了为什么很多教程里反复强调“多编译几次”,不是因为玄学,而是因为 LaTeX 的状态是分散在不同辅助文件中的,一轮操作只能完成一个环节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. VSCode 里的编译配置:让 BUAA 模板的参考文献链路自动转起来
理解了多轮编译原理之后,你要做的事就变成:让 VSCode 里的 LaTeX Workshop 插件自动替你跑完上面那一串顺序。这个过程的核心是 tools 和 recipes 两个配置,很多同学配置文件写得不对,导致点一下编译按钮只是跑了一次 xelatex,参考文献自然永远不出来。
2.1 一个能实际跑通的标准 tools 配置
打开你的项目工作区,在 .vscode/settings.json 里可以这样写:
json复制{
"latex-workshop.latex.recipes": [
{
"name": "xelatex -> bibtex -> xelatex -> xelatex",
"tools": [
"xelatex",
"bibtex",
"xelatex",
"xelatex"
]
}
],
"latex-workshop.latex.tools": [
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"%DOC%"
]
},
{
"name": "bibtex",
"command": "bibtex",
"args": [
"%DOCFILE%"
]
}
],
"latex-workshop.latex.option.maxPrintLine": 200
}
这里特别提醒几个细节:
bibtex的参数通常是用%DOCFILE%而不是%DOC%,因为它需要不带扩展名的主文件名。-outdir=%OUTDIR%和-pdf能保证输出目录干净,避免中间文件堆在主目录。-interaction=nonstopmode让编译出错时不会停在交互界面等你输入。
2.2 为什么很多时候建议用 latexmk
上面这种手动 recipe 能解决问题,但如果条目引用比较复杂,或者参考文献后端换成了 biber,那手动 recipe 就很容易出现“编译序对不上”的情况。后来我改成了 latexmk 工具,它本身就是专门为 LaTeX 多轮编译设计的调度器,能通过解析日志自动判断需要跑多少次、要不要调 bibtex 或 biber。VSCode 的 LaTeX Workshop 插件默认也推荐 latexmk。
我的 setting 里额外加了一个 latexmk 工具:
json复制{
"name": "latexmk",
"command": "latexmk",
"args": [
"-xelatex",
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-outdir=%OUTDIR%",
"%DOC%"
]
}
然后 recipe 里只需要放 latexmk 这一个工具就能跑完整个流程。实测下来,即使在 BUAA 模板这种章节目录比较多、还有 \include 结构的大文档里也能稳定出结果,至少比我自己盯着编译日志判断下一步靠谱得多。
2.3 设置了但没生效?检查你有没有找到真正的根文件
LaTeX Workshop 插件能不能正确选择主文件,直接决定 recipe 跑的是不是你的 thesis 根文档。如果 VSCode 打开的是 .bib 文件,或编辑器焦点在某个被 include 的 .tex 文件上,插件可能找不到正确的根文件,甚至会报 “No LaTeX document found” 一类的问题。
我自己摸索出的习惯是:
- 始终从根文件开始编译,比如
main.tex或thesis.tex。 - 在根文件第一行加一个魔法注释,比如:
latex复制% !TEX program = xelatex
% !BIB program = bibtex
这样不只在 VSCode 里有效,换成其他编辑器也能保持一致的编译意图。
- 在
settings.json里设置latex-workshop.latex.rootFile.doNotPrompt会让插件按文件名猜测根文档,有时候猜不准。更稳的方式是:
json复制"latex-workshop.latex.rootFile": [
"thesis.tex"
]
指向你的根文件名,编译时就不会抓错对象了。
3. .bib 数据源才是 BUAA 模板参考文献是否规范的胜负手
编译链路通了以后,下一个大问题就是 .bib 文件里的条目本身。BUAA 的模板对中英文文献混排、作者字段、标题大小写都有特定处理方式,我在 .bib 里犯了特别多低级错误,最影响观感的几个坑在这里集中列一下。
3.1 中英文混排下的 author 字段写法
下面这段经验非常推荐背下来:在 BibTeX 中,作者字段默认用空格分隔姓名和名,许多英文文献格式会把名字缩写。对英文条目你写成 author = {Smith, John and Wang, XiaoMing} 的意思是容易看懂的。但到了中文条目,如果直接写 author = {张三 and 李四},排版样式在试图解析“名”和“姓”时可能会把中文名处理得很怪,甚至在个别 bst 样式下会丢失名字或错误换位。
稳妥的做法是给中文人名整体套上花括号,明确告诉 BibTeX:这是一个不可拆分的整体,不需要做大小写切换或缩写处理。
bibtex复制@article{zhangsan2024,
author = {{张三} and {李四}},
title = {一种改进的路径规划算法},
journal = {北京航空航天大学学报},
year = {2024}
}
同样道理,机构名也建议用双重大括号保护。比如 author = {{北京航空航天大学自动化科学与电气工程学院}},否则引擎可能把机构名当成“姓 + 名”的结构去尝试切分,最终出现莫名其妙的逗号或缩写。
3.2 title 字段的大小写陷阱
BibTeX 默认对不同文献样式处理标题时可能会把英文标题的首字母大写、其余改为小写,这就是为什么你会看到导出的英文文献标题里的专有名词全部变成小写,比如把 Transformer 变成 transformer。解决办法是在需要保留大小写的地方用花括号括起来:
bibtex复制title = {An Empirical Study of {BERT} on {Semantic Role} Labeling}
在实际录入时,不需要整句话都用花括号,只需要锁定专有名词、缩写、特殊术语的首字母即可。否则你在第三方学术搜索引擎导出 .bib 时会看到一些条目把整个标题都包了一层花括号,这虽然能用,但后续如果手动改动索引就不太清爽。
3.3 页码、卷号、日期这些隐蔽格式
很多人会忽略页码里的连字符。正确写法是:
bibtex复制pages = {100--110}
两个连字符 -- 在 LaTeX 里渲染出来是一个排版用的连线,如果写成 100-110,很多模板里会显示成单短横,视觉上非常业余。年份和月份也要保持一致,个别模板还会提示月份字段不能为空。
下面是我常用的一个字段对照表,列出来供录入时对照:
| 字段 | 必填程度 | 说明 |
|---|---|---|
| author | 必须 | 多个作者用 and 连接,中文名建议整体花括号 |
| title | 必须 | 专有名词用 {} 保护大小写 |
| journal / booktitle | 必须 | 区分期刊名称和会议论文集名称 |
| year | 必须 | 数字,不要写成 2024年 |
| volume | 根据样式 | 卷号,常见于期刊 |
| number | 根据样式 | 期号,英文期刊中常见 |
| pages | 根据样式 | 页码范围用 -- 分隔 |
| doi | 推荐 | 现在很多模板和期刊会要求显示 DOI |
| url | 可选 | 注意是否能让链接正常换行 |
3.4 善用编辑器批量清洗从网页复制的 .bib 条目
我最早是从各类学术搜索引擎直接导出 .bib 文件的,一个条目导出来可能有十几个字段,包括 abstract、keywords、publisher 等等,堆在 .bib 文件里会让文件膨胀,还有可能引入特殊字符或坏行。后来我一般会在文本编辑器里做一次字段清洗,把不用的字段删掉,只保留与排版模板相关的核心字段。VSCode 里可以直接用正则查找多行区域删除,也可以装一个 Sort Lines 一类的扩展把条目排序。真要图方便,也可以用 JabRef 打开 .bib 来管理和清理,效果比手写稳定很多。
4. VSCode 里引用补全、跳转和引用预览的实用套路
参考文献资料理清楚了,接下来是效率问题。在 VSCode 中插入参考文献引用,真的不必每次都手动敲 key,或者切出去到 .bib 文件里翻条目。LaTeX Workshop 提供的引用补全已经很好用。
4.1 让 cite 补全出现在智能提示里
只需确保主文档已经引用了一个 .bib 文件。比如正文里一般会写:
latex复制\bibliography{bib/refs}
或
latex复制\addbibresource{bib/refs.bib}
这样插件在检测到上下文中有 \cite{}、\citep{}、\citet{}、\parencite{} 等命令时,只要你输入 \cite{ 并按下快捷键 Ctrl + Space,就可以列出当前 .bib 文件中所有条目。选择后插件会自动补全 key。对于一个有几十甚至上百篇文献的论文来说,这能省下非常多的时间。
4.2 从正文反向跳到 .bib 条目位置
我在写文献综述时经常需要确认某条引用到底对应哪篇论文。VSCode LaTeX Workshop 支持按住 Ctrl 并鼠标悬停在 \cite{key} 上显示引用详情,也支持直接跳转到 .bib 文件中对应条目。方法是光标放在 \cite{key} 中,使用“转到定义”快捷键,默认通常是 F12 或通过命令面板执行 latex-workshop.actions.goto 相关命令,就能跳到对应条目所在行。这个功能配合分屏操作非常顺手,建议把正文 .tex 放在左屏,.bib 文件放在右屏,边写边核对。
4.3 不引用但想列入参考文献目录的条目
有的文献你是真想放进“参考文献”列表,比如学校要求列出所有阅读过的文献,或者模板评审希望展示全部调研成果,但正文中确实没有显式引用。这时可以在正文中某处使用 \nocite{key},如果是很多条,可以用 \nocite{*} 列出 .bib 文件中的所有条目。\nocite{*} 放在附录盘点阶段很有用,但提交前一定要检查清楚,不要因此把没读过的无关文献也带进目录。
4.4 补全不出来的常见原因
如果按 Ctrl + Space 时提示列表为空,最常见的三个原因是:
.bib文件的编码或语法有问题,BibTeX 后端解析失败。- 当前打开的根文档没有通过
\bibliography指定数据库。 - 你的
.bib文件中条目 key 包含隐藏字符或中文标点。
我给个土办法:新建一个最小测试文件,里面只放一条最简单的 @article,正文只写一句引用,编译一次,如果能通,说明项目自身链路没问题;如果还不通,再回查插件配置。
5. 排查 undefined citation、empty bibliography 这类问题的完整链路
编译报了 LaTeX Warning: Citation 'xxx' on page 1 undefined,是很多同学最头疼的时候。我不赞成每次遇到就直接去搜代码或重新安装一堆工具,正确的做法是从编译产生的辅助文件入手一步步定位。
5.1 第一步:看 .bbl 文件是否存在
用 VSCode 打开项目文件夹,找到 .aux 同名的 .bbl 文件。如果 .bbl 文件不存在,说明 BibTeX 没有被执行过,或执行时发生了错误。这时你应该重点看 .blg 文件,这是 BibTeX 运行留下的日志。
我见过的情况包括:
.blg中出现I couldn't open database file,说明主文档里写的.bib数据库路径不对。.blg中出现Repeated entry或You're missing an entry type之类的提示,说明.bib语法有问题。- 缺少带大写后缀的
.bib数据库文件,虽然 Windows 不区分大小写,但跨平台最好统一命名为小写,并在\bibliography中保持一致。
5.2 第二步:确认 .aux 里有没有引用记录
打开 .aux 文件,搜索 citation 关键字。如果里面没有 \citation{...} 记录,说明第一次编译其实没有把正文中的 \cite 正确写入辅助文件。这时优先级是检查 \cite 命令拼写是否写入了某个不存在的 key,或者是否存在大小写不一致。
5.3 第三步:清理旧辅助文件后重编
按我个人的经验,越是在频繁改动 .bib 与正文后,越容易遇到“旧状态残留”的问题。.aux、.bbl、.blg、.out 这些文件记录的是上一次编译的状态,如果不清理,很可能出现旧内容覆盖新内容,或 bbl 文档结构在多次编译间冲突。
在 LaTeX Workshop 中有一个 “Clean up auxiliary files” 一类的命令,删除后重新编译。我在文章编写过程中一般会定期做一次“彻底清理再从零编译”,用来检查最终产物,效果和重新开始一次全新构建几乎相同。
5.4 一个特别值得警惕的坑:多主文件结构下的辅助文件冲突
BUAA 模板偶尔会有多个章节主文件,或者部分同学喜欢在多个 .tex 文件中各自写一句 \bibliography,这会让 BibTeX 在不同章节之间相互干扰。最终结果可能是某些章节里有参考文献,某些章节里没有。更稳妥的方式是:所有文献数据只放在论文的总根文件中统一管理,其它章节只管 \cite,不要重复引入 \bibliography。
5.5 另一个隐蔽问题:工具链虽然执行了,但 bibliography style 没配对
即使在 settings.json 中配置了 BibTeX,主文档中如果不写:
latex复制\bibliographystyle{gbt7714}
或模板本身并不要求写,那样式就默认成空或 plain,呈现出来的风格很可能不是 BUAA 论文要求的。因此当参考文献能出来但格式一看就不对时,优先查两处:
- 模板源码中是否已有
\bibliographystyle命令,位置在哪。 - 是否被自定义选项覆盖了默认样式。
我记得自己第一次拿到 BUAA LaTeX 模板时,想当然在正文里加了一个 IEEE 样式,结果整个文献列表编号变样,后来才知道模板自带的机制会通过 \bibliographystyle 或 biblatex 选项控制,用模板统一的即可,不要另外覆盖。
6. 零散但影响成败的操作经验:从开题到提交前的文献管理技巧
最后这部分不是系统教程,更像是我个人在整套流程里形成的习惯,供你直接复制进自己的工作流。
6.1 给你的引用 key 定一套命名规范
一开始我在 .bib 里把 key 起得乱七八糟,有 zhang2024、Wang_et_al_2023、paper1。后来项目大了,正文里引用几十篇论文时发现根本分不清。现在我固定用这种结构:第一作者姓氏 + 年份 + 关键词首字母,比如 vaswani2017attention、li2024pathplan。这样做的好处是只需要看 key 就能大概想起是谁的工作,也极大降低了重名概率。
6.2 每写一段就给引用打一个本地快照
写长论文时有个很反直觉但非常有用的方法:每次完成一个章节的大量修改,不要只看 PDF 里显示正常就收工,而是把 .bib 和正文的改动记录放到版本管理里。我用 git 做版本管理,提交信息里写明“第 3 章补充 5 篇引用”。这让我在后期遇到“导师说参考文献少了哪篇”时,能准确回溯曾经引过什么,不会陷入重新翻 PDF 找来源的麻烦。
6.3 提交前用两遍法校对参考文献
第一遍校对只做“有没有”,检查:
- 正文每个
\cite{key}都能跳转到.bbl里的一条文献。 .bbl没有空条目、输出末尾没有明显的 BibTeX warning。- 中英文文献混排正常,中文作者名没有不合理的缩写或逗号。
第二遍校对只做“对不对”,把编译好的 PDF 导出来逐条对照原始文献来源,重点核对作者拼写、年份、卷号、页码和期刊名。这个步骤非常枯燥,但恰恰是手动维护式参考文献最容易翻车的地方。我曾在某一轮提交前发现有一篇论文的页码多写了一位,这种错误在内容审核时极其显眼,也会暴露出整体写作不够细心。
6.4 遇到模板升级就重建一次环境
BUAA LaTeX 这类模板更新频率不高,但一旦更新,目录结构、cls 文件选项、参考文献宏包可能都有变动。如果你发现同一份 .bib 文件在旧版模板下编译正常,换了新模板后格式乱了,不要在旧环境下硬凑,直接把模板自带文档中的 tex 和 bib 示例完整跑通,再把你的内容迁移过去。这样能避免很多隐藏的宏包冲突。
在 VSCode 里整理 BUAA LaTeX 参考文献这件事,说难也难在“看不见的中间状态”,说简单也简单在经过一次完整链路梳理后,后面其实都是体力活。我最大的感受是:不要心急地往 .bib 里堆数据,先花二十分钟把 tools、recipes、根文件、.bib 语法这几个基础点确认清楚,后续的工作才会真正顺畅起来。
