科技报告模板字体调整:西文改衬线、目录统一、代码换等宽 #19

Closed
opened 2026-10-29 07:36:44 +00:00 by laoyang · 1 comment
Owner

科技报告模板字体调整:西文改衬线、目录条目统一、代码换真等宽

问题现象

用户反馈:「字体不太好看,标题一会黑体一会什么体的」。

用 pymupdf 提取 report.pdf 的渲染文本,实际用到的字体如下:

位置 实际字体 评价
各级标题 HarmonyOS_Sans_SC_Bold 符合要求
正文中文 OUCSerif-Regular 符合要求
内容块(信息框) OUCKai-Regular 符合要求
正文西文 HarmonyOS_Sans 不搭:中文宋体 + 英文无衬线
目录条目 编号 HarmonyOS_Sans_Bold + 标题 OUCSerif-Bold 同一条里两种字体,这就是用户看到的「一会黑体一会什么体」
代码块(\ttfamily) HarmonyOS_Sans 无衬线顶替等宽,代码对不齐

根因

cls/font.cls:52 把 \setmainfont 设成了 HarmonyOS Sans:

\setmainfont{HarmonyOS_Sans_Regular.ttf}[...]

这是从旧版(方正系列)继承下来的设置。旧版中文默认是方正书宋、西文是鸿蒙,两者本来也不搭;
后来中文换成了思源宋体(衬线),西文却还是鸿蒙(无衬线),反差比旧版更明显。

\setmainfont 是西文字体的总开关,同时也是:

  • 正文里所有英文、数字、DOI 的字体
  • \ttfamily 没单独指定时,等宽位的回退目标
  • 目录条目编号(数字)的字体 —— 因为编号是西文,走 \setmainfont;
    而标题文字是中文,走 \setCJKmainfont。这就是同一条目录里字体分裂的原因。

改动方案

  1. 西文正文改 Cochineal(fonts/cochineal/,Minion 风格,OFL 1.1)

    • 仓库里已有,fonts.tex 已登记,简历模板在用
    • 与思源宋体灰度接近,中西文混排不打架
    • 度量与 Termes 只差 1.9%,不会推着断行和列宽变
  2. \setsansfont 保持鸿蒙 —— 标题用 \hm(CJK 族名 OUCHM)来切,
    西文 sans 位仍是鸿蒙。标题的中西文都还是鸿蒙,与正文区分得开。

  3. \setmonofont 与 \setCJKmonofont 换成真等宽

    • 现状:代码块用 HarmonyOS Sans 顶替,不是等宽,代码对不齐
    • 目标:西文用 lmmono(Latin Modern Mono,TeX Live 自带),中文用思源黑体
  4. 目录条目字体统一 —— 加了 \ttfamily 那类隐性回退之后,还要显式把
    目录条目的西文编号也指到正文西文字体,避免编号与标题两种字体。

验收标准

  • 正文西文与中文同为衬线,混排不割裂
  • 目录条目里编号与标题同一字族
  • 标题(一/二/三级、目录标题、封面主副标题)统一鸿蒙
  • 内容块(titledbox / notebox / importantbox)统一楷体
  • 代码块真等宽
  • 10 页、0 error,无新增 Overfull/Underfull
  • WSL 与 Windows 两端都能编译通过(TeX Live 2025 / 2022)

备注

用户明确要求的方向:标题鸿蒙、正文思源宋、内容块楷体、西文另选一款。
前三条现状已满足,故本次不改;重点是西文与目录这两处真正的问题。

