北航论文模板(buaathesis)在 XeLaTeX 下编译论文的时候,很多人会遇到这么一行警告:
LaTeX Warning: Font shape 'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' instead on input line 27.我第一次看到这行警告时,第一反应是查了一遍“是不是我没安装宋体”,结果系统里 SimSun 明明就在。后来真正踩进去才发现,这个警告和“有没有字体”关系不大,真正的问题出在字体样式映射上——模板某处想让宋体输出粗体,但 XeLaTeX 找不到对应的粗体字形定义,于是只能退回去用常规粗细顶替。这篇内容就围绕这个警告展开,我会把警告怎么读、模板为什么触发、以及我实际用过的几种修复方案全部讲清楚,适合正在用北航学位论文模板、或者任何用到宋体加粗场景的 LaTeX 用户参考。
1. 先摸清警告的含义:Who 是 SimSun(1),Who 是 b/n
很多教程会直接告诉你“这是字体缺失,装字体就行”,但这句话其实不够准确。要解决问题,先把警告本身的语法拆开。
1.1 警告信息逐段拆解
XeLaTeX 的字体警告格式通常长这样:
Font shape 'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' instead把它按斜杠拆开,可以得到四个关键信息:
TU是字体编码。在 XeLaTeX 和 LuaLaTeX 环境下,字体默认走 Unicode 路由,内部编码名就叫TU(Text Unicode),可以理解为“这个字体按 Unicode 字符集来使用”。SimSun(1)是字体内部名字。这里的括号数字(1)不是版本号,而是 fontspec/xeCJK 在内部给字体实例做的编号标记。意思是“这是当前文档里被引用的第 1 个宋体实例”。b/n是请求的字体样式,b代表 bold(粗体),n代表 upright(直立)。合起来就是“粗体+常规字形”。m/n是真正被换用的样式,m代表 medium(中等粗细)。也就是说,XeLaTeX 想用粗体宋体,但没找到,最后实际渲染成了常规字重宋体。
所以整条警告翻译成人话就是:文档某处要求用“宋体粗体”,但当前环境中根本没有定义这个字形,XeLaTeX 很无奈地给你换成了“宋体常规”。
1.2 “undefined(font)”和“字体缺失”的区别
这里很容易混淆,我多解释一句。undefined(font)并不等于“系统里没装宋体”,而是指“在当前 LaTeX 字体表里,不存在宋体的粗体系列”。
LaTeX 处理字体有一套自己的映射逻辑:字体家族(family)、字形系列(series)、形状(shape)三个维度组合出一个样式。宋体在 Windows 下通常只有 Regular 这一个物理字体文件,并没有自带一个独立的 SimSun Bold 文件。当你告诉 XeLaTeX“这里的文字要粗体”时,它去字体表里查“SimSun + Bold”,查不到,就会打印 undefined 警告,然后退回普通字重。
这种情况在纯英文的 LaTeX 文档里很少见,因为英文主流字体(比如 Latin Modern、Times New Roman)通常都有完整的 Regular、Bold、Italic、BoldItalic 四个文件。而中文字体不一样,很多中文字体发行版只提供一个字重文件,粗体要靠“伪加粗”或者“换字体”来实现。
2. 为什么偏偏是北航模板频繁触发这个警告
知道警告本身的含义之后,下一个问题是:为什么我用别的模板不报,换成北航模板就疯狂刷警告?这跟模板的字体配置方式有关系。
2.1 模板里宋体粗体的配置逻辑
北航模板基于常见的大学论文模板框架,会通过 xeCJK 宏包来设置中文字体,典型配置类似这样:
\setCJKmainfont[BoldFont = SimHei, ItalicFont = KaiTi]{SimSun}这段配置的意思是:正文中文主字体用宋体,当需要粗体时改用黑体,需要斜体时改用楷体。理论上这样配置不会触发宋体粗体警告,因为BoldFont已经被明确指定为 SimHei(黑体)。
但在实际模板的历史版本里,有一部分配置文件并没有把所有需要加粗的地方都指向黑体,而是直接对宋体使用\bfseries或者\textbf。还有一种情况,模板里定义了类似这样的命令:
\newcommand{\songti}{\CJKfamily{SimSun}} \newcommand{\heiti}{\CJKfamily{SimHei}}然后某个章节标题样式里,先切换到宋体,再要求加粗:
{\songti\bfseries 第1章\ 绪论}此时\bfseries试图在 SimSun 家族的字体表里寻找粗体系列,触发了我们看到的警告。
2.2 模板加载顺序带来的“连锁反应”
北航模板通常是分文件组织内容的,主文件、设置文件、章节文件层层嵌套。字体设置往往集中在主文件或专门的buaa.cfg/setup.tex里,但实际使用粗体的地方分散在章节标题、表格标题、参考文献、附录等各个角落。
如果你的模板版本里,\setCJKmainfont没有被正确执行,或者被后续某个宏包重置了,那么后面所有涉及“宋体加粗”的地方都会依次报错。这也是为什么有时候你看到警告不是一条,而是连续几十条,因为文档里有几十处加粗标题,XeLaTeX 每遇到一处就报一次。
2.3 编译引擎和字体库的影响
还有一个现实因素:北航模板官方说明通常建议用 XeLaTeX 编译,因为它天然支持系统中文字体。但 XeLaTeX 本身对字体样式的推导逻辑比较“死板”。当它发现你设置了AutoFakeBold或者BoldFont时,会优先按指定映射走;如果没设置,它就认为“你这个字体家族没有粗体”,然后老老实实退回常规字重。
你可能会问:为什么不像 Word 那样自动加粗一下?因为 LaTeX 的设计哲学里,字形替换必须显式声明,不能默认做“视觉假加粗”。字体设计者觉得那样不严谨,用户却觉得麻烦——这就是这个警告会反复出现的根本原因。
3. 修复方案:让模板在 XeLaTeX 下安静编译
这个警告虽然不阻断编译流程,但会刷屏,而且实际的加粗效果确实达不到预期。有两个方向可以修复:一是让宋体支持粗体,二是把所有需要粗体的宋体替换成其他字体。下面三种方案我都实际验证过。
3.1 方案一:给宋体开启“伪粗体”,最通用也最简单
在 xeCJK 里,开启伪粗体只需要在设置宋体时加一个选项:
\setCJKmainfont[AutoFakeBold = 3]{SimSun}这里的AutoFakeBold = 3表示伪粗体的加粗程度,取值范围一般是 1 到 4,数值越大加粗越明显。我实测下来,2.5到3之间最接近正式文档要求的视觉重量,太小的值几乎看不出加粗,太大的值字体边缘会出现明显的“发虚”和笔画糊。
如果你不想改主字体设置,只想针对模板里某个地方关掉警告,也可以把警告出现的那个命令临时改成普通字重,但这样治标不治本。我的建议是优先改全局设置:
\setCJKmainfont[ AutoFakeBold = 3, ItalicFont = KaiTi ]{SimSun}改完重新编译,原来刷屏的Font shape 'TU/SimSun(1)/b/n' undefined警告会直接消失。
注意:
AutoFakeBold的作用范围是当前 CJK 主字体。如果模板里还有\setCJKsansfont、\setCJKmonofont,它们各自需要单独设置。
3.2 方案二:把宋体粗体映射到黑体,符合出版规范
很多高校论文格式要求里,“宋体加粗”本质上就是要你显示成黑体效果。既然模板报错是因为找不到宋体粗体,那不如直接告诉 XeLaTeX:宋体要加粗时,用黑体替代。
配置方式:
\setCJKmainfont[ BoldFont = SimHei, ItalicFont = KaiTi, BoldItalicFont = KaiTi ]{SimSun}这样设置之后,文档里所有\textbf{...}或\bfseries ...的汉字都会变成黑体,同时不会再有任何 undefined 警告。
这个方案的好处是最终 PDF 的观感更符合国内学术论文的排版习惯,黑体的笔画对比强,标题层次分明。坏处是你失去了“宋体加粗”的可能性,如果你的导师明确要求标题使用“加粗宋体”而不是黑体,那这个方案就不合适。
我自己做学位论文时,学院格式要求写的是“一级标题:三号黑体;二级标题:四号黑体;正文:小四号宋体”,这种要求下方案二就是标准答案。
3.3 方案三:修模板里具体的粗体触发点,保留宋体加粗语义
如果你既不想用伪粗体,又不想改成黑体,那就只能把模板里触发这个警告的地方逐个找出来,改成不会回溯到宋体粗体的实现。
以章节标题为例,假设模板有这样一段:
\titleformat{\chapter} {\songti\bfseries\Large} {...} {...} {...}可以改成:
\titleformat{\chapter} {\heiti\Large} {...} {...} {...}对应的,把正文里那些“先切宋体再要求加粗”的地方,统一改成直接使用黑体。这个方法最费工时,但最精准:它能完全保留模板原本的字号、间距、对齐设置,只是把“宋体粗体”这个不存在的样式替换成实际可渲染的样式。
查找触发点有一个技巧:在编译日志里搜索undefined(font),每一行都会带上on input line XX,你可以根据行号定位到对应的.tex文件。如果你用的是 Overleaf,直接点日志里的行号一般也能跳转到具体代码位置。
4. 完整实操记录:我按方案一改完的整个流程
下面用我在一台 Windows 10 机器上实际操作的过程为例,给你完整跑一遍从发现问题到确认修复的流程。
4.1 环境确认和日志定位
首先,我用的编译命令是:
xelatex main.tex编译完成后,打开main.log,搜索undefined(font),得到了一大串相同格式的警告。我数了一下,一共 47 条,分布在正文的各个章节标题、表格标题、以及参考文献条目里。
我确认了模板主文件的字体设置段落,位置在main.tex的导言区,原来是这样:
\setCJKmainfont[BoldFont = SimHei]{SimSun}注意这里有个细节:明明已经指定了BoldFont = SimHei,为什么还会警告?因为模板里有其他局部字体命令绕过了这个设置,比如某处直接用\CJKfontspec{SimSun}开启了新的宋体字体实例,\CJKfontspec不会继承主字体的 BoldFont 映射,于是又回到了“宋体没有粗体”的状态。
4.2 修改字体配置
为了让所有宋体实例都能正确处理粗体,我选择直接在主设置里加伪粗体:
\setCJKmainfont[ AutoFakeBold = 3, BoldFont = SimHei, ItalicFont = KaiTi ]{SimSun}同时,我把模板里一个自定义的“正文宋体”命令也加上了伪粗体:
\newCJKfontfamily\songti[ AutoFakeBold = 3 ]{SimSun}这样处理后,原来通过\songti切换的宋体段落也能正确处理\bfseries了。
4.3 重编译和结果验证
我再次执行xelatex main.tex,这次日志里undefined(font)的数量降到了 0。我又检查了生成的 PDF,重点看几个原本警告密集的位置:目录页、第一章标题、二级标题、表格标题。视觉上加粗效果正常,伪粗体的笔画没有明显发虚,整体观感能满足打印要求。
我还做了一次对比实验:把AutoFakeBold的值从 3 改成 4,重新编译后放大 PDF 局部截图,能明显看到笔画边缘出现细小锯齿,于是我又改回了 3。这个参数在不同屏幕和打印机上的表现会有差异,建议你最终定稿前用自己学校的打印店要求试一次。
经验:如果你的模板同时存在多个宋体实例,最稳妥的做法不是去追每一个实例,而是先在
main.tex导言区定义一个新的“带伪粗体的宋体系列”,然后把模板里所有\songti这样的命令替换成新定义的命令。一次替换,全局生效。
5. 常见问题与排查技巧实录
在这个警告上踩过几次坑之后,我把常见的情况整理成了一份速查表,你可以直接对照排查。
5.1 问题现象和解决方案速查表
| 场景 | 现象 | 处理方式 |
|---|---|---|
| 模板未设置 BoldFont | 日志里出现大量SimSun(1)/b/n警告 | 在\setCJKmainfont加AutoFakeBold = 3或BoldFont = SimHei |
| 模板已设置 BoldFont,但局部命令绕过 | 警告只在某些章节标题出现 | 搜索\CJKfontspec、\newCJKfontfamily等局部字体命令,为它们补上粗体映射 |
| Overleaf 在线编译 | 警告时有时无,与本地不一致 | 检查 Overleaf 的 TeX Live 版本;不同版本对伪粗体参数的解析略有差异 |
| 使用 macOS,没有 SimSun | 提示找不到字体或乱码 | 将SimSun替换为Songti SC,或下载安装宋体字体文件 |
模板里用了\textbf{中文} | 警告出现但 PDF 文字居中显示正常 | 属于正常回退,按需选用方案一或方案二消除警告 |
5.2 Overleaf 上处理这个警告的细节
如果你用的是 Overleaf,而不是本地 TeX Live,有一个额外的问题需要注意:Overleaf 的字体缓存是独立的,部分版本对字体名称的大小写敏感,SimSun写成simsun都可能影响粗体映射。我在本地正常、在 Overleaf 刷警告的情况就遇到过。
解决方法是在 Overleaf 项目里手动检查字体配置,并显式指定粗体映射,不要依赖默认行为。用方案一的配置时,AutoFakeBold在 Overleaf 上也能正常生效,我实测过。
另外,Overleaf 的日志窗口会把警告折叠起来,你需要展开“Warnings”标签或者直接下载.log文件查看。否则你可能会以为编译没问题,实际 PDF 里标题加粗效果已经丢失了。
5.3 修改模板会不会影响格式审查
很多同学担心改了模板字体设置会影响学校格式审查。我的建议是:保留模板原本的字号和间距设置,只修改字体样式映射。具体操作时,不要删除原有的\setCJKmainfont相关配置,而是在原有配置基础上增加AutoFakeBold参数;如果模板里没有这一行,就在导言区自行添加。
这样修改后,页面排版不会变化,只是“宋体加粗”的渲染方式从不可用变成了可用。打印出来的效果和 Word 里“宋体加粗”差别不大,格式审查人员一般不会察觉。
6. 几个容易被忽略的细节和一处实用心得
修复过程中,有几个细节想单独拎出来说,因为它们不在任何文档里写得特别明白,但实际影响却很大。
第一,AutoFakeBold对英文和中文字符都有影响吗?实测结果:xeCJK 的AutoFakeBold只对 CJK 字符生效,拉丁字符的粗体仍由西文字体控制。如果模板正文里夹杂大量英文,英文粗体的视觉效果可能和中文伪粗体的视觉重量不一致,这一点在排版混排文档时要注意。如果要求严格,可以把西文粗体和中文伪粗体的粗细分别调整,但大多数论文场景下不需要这么精细。
第二,如果你用了AutoFakeBold = 3后,生成的 PDF 在部分阅读器里显示偏淡,这不是字体的锅,是渲染器的字体平滑策略在搞事情。建议导入 PDF 到 Adobe Acrobat 或者发给打印店时再次检查,最好做一次打印测试,避免最后交上去的版本在打印后出现“标题跟正文一样粗”的尴尬。
第三,在排查时不要只盯着一处警告看。这个警告往往意味着模板里存在多处类似的“宋体加粗”调用。你修好一个地方,重新编译后可能又冒出来新的行号。耐心一点,把日志里的on input line按顺序全部过一遍。
根据我个人的使用经验,最省心的做法其实是一开始就确定好自己学校的格式要求:如果格式手册里写“标题用黑体”,直接方案二,把宋体粗体映射成黑体,一劳永逸;如果格式手册没有明确说明,只是要求“加粗、宋体”,那就用方案一,开AutoFakeBold,视觉上最容易通过。
这个内容后续还可以继续扩展:比如把同样的分析思路用于解决“楷体没有粗体”“黑体没有斜体”等类似场景。实际上,所有中文字体+i 门类缺失的问题,修复逻辑都是一样的,先看是字体缺失还是样式缺失,再决定是补映射、开伪粗体,还是换字体。搞懂这一条思路,比记住这一条警告的解法更有用。