Skip to content

⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册.#909

Merged
Liam0205 merged 11 commits into
CTeX-org:masterfrom
myhsia:master
Jun 27, 2026
Merged

⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册.#909
Liam0205 merged 11 commits into
CTeX-org:masterfrom
myhsia:master

Conversation

@myhsia

@myhsia myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

closes #603

PR 概述

  1. \ExplFileData 的描述不要释放到 package 里面 —— 即使是开发者也 一般 不会直接去看 .sty, 而是去看 .dtx 文档; 同时这一定程度上违背了 DocStrip 的初衷, DocStrip 提取的 installfiles 就是干干净净的底层代码, 注释一律放到 .dtx 里.

  2. ctxdoc 已经加载了 unicode-math, 所以应该在其之前就去 \RequirePackage{mathtools}, 这样 zhlineskip.sty 里的 \RequirePackage{mathtools} 就会失效, 也就保证了 mathtools 一定在 unicode-math 前加载; BTW, unicode-math 会弹出覆盖一些东西的警告, 也给通过选项 suppress 掉了.

  3. 为了保证视觉效果, 使文档的 monofontCJKmainfont 尺寸上匹配, 我经过了手段计算, 方法如下

\documentclass[cs-break, zihao = 5, a4paper, fontset = none]{ctxdoc}
\setmonofont{Inconsolatazi4}[
  Extension         = .otf,
  UprightFont       = *-Regular,
  BoldFont          = *-Bold,
  Scale             = 1,
  AutoFakeSlant     = .111
]
\setCJKmainfont{Noto Serif CJK SC}[
  UprightFont       = * Medium,
  ItalicFont        = * Black,
  BoldFont          = * Bold
]

\begin{document}

\sbox0{哈哈哈哈哈}

\sbox1{\cmd{ABCDEFGHIJKLMNOPQRSTUVWXYZfgpqy}}

\copy0

\copy1

\the \numexpr \ht0

\the \numexpr \ht1 + \the \numexpr \dp1

\end{document}

将得到的两个数字前者除以后者即可. 最后得到比值为 1.00118564817432455.

[实话实说] 之前为什么设置为 <1 的数: 因为这个包的选项名字太长了, 以至于超出了页边界; 但是后来我对 docext 模仿 l3doc 的 macro 和 variable 环境, 采用长名字水平压缩的手段, 如下图)
image

[注: CI 使用的镜像可能还未更新, @RuixiZhang42 可在明日 18:13 后上传, 那时候 99% 没问题的]

  1. 同时对 monofont 启用伪斜体, 但是程度设置为 .111 ≈ 1/9 而非默认的 .167, 否则我看需要 monofont 伪斜体的地方太斜了以至于都和后面的贴上了 (在不使用 \/ 的情况下).
  2. @RuixiZhang42 最初的设计中, 使用了 Boolean UseMSWordMultipleLineSpacing, 然后用户才被允许使用 MSWordLineSpacingMultipleMSWordSinglespaceRatio, 这一点很麻烦, 而且经过测试, 用户在宏包选项中必须把 UseMSWordMultipleLineSpacing 放在 MSWordSinglespaceRatio 前面. 如今有了 LaTeX3, 这里放着了 ctex (xeCJK 里也有), 使用选项格式: MSWordSinglespaceRatio 不仅可以 truefalse, 还可以支持数字; 并且在之前用户如果未把 UseMSWordMultipleLineSpacing 设置为 true 并直接使用 MSWordSinglespaceRatio 时, 如果是个不认真看手册的小白 TA 甚至自己都无法察觉到. 现在如果发生这种情况, 添加了 AtEndOfPackage 检测机制, 会弹出警告.
  3. 修订了文档对 初始值 (对应 l3keys里的initial)默认值 (对应 l3keys 里的 default) 的划分.
  4. 优化了警告/报错信息的描述; 经查阅 interface3.pdf, 得知 \msg_<error/warning/info/...>:nnn 存在 e-type, 所以在 package optionunknown .code 中删掉了 \exp_args: 展开命令.
  5. 规范了一些变量名字. 既然提到了是 临时浮点数与 |dim| 变量, 那就要用 \l_@@_..., 而非 \g_@@_..., 更何况是夹在 group 里而且确实是临时计算的过程值.

自查

  1. 无新包加入
  2. 重大的修改: UseMSWordMultipleLineSpacing 已在 \changes 中填入
  3. 编译好的手册 zhlineskip.pdf 供浏览.

@myhsia

myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

OMG 这简直是太爽了 升级后 CI 只 check 更改的 package, 再也不用苦苦等待了.
(甚至 Ai 检查的速度都比 regex test 慢了 😂)

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 ⚠️ REQUEST_CHANGES
审查截止 4e174e936b29d2dad97a147f98672ca5038f846e

整体改动思路清晰——移除 UseMSWordMultipleLineSpacing 布尔选项并合入 MSWordLineSpacingMultiple.choice: 是合理的简化;临时变量 g→l 改名、e-type variant 替代 \exp_args、注释从 %<package> 迁移到 % ^^A 等均符合项目约定。但发现一处文档与代码不一致的阻塞问题。

