ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

LaTeX字体警告修复:北航论文模板宋体加粗失效的完整解法

2026/10/5 1:23:54 拓冰建站 浏览量
LaTeX字体警告修复:北航论文模板宋体加粗失效的完整解法 我处理过不少北航论文模板的编译问题其中出现频率最高的就是开头这几行黄色告警LaTeX Font Warning: Font shape TU/SimSun(1)/b/n undefined(font) (font) using TU/SimSun(1)/m/n instead on input line 42.第一次看到的同学基本都会慌是不是模板坏了是不是缺字体但实际编译还能出PDF正文也都在只是所有本该加粗的汉字全都没有加粗。这个现象几乎是北航模板的“经典开场白”而且不只是北航很多基于ctexbook的学位论文模板都会踩到。这篇文章我不打算只给一条“复制粘贴就能跑”的配置而是把告警的来源、字体加载机制、三条修复路线、以及在模板里具体改哪几行都讲透。如果你正在用北航模板写学位论文或者准备把论文从 Windows 本地环境迁到 Overleaf这篇应该能帮你省下大半天时间。1. 告警原文拆解TU/SimSun(1)/b/n 到底代表什么1.1 一次典型的编译现场用北航模板写论文时最常规的编译命令是latexmk -xelatex main.tex或者直接多次运行xelatex main.tex然后控制台里就会出现这条“不打断编译、却让你心里咯噔一下”的字体警告。它通常出现在第一章或者目录之后触发点往往是第一个\section、第一个\caption或者任意一个\textbf{中文内容}。这里的关键点**它要求的是中文粗体但对西文字体没有影响。**所以很多人一开始发现不了直到检查 PDF 时才发现“怎么标题和正文一样粗”1.2 NFSS 字体形状的五个字段要理解这条告警得先知道 LaTeX 的字体描述体系。在 NFSSNew Font Selection Scheme里一个字体用编码/字族/字重/字形四段描述。这条告警拆开看是字段值含义编码TUXeLaTeX 下的 Unicode 字体编码字族SimSun(1)fontspec 加载的 SimSun 字体实例字重bbold粗体字形nnormal常规字形也就是说LaTeX 在排版时发现当前字体族SimSun(1)下粗体常规字形TU/SimSun(1)/b/n不存在。它没有直接报错而是自动往下降一档用了TU/SimSun(1)/m/n也就是中粗体实际上就是常规字重来替代。m是 medium中文里面通常就当常规字重看。所以这条告警的本质就是SimSun 没有粗体LaTeX 用普通宋体顶替了。1.3 为什么这个告警不致命但很烦人说它不致命是因为论文还是能编译成功的PDF 也能正常打开内容不会少。说它烦人是因为它带来的问题会在最后冲击盲审时集中爆发章节标题本来应该有层级感结果一级二级标题和正文字重一样目录里也看不出层级。表格表头或关键词里的\textbf完全无效。摘要、图注里的中文粗体整体失效导师一眼就能看出来。更麻烦的是xelatex多编译几轮以后日志文件里面全是这种警告真正的报错信息反而被淹没。所以那条using ... instead不是一句轻飘飘的提示它是模板字体配置出问题的信号。接下来我讲讲这根因到底出在哪。2. 根因分析SimSun 为什么没有粗体模板又是怎么踩上去的2.1 中易宋体的字体文件只有常规字重Windows 自带的简体中文字体里SimSun宋体对应的字体文件是simsun.ttc。在系统中查看字体属性你会注意到它的样式只有“常规”没有“粗体”和“斜体”。中易宋体并不是一套包含多字重的字体家族它只提供了一种正文字重。这在日常 Office 软件里不明显因为 Word 里你把中文设成“加粗”本质上是用渲染引擎做了一个伪粗体。但 XeLaTeX 走的是另一条路它通过 fontconfig 向系统查询字体信息要看这个字体到底有没有真正的 bold 字重。查询结果是没有于是它就不知道粗体该怎么办了。2.2\setCJKmainfont{SimSun}只说明主字体没说粗体用哪个北航论文模板大多基于ctexbook文档类常见配置会写成类似这样\documentclass[fontsetnone, zihao-4]{ctexbook} \setCJKmainfont{SimSun}这一行\setCJKmainfont{SimSun}的意思很简单让中文主字体用宋体。但问题在于它没有告诉 xeCJK“宋体没有粗体时该用什么”。于是 xeCJK 内部会试图为 SimSun 找一个粗体版本找不到就发出了那条undefined(font)告警。这就像一个界面设计稿上写了“这里放一个加粗的宋体”但字体包里根本没有这个字重排版软件只能拿普通宋体硬顶。2.3 北航模板的“宋体标题”与\bfseries北航的学位论文格式要求里正文用宋体、章节标题用黑体是比较常见的规范。但不少模板为了省事直接在标题格式里用了\bfseries。比如\ctexset{ section { format {\Large\bfseries}, } }这个\bfseries在英文排版语境下是“加粗”但套用到中文宋体时它就触发了上面说的粗体缺失链。如果模板在标题格式里使用的是\heiti或者\CJKfamily{zhhei}一般不会出现这个告警因为它已经明确切换到黑体了。所以从根因上讲这不是“XeLaTeX 有问题”而是模板的字体语义没闭环。2.4 为什么告警里是 SimSun(1) 而不是 SimSun还有一个让很多人困惑的点为什么字体名后面带个(1)这不是北航模板专属而是 fontspec 的内部机制。当一个字体在文档里被多次加载、或者同时作为CJKmainfont和某个CJKfamily的基础字体时fontspec 会为它生成内部编号用来区分不同实例。SimSun(1)就是第二个 SimSun 实例。比如模板里同时写了\setCJKmainfont{SimSun} \setCJKfamilyfont{zhsong}{SimSun}或者某个宏包内部也加载了 SimSun这时候就会出现SimSun(0)、SimSun(1)这种编号。看到(1)不要慌它只是定位用的标签真正要解决的是/b/n缺失。3. 三条修复路线黑体替代、伪粗体、换字体3.1 路线A把中文字体的粗体映射到黑体我最推荐的方案是直接告诉 LaTeX中文粗体请使用黑体。\setCJKmainfont[BoldFontSimHei]{SimSun}这一行的意思是中文主字体仍用宋体但当需要加粗时切换到黑体SimHei。这非常符合中文科技论文的排版传统——正文宋体、标题黑体字重层次分明而且不需要依赖任何伪造效果。改动之后\section、\textbf{中文}、\caption里的加粗中文都会变成黑体告警也随之消失。如果你希望英文部分不受影响也完全不用担心\setCJKmainfont只管中文西文字体由\setmainfont单独管理。3.2 路线B打开 AutoFakeBold 伪粗体有些人希望“保持宋体外貌只是变粗一点”那就可以用伪粗体。xeCJK 提供了一个开关\setCJKmainfont[AutoFakeBold2.5]{SimSun}或者全局设置\xeCJKsetup{AutoFakeBold2.5}AutoFakeBold的原理不是调用真正的粗体字体文件而是让排版引擎在渲染时对字形做加粗处理。参数2.5控制加粗程度数字越大越粗一般 2~3 之间比较合适。这个方案的好处是改动最小一行代码就能消掉告警。缺点也很明显伪粗体本质是图形算法拉伸不是真正的字体设计在屏幕上看着还行打印出来或转到高分辨率 PDF 后笔画边缘会有点发“糊”不够精致。如果你的论文要送盲审或正式归档我对这种方案保留意见。3.3 路线C换成自带粗体的开源字体如果不想碰伪粗体也不想把中文粗体映射成黑体那最干净的办法是换一套自带 Bold 字重的 CJK 字体。常见选择FandolSongctex 宏包内置配套Noto Serif CJK SCSource Han Serif思源宋体比如\setCJKmainfont[BoldFont{Noto Serif CJK SC Bold}]{Noto Serif CJK SC}或者直接用 ctex 的字体集\documentclass[fontsetfandol]{ctexbook}这样整套中文排版都会换成开源字体粗体、斜体都齐全编译日志干净清爽。但这里有一个非常现实的坑北航模板对中文字体有严格要求很多学院明确要求“宋体”“黑体”“楷体”“仿宋”四件套而FandolSong、Noto Serif CJK SC在字形上和中易宋体存在细节差异。正式提交前最好先问清楚教务处或导师能不能接受。3.4 三条路线横向对比方案代码成本是否维持宋体是否符合论文规范风险点BoldFontSimHei低正文是宋体加粗变黑体推荐符合标题黑体规范如果导师要求“宋体加粗”会有歧义AutoFakeBold极低是伪粗宋体勉强通过高分辨率下笔画发虚换开源字体中否字形有差异需确认学院要求可能影响提交格式一致性从实际论文提交角度我绝大多数情况会选路线A。它既保留了正文宋体又让标题黑体化和北航模板的格式要求天然一致。4. 在北航模板的导言区落地修改4.1 先定位模板里的字体配置代码拿到一个北航模板先不要急着大改打开主.tex文件按这些关键词搜索setCJKmainfontsetCJKsansfontsetCJKfamilyfontsetmainfontctexset典型的北航模板导言区大概长这样\setCJKmainfont{SimSun} \setCJKsansfont{SimHei} \setCJKmonofont{FangSong} \setCJKfamilyfont{zhsong}{SimSun} \setCJKfamilyfont{zhhei}{SimHei} \setCJKfamilyfont{zhkai}{KaiTi} \setCJKfamilyfont{zhfang}{FangSong}如果你的模板长这样那恭喜你问题很明确。你只需要把\setCJKmainfont{SimSun}这一行改成\setCJKmainfont[BoldFontSimHei, ItalicFontKaiTi]{SimSun}这里顺带把ItalicFont配成楷体是因为中文排版里习惯用楷体表示强调或引文比真正的“倾斜”更像样。如果你确定不需要斜体也可以只写BoldFontSimHei。4.2 最小可复现案例为了说明问题我给一个最小化案例。下面这段代码在 Windows TeX Live 本地环境下编译后必然出现开头那条告警\documentclass[fontsetnone]{ctexbook} \setCJKmainfont{SimSun} \begin{document} \chapter{绪论} 中文粗体测试\textbf{北航论文模板}。 \end{document}把\setCJKmainfont{SimSun}改成\setCJKmainfont[BoldFontSimHei]{SimSun}再编译告警消失\textbf{北航论文模板}会以黑体渲染。这个最小案例可以用来快速验证你的 TeX Live 环境本身没有问题再往北航模板里套。4.3 容易漏掉的第二处配置zhsong 字体族如果你按 4.1 改了\setCJKmainfont发现告警还在那大概率是模板里用了\songti或\CJKfamily{zhsong}这类字体族命令。比如摘要的格式设置里可能写了{\songti 摘要标题}这时候 LaTeX 使用的是zhsong字体族而不是CJKmainfont。你需要额外给它配置粗体映射\setCJKfamilyfont{zhsong}[BoldFontSimHei]{SimSun}同理如果模板里还有zhkai、zhfang这些族也要检查它们是否会被用在需要加粗的场景。一般情况下黑体族zhhei不需要管因为它本身就是标题字体但楷体和仿宋如果被\textbf包裹也会出现类似的 undefined 告警。4.4 不推荐的做法处理这个告警时有几种做法我强烈不建议不要为了消除告警在导言区写\documentclass[fontsetwindows]后又手动覆盖字体。ctex 的fontsetwindows本身已经把中文粗体映射成黑体了你再覆盖反而可能重新引入问题。不要把章节标题里的\bfseries改成\textbf两者对 CJK 来说走的是同一套字体选择机制改完没用。不要用\pdfmapfile{}这类偏门命令去“绕”XeLaTeX 根本不走 bitmap 字体映射那套流程。更不要直接删除告警不处理因为它本质是粗体失效而不是多余提示。5. 改完怎么验证换环境后又怎么应对5.1 三步验证法改完配置后不要只看“编译没报错”就完事建议按三步验证查日志。重新编译后在.log文件里搜索undefined(font)如果搜不到SimSun相关的undefined(font)说明字体配置已经不再回退。看 PDF 字形。在 PDF 里找一个章节标题用 PDF 阅读器的“属性”或“字体”面板检查它嵌入的字体。如果标题用的是 SimHei说明BoldFontSimHei已生效。翻目录。目录里的章节标题往往单独有一套 TOC 格式有些模板的目录字体设置和正文标题不同。如果目录里仍是普通宋体说明模板在toc格式里单独立了字体配置还需要继续排查。5.2 Overleaf、Linux 与老版本 TeX Live 的差异北航模板在国内学生手里基本都是本地 Windows TeX Live 编译但如果你想放到 Overleaf 上写环境差异会带来连锁问题。Overleaf 的云端环境是 Linux默认没有 SimSun、SimHei、KaiTi、FangSong 这些中易字体。你如果在 Overleaf 上仍然写\setCJKmainfont{SimSun}得到的将不是 undefined 告警而是直接的The font SimSun cannot be found。因为字体文件压根不存在。在 Overleaf 上正确做法是使用 ctex 内置的开源字体集\documentclass[fontsetfandol]{ctexbook}或者手动指定\setCJKmainfont[AutoFakeBoldtrue]{FandolSong}另外要注意不同版本的 TeX Live 里ctex 宏包的默认行为也不完全一样。老版本 ctex 在fontsetnone下对字体配置的解析可能更粗暴如果你升级了 TeX Live 之后才出现告警多半是宏包版本导致字体加载方式变化而不是模板本身坏了。5.3 举一反三的方法论这条告警不只出现在北航模板也不只出现在 SimSun 上。只要看到这种格式Font shape TU/字体名/b/n undefined都可以按这个思路处理确认哪个字体被要求加粗。去导言区搜索这个字体是以什么身份被加载的是CJKmainfont、CJKsansfont还是CJKfamilyfont。给对应的字体设置补上BoldFont...或者打开AutoFakeBold。重新编译并检查日志和 PDF 字形。举例来说如果以后看到TU/SimHei(1)/b/nundefined那就是有人在黑体上又叠了一层\bfseries这属于格式设置冗余应该去改调用处的代码而不是继续给黑体配粗体字体。如果看到TU/TimesNewRoman(1)/b/nundefined则是西文字体缺粗体需要去看\setmainfont的配置。把这条方法论记下来下次再碰到类似的字体回退告警就不用再靠搜索答案碰运气了。按照我处理北航模板这类问题的习惯第一选择永远是BoldFontSimHei而不是AutoFakeBold。原因很简单学位论文是正式存档文档格式审查时导师和教务老师看的是 PDF 成品的视觉层级伪粗体在屏幕上蒙混得过去打印后笔画边缘容易发虚到时候挨批评的还是你自己。另外一个小技巧排查时在导言区加一行\listfiles重新编译后.log文件末尾会列出所有加载的宏包版本和字体文件路径这对定位“为什么我改了没生效”非常有用。最后想提醒一句北航模板只是载体真正要用好 XeLaTeX还是得理解字体选择这一层。只有当你明白undefined(font)的意思是“缺字重而不是缺字体”时这句告警才算真正被消化掉。