
用 Elsevier 模板投稿的时候我猜绝大多数人默认走的都是 pdflatex 这套老路子Overleaf 里新建项目直接编译公式好好的根本不觉得字体有什么问题。直到某天你为了用系统里的中文字体、为了跟 Word 稿子的排版对齐或者单纯想在本地用 xelatex 编译器跑一遍然后就看见了让你头皮发麻的一幕求和符号变成空心方框、希腊字母的笔画粗细发飘、行内公式的上下标贴在一起整个数学符号区域像是直接从 PDF 里“掉出去”了。这不是你的论文公式有问题也不是 LaTeX 语法写错了而是 Elsevier 模板在 XeLaTeX 下出现了经典的“数学字体映射断链”。我在这条路上绕了不少弯今天把完整的解决思路、可复现操作和踩坑记录整理出来希望对正在被同样问题折磨的人有点帮助。这篇文章会讲清楚现象背后的原理、怎么快速定位异常类型、两种靠谱的修复方案以及一套可以直接抄的 XeLaTeX 配置模板。1. 先搞清楚XeLaTeX 下数学符号为什么会“变脸”1.1 从 TeX 到 XeTeX字体处理逻辑完全不同要弄懂这个问题得先放下“LaTeX 只是换个编译器”这个错觉。pdflatex 时代所有字体都是通过 TeX 自己的 TFM 文件、字体编码OT1、T1和一系列字体族\rmfamily、\sffamily、\mathfamily 等来管理的。数学字体更是有一套专门的机制TeX 启动时会加载若干个“数学字体族”每个符号比如 \sum、\alpha、括号都被分配到某个字体族的固定槽位上。这套机制稳定运行了四十年几乎所有经典模板都是围绕它设计的。XeTeX 则完全是另一套逻辑它直接调用操作系统里的 TrueType、OpenType 字体字体选择通过 fontspec 宏包完成。数学符号不再走传统的 TFM 槽位机制而是需要一个新的宏包来接管“数学字体表”把 \sum、\int、\alpha 这些符号映射到 OpenType Math 字体里去。这个接管工作主流方案就是 unicode-math。用大白话类比pdflatex 像一个只认纸质地图的老司机路线固定、不会走错XeLaTeX 像一个必须依赖导航的新手导航没设置好它就不知道往哪开。Elsevier 模板从出生起就是按老司机的方式调教的突然换到导航体系里它当然不知道数学符号该找谁要。1.2 Elsevier 模板自身埋下的“坑”elsarticle 是 Elsevier 官方投稿模板类文件内部为了模拟期刊最终排版风格做了很多字体预设。常见的情况是这类模板会在内部加载或者强烈依赖基于 pdflatex 编码机制的传统数学字体宏包比如 mathptmx、newtxtext/newtxmath 这一挂。这些宏包在 pdflatex 下表现很好能让正文和数学字体都接近 Times 风格投稿预览时跟期刊排版很像。问题就出在这。当你把编译器切成 XeLaTeX 后fontspec 也开始接管字体但模板里那套传统数学字体宏包还在试图按老办法运行。两套机制在导言区里互相撕扯结果就是有的符号能被新机制接管有的符号还卡在旧机制的半路上最终 PDF 里出现缺字符方框、字形发飘、字体风格不统一这些现象。更麻烦的是很多人不理解为啥已经装了 unicode-math 还是出问题。其实常见原因就在加载顺序和宏包冲突上如果模板在你的 \usepackage{unicode-math} 之前就已经把 mathptmx 之类的宏包塞进去了unicode-math 某些情况下还能硬覆盖一遍但覆盖不干净的话部分符号依然会走旧路径。也有一些人是在加载了 unicode-math 之后又手滑 \usepackage{newtxmath}这等于把刚接好的管道又拆了符号自然继续异常。1.3 典型现象与原因对照表为了让你少走弯路我把实际中见过的高频异常现象和对应原因整理成了对照表。你可以先对照自己的截图或日志快速缩小排查范围。异常现象典型原因优先处理方向求和、积分符号变成空心方框或“”系统缺少 OpenType Math 字体或未设置数学字体安装配套数学字体显式 \setmathfont希腊字母、运算符字形发飘、粗细不均模板内传统数学字体宏包与 unicode-math 机制冲突调整加载顺序禁用冲突宏包统一由 unicode-math 接管数学变量变成直立体而非斜体数学字母表没有被正确映射检查数学字体设置范围必要时用 range 选项强制映射行内公式上下标挤压、整体忽大忽小使用了不完整的数学字体导致不同字号映射异常更换为完整 OpenType Math 字体如 Latin Modern Math、TeX Gyre Termes Math正文是 Times 风格公式却是 CM 风格只设置了正文字体没有设置配套数学字体成对设置 \setmainfont 与 \setmathfont2. 动手前先定位你的“异常”属于哪一类2.1 看编译日志Missing character 是关键线索不要一上来就盲目改代码先学会看日志。用 XeLaTeX 编译后在终端输出或者 Overleaf 的 Log 面板里搜几个关键词Missing character、No character、fontspec 警告。如果看到类似下面这样的记录Missing character: There is no ∑ (U2211) in font [lmmath]!那基本可以断定某个数学符号对应的字形在当前数学字体里根本不存在。这种情况通常是数学字体没有正确加载或者加载的字体本身不是完整的 OpenType Math 字体。如果日志里乱糟糟的都是 fontspec 的 warning比如“Font ... does not contain script Math”那大概率是字体选错了得换成真正带数学表Math table的字体。2.2 做最小化复现MWE我处理这类问题习惯先做最小化复现。别直接在几十页的论文原稿里调试容易分不清是模板问题、宏包冲突还是自己的代码问题。操作方法是新建一个空文档先只加载 elsarticle 类和最基础的 amsmath、amssymb切 XeLaTeX 编译看数学符号是否正常。然后一步步添加字体配置和其余宏包每加一步编译一次直到异常复现。这一步能帮你把“模板预设问题”和“你自己的导言区问题”区分开。很多人最后发现问题根本不是模板而是自己为了用中文字体加载了 fontspec 之后忽略了数学字体接管还有人发现amsmath 和 amssymb 的加载顺序不对也会牵连符号映射在 XeLaTeX 下尤其敏感。2.3 区分“缺字体”还是“字体没切”有时候日志里没有 Missing character但符号就是长得不对那往往是“字体没切对”而不是“缺字体”。你可以检查当前系统到底装了哪些可用数学字体。Linux 和 macOS 下用 fc-list 过滤数学字体关键词Windows 下可以用 otfinfo 或者安装字体管理工具。fc-list | grep -i math如果输出里能看到 Latin Modern Math、TeX Gyre Termes Math、STIX Two Math 或者 Cambria Math 之类说明系统里有可用的数学字体。接下来就看你的 LaTeX 代码里有没有用 \setmathfont 把它们真正设置进去。记住一个原则XeLaTeX 下没有任何魔法你不在导言区里显式指定数学字体数学符号就不知道该去哪找字形。3. 方案一用 unicode-math 彻底接管数学字体最推荐3.1 为什么 unicode-math 是正解解决 Elsevier 模板在 XeLaTeX 下的数学符号异常最干净、最不容易留尾巴的方案就是引入 unicode-math 宏包让它全面接管数学字体。unicode-math 的作用通俗地说就是给 XeLaTeX 造了一个“数学字体调度中心”你告诉它正文字体叫什么它就知道该从哪套数学字体里取符号、该用什么字形变体、加粗和斜体怎么切换。相对另一个方案 mathspecunicode-math 的优势在于它是体系化的它把普通字母、希腊字母、数字、运算符、括号、上标下标全部纳入同一套 OpenType Math 字体框架。只要选一个完整的数学字体符号风格天然统一不像 mathspec 那样容易只改了字母、运算符还是老样子。还有一个实际好处unicode-math 对 \boldsymbol、\bm 这类加粗命令的支持更顺滑投稿时有些期刊要求公式变量加粗这很重要。3.2 推荐三组“正文数学”成对字体实际操作中我建议把正文字体和数学字体当成一对来设置而不是单独选。这里给三组经过我验证、反复用下来的组合组合名称正文字体数学字体视觉风格适用场景CM 经典Latin Modern RomanLatin Modern Math最接近 LaTeX 默认风格不想改变公式原有观感Times 风格TeX Gyre TermesTeX Gyre Termes Math接近 Elsevier 模板默认 Times 感投稿预览与期刊排版匹配学术出版风格STIX Two TextSTIX Two Math现代、印刷感强数学密集型论文、科技期刊这些字体在完整版 TeX Live 或者 Overleaf 里基本都内置不需要额外安装。如果你用的是精简版 TeX Live可能缺 TeX Gyre 或 STIX 系列后面我会讲怎么补装。3.3 和 elsarticle 模板整合的注意事项整合时的核心原则是让 unicode-math 成为数学字体的唯一管理者而不是跟模板预载的传统数学字体宏包共存。导言区里不要再去加载 mathptmx、newtxmath、txfonts 这些基于 pdflatex 的数学字体宏包否则等于给自己埋雷。同时要注意加载顺序。我的习惯是先载入 fontspec设置正文字体然后载入 amsmath、amssymb注意 amssymb 在 unicode-math 下某些符号的行为会有细微差异但基本兼容最后载入 unicode-math并立即用 \setmainfont 和 \setmathfont 把字体定下来。如果模板的 cls 文件内部强制加载了旧数学字体宏包导言区的设置有时会被压过去这时你要么修改模板包要么用一个 wrapper 文档类隔离掉那部分逻辑。一般投稿场景不建议改模板原生代码更推荐在 Overleaf 里把模板复制一份在导言区用 unicode-math 显式覆盖。这个操作听起来简单但能解决掉绝大多数“在 Overleaf 正常、本地却异常”的悬案。下面是一个可运行的最小配置片段我建议直接放到 elsarticle 模板的导言区里\usepackage{fontspec} \usepackage{amsmath,amssymb} \usepackage{unicode-math} \setmainfont{TeX Gyre Termes} % 正文采用 Times 风格 \setmathfont{TeX Gyre Termes Math} % 数学字体配套 \setmathfont{Latin Modern Math}[range{cal,bfcal}] % 花体字母单独选用经典风格最后那行是在某些需要 \mathcal 风格保持 CM 观感时的微调不需要可以直接删掉。但它的存在提醒你unicode-math 支持 range 选项可以精确控制某类符号用哪套字体后期微调时要记住这个利器。4. 方案二mathspec 只改字母保留传统数学符号4.1 mathspec 的应用场景并不是所有人都需要整体切换数学字体。有些人切换到 XeLaTeX 的唯一目的是让英文正文里的普通字母用上系统里的 Times New Roman或者某个期刊要求的指定字体而数学符号希望保持原来的 Computer Modern 风格。这种场景下mathspec 比 unicode-math 更轻量。mathspec 的设计思路是“只调节字体不接管全局”。它允许你单独指定数学模式下的拉丁字母、希腊字母、数字用哪些字体而运算符、积分号、求和号这些特殊符号仍然走 TeX 原有的数学字体机制。如果你的目标只是“正文和公式里的变量字母换成 Times”mathspec 能在几行代码里搞定不用动整个字体体系。4.2 语法与实现步骤在 elsarticle 模板里使用 mathspec同样要先载入 fontspec然后载入 mathspec。注意一点mathspec 和 unicode-math 不能同时使用这两个宏包会互相打架选一个就好。\usepackage{fontspec} \usepackage{mathspec} \setmainfont{Times New Roman} % 或 TeX Gyre Termes \setmathfont(Digits,Latin){Times New Roman} % 数字和拉丁字母用 Times \setmathfont(Greek){TeX Gyre Termes Math} % 希腊字母单独指定这里 \setmathfont(Digits,Latin) 的括号是可选的字母范围参数只有你列出来的类别会被替换其余保持默认。使用 mathspec 时要注意它不会改变 \sum、\int 这些运算符的字体所以如果你遇到的正好是运算符方框问题mathspec 帮不上忙还是得回到 unicode-math 方案。4.3 对比与取舍两个方案没有绝对好坏关键看你的投稿需求和期望效果。我做了个对比供选择时参考对比项unicode-mathmathspec接管范围全部数学符号、字母、数字、算子仅指定的字母、数字、希腊字母等运算符显示随数学字体统一变化保持默认 Computer Modern 风格与 elsarticle 预设冲突需要覆盖/禁用旧数学字体宏包冲突更小但需小心加载顺序高级特性支持 OpenType Math 的各项特性、range 精确控制不支持语法相对简单适合场景公式多、要求字体风格统一只改正文/字母样式、公式少如果你拿不准我的建议是优先上 unicode-math。因为它的行为更可预测出了问题日志也更容易定位。mathspec 更像是“拧一颗螺丝”的方案适合那种不想大动干戈的确定性需求。5. 实操验证一套可以直接抄的 XeLaTeX 模板5.1 完整 MWE 代码带 elsarticle光讲原理不够下面给出一份可以直接在 Overleaf 或本地 TeX Live 里运行的完整模板。它包含了单栏排版、标题作者机构摘要、一个简单的求和公式和一个表格并把字体方案整合好。你把它当成一个“已验证的基础模板”后续把论文内容填进去即可。% !TEX program xelatex \documentclass[preprint,12pt]{elsarticle} \usepackage{fontspec} \usepackage{amsmath,amssymb} \usepackage{unicode-math} \usepackage{booktabs} \usepackage{graphicx} \setmainfont{TeX Gyre Termes} \setmathfont{TeX Gyre Termes Math} \biboptions{numbers,sortcompress} \begin{document} \begin{frontmatter} \title{A Minimal Working Example for XeLaTeX Math Fix} \author{Your Name\affiliation{Your Institution}} \begin{abstract} This is a test abstract. The formula should render correctly under XeLaTeX. \end{abstract} \begin{keyword} XeLaTeX \sep Elsevier \sep math font \end{keyword} \end{frontmatter} \section{Test Math} Inline math like $\alpha\beta\gamma$ and display math: \begin{equation} f(x) \sum_{n1}^{\infty} \frac{1}{n^2} \frac{\pi^2}{6} \label{eq:sum} \end{equation} \begin{table}[htbp] \centering \caption{Font compatibility summary} \begin{tabular}{lcc} \toprule Font Pair Status Note \\ \midrule CM LM Math OK default style \\ Termes Termes Math OK Times style \\ STIX Two STIX Two Math OK modern style \\ \bottomrule \end{tabular} \end{table} \end{document}如果这份代码在你的环境下编译后没有任何 Missing character 警告求和符号、希腊字母、上下标都正常那说明你的修复链路是通的。接下来就可以把你原来的论文内容逐步搬进来每搬一段编译一次发现异常立刻定位到对应宏包或代码。5.2 Overleaf 和本地的编译设置细节在 Overleaf 里使用这份模板要做两件事一是把编译器从默认的 pdfLaTeX 切换成 XeLaTeX菜单路径是 Menu → Settings → Compiler选 XeLaTeX二是每次切换编译器或者清空缓存后重新编译如果还有奇奇怪怪的字体问题先把 Overleaf 的“Recompile from scratch”跑一遍它会重建所有辅助文件。这个操作对应很多人在清理辅助文件上踩过的坑尤其是参考文献和目录缓存旧辅助文件最容易掩盖问题。本地 TeX Live 环境就靠命令行控制。第一步用 -xelatex 指定引擎如果有参考文献还需要按照 xelatex → bibtex → xelatex → xelatex 的顺序跑两到三遍确保交叉引用和参考文献完整。相关命令参考如下latexmk -xelatex -interactionnonstopmode main.tex # 或者手动执行 xelatex -interactionnonstopmode main.tex bibtex main xelatex -interactionnonstopmode main.tex xelatex -interactionnonstopmode main.tex顺便提醒一个很容易被忽视的点切换到 XeLaTeX 后如果模板里使用的某些老宏包不兼容编译过程可能停在某个文件里不动。这时候不要怀疑是自己的公式问题先用 -interactionnonstopmode 让编译跑完把真正报错的宏包揪出来。另外不要忘记在更换编译器后清理 .aux、.bbl、.toc 这些辅助文件旧缓存里的字体映射信息可能残留导致明明改了配置却不生效这一条我吃了好几次亏。5.3 修复完成后的检查清单修复完成后不要只看一眼 PDF 就收工。我建议花两分钟做一次系统检查编译日志里搜索 Missing character应该没有任何输出或极少输出用 PDF 查看器搜索文本确认公式中的希腊字母可以正常复制而不是变成空白或乱码检查行内公式比如 $\alpha\beta$和行间公式Equation 环境的字体风格是否统一对照 pdflatex 编译输出的 PDF确认公式整体观感没有出现“某个符号明显偏小或偏大”的异常检查表格、图片引用的编号是否正确确保切换引擎没有顺带破坏交叉引用系统。6. 常见问题与排查技巧实录6.1 换了 XeLaTeX 后参考文献、中文摘要又出问题数学符号修好了不代表整个文档就万事大吉。很多人在切到 XeLaTeX 后会发现新的麻烦参考文献格式变了、中文摘要显示乱码、超链接失效。这些问题跟数学符号异常不是同一个根源但常常被一起遇到因为大家往往是同时引入 XeLaTeX 和字体改造的。参考文献如果用的是传统的 bibtex 方式一般不会受引擎影响但如果你用了 biblatex就要注意 biber 和 xelatex 的配合。中文摘要则是另一套体系XeLaTeX 下需要 xeCJK 或者 ctex 宏包来管理中文单纯 load fontspec 并不能让 LaTeX 知道怎么断行、怎么处理标点。我的建议是分开排查先注释掉所有中文内容只保留英文和公式确认数学正常再逐段加入中文环境和参考文献避免所有问题混在一起互相干扰。Word 公式转 LaTeX 也一样转换结果里经常混入一些非标准命令在 XeLaTeX 下更容易触发字体缺失转入后要人工检查所有符号宏包是否完备。6.2 Overleaf 正常、本地却异常多半是字体没装全这个现象我遇到过好多次同样的代码在 Overleaf 上编译美滋滋下载到本地用同一份模板编译公式却缺一堆符号。原因基本都出在本地 TeX Live 安装不完整缺了 OpenType Math 字体集合。解决办法不复杂用 TeX Live Manager 补装字体相关的包。Linux 和 macOS 下一般装 collection-fontsrecommended 就够了里面包含 Latin Modern、TeX Gyre、STIX 等常用数学字体。Windows 下如果有问题先确认 TeX Live 安装时选择了完整字体集合别用什么精简镜像。装完之后如果还不生效再刷新一下字体缓存具体命令是更新 luaotfload 的数据库luaotfload-tool --update这个操作相当于告诉字体引擎“我有新字体了”很多本地环境下改了配置不生效的问题靠这一条就能解决。6.3 几个我踩过的高频坑记录问题原因解决设置了 \setmathfont 后部分符号还是方框加载了与 unicode-math 冲突的旧数学字体宏包全局搜索并移除 mathptmx、newtxmath、txfonts正文设置 TeX Gyre Termes公式却是 CM只写了 \setmainfont漏了 \setmathfont成对设置正文和数学字体\mathcal 花体字母显示异常unicode-math 下默认花体来自当前数学字体用 range 选项指定 cal 范围使用 Latin Modern Math中文摘要可以编译但英文公式发飘中文字体和数学字体混用导致行内盒尺寸变化用 xeCJK 管理中文数学字体独立设置本地编译速度突然变慢字体缓存失效导致重新扫描全部字体执行 luaotfload-tool --update 刷新缓存值得专门说一句的是表格跨页和图片浮动位置切换引擎后偶尔也会出问题那是因为浮动的算法在 XeLaTeX 下对某些宏包的容错略有不同这不是你公式代码的问题别被它带偏了排查方向。6.4 实在不行回到 pdflatex 的临时方案如果你试了所有方案还是摆不平而且切换到 XeLaTeX 的原始需求并不强烈那就果断回到 pdflatex。Elsevier 模板的默认投稿流程本来就是 pdflatex 优先模板内置的传统字体宏包与 pdflatex 的配合极其成熟数学符号几乎不会出问题。用 pdflatex 并不丢人很多投稿系统上传源文件时还明确要求 pdfLaTeX 编译。把 XeLaTeX 当备选项只在确实需要系统字体、中文字体混排、特定 OpenType 特性时再切。这不代表你前面做的是无用功因为理解了一遍字体机制之后以后再遇到其他期刊模板的同类问题你基本能一眼看穿根源直接对症下药。我个人在实际操作里的体会是遇到这类模板字体问题最快的路径不是反复改配置瞎试而是先做三件事查看模板 cls 文件里到底预设了什么字体宏包、检查编译日志里的 Missing character 指向什么字符、用一个最小示例把问题范围框死。只要这三步走完解决思路基本就出来了。最后再分享一个小技巧如果你经常要处理不同期刊模板的 XeLaTeX 编译把我上面给出的那套字体配置片段存成一个独立 style 文件比如 myxefonts.sty每次投稿直接把对应模板和这个文件配合使用可以省掉大量重复调试的时间。