🔴 阻塞问题 (1)

  • 文件: zhlineskip/zhlineskip.dtx

  • 代码链接: 文档部分 / 代码部分

  • 问题: restoremathleading 选项的文档初始值与代码不一致

    文档(用户手册)描述为:

    (初始值:|false|,默认值:|true|)

    但代码实现仍为:

    restoremathleading .initial:n = { true },
    restoremathleading .default:n = { true },

    .initial:n 对应文档中的"初始值",代码是 true,文档却写了 false。这会直接误导用户:用户读文档以为默认不恢复数学行距(且不加载 mathtools),实际行为却是默认恢复。

  • 建议: 二选一——

    1. 如果意图保持原行为(默认恢复数学行距),将文档改为 (初始值:|true|,默认值:|true|)
    2. 如果意图改变默认行为,需同步修改代码 .initial:n = { false },并在 \changes 中记录此 breaking change。

🟠 重要建议 (1)

  • 文件: zhlineskip/zhlineskip.dtxMSWordLineSpacingMultiple choice 代码

  • 问题: .code:n 中使用 \bool_set_true:N / \bool_set_false:N / \fp_set:Nn 操作 \g_@@_MSWordLineSpacingMultiple_bool\g_@@_MSWordLineSpacingMultiple_fp——局部赋值 (set) 用于全局命名 (\g_@@_) 变量。

    虽然在 \ProcessKeyOptions 顶层执行时 l/g 等价,但与 expl3 作用域命名约定不匹配(\g_ 变量应使用 gset 系列函数)。如果未来有人在分组内通过 \keys_set:nn 重新设置此选项,局部赋值会在组结束后回退,产生非预期行为。

    注:bodytextleadingratio 等使用 .fp_set:N 属性的键是 l3keys 内置行为(pre-existing),此处仅针对新引入的 .code:n 中的显式赋值。

  • 建议: 将 .code:n 块中的赋值改为 gset 系列:

    \bool_gset_true:N  \g_@@_MSWordLineSpacingMultiple_bool
    \fp_gset:Nn        \g_@@_MSWordLineSpacingMultiple_fp { 1.15 }
    % ...
    \bool_gset_false:N \g_@@_MSWordLineSpacingMultiple_bool
    % ...
    \bool_gset_true:N  \g_@@_MSWordLineSpacingMultiple_bool
    \fp_gset:Nn        \g_@@_MSWordLineSpacingMultiple_fp {#1}

🟢 小问题 (2)

  1. 文件: zhlineskip/zhlineskip.dtxInvalid Option 消息

    • 问题: 消息模板末尾缺少句点,且 "It is valid when XeTeX 支持 GBK 编码 #2" 可读性稍弱。
    • 建议: 考虑改为 It ~ takes ~ effect ~ only ~ when ~ #2.,并在末尾加句点以保持与其他消息风格一致。
  2. 文件: zhlineskip/zhlineskip.dtx消息变体定义

    • 问题: \clist_map_inline:nn { new, error, warning, info } 循环为 new 也生成了 ne/nee 变体(即 \@@_msg_new:ne\@@_msg_new:nee),但 \msg_new:nne / \msg_new:nnee 对消息模板做 e-expansion 在语义上不合理,且这些变体在当前代码中未被调用。
    • 建议: 可将 new 从循环中拆出,仅保留 nn/nnn 变体;或保持现状(不影响运行时行为)。

@myhsia

myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

🔍 PR 审查

项目 结果
结论 ⚠️ REQUEST_CHANGES
审查截止 4e174e936b29d2dad97a147f98672ca5038f846e

整体改动思路清晰——移除 UseMSWordMultipleLineSpacing 布尔选项并合入 MSWordLineSpacingMultiple.choice: 是合理的简化;临时变量 g→l 改名、e-type variant 替代 \exp_args、注释从 %<package> 迁移到 % ^^A 等均符合项目约定。但发现一处文档与代码不一致的阻塞问题。

🔴 阻塞问题 (1)

* **文件**: `zhlineskip/zhlineskip.dtx`

* **代码链接**: [文档部分](https://github.com/CTeX-org/ctex-kit/blob/4e174e936b29d2dad97a147f98672ca5038f846e/zhlineskip/zhlineskip.dtx#L462) / [代码部分](https://github.com/CTeX-org/ctex-kit/blob/4e174e936b29d2dad97a147f98672ca5038f846e/zhlineskip/zhlineskip.dtx#L870)

* **问题**: `restoremathleading` 选项的**文档初始值与代码不一致**。
  文档(用户手册)描述为:
  > `(初始值:|false|,默认值:|true|)`
  
  
  但代码实现仍为:
  ```
  restoremathleading .initial:n = { true },
  restoremathleading .default:n = { true },
  ```
  
  
      
        
      
  
        
      
  
      
    
  `.initial:n` 对应文档中的"初始值",代码是 `true`,文档却写了 `false`。这会直接误导用户:用户读文档以为默认不恢复数学行距(且不加载 `mathtools`),实际行为却是默认恢复。

* **建议**: 二选一——
  
  1. 如果意图保持原行为(默认恢复数学行距),将文档改为 `(初始值:|true|,默认值:|true|)`;
  2. 如果意图改变默认行为,需同步修改代码 `.initial:n = { false }`,并在 `\changes` 中记录此 breaking change。

🟠 重要建议 (1)

* **文件**: `zhlineskip/zhlineskip.dtx` — [MSWordLineSpacingMultiple choice 代码](https://github.com/CTeX-org/ctex-kit/blob/4e174e936b29d2dad97a147f98672ca5038f846e/zhlineskip/zhlineskip.dtx#L876)

* **问题**: `.code:n` 中使用 `\bool_set_true:N` / `\bool_set_false:N` / `\fp_set:Nn` 操作 `\g_@@_MSWordLineSpacingMultiple_bool` 和 `\g_@@_MSWordLineSpacingMultiple_fp`——局部赋值 (`set`) 用于全局命名 (`\g_@@_`) 变量。
  虽然在 `\ProcessKeyOptions` 顶层执行时 l/g 等价,但与 expl3 作用域命名约定不匹配(`\g_` 变量应使用 `gset` 系列函数)。如果未来有人在分组内通过 `\keys_set:nn` 重新设置此选项,局部赋值会在组结束后回退,产生非预期行为。
  注:`bodytextleadingratio` 等使用 `.fp_set:N` 属性的键是 l3keys 内置行为(pre-existing),此处仅针对新引入的 `.code:n` 中的显式赋值。

* **建议**: 将 `.code:n` 块中的赋值改为 `gset` 系列:
  ```
  \bool_gset_true:N  \g_@@_MSWordLineSpacingMultiple_bool
  \fp_gset:Nn        \g_@@_MSWordLineSpacingMultiple_fp { 1.15 }
  % ...
  \bool_gset_false:N \g_@@_MSWordLineSpacingMultiple_bool
  % ...
  \bool_gset_true:N  \g_@@_MSWordLineSpacingMultiple_bool
  \fp_gset:Nn        \g_@@_MSWordLineSpacingMultiple_fp {#1}
  ```

🟢 小问题 (2)

1. **文件**: `zhlineskip/zhlineskip.dtx` — [Invalid Option 消息](https://github.com/CTeX-org/ctex-kit/blob/4e174e936b29d2dad97a147f98672ca5038f846e/zhlineskip/zhlineskip.dtx#L824)
   
   * **问题**: 消息模板末尾缺少句点,且 "It is valid when [XeTeX 支持 GBK 编码 #2](https://github.com/CTeX-org/ctex-kit/issues/2)" 可读性稍弱。
   * **建议**: 考虑改为 `It ~ takes ~ effect ~ only ~ when ~ #2.`,并在末尾加句点以保持与其他消息风格一致。

2. **文件**: `zhlineskip/zhlineskip.dtx` — [消息变体定义](https://github.com/CTeX-org/ctex-kit/blob/4e174e936b29d2dad97a147f98672ca5038f846e/zhlineskip/zhlineskip.dtx#L781)
   
   * **问题**: `\clist_map_inline:nn { new, error, warning, info }` 循环为 `new` 也生成了 `ne`/`nee` 变体(即 `\@@_msg_new:ne`、`\@@_msg_new:nee`),但 `\msg_new:nne` / `\msg_new:nnee` 对消息模板做 e-expansion 在语义上不合理,且这些变体在当前代码中未被调用。
   * **建议**: 可将 `new` 从循环中拆出,仅保留 `nn`/`nnn` 变体;或保持现状(不影响运行时行为)。

稍后更改; 这里建议关闭 #603, 本次 PR 已全部覆盖 #603 中的 合理 要求.

@myhsia myhsia changed the title ⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册. WIP:⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册. Jun 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR #909 审查报告

概述

本 PR 对 zhlineskip 宏包进行了多项改进:移除逻辑混乱的 UseMSWordMultipleLineSpacing 布尔选项并将其功能并入 MSWordLineSpacingMultiple(使用 .choice: 机制同时支持 true/false/数值);修正文档中"缺省值"与"初始值"的混淆;规范临时变量命名(\g_@@_tmp*\l_@@_tmp*);改进消息管理系统以使用 e-type 展开。


重要建议 (2)

1. 消息管理循环为 msg_new 生成了无意义的 :ne / :nee 变体(死代码)

https://github.com/CTeX-org/ctex-kit/blob/main/zhlineskip/zhlineskip.dtx — 新增的消息管理循环:

\clist_map_inline:nn { new, error, warning, info }
  {
    \cs_new_protected:cpn { @@_msg_#1:ne  }
      { \use:c { msg_#1:nne  } { ZhLS } }
    ...
    \cs_new_protected:cpn { @@_msg_#1:nee }
      { \use:c { msg_#1:nnee } { ZhLS } }
  }

error/warning/info 生成 :ne/:nee 变体是合理的(interface3.pdf 确认 e-type 存在)。但对 new 来说:

  • msg_new:nne / msg_new:nnee 在语义上无意义——模板文本是静态定义的,不需要 e-type 展开;
  • 这些变体可能根本不存在于 l3msg(\use:c 会将未定义的 csname 生成为 \relax);
  • 在代码中从未调用 @@_msg_new:ne@@_msg_new:nee

建议:将 new 从循环中分离,或在循环内对 new 只生成 :nn:nnn 变体。例如:

\clist_map_inline:nn { new }
  {
    \cs_new_protected:cpn { @@_msg_#1:nn  }
      { \use:c { msg_#1:nnn  } { ZhLS } }
    \cs_new_protected:cpn { @@_msg_#1:nnn }
      { \use:c { msg_#1:nnnn } { ZhLS } }
  }
\clist_map_inline:nn { error, warning, info }
  {
    \cs_new_protected:cpn { @@_msg_#1:nn  }
      { \use:c { msg_#1:nnn  } { ZhLS } }
    \cs_new_protected:cpn { @@_msg_#1:ne  }
      { \use:c { msg_#1:nne  } { ZhLS } }
    \cs_new_protected:cpn { @@_msg_#1:nnn }
      { \use:c { msg_#1:nnnn } { ZhLS } }
    \cs_new_protected:cpn { @@_msg_#1:nee }
      { \use:c { msg_#1:nnee } { ZhLS } }
  }
2. 向后兼容性:移除 UseMSWordMultipleLineSpacing 是破坏性变更,建议明确迁移路径

移除 UseMSWordMultipleLineSpacing 后,使用旧写法的用户:

\usepackage[UseMSWordMultipleLineSpacing, MSWordLineSpacingMultiple=1.62]{zhlineskip}

将直接收到 "Unknown Option" 错误。

\changes 中已记录此变更,PR 标题也标注了 WIP。但考虑到:

  • 这是一个公开发布到 CTAN 的宏包;
  • 论文排版用户可能在模板中硬编码了旧选项名。

建议考虑是否提供过渡方案(例如将 UseMSWordMultipleLineSpacing 保留为 deprecated alias 并发出警告),或至少在手册中明确说明迁移方法。如果团队决策为直接移除,建议在版本号上做 minor bump 以示不兼容。


小问题 / 建议 (3)

1. MSWordLineSpacingMultiple / unknown 分支未校验数值合法性
MSWordLineSpacingMultiple / unknown .code:n =
  {
    \bool_gset_true:N \g_@@_MSWordLineSpacingMultiple_bool
    \fp_gset:Nn \g_@@_MSWordLineSpacingMultiple_fp {#1}
  },

如果用户传入非数值字符串(如 MSWordLineSpacingMultiple = abc),\fp_gset:Nn 会抛出 l3fp 底层错误,信息对用户不够友好。可考虑在设置前加一层 \fp_if_nan:nTF 校验,给出更明确的宏包级错误信息。不过这是锦上添花,l3fp 自身的报错也足够定位问题。

2. 文档示例中 \RestoreTextEnvironmentLeading {tabular} 的空格风格
|\RestoreTextEnvironmentLeading {tabular}|

旧版为 |\RestoreTextEnvironmentLeading{tabular}|。用户文档示例中,LaTeX 命令后紧跟大括号(无空格)是更常见的 LaTeX 写法习惯。expl3 风格的空格分隔在实现代码中合理,但在面向用户的示例中可能引起困惑。建议保持用户文档示例的 LaTeX 惯用写法。

3. monofont Scale 精度
Scale = 1.00118564817432455,

17 位有效数字。TeX 内部使用 fixed-point 算术(sp 精度约 5 位小数),超高精度在排版引擎层面无实际意义。PR body 中详细解释了计算方法,记录目的可以理解,但实际效果与 Scale = 1.00119 无异。非阻塞,仅供参考。


亮点

  • MSWordLineSpacingMultiple.choice: + unknown 设计简洁优雅,允许 true/false/数值三态,符合 l3keys 的最佳实践。
  • 临时变量从 \g_@@_tmp* 更名为 \l_@@_tmp* 是正确的作用域修正——这些变量在 \group_begin:/\group_end: 内使用且结果通过 \fp_gset:Nn 写出,局部命名更准确地反映了意图。
  • AtEndOfPackage 检测机制对用户友好:当用户修改了 MSWordSinglespaceRatio 但忘记启用 MSWordLineSpacingMultiple 时能给出警告。
  • 消息系统迁移到 e-type 展开,与项目编码约定(llmdoc/reference/coding-conventions.md)保持一致。
  • DocStrip 注释迁移(%<package>% ^^A)符合 DocStrip 设计初衷。

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 增量审查

项目 结果
结论 ✅ APPROVE
审查范围 4e174e936b29d2dad97a147f98672ca5038f846e..5d98847fba720c3b2d4aa6b2708c99e360ba03f2

上次审查提出的三个问题全部已修复:

  1. 🔴 阻塞: restoremathleading 文档初始值与代码不一致 → 文档已改为 (初始值:|true|,默认值:|true|),与代码 .initial:n = { true } 一致。(diff)
  2. 🟠 重要: \g_@@_ 变量使用局部赋值.code:n 块中已全部改为 \bool_gset_true:N / \bool_gset_false:N / \fp_gset:Nn。(diff)
  3. 🟢 小问题: 消息文本与 new 变体Invalid ~ Option 消息改为 It ~ takes ~ effect ~ only ~ when ~ #2.,末尾补句点;\@@_msg_new:nn / \@@_msg_new:nnn 改为直接定义,不再通过循环生成无用的 ne / nee 变体。(diff)

增量改动干净,无新问题。代码良好。

审查截止: 5d98847

@myhsia myhsia changed the title WIP:⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册. ⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册. Jun 27, 2026
@Liam0205

Copy link
Copy Markdown
Contributor

OMG 这简直是太爽了 升级后 CI 只 check 更改的 package, 再也不用苦苦等待了. (甚至 Ai 检查的速度都比 regex test 慢了 😂)

哈哈哈,所以说,这一套改动很有价值啊←_←

根据 Bot 之前的指示,
> 17 位有效数字。TeX 内部使用 fixed-point 算术(sp 精度约 5 位小数),超高精度在排版引擎层面无实际意义。PR body 中详细解释了计算方法,记录目的可以理解,但实际效果与 Scale = 1.00119 无异。非阻塞,仅供参考。
但是保留5位小数一定程度上还是有点粗糙, 因为 `\fp_eval:n { 584339 / 583647 }` 的结果为 `1.001185648174325`, 那就统一把所有 `Scale` 后面的一律保留 16 位有效数字 / 小数点后15位.
@github-actions

Copy link
Copy Markdown
Contributor
🤖 PR 审查: ⟨doc|fix⟩(zhlineskip): 移除 UseMSWordMultipleLineSpacing 选项; 订正手册

总体评价

PR 目标清晰:将逻辑混乱的布尔选项 UseMSWordMultipleLineSpacing 并入 MSWordLineSpacingMultiple(支持 true/false/数值三态),同时大幅修订手册文档。改动方向正确,代码质量整体良好,符合项目 expl3 编码规范。

CI 状态: Ubuntu 已通过,macOS / Windows pending。


重要建议

1. \l_@@_tmpa_fp / \l_@@_tmpa_dim / \l_@@_tmpb_dim\group_begin: 内用 \fp_set:Nn 赋值,但在组外用 \fp_new:N 声明——作用域语义正确但命名有细微矛盾

变量命名改为 l_ 前缀是合理的(它们确实是临时计算值,夹在 \group_begin:/\group_end: 内),但需注意:

  • \fp_new:N / \dim_new:N全局操作(等价于 \global\newcount),无论变量名是 l_ 还是 g_ 都一样——它只是注册变量,不受分组约束。
  • 赋值用的 \fp_set:Nn(非 \fp_gset:Nn)是局部赋值,组结束后值会回退。

这里的关键是:\l_@@_tmpa_fp\fp_set:Nn 赋值后,紧接着就在同一组内\fp_gset:Nn \g_@@_targetbodyleading_fp 消费,所以逻辑上没有 bug。但 PR body 的说明 "既然提到了是临时浮点数与 dim 变量, 那就要用 \l_@@_..." 是正确的。非阻塞,确认无误。

2. 声明了但未使用的消息变体

新消息管理系统声明了 @@_msg_info:ne@@_msg_info:nne@@_msg_error:nne@@_msg_info:nee 等变体,但实际代码中均未使用。已使用的变体为:

  • @@_msg_error:ne — Unknown Option
  • @@_msg_warning:nnn — Invalid Option / Not Loaded Package
  • @@_msg_warning:nee — MSWord Multiple Line Spacing

建议:既然是按需定义,可以考虑只在 \clist_map_inline:nn 中保留实际使用的变体,或至少在注释中说明哪些是为将来扩展预留的。非阻塞。

3. \@@_msg_new:nn\@@_msg_new:nnn 手动定义,而非在 \clist_map_inline 中生成

当前 new 从循环中抽出单独定义:

\cs_new_protected:Npn \@@_msg_new:nn  { \msg_new:nnn  { ZhLS } }
\cs_new_protected:Npn \@@_msg_new:nnn { \msg_new:nnnn { ZhLS } }

这是因为 msg_new 不需要 e 变体。逻辑合理,代码清晰。确认无误。


小问题 / 风格建议

4. \exp_args:Nno\@@_msg_error:ne 的改进正确

原代码 \exp_args:Nno \@@_msg_error:nn { Unknown ~ Option } { \l_keys_key_str } 改为 \@@_msg_error:ne { Unknown ~ Option } { \l_keys_key_str },符合项目 e-type 优先于 x-type 的编码约定。PR body 也正确引用了 interface3.pdf 关于 e-type 的说明。

5. .choice: 实现的 MSWordLineSpacingMultiple 三态选项设计合理

MSWordLineSpacingMultiple           .choice:,
MSWordLineSpacingMultiple           .default:n  = { true  },
MSWordLineSpacingMultiple / true    .code:n     = { ... },
MSWordLineSpacingMultiple / false   .code:n     = { ... },
MSWordLineSpacingMultiple / unknown .code:n     = { ... },

利用 l3keys 的 .choice: + .default:n + unknown 分支,将原来需要两个选项(布尔 UseMSWordMultipleLineSpacing + 数值 MSWordLineSpacingMultiple)合并为一个,用户体验更好。注意到 MSWordLineSpacingMultiple 不带值时默认为 true(使用 1.15),带数值时直接设置——这与原语义兼容。

6. \AtEndOfPackage 检测机制

当用户修改了 MSWordSinglespaceRatio 但未启用 MSWordLineSpacingMultiple 时发出警告,这是一个很好的用户体验改进。逻辑用 \bool_lazy_or:nnF 实现——只有当两个条件都为假时才触发警告:

  1. MSWordLineSpacingMultiple 未开启
  2. MSWordSinglespaceRatio 不等于初始值

7. 手册"缺省值"→"初始值"的术语修正

将"缺省值"统一为"初始值"以对应 l3keys 的 initial,区分 default("默认值",即不带值时的值)。术语更精确。

8. 文档中 fontset = fandolfontset = none + 手动设置 CJK 字体

因为需要精确控制字体 Scale 以匹配 CJK 与 mono 字体尺寸,改为手动设置是合理的。Scale 精度(15 位小数)在 TeX 层面超出了 sp 精度的实际意义,但作为文档记录不影响排版结果。

9. 缩进修复

zhlineskip.dtx 第 1063 行第 1147 行 的花括号缩进修复(} 对齐到正确位置)是好的清理工作。


审查结论

APPROVE — 改动方向正确,核心逻辑(.choice: 三态合并、\AtEndOfPackage 检测、l_ 临时变量重命名、e-type 迁移)均无功能性问题。文档修订大幅提升了用户手册的准确性。建议关注 CI macOS / Windows 结果后合并。


🤖 Automated review by Claude Code

@Liam0205

Copy link
Copy Markdown
Contributor

@myhsia 如果你使用的是 Claude Code 或者 Codex 的话,可以搭配仓库内的 pre-push hook 使用。push 会自动等待 CI(包括 review bot)的结果,然后据此做出反应。真有什么问题需要处理的话,它们应该会自动接着处理,不需要人工干预。

- 移除掉未使用的 `\@@_msg_info:<nn|nnn|ne|nee>`, 但为保证 `\clist_map_inline:nn` 的完整性与连续性, 同时方便后期万一哪天可能会用到, 所以其他的保留;
- 统一使用 L3 风格: `\endinput` -> `\file_input_stop:`
@github-actions

Copy link
Copy Markdown
Contributor

PR #909 审查报告

审查概要

PR 标题: ⟨doc|fix⟩(zhlineskip): 移除逻辑混乱的 UseMSWordMultipleLineSpacing 选项; 订正手册.
作者: @myhsia
结论: ✅ APPROVE — 代码质量良好,API 简化设计合理,符合项目编码规范。发现 2 个建议供参考。


✅ 亮点

  1. API 简化设计良好:将 UseMSWordMultipleLineSpacing + MSWordLineSpacingMultiple 合并为单一 .choice: key,支持 true/false/数字三种输入,用户体验显著改善。zhlineskip.dtx 选项定义

  2. AtEndOfPackage 防误用检测:当用户修改了 MSWordSinglespaceRatio 但未启用 MSWordLineSpacingMultiple 时发出警告,能有效避免 PR body 中提到的"小白用户无法察觉"问题。

  3. 临时变量作用域修正\g_@@_tmpa_fp / \g_@@_tmpa_dim / \g_@@_tmpb_dim 改为 \l_@@_ 前缀是正确的——它们在 \group_begin: / \group_end: 内使用且仅用于临时计算,不需要全局可见性。

  4. e-type 优先\exp_args:Nno \@@_msg_error:nn\@@_msg_error:ne\exp_args:Nnff \@@_msg_warning:nnn\@@_msg_warning:nee,符合项目自 跟进 l3kernel 改变,尽量使用 e-type variant 代替 x-type #679 起确立的 e-type 优先约定

  5. DocStrip 注释处理:将 %<package>% 注释改为 % ^^A 是正确做法——docstrip 提取的 .sty 应保持干净,注释留在 .dtx

  6. \file_input_stop: 替代 \endinput:遵循 expl3 风格统一。

  7. 文档术语修正:将"缺省值"统一改为"初始值"(对应 l3keysinitial),与"默认值"(对应 default)正确区分,消除歧义。


💬 建议 (非阻塞)

建议 1: 消息文案 Invalid ~ Option 的英文措辞可推敲
The ~ `#1' ~ Option ~ is ~ invalid ~ now.
It ~ takes ~ effect ~ only ~ when ~ #2.

"invalid now" 语义上暗示选项曾经有效但现在无效了,但实际意图是"在当前配置下不生效"。建议考虑类似:

The ~ `#1' ~ option ~ is ~ ineffective.
It ~ only ~ takes ~ effect ~ when ~ #2.

非阻塞,仅供参考。

建议 2: Scale 精度 15 位小数在 TeX 层面无实际意义

Scale = 1.059248554913295 (15 位小数) — TeX 内部使用 fixed-point 算术(sp 精度约 5 位有效小数),超高精度在排版引擎层面无实际区别。但作者已在 PR body 和 commit 中解释了保留 16 位有效数字的一致性考虑,可以理解。非阻塞。


📋 审查清单

检查项 状态
无新包依赖引入
\changes 记录了 UseMSWordMultipleLineSpacing 移除
选项 .choice:true/false/unknown 分支逻辑正确
\bool_new:N 默认 false 与旧 .initial:n = { false } 一致
e-type variant 生成完整(ne/nee 均有)
info 变体移除(确认未使用)
\l_@@_tmpa_*\group_begin:/\group_end: 内赋值,作用域正确
AtEndOfPackage 警告的 \bool_lazy_or:nnF 逻辑正确

🤖 Generated with Claude Code

@myhsia

myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

@Liam0205 有个 CI bug 还需要解决下: 我自己 (当然 也包括其他已经 sync 的 fork) 的分支为什么还在运行 ctex/xecjk/... 的测试? 我已经同步了并且目前我的分支超前于 CTeX-org/ctex-kit/master, 没有任何 commit behind.
2026-06-28_00-36-45
2026-06-28_00-37-00

@myhsia

myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

@Liam0205 有个 CI bug 还需要解决下: 我自己 (当然 也包括其他已经 sync 的 fork) 的分支为什么还在运行 ctex/xecjk/... 的测试? 我已经同步了并且目前我的分支超前于 CTeX-org/ctex-kit/master, 没有任何 commit behind. 2026-06-28_00-36-45 2026-06-28_00-37-00

是因为这个依赖于 LLM 吗? 去判断 commit 了哪些文件夹? 如果是, 那我觉得完全没必要 —— 按常理来说, 我觉得 Git 这个工具自己就可以判断 (当然我也没具体实践过)

@Liam0205

Copy link
Copy Markdown
Contributor

@Liam0205 有个 CI bug 还需要解决下: 我自己 (当然 也包括其他已经 sync 的 fork) 的分支为什么还在运行 ctex/xecjk/... 的测试? 我已经同步了并且目前我的分支超前于 CTeX-org/ctex-kit/master, 没有任何 commit behind.

这个根据 trigger 的类别行为会有不同。trigger by push 会全部跑。因为它看的是当前分支 HEAD 的状态,所以不能只跑有变更的部分。trigger by pull request 会只看有变更的部分。

是因为这个依赖于 LLM 吗? 去判断 commit 了哪些文件夹? 如果是, 那我觉得完全没必要 —— 按常理来说, 我觉得 Git 这个工具自己就可以判断 (当然我也没具体实践过)

不依赖 LLM。是根据路径匹配设置的硬规则。

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 审查

项目 结果
结论 ⚠️ REQUEST_CHANGES
审查截止 f2235f8523608518922f0d7ab1993a0db067a9df

整体改动质量很高:移除 UseMSWordMultipleLineSpacing 布尔选项并合入 MSWordLineSpacingMultiple.choice: 是合理的 API 简化;临时变量 g→l 改名、e-type variant 替代 \exp_args、注释从 %<package> 迁移到 % ^^A\endinput\file_input_stop: 等均符合项目约定。上轮审查的阻塞问题(restoremathleading 文档初始值 false 与代码 true 不一致)已修复,gset 作用域问题也已更正。但发现一处新的阻塞问题。

🔴 阻塞问题 (1)

消息名称不匹配导致运行时错误

  • 定义: zhlineskip.dtx — Ineffective Option 消息定义

    \@@_msg_new:nn { Ineffective ~ Option }
  • 调用: zhlineskip.dtx — AtEndOfPackage 警告

    \@@_msg_warning:nnn { Invalid ~ Option } { MSWordSinglespaceRatio }
      { MSWordLineSpacingMultiple ~ = ~ true }
  • 问题: 消息定义名为 Ineffective ~ Option,但调用点使用 Invalid ~ Option。这两个名称不匹配。当用户设置了 MSWordSinglespaceRatio 却未启用 MSWordLineSpacingMultiple = true 时,\msg_warning:nnnn { ZhLS } { Invalid Option } 会因消息未定义而触发 LaTeX 错误(而不是预期的警告)。

    推测原因:最后一次提交 f2235f85 将消息从 Invalid 重命名为 Ineffective,但遗漏了 \AtEndOfPackage 中的调用点。

  • 修复: 将调用改为匹配定义:

    \@@_msg_warning:nnn { Ineffective ~ Option } { MSWordSinglespaceRatio }
      { MSWordLineSpacingMultiple ~ = ~ true }

🟢 小问题 (2)

  1. \@@_msg_error:nee 已定义但未使用

    消息管理循环为 errorwarning 都生成了 nee 变体,但 \@@_msg_error:nee 在当前代码中无调用点。\@@_msg_warning:nee 有一处使用。这不影响运行时行为,仅是冗余定义,可保留以备后用。

  2. CI 测试尚未完成

    test-zhlineskip 在三个平台上均处于 pending 状态。建议等 CI 全部通过后再合入,确保消息管理重构和选项逻辑变更未破坏现有测试基线。


🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR 增量审查

项目 结果
结论 ✅ APPROVE
审查范围 f2235f85..9ca15313 (最终 commit)
上轮审查 f2235f85 — 阻塞问题: 消息名称不匹配

上轮审查发现的阻塞问题已在 9ca15313 中修复:

  • 🔴 阻塞: Invalid ~ Option vs Ineffective ~ Option 消息名称不匹配 → 调用点已改为 Ineffective ~ Option,与定义一致。

最终状态验证

对 PR 最终状态(11 个 commit 合计)进行全面检查:

检查项 状态
消息定义与调用点名称完全匹配(5 条消息,6 处调用)
.choice: 三态逻辑(true/false/数值)正确
\bool_gset_true:N / \bool_gset_false:N / \fp_gset:Nn 作用域一致
\l_@@_tmpa_*\group_begin:/\group_end: 内使用,作用域正确
\AtEndOfPackage 警告的 \bool_lazy_or:nnF 逻辑正确
e-type 优先约定(\@@_msg_error:ne\@@_msg_warning:nee
\@@_msg_new:nn / \@@_msg_new:nnn 独立定义,未生成无意义 ne 变体
文档"初始值"/"默认值"与代码 .initial:n / .default:n 一致
\changes 记录了 UseMSWordMultipleLineSpacing 移除
\endinput\file_input_stop: L3 风格统一
DocStrip 注释 %<package>% ^^A 迁移正确
CI: Ubuntu ✅ macOS ✅ Windows pending

遗留建议(非阻塞,供参考)

1. 向后兼容性考量

移除 UseMSWordMultipleLineSpacing 是破坏性变更。使用旧写法的用户将收到 "Unknown Option" 错误。如果团队认为有必要,可考虑保留为 deprecated alias 并发出警告。如果决定直接移除(考虑到用户量有限且语义已合入 MSWordLineSpacingMultiple),当前方案也是合理的。

2. @@_msg_error:nee 已定义但未使用

消息管理循环为 error 生成了 nee 变体,但代码中无调用点。不影响运行时行为,可保留以备后用或移除以减少冗余。

代码质量良好,建议等 Windows CI 通过后合并。


🤖 Generated with Claude Code

@myhsia

myhsia commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

就这样了

  1. 向后兼容性考量
    移除 UseMSWordMultipleLineSpacing 是破坏性变更。使用旧写法的用户将收到 "Unknown Option" 错误。如果团队认为有必要,可考虑保留为 deprecated alias 并发出警告。如果决定直接移除(考虑到用户量有限且语义已合入 MSWordLineSpacingMultiple),当前方案也是合理的。

关于这点, 其实早就有一个事情给 cover 掉了: 提交 #06ca468 中已经声明 LaTeX2e 版本不得低于 2026/06/01; 更何况即使真有人 只升级 LaTeX kernel, 不升级 zhlineskip, 那我觉得报错信息已经很直球了.

  1. @@_msg_error:nee 已定义但未使用
    消息管理循环为 error 生成了 nee 变体,但代码中无调用点。不影响运行时行为,可保留以备后用或移除以减少冗余。

这个就这样吧, 毕竟用了 \clist_map_inline, 没法直接删, 除非一条一条写, 弄的乱乱的, 没必要, 就当备用了.

代码质量良好,建议等 Windows CI 通过后合并。

🤖 Generated with Claude Code

CI 都过了, Over. CTAN 发布等 @RuixiZhang42

@Liam0205 Liam0205 merged commit 1b8f409 into CTeX-org:master Jun 27, 2026
14 checks passed
@RuixiZhang42

Copy link
Copy Markdown
Member

@myhsia 感谢你这么大的贡献,如果你愿意的话,可以考虑加成co-author

@myhsia

myhsia commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

@myhsia 感谢你这么大的贡献,如果你愿意的话,可以考虑加成co-author

可以的~

目前 zhlineskip 的 L3+DocStrip 已经基本完善,发布 CI 以及操作方法已经由 @Liam0205 写好,见 #892 (comment)

检查没问题的话,可以填入你的 CTAN 信息后运行一下对应的 CI 发一次版

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.

3 participants