科技报告模板字体调整:西文改衬线、目录条目统一、代码换真等宽 ## 问题现象 用户反馈:「字体不太好看,标题一会黑体一会什么体的」。 用 pymupdf 提取 `report.pdf` 的渲染文本,实际用到的字体如下: | 位置 | 实际字体 | 评价 | |---|---|---| | 各级标题 | `HarmonyOS_Sans_SC_Bold` | 符合要求 | | 正文中文 | `OUCSerif-Regular` | 符合要求 | | 内容块(信息框) | `OUCKai-Regular` | 符合要求 | | **正文西文** | `HarmonyOS_Sans` | **不搭:中文宋体 + 英文无衬线** | | **目录条目** | 编号 `HarmonyOS_Sans_Bold` + 标题 `OUCSerif-Bold` | **同一条里两种字体,这就是用户看到的「一会黑体一会什么体」** | | 代码块(`\ttfamily`) | `HarmonyOS_Sans` | 无衬线顶替等宽,代码对不齐 | ## 根因 `cls/font.cls:52` 把 `\setmainfont` 设成了 HarmonyOS Sans: ```latex \setmainfont{HarmonyOS_Sans_Regular.ttf}[...] ``` 这是从旧版(方正系列)继承下来的设置。旧版中文默认是方正书宋、西文是鸿蒙,两者本来也不搭; 后来中文换成了思源宋体(衬线),西文却还是鸿蒙(无衬线),反差比旧版更明显。 `\setmainfont` 是**西文字体**的总开关,同时也是: - 正文里所有英文、数字、DOI 的字体 - `\ttfamily` 没单独指定时,等宽位的回退目标 - 目录条目编号(数字)的字体 —— 因为编号是西文,走 `\setmainfont`; 而标题文字是中文,走 `\setCJKmainfont`。**这就是同一条目录里字体分裂的原因。** ## 改动方案 1. **西文正文改 Cochineal**(`fonts/cochineal/`,Minion 风格,OFL 1.1) - 仓库里已有,`fonts.tex` 已登记,简历模板在用 - 与思源宋体灰度接近,中西文混排不打架 - 度量与 Termes 只差 1.9%,不会推着断行和列宽变 2. **`\setsansfont` 保持鸿蒙** —— 标题用 `\hm`(CJK 族名 OUCHM)来切, 西文 sans 位仍是鸿蒙。标题的中西文都还是鸿蒙,与正文区分得开。 3. **`\setmonofont` 与 `\setCJKmonofont` 换成真等宽** - 现状:代码块用 HarmonyOS Sans 顶替,不是等宽,代码对不齐 - 目标:西文用 `lmmono`(Latin Modern Mono,TeX Live 自带),中文用思源黑体 4. **目录条目字体统一** —— 加了 `\ttfamily` 那类隐性回退之后,还要显式把 目录条目的西文编号也指到正文西文字体,避免编号与标题两种字体。 ## 验收标准 - [ ] 正文西文与中文同为衬线,混排不割裂 - [ ] 目录条目里编号与标题同一字族 - [ ] 标题(一/二/三级、目录标题、封面主副标题)统一鸿蒙 - [ ] 内容块(titledbox / notebox / importantbox)统一楷体 - [ ] 代码块真等宽 - [ ] 10 页、0 error,无新增 Overfull/Underfull - [ ] WSL 与 Windows 两端都能编译通过(TeX Live 2025 / 2022) ## 备注 用户明确要求的方向:标题鸿蒙、正文思源宋、内容块楷体、西文另选一款。 前三条现状已满足,故本次不改;重点是西文与目录这两处真正的问题。
Author
Owner

已实现并验证,提交 5d59aa1

用户需求与落点对照

用户原话 落点 实际字体
标题用鸿蒙 各级标题、封面主标题、摘要标题、目录标题、文本框标题 HarmonyOS_Sans_SC_Bold(中文)+ HarmonyOS_Sans_Bold(西文)
正文用思源宋 \setCJKmainfont OUCSerif-Regular / OUCSerif-Bold
内容块用楷体 boxes.cls 的 fontupper=\fzkai OUCKai-Regular
英文字体自己找 \setmainfont Cochineal-Roman(Minfo 风格衬线,OFL 1.1)
(附带)代码位 \setmonofont LMMono10-Regular(真等宽)

根因:\hm 只管中文

「标题一会儿黑体一会儿什么体」的真正来源不是 \setmainfont,而是 \hm 的定义:

% fonts.tex:343
\def\hm{\CJKfamily{OUCHM}}   % 纯 xeCJK 中文字族,管不到数字和拉丁字母

而标题编号 1.、3.1 是阿拉伯数字 → 被判西文 → 走 \setmainfont。于是:

  • 章节标题:编号鸿蒙粗 + 文字宋体粗
  • 这是一个很好用的 LaTex 模板:中文鸿蒙 + LaTex 衬线
  • 目录条目:编号走西文、标题走中文 → 同一条里两种字体

修法:本模板内重定义 \hm 为 \hmlatin\CJKfamily{OUCHM},中西文一起切。

