Skip to content

fix(xeCJK): 排除 fntef 装饰字符的 PDF 文本语义 - #1023

Merged
Liam0205 merged 6 commits into
masterfrom
fix/1017-fntef-actualtext
Jul 25, 2026
Merged

fix(xeCJK): 排除 fntef 装饰字符的 PDF 文本语义#1023
Liam0205 merged 6 commits into
masterfrom
fix/1017-fntef-actualtext

Conversation

@Liam0205

Copy link
Copy Markdown
Contributor

Closes #1017

Related to #1012(本 PR 不改变线条绘制和重叠行为)。

问题

xeCJKfntef 的部分装饰由真实字符或数学内容组成,再由 ulem 的 leaders 重复排出。页面看起来只有下划线或删除线,但复制、搜索和文本提取会把装饰字符也当成正文。

同一组八类装饰命令在修复前的原始文本提取结果中混有 :/.*

甲 A 乙 | 丙 B 丁 |:::
戊: ::
C: :::
己 | 庚 D 辛 |// // 壬 / / // / E // // // 癸 | 子 F 丑 | . 寅 G . 卯 |
*
辰 H
*
巳

修复后的普通 PDF 和 tagged PDF 均只提取正文:

甲 A 乙 | 丙 B 丁 | 戊 C 己 | 庚 D 辛 | 壬 E 癸 | 子 F 丑 | 寅 G 卯 | 辰 H 巳

修复

flowchart LR
  A[构造 fntef 装饰盒] --> B[用空 ActualText 包住装饰内容]
  B --> C{LaTeX tagging 接口存在?}
  C -- 是 --> D[暂停 tagging]
  D --> E[排出装饰]
  E --> F[恢复 tagging]
  C -- 否 --> G[直接排出装饰]
  F --> H[页面视觉不变,文本提取忽略装饰]
  G --> H
Loading
  • 在所有线条和符号装饰共用的 \xeCJK_fntef_sbox:n 中,用空的 ActualText 标记装饰盒。
  • tagged PDF 下,在最小作用域内暂停并恢复 LaTeX tagging,避免装饰盒中的内层数学标记穿过外层 ActualText
  • 保留既有的 command-boundary capture 暂停/恢复;它负责隔离 xeCJK 边界状态,和本次 PDF 文本语义隔离各司其职。
  • xeCJKfntef 增加 accsupp 软依赖,并把普通和 tagged PDF 回归所需的 TeX Live 包加入 CI 清单。
  • 将变更登记在尚未发布的 v3.10.5

验证

  • xeCJK:112/112。
  • ctex XeTeX:185/185。
  • contrib:3/3(elegantbookpkuthssthuthesis)。
  • 新增 fntef-actualtext01,覆盖下划线、双下划线、波浪线、删除线、交叉删除线、自定义线条、着重号和自定义符号,并检查八组空 ActualText 与 tagging 暂停/恢复。
  • 普通 PDF 与 tagged PDF 的 pdftotext -layout-raw 均只保留正文。
  • 修复前后按 300 dpi 栅格比对,magick compare -metric AE0 (0);因此本 PR 没有改变 xeCJKfntef: 删除线/下划线存在重叠 #1012 讨论的线条外观,也不声称解决该问题。

同分支的工作流更新

按维护者的同步修改,三个 Agent caller 已升级到 reusable workflow 提交 2a0bb28e6583d869645e0a0522568df4a5d4d921;离线合同测试和稳定文档中的固定 SHA 已一并更新。

@Liam0205
Liam0205 requested a review from a team as a code owner July 25, 2026 13:30
@github-actions

Copy link
Copy Markdown
Contributor

PR 审查

项目 结果
结论 APPROVE
审查模式 full
审查范围 b22206eee90b3181fce822d650f3976d2b643daa...2abacf06ebfb627921bf2ff56a78059b2f14eb41
Head commit 2abacf06ebfb627921bf2ff56a78059b2f14eb41

实现、依赖清单、回归基线、llmdoc 和固定 SHA 的 reusable workflow 合同保持一致,未发现需要修改的问题。runner 未安装 xetexl3buildpdftotext,因此未在本轮重跑 xeCJK 与 PDF 文本提取测试;已核对测试输入和基线,并确认 git diff --checkpython3 scripts/test-agentic-workflow-contract.py 通过。

风险分级:高 —— 变更包含 PDF 文本语义处理以及具有写权限的第三方 reusable workflow 固定版本升级;已按高风险范围核对实现、权限边界和模板提交差异。

完整性声明:据本轮审查,以上为本 PR 已知的全部阻塞级风险;未发现阻塞问题。

历史问题复核

无可信历史 review。

阻塞问题 (0)

