# clreq 符合度声明矩阵 > 依据:W3C《Requirements for Chinese Text Layout / 中文排版需求》。 > 条款编号取自 W3C TR 快照(2026-08-04 抓取;与 gh-pages Editor's Draft > 在本文涉及的条款上无实质差异)。 > 对象:`luatex-cn` main 分支(v0.3.8 + 未发布改动)。 > 配套内部文档:`CLREQ-GAP-ANALYSIS.md`(差距分析与规划)、 > `CLREQ-HORIZONTAL-PLAN.md`(横排实施)、`ai_must_read/clreq-shared-core.md`(共享内核契约)。 --- ## 0. 声明口径 ### 0.1 后端列 | 列 | 指代 | 说明 | |----|------|------| | **横排** | `\usepackage{luatex-cn}`(统一入口的默认分支;实现在 `tex/hori/` + `tex/shared/`,内部名 `luatex-cn-hori` 仍可直接加载) | 挂在任意 LaTeX 横排文档类上 | | **竖排** | `ltc-cn-vbook` / `ltc-tw-vbook` 文档类(`tex/core/` + `tex/shared/`) | 现代竖排书 | **`ltc-guji` / `ltc-guji-digital` 不在本矩阵声明范围内。** clreq 明确写道 「至于古籍排版,非本文件所及」;古籍类以复刻底本版面为最高优先级,标点挤压 保持 `squeeze-mode=legacy`(无条件挤压)等历史行为,**不宣称 clreq 符合**。 用户可通过与竖排列相同的配置键显式启用各项新规则。 ### 0.2 状态取值 | 记号 | 含义 | |------|------| | ✅ 实现 | 条款的规范性要求已实现,且有可核查证据(断言/单测/回归用例) | | 🟡 部分实现 | 条款的一部分要求已实现;备注列说明缺哪一部分 | | ⚠️ 有意偏离 | 已实现但与 clreq 字面不一致,偏离内容与理由见第 9 节 | | ❌ 未实现 | 未实现,在路线图内(见差距分析 P1–P7 / H4–H6) | | 🚫 不实现 | 有意不实现,理由见第 10 节 | | ➖ 不适用 | 对该后端无意义(如直排专属条款之于横排),或非排版引擎职责 | ### 0.3 证据与复核 「证据」列给出实现位置与测试位置。所有声明可用以下命令复核: ```bash texlua test/run_all.lua # 单元测试(43 个文件) python3 test/clreq_test.py # clreq 度量断言(119 条,每条注明条款) python3 test/geometry_test.py # 列内基线等距自校验 python3 test/regression_test.py check # 像素回归(basic/past_issue/complete) ``` 断言测试直接解析 PDF 内容流度量「行末逗号占多宽」「中西间距是否在 [1/8, 1/2] em 内」等规范量,并带负对照(关闭开关后断言应失败)证明区分力。 ### 0.4 统计速览(2026-08-05) 对每个后端只统计其适用条款(剔除 ➖ 与 🚫),✅ 计 1、🟡/⚠️ 计 0.5、❌ 计 0, 各条款等权: | 后端 | 适用条款 | ✅ | 🟡/⚠️ | ❌ | 覆盖率 | |------|---------|----|-------|----|--------| | 横排 `luatex-cn-hori` | 43 | 29 | 5 | 9 | **≈ 73%** | | 竖排 `ltc-cn-vbook` / `ltc-tw-vbook` | 43 | 22 | 10 | 11 | **≈ 63%** | | 两后端合并 | 86 | 51 | 15 | 20 | **≈ 68%** | 百分比只是速览,**逐条状态与证据(下文各表)才是本文的声明本体**; 条款等权也意味着它与工作量完成度(见差距分析第 7 节,按人日约 54%)不是 同一口径——剩余条款集中在实现成本最高的中西混排、注音与标题层。 --- ## 1. 第 2 章 · 文本方向 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 2.1.1 | 中文的行文模式(横排左起 / 直排右起换列向左) | ✅ | ✅ | 竖排网格引擎(`core/luatex-cn-layout-grid.lua`);直排列右→左、页序右翻 | | 2.1.2 | 横直排差异点(标点直排形式、装订方向、页面镜像) | ➖ | 🟡 | vert 形替换 + PUA/tounicode 还原(`core/luatex-cn-core-punct.lua`)、`twoside` 镜像边距;个别标点直排形式依赖字体,缺字时对 `—`/`…` 退化为旋转 | | 2.1.3 | 直排的中、西文混排配置(全角直立 / 旋转 90° / 中横排;汉字与西文间距) | ➖ | ✅ | **中西间距已实现**(P3 第一步):汉字与西文字母/数字边界 1/4em、可挤 1/8 拉 1/2、点号旁与夹注号内侧不加——规则本体 `shared/luatex-cn-cjk-western.lua` 与横排同源,`western-space` 键可关,仅 context 挡位生效;断言 8 条 + 负对照。三种西文配置:全角直立 = 默认逐字入格;**旋转 90° 已实现**(`\横置`/`\Sideways`:字幅 = advance、串内零字距、共用竖直基线,断言「字母连排步长 0.5em vs 直立 1.1em」,回归 `sideways.tex`);**中横排已实现**(`\中横排`/`\CombineUpright`:整组共占一个字幅,超 1em 只做横向压缩、字高不变,适合两三位数字/极短西文;断言 6 条含负对照——跨组步长 2.5em vs 直立 3.6em,回归 `combine-upright.tex`)。三种西文配置至此齐备 | | (2 章相关) | 双向文本(bidi) | 🚫 | 🚫 | 见第 10 节 | ## 2. 第 3 章 · 字形的变形与定位 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 3.1.1 | 宋 / 楷 / 黑 / 仿宋四体及其用途 | 🟡 | 🟡 | 字体族探测与回退完善(`fonts/`,Linux 方案全开放授权字体);缺「宋体作正文、黑体作强调」的语义化字体角色层 | ## 3. 第 4 章 · 排版单元 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 4.1 | 字符与编码(以 Unicode 字符为排版单元) | ✅ | ✅ | LuaTeX 原生按 Unicode 处理 | | 4.1.1 | 儿化小字(U+16FF2/3) | 🚫 | 🚫 | 见第 10 节 | ## 4. 第 5 章 · 标点符号与其他行内特性 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 5.1 | 点号 / 标号分类与基本用法 | ✅ | ✅ | 共享标点全表 24 类单一数据源(`shared/luatex-cn-punct-table.lua`);竖排分类从表派生(PR #126);单测 `shared/punct-table-test` | | 5.1.1.1 | 科技文献(句点作 `.` 等特殊体例) | ❌ | ❌ | 低优先级,未列入近期路线图 | | 5.1.1.2 | 港台出版品的特殊情况(点号居中、`?!` 不调整等) | ✅ | ✅ | `style=taiwan` 预设;断言「台式?!固定一字宽」「台式行末 0.75em 占位」;回归 `hori-taiwan.tex`、`tw-vbook.tex` | | 5.1.1.3 | 叹问号叠加(?? !! ?! !? 及 ‼ ⁇) | ✅ | ✅ | 两字宽刚性整体(PR #139 共享层;竖排经 `ATTR_RIGID_PREV=2` 落地);压力用例相位扫描 23 处 + 负对照 | | 5.1.1.4 | 示亡号 | ❌ | ❌ | 竖排可用 `\decorate` 手工近似;未做自动排版 | | 5.2 | 引文(引号体例;直排用直角引号) | ✅ | ✅ | 横排 `quote-style`(keep/auto/curly/corner,默认不改来稿);竖排弯引号→直角引号替换;断言「台湾用传统引号先单后双」 | | 5.3.1 | 着重号(字下/右侧圆点、标点上不加、逐字对心) | ✅ | ✅ | 横排 `\着重`;竖排 `\着重号` 在 vbook 两类的 cfg 里配 `char=●, skip-punct=true`(clreq 规定的 U+25CF/U+2022,直排在右侧 + 标点上不加),判定走共享标点表 `decorate.is_punct_char`。`ltc-guji` 保持古籍圈点体例(`○`、标点也圈)。回归 `emphasis-clreq.tex`(含 `skip-punct=false` 负对照)。**台湾式依据不同**:clreq 注明台湾《重订标点符号手册》未收录着重号,此处取通用形态,见第 9 节第 6 条 | | 5.4.1 | 省略号(占两字、不可拆、不可置行首末拆开) | ✅ | ✅ | 两字宽整体单元(横排 penalty 包裹;竖排 #119 不拆列、内部字距归零);断言「总占位 ≈ 2em、内部零间隙」 | | 5.5.1–5.5.2 | 行间注用途与排版概述 | ➖ | ➖ | 描述性条款,无独立规范量 | | 5.5.3.1–.5 | 注音符号标音(位置、3:10 比例、声调号、分离禁则) | ❌ | ❌ | 度量常量已入 `shared/luatex-cn-ruby-metrics.lua`,排布未做。规划 H4 收尾 / P4 | | 5.5.4.1–.3 | 罗马拼音标音(基本规则、单字标音、分词连写标音) | 🟡 | ➖ | `\拼音` 已实现基本规则与词对齐;缺注文悬伸与单字标音的正文字距联动。clreq 规定罗马拼音仅用于横排,竖排不适用 | | 5.5.5 | 汉字标音的非典型情况(儿化标音等) | 🚫 | 🚫 | 随 4.1.1,见第 10 节 | | 5.5.6 / 5.5.6.1 | 中外文对照与词的对齐 | ✅ | ❌ | `\对照`:注文短于基文加大注文字距、长于基文加大基文字距;断言「注文块与基文块中心对齐 ≤ 0.1em」 | | 5.5.7 | 行间批语(直排位基文左侧、长度不拘、可换色) | ❌ | ✅ | 竖排侧批 / 夹注 / 眉批体系(`core/luatex-cn-core-sidenote.lua`、`guji/`)能力超出条款要求;横排批语未做 | | 5.6.1 | 行间标点(专名号 / 书名号甲式;相邻标注两侧缩短 ≤1/8em;行距下限) | ✅ | 🟡 | 横排 `\专名` `\书名号甲` 单面装、相邻各缩 1/16em、行距 ≥0.5em 校验 + warning(`hori/luatex-cn-hori-linemark.lua`);竖排 `\专名号` `\书名号` 线左着重右、分段正确,但相邻缩短与行距校验未做。双面装为直排概念,横排 ➖ | | 5.7 | 数据格式与数字(数字串整体性等) | 🟡 | 🟡 | 数字串不拆已由 6.1.2.2 覆盖;全半角数字选用属作者/上游职责,引擎不转换 | ## 5. 第 6 章 · 行与段落版式 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 6.1.1 | 行首行尾禁则(不处理 / 基本 / GB / 严格 四级) | ✅ | 🟡⚠️ | 共享 `shared/luatex-cn-kinsoku.lua`;横排 `kinsoku-level` 四级可配、penalty 注入、TeX 全局最优;竖排已接 `kinsoku.resolve_overflow`(先挤进后推出的比价),但**级别硬编码为基本级**。禁则解决方式用词典序比价,对 clreq 字面有意偏离(第 9 节第 1 条)。断言:行首禁则相位扫描 + 负对照 | | 6.1.2.1 | 符号分离禁则 · 两字宽标点不可拆 | ✅ | ✅ | 破折号/省略号/叹问号叠加整体单元(横排 penalty;竖排 #119);断言「两字宽标点同行零间隙」;回归 `dash_continuity_issue119.tex` | | 6.1.2.2 | 符号分离禁则 · 数字及前后缀(数字串、%/°/℃、±、货币) | ✅ | ✅ | 共享层字符集判定;竖排经 `ATTR_RIGID_PREV=1` 锁死字距;断言「数字串/单位/货币同行零间隙」+ 负对照(关禁则后确实拆行) | | 6.1.2.3 | 符号分离禁则 · 注释符号(上下标、注号不与被注文字分离) | ❌ | ❌ | 需要 node 级属性,共享层明确留给后端(`kinsoku.lua` 头注释),两后端均未实现 | | 6.1.3 | 行尾点号悬挂 | ✅⚠️ | ✅⚠️ | 两后端均由 `hanging-punct` / `标点悬挂` 开关控制,**默认关**(第 9 节第 2 条)。竖排开启时列末点号整幅出列(`ATTR_PUNCT_HANG` → `build_column_gaps` 令 rigid 归零),正文不因它被压缩——clreq 注明悬挂正适用于直排。断言 3 条 + 负对照;回归 `hanging-punct.tex` | | 6.1.4 | 西文比例字体的断词连字 | ✅ | ❌ | 横排交 TeX 断行器原生处理;竖排无西文断词(规划 P3) | | 6.2.1.1 | 段首缩排 | ✅ | ✅ | 横排 `paragraph-indent`;竖排缩进体系(含抬头/挪抬) | | 6.2.1.2 | 段落缩排 / 凸排 | ✅ | 🟡 | 横排 `凸排` / `段落缩排` 环境;竖排段落缩排有、凸排需手工 | | 6.2.1.3 | 单行对齐(居中 / 行首 / 行尾 / 均排四种) | ✅ | 🟡 | 横排前三种由行盒对齐、`\均排` + `last-line=left/center/right/justify`;竖排 `vertical-align` 提供前三种,均排无用户级开关(引擎层已有,见 6.3.1.2) | | 6.2.2.1–.2 | 行内调整的必要性 / 挤压与拉伸处理 | ✅ | ✅ | 共享求解器 `shared/luatex-cn-adjust.lua`;横排在 `post_linebreak_filter` 覆写 TeX 比例分配;竖排 `build_column_gaps` + `adjust.solve`(PR #143) | | 6.2.2.3 | 挤压优先顺序(7 级:行末标点 → 西文词距 → 间隔号 → 夹注符号 → 逗顿分号 → 中西间距 → 句问叹号) | ✅ | ✅⚠️ | 同上;竖排在 clreq 七步之后追加「字距」为最后手段(项目版式选择,第 9 节第 3 条)。断言:挤压行标点空白先于字距被压缩 | | 6.2.2.4 | 拉伸优先顺序(西文词距 → 中西间距 → 兜底均分;不可拉伸不可分离单元) | ✅ | ✅ | 同上;刚性单元 shrink/stretch 全清零 | | 6.2.3 | 对齐时西文词距参与行内调整 | ✅ | ❌ | 横排西文词距列挤压第 2 级 / 拉伸第 1 级;竖排无西文词距概念(规划 P3) | | 6.2.4 | 纵横对齐下的中西文混排(西文占汉字整数倍) | ❌ | ❌ | 规划 P3 | | 6.3.1.1 | 增加字距(疏排) | ❌ | 🟡 | 竖排可用 `cell_gap` 近似;两侧均无专用「疏排」键 | | 6.3.1.2 | 均排 | ✅ | 🟡 | 横排 `\均排{}`;竖排引擎层已做(写满换列的列均排到列底,段末列不均排——符合 clreq 正文末行不均排),缺用户级命令 | | 6.3.1.3 | 减少字距(紧排) | ❌ | ❌ | 两侧均无负字距键;默认密排(无附加字距)两侧 ✅ | | 6.3.2.1 | 标点符号的调整空间(字面分布与可调空白) | ✅ | ✅ | 墨心度量锚定 `shared/luatex-cn-punct-anchors.lua`(PR #138 中国大陆/台湾 × 横/竖全矩阵;#145 直排夹注号归上/下半格,图 30)。横排夹注号不锚为有意决定(第 9 节第 4 条)。断言「中国大陆式偏靠 Tm 右移 >0.2em」;回归 `bracket_ink_issue105.tex` | | 6.3.2.2 | 连续标点符号的调整(2 → 1.5 字宽,挤压方向) | ✅ | ✅ | `shared/luatex-cn-punct-squeeze.lua`(PR #132);`adjacent-punct=1` 可收到 1 字宽;「空白在哪侧就往哪边让」;断言「连续标点 1.5 字幅 + 挤压方向」 | | 6.3.2.3 | 行首行尾标点挤压(行首开始夹注号半字、行末点号半字) | ✅ | ✅ | 横排 H2(行末标点 ≤ 半字宽为强制断言);竖排 flatten 预算 `ATTR_PUNCT_TRIM_START/END`、flush 按断列结果取用(PR #143);断言「行首夹注符号只占半字幅」 | | 6.3.3 | 横排的中、西文混排配置(1/4em,可挤 1/8、拉 1/2,三类例外) | ✅ | ➖ | `hori/luatex-cn-hori-spacing.lua`;断言「中西间距 ∈ [1/8, 1/2] em」「点号旁不加」「夹注号内侧不加」。直排的对应间距已实现,见 2.1.3 | | 6.4 | 基线、行高等 | 🟡 | 🟡 | 竖排格内垂直居中按 em 框基线对齐(#113,`geometry_test.py` 自校验);横排交 TeX 行高模型;未逐条核对本节全部细则 | ## 6. 第 7 章 · 页面与书籍版式 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | 7.1.1.1–.5 | 页面设计(基本版式:字号 / 行长 / 行数 / 行距 / 栏数 / 栏距 / 定版) | 🟡 | ✅ | 竖排 type area 要素齐备、band 分栏;横排版面交宿主文档类(geometry 等),号数字号 `\字号`(初号…八号)横竖排共享。**术语消歧**:clreq「版心」= type area,本项目「版心」= 书页中缝(鱼尾/象鼻) | | 7.1.2 | 孤行与孤字处理(孤字不成行、孤行不成页) | ✅ | ❌ | 横排 `orphan-char`(段末借字 + 该行均排)+ `widow/club-penalty`;竖排规划 P5 | | 7.1.3.1–.5 | 标题处理(种类、突显、单页起 / 换页、前页留空、同行标题) | ❌ | ❌ | 竖排 `\换页` 可手工近似 7.1.3.3;占行 / 单页起 / 同行标题 / 跨栏标题未做(需 sectioning 集成,规划 H5 遗留 / P5) | ## 7. 第 8 章 · 表单与用户交互 | 条款 | 横排 | 竖排 | 备注 | |------|------|------|------| | 8(全章) | ➖ | ➖ | 面向浏览器/交互式表单,非批排版引擎职责 | ## 8. 附录 A · 中文标点符号表 | 条款 | 要求 | 横排 | 竖排 | 证据 / 备注 | |------|------|------|------|------------| | A.1–A.5 | 标点全表(类别、宽度、可调空间、「不可分离」、「直排时的形式」) | ✅ | ✅ | `shared/luatex-cn-punct-table.lua` 单一数据源;竖排分类从表派生(PR #126),连接号 / 间隔号 / 分隔号扩类已派生(`LEGACY_MAP` → middle,中国大陆式间隔号固定半字宽);「直排时的形式」经 vert 形替换 + 缺字旋转兜底覆盖。断言:扩类宽度 3 条 | --- ## 9. 有意偏离清单 对外宣称符合度时,下列各条**不得表述为完全符合**: 1. **禁则解决方式用词典序比价(6.1.1)**。clreq 字面是「最后没有挤压机会, 再从前一行取最后一个字」,即挤得进就挤进;本实现对「挤进 / 推出」两个候选 各解一次求解器,按 clreq 优先顺序的词典序比价——尽量少动最后手段(字距)。 分歧发生在「挤进可行、但要把字距压得比推出拉得更狠」时:实测有列挤进须把 字距从 0.1em 压到 0.048em(−52%),推出只需拉到 0.132em(+32%),本实现 选推出。理由:−52% 的字距在竖排密排里非常刺眼。 2. **行尾点号悬挂两后端均默认关(6.1.3)**。clreq 注明悬挂适用于直排、 港台横排因点号居中不宜;故做成 `hanging-punct`(竖排别名 `标点悬挂`) 开关。横排默认关是规范本身的建议;竖排默认关是本项目的取舍——悬挂会 改变既有 vbook 文档的版面,留给作者按书体例选择。 3. **竖排挤压顺序在 clreq 七步之后追加「字距」兜底(6.2.2.3)**。直排 0.1em 基准字距是本项目的版式选择,不在 clreq 步骤内,只作最后手段、绝不先于 标点空白被压缩。 4. **横排夹注号字面不锚定(6.3.2.1)**。横排 advance 起点即字幅始端,字体 画在哪就是字面分布;实测四款字体开始夹注号墨心在 0.65–0.75em(空白都在 外侧),强制统一落点反而破坏更贴紧的字体设计(PR #145 的调查结论)。 5. **`ltc-guji` 整类不宣称符合(0.1 节)**。古籍复刻以底本版面为准,默认 `squeeze-mode=legacy` 无条件挤压等历史行为;新规则仅显式开启时生效。 6. **台湾式着重号无规范依据(5.3.1)**。clreq 原文注明「台湾教育部的 《重订标点符号手册》(2008 年修订版)中未收录此符号,但仍可见于部分 台湾的出版物」——台湾官方规范里没有着重号,clreq 也未为台湾式定义 另一种形态。`ltc-tw-vbook` 默认取 clreq 的通用形态(`●`),属 「规范外但实务通行」,不是《重订标点符号手册》背书的行为;作者可用 `\着重号设置{char=…}` 改成本书体例。另注:clreq 的「标点上不加着重号」 原文是「**通常**不再添加」(建议而非强制),故做成 `skip-punct` 开关。 ## 10. 不实现清单(附理由) | 条款 | 内容 | 理由 | |------|------|------| | 第 2 章相关 | 双向文本(bidi) | 阿拉伯文/希伯来文混排超出本引擎职责,LuaTeX 生态有专门方案(如 luabidi);与竖排网格模型的交互无实际需求 | | 4.1.1 / 5.5.5.1 | 儿化小字(U+16FF2/3) | 用字极罕见,几乎没有字体覆盖该码位;普通「儿」字排版不受影响 | | 第 8 章 | 表单与用户交互 | 面向浏览器渲染,非批排版引擎职责 | 「未实现(❌)」各项不在此列——它们在路线图内,状态与工作量见 `CLREQ-GAP-ANALYSIS.md` 第 6–7 节。 --- ## 11. 维护约定 - 每完成一个 clreq 相关 PR,**同步更新本矩阵对应行**(状态、证据、PR 号), 与 `CLREQ-GAP-ANALYSIS.md` 第 0.1 节进度快照同批提交。 - 新增偏离必须进第 9 节,新增放弃必须进第 10 节并给出理由。 - 断言数、测试计数以实际运行输出为准(0.3 节命令),不手算。