中途走过弯路:先在 \ctexset 的每个 format 里补 \hmlatin。虽然标题好了,但封面、摘要、目录标题、文本框标题各漏一次(实测漏 4 处)。确认「在调用点逐个补必然漏」之后改回源头解决。

不动 ../fonts.tex 的 \hm:幻灯片和简历也在用,它们没有标题混西文的问题,全局改会外溢。

目录页码单独处理

\cftsecfont 等三条只管条目文字,页码走 \cft*pagefont。不显式清掉的话,目录里页码比标题还粗、一眼看过去页码最抢眼。两组共 6 条一起设 \normalfont。

内容块 3 个 Underfull:保留,不修

\verb|Illuminate\Foundation\Http\Kernel| 是 35 字符不可断串,内容块内宽 371pt 塞不下。

试过无效的:

  • \emergencystretch 2em / 10em —— 无效。不是额度不够,是这行没有足够可拉伸的 glue
  • \sloppy —— 更差,badness 1231 → 3590

有效但不采用的:

  • \seqsplit —— 归零,但任意字符处断行,代码路径被切两段
  • 窄体 lmmonoltcond —— 归零,但压缩可读性

结论:保留。badness 1231 属轻微(10000 才严重),渲染只是行末留白略多。日志里看到这 3 个属预期,不是回归。

验证:两套 TeX Live 各两遍,逐字同数

环境 rc error Overfull Underfull 页数
WSL / TeX Live 2025 0 0 0 4 10
Windows / TeX Live 2022 0 0 0 4 10

pymupdf 提取字体分布,两侧完全一致:

Cochineal-Roman 782   OUCSerif-Regular 143   LMMono10-Regular 98
OUCKai-Regular 33     HarmonyOS_Sans_SC_Bold 22   HarmonyOS_Sans_Bold 14
OUCSerif-Bold 8       FontAwesome 5   HarmonyOS_Sans_SC 3
ZhuqueFangsong 2      OUCSans-Regular 2   CMSY10 1   CMEX10 1

标题逐页核对(中西文双档均属鸿蒙):

p1 封面  HarmonyOS_Sans_SC_Bold「这是一个很好用的」+ HarmonyOS_Sans_Bold「LaTex」
p2 目录  HarmonyOS_Sans_SC_Bold「目录」
p5 摘要  HarmonyOS_Sans_SC_Bold + HarmonyOS_Sans_Bold「LaTex」
p6 正文  HarmonyOS_Sans_Bold「1.」+ HarmonyOS_Sans_SC_Bold「准备工作」
p10 正文 HarmonyOS_Sans_Bold「8.」+ HarmonyOS_Sans_SC_Bold「图标」

三处少量命中已逐个查清,都不是回归

  • p6「黑体」「仿宋」→ 正文故意演示 \fzzdx / \fzfs 的示例文字
  • p8 每页同 bbox、45° 旋转、29.8pt → 全页水印,设计如此
  • p10「HTTP/Console」→ 文本框标题走 fonttitle=\hm,改后已是 HarmonyOS_Sans + HarmonyOS_Sans_SC,中西文都属鸿蒙

附带修正

report.tex 第 52/58 行原文说「英文字体默认使用鸿蒙」,改后已不准确,重写为 Cochineal + Latin Modern Mono 的实际状况,并说明标题编号统一的原因。