重要建议 (0)

小问题 (0)

Sources cited

做得对的地方

  • 将空 ActualText 与 tagging 暂停集中放在共享装饰盒构造路径,覆盖八类装饰入口,同时保留既有 boundary capture 隔离。
  • accsupp 的包级依赖和精简 CI 依赖已同步,新增机制回归及既有节点基线也一并更新。
  • 三个 reusable workflow caller、离线合同测试和稳定文档均固定到同一完整提交 SHA;本地审计的模板差异未发现权限边界回退。

开放问题


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

@github-actions

Copy link
Copy Markdown
Contributor

PR 审查

项目 结果
结论 APPROVE
审查模式 full
审查范围 b22206eee90b3181fce822d650f3976d2b643daa...aabbd21ec5b57e38131c47c3f20e737c82a53c17
Head commit aabbd21ec5b57e38131c47c3f20e737c82a53c17

实现将空 ActualText 和 tagging 暂停/恢复限制在共用装饰盒内,依赖、测试基线与文档契约保持一致,未发现需要修改的问题。

风险分级:中 —— 变更影响 PDF 文本提取语义,但实现集中于 xeCJKfntef 的装饰盒构造路径,并有八类装饰及既有节点基线覆盖。

完整性声明:据本轮审查,以上为本 PR 已知的全部阻塞级风险。已通过 workflow 契约测试、Python 编译检查和 git diff --check;当前 runner 未安装 TeX 工具链,因而未在本地复跑 l3build 或 PDF 文本提取验证。

历史问题复核

阻塞问题 (0)

重要建议 (0)

小问题 (0)

Sources cited

做得对的地方

  • 将处理放在所有字符型装饰共用的盒子构造函数中,避免各装饰入口出现语义差异。
  • tagging 暂停/恢复保持最小作用域,并保留原有 boundary capture 暂停/恢复职责。
  • accsupp、tagged PDF 测试依赖同时更新包级声明和 CI 安装清单;新增测试覆盖八类装饰,并检查调用严格成对。
  • workflow 固定 revision 与仓库契约测试中的期望 SHA 同步更新,契约测试通过。

开放问题


本次审查由 Codex 主链路 (gpt-5.6-sol) 完成。

@Liam0205

Copy link
Copy Markdown
Contributor Author

已核对本轮审查:结论为 APPROVE,阻塞问题、重要建议和小问题均为 0。新增的两份 github472-02 基线只移除了新版 LaTeX 不再输出的末尾字体替代汇总警告;同一轮 CI 中 XeTeX/LuaTeX 的 ctex 测试已在 Ubuntu、macOS 和 Windows 全部通过,其余测试与文档构建也全部通过,无需继续修改。

@Liam0205

Copy link
Copy Markdown
Contributor Author

补充说明本 PR 中 github472-02 基线末尾删除字体警告的原因及复现结果。

CI 与本机原有环境的差异确实同时包含 LaTeX 内核和 l3build 更新:

  • 本机更新前:latex revision 79234l3build revision 79575(2026-07-03);
  • 当前 TeX Live:latex revision 79618l3build revision 79721(Release 2026-07-20)。

进一步做了最小因果实验:保持旧版 LaTeX 内核不变,只临时模拟新版 l3build 的日志截取逻辑,XeTeX 和 LuaTeX 的 github472-02 都能通过新基线。因此,这次基线变化并不是 LaTeX 字体替换行为发生了变化,直接原因是 latex3/l3build@2023c470 调整了测试结束阶段的处理。

github472-02.lvt 在文档末尾使用 \OMIT,且没有再用 \TIMO 结束省略区间。旧版 l3build 在测试结束阶段额外插入的标记会让 \end{document} 时汇总的

LaTeX Font Warning: Some font shapes were not available, defaults substituted.

进入规范化日志;新版不再插入这些标记,因此末尾的 \OMIT 会继续屏蔽这条汇总警告。基线中删除该行正是新版 l3build 下的预期结果。

随后已实际全量更新本机 TeX Live,并在不修改测试文件的情况下重新运行:

$ l3build check -q -e xetex --first github472-02 --last github472-02
All checks passed

$ l3build check -q -e luatex --first github472-02 --last github472-02
All checks passed

因此,这两处 .tlg 基线变更与当前 CI 使用的工具链一致,是合理的;它们不表示产品代码新增或消除了字体警告。复现后已清理构建产物,工作区保持干净。

@Liam0205
Liam0205 merged commit 01d5624 into master Jul 25, 2026
53 checks passed
@Liam0205
Liam0205 deleted the fix/1017-fntef-actualtext branch July 25, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

xeCJKfntef: 禁用对波浪下划线和删除线的 pdfmap

1 participant