## 已实现并验证,提交 `5d59aa1` ### 用户需求与落点对照 | 用户原话 | 落点 | 实际字体 | |---|---|---| | 标题用鸿蒙 | 各级标题、封面主标题、摘要标题、目录标题、文本框标题 | `HarmonyOS_Sans_SC_Bold`(中文)+ `HarmonyOS_Sans_Bold`(西文) | | 正文用思源宋 | `\setCJKmainfont` | `OUCSerif-Regular` / `OUCSerif-Bold` | | 内容块用楷体 | `boxes.cls` 的 `fontupper=\fzkai` | `OUCKai-Regular` | | 英文字体自己找 | `\setmainfont` | `Cochineal-Roman`(Minfo 风格衬线,OFL 1.1) | | (附带)代码位 | `\setmonofont` | `LMMono10-Regular`(真等宽) | ### 根因:`\hm` 只管中文 「标题一会儿黑体一会儿什么体」的真正来源不是 `\setmainfont`,而是 `\hm` 的定义: ```latex % fonts.tex:343 \def\hm{\CJKfamily{OUCHM}} % 纯 xeCJK 中文字族,管不到数字和拉丁字母 ``` 而标题编号 `1.`、`3.1` 是阿拉伯数字 → 被判西文 → 走 `\setmainfont`。于是: - 章节标题:编号鸿蒙粗 + 文字宋体粗 - `这是一个很好用的 LaTex 模板`:中文鸿蒙 + `LaTex` 衬线 - 目录条目:编号走西文、标题走中文 → 同一条里两种字体 **修法**:本模板内重定义 `\hm` 为 `\hmlatin\CJKfamily{OUCHM}`,中西文一起切。 中途走过弯路:先在 `\ctexset` 的每个 `format` 里补 `\hmlatin`。虽然标题好了,但封面、摘要、目录标题、文本框标题**各漏一次**(实测漏 4 处)。确认「在调用点逐个补必然漏」之后改回源头解决。 **不动 `../fonts.tex` 的 `\hm`**:幻灯片和简历也在用,它们没有标题混西文的问题,全局改会外溢。 ### 目录页码单独处理 `\cftsecfont` 等三条只管条目文字,页码走 `\cft*pagefont`。不显式清掉的话,目录里页码比标题还粗、一眼看过去页码最抢眼。两组共 6 条一起设 `\normalfont`。 ### 内容块 3 个 Underfull:保留,不修 `\verb|Illuminate\Foundation\Http\Kernel|` 是 35 字符不可断串,内容块内宽 371pt 塞不下。 试过**无效**的: - `\emergencystretch` 2em / 10em —— 无效。不是额度不够,是这行没有足够可拉伸的 glue - `\sloppy` —— 更差,badness 1231 → 3590 有效但**不采用**的: - `\seqsplit` —— 归零,但任意字符处断行,代码路径被切两段 - 窄体 `lmmonoltcond` —— 归零,但压缩可读性 结论:保留。badness 1231 属轻微(10000 才严重),渲染只是行末留白略多。**日志里看到这 3 个属预期,不是回归。** ### 验证:两套 TeX Live 各两遍,逐字同数 | 环境 | rc | error | Overfull | Underfull | 页数 | |---|---|---|---|---|---| | WSL / TeX Live 2025 | 0 | 0 | 0 | 4 | 10 | | Windows / TeX Live 2022 | 0 | 0 | 0 | 4 | 10 | pymupdf 提取字体分布,两侧完全一致: ``` Cochineal-Roman 782 OUCSerif-Regular 143 LMMono10-Regular 98 OUCKai-Regular 33 HarmonyOS_Sans_SC_Bold 22 HarmonyOS_Sans_Bold 14 OUCSerif-Bold 8 FontAwesome 5 HarmonyOS_Sans_SC 3 ZhuqueFangsong 2 OUCSans-Regular 2 CMSY10 1 CMEX10 1 ``` 标题逐页核对(中西文双档均属鸿蒙): ``` p1 封面 HarmonyOS_Sans_SC_Bold「这是一个很好用的」+ HarmonyOS_Sans_Bold「LaTex」 p2 目录 HarmonyOS_Sans_SC_Bold「目录」 p5 摘要 HarmonyOS_Sans_SC_Bold + HarmonyOS_Sans_Bold「LaTex」 p6 正文 HarmonyOS_Sans_Bold「1.」+ HarmonyOS_Sans_SC_Bold「准备工作」 p10 正文 HarmonyOS_Sans_Bold「8.」+ HarmonyOS_Sans_SC_Bold「图标」 ``` ### 三处少量命中已逐个查清,都不是回归 - p6「黑体」「仿宋」→ 正文**故意演示** `\fzzdx` / `\fzfs` 的示例文字 - p8 每页同 bbox、45° 旋转、29.8pt → **全页水印**,设计如此 - p10「HTTP/Console」→ 文本框标题走 `fonttitle=\hm`,改后已是 `HarmonyOS_Sans` + `HarmonyOS_Sans_SC`,中西文都属鸿蒙 ### 附带修正 `report.tex` 第 52/58 行原文说「英文字体默认使用鸿蒙」,改后已不准确,重写为 Cochineal + Latin Modern Mono 的实际状况,并说明标题编号统一的原因。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/ouc_latex_template#19