@chengzhao-dev/dsh-quarto-book 0.4.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.en.md +3 -3
  2. package/README.md +3 -3
  3. package/lib/tools/render-check.js +5 -2
  4. package/package.json +5 -2
  5. package/skills/designing-theme/SKILL.md +3 -2
  6. package/skills/designing-theme/assets/theme/css/base.css +216 -55
  7. package/skills/designing-theme/assets/theme/css/callouts.css +32 -23
  8. package/skills/designing-theme/assets/theme/css/code.css +84 -2
  9. package/skills/designing-theme/assets/theme/css/content.css +152 -36
  10. package/skills/designing-theme/assets/theme/css/landing.css +175 -54
  11. package/skills/designing-theme/assets/theme/css/nav.css +462 -35
  12. package/skills/designing-theme/assets/theme/css/sidebar.css +76 -31
  13. package/skills/designing-theme/assets/theme/css/tokens.css +34 -16
  14. package/skills/designing-theme/assets/theme/includes/fonts.html +1 -1
  15. package/skills/designing-theme/assets/theme/includes/footer.html +16 -7
  16. package/skills/designing-theme/assets/theme/includes/palette.html +420 -0
  17. package/skills/designing-theme/assets/theme/palettes/flexoki/brand-mark.svg +3 -0
  18. package/skills/designing-theme/assets/theme/palettes/flexoki/favicon-dark.svg +5 -0
  19. package/skills/designing-theme/assets/theme/palettes/flexoki/favicon-light.svg +5 -0
  20. package/skills/designing-theme/assets/theme/palettes/flexoki/highlight-dark.theme +214 -0
  21. package/skills/designing-theme/assets/theme/palettes/flexoki/highlight-light.theme +214 -0
  22. package/skills/designing-theme/assets/theme/palettes/flexoki/meta.md +53 -0
  23. package/skills/designing-theme/assets/theme/palettes/flexoki/theme-dark.scss +43 -0
  24. package/skills/designing-theme/assets/theme/palettes/flexoki/theme-light.scss +40 -0
  25. package/skills/designing-theme/assets/theme/palettes/flexoki/tokens.css +156 -0
  26. package/skills/designing-theme/assets/theme/palettes/hill-light/brand-mark.svg +3 -0
  27. package/skills/designing-theme/assets/theme/palettes/hill-light/favicon-dark.svg +5 -0
  28. package/skills/designing-theme/assets/theme/palettes/hill-light/favicon-light.svg +5 -0
  29. package/skills/designing-theme/assets/theme/palettes/hill-light/meta.md +78 -0
  30. package/skills/designing-theme/assets/theme/palettes/hill-light/syntax.css +150 -0
  31. package/skills/designing-theme/assets/theme/palettes/hill-light/tokens.css +322 -0
  32. package/skills/designing-theme/assets/theme/palettes/solarized/brand-mark.svg +3 -0
  33. package/skills/designing-theme/assets/theme/palettes/solarized/favicon-dark.svg +5 -0
  34. package/skills/designing-theme/assets/theme/palettes/solarized/favicon-light.svg +5 -0
  35. package/skills/designing-theme/assets/theme/palettes/solarized/highlight-dark.theme +214 -0
  36. package/skills/designing-theme/assets/theme/palettes/solarized/highlight-light.theme +214 -0
  37. package/skills/designing-theme/assets/theme/palettes/solarized/meta.md +66 -0
  38. package/skills/designing-theme/assets/theme/palettes/solarized/syntax.css +67 -0
  39. package/skills/designing-theme/assets/theme/palettes/solarized/theme-dark.scss +43 -0
  40. package/skills/designing-theme/assets/theme/palettes/solarized/theme-light.scss +41 -0
  41. package/skills/designing-theme/assets/theme/palettes/solarized/tokens.css +154 -0
  42. package/skills/designing-theme/knowledge/reading-surface.md +27 -15
  43. package/skills/designing-theme/references/theme-spine.md +2 -2
  44. package/skills/designing-theme/references/theme-system.md +82 -36
  45. package/skills/designing-theme/scripts/checking-layout.py +306 -48
  46. package/skills/designing-theme/scripts/measuring-pages.mjs +40 -3
  47. package/skills/writing-quarto/examples/01-language-scope.md +3 -3
  48. package/skills/writing-quarto/examples/02-structure-shape.md +5 -5
  49. package/skills/writing-quarto/examples/03-block-after.md +2 -2
  50. package/skills/writing-quarto/examples/03-excerpt-lead.md +6 -6
  51. package/skills/writing-quarto/examples/03-layout-list.md +15 -15
  52. package/skills/writing-quarto/examples/03-qmd-elements.md +4 -4
  53. package/skills/writing-quarto/examples/04-paragraph-cases.md +5 -5
  54. package/skills/writing-quarto/examples/04-paragraph-opening.md +3 -3
  55. package/skills/writing-quarto/examples/05-sentence-brevity.md +5 -5
  56. package/skills/writing-quarto/examples/05-sentence-frame.md +6 -6
  57. package/skills/writing-quarto/examples/05-sentence-reference.md +5 -5
  58. package/skills/writing-quarto/examples/06-wording-cases.md +8 -8
  59. package/skills/writing-quarto/examples/08-appendix.md +4 -4
  60. package/skills/writing-quarto/quarto/basics.md +24 -2
  61. package/skills/writing-quarto/quarto/comments.md +43 -0
  62. package/skills/writing-quarto/quarto/coords.md +4 -4
  63. package/skills/writing-quarto/quarto/encoding.md +35 -0
  64. package/skills/writing-quarto/quarto/mermaid.md +1 -1
  65. package/skills/writing-quarto/quarto/prose.md +86 -0
  66. package/skills/writing-quarto/quarto/render.md +17 -16
  67. package/skills/writing-quarto/quarto/terminal.md +3 -3
  68. package/skills/writing-quarto/scripts/checking-dom.py +20 -8
  69. package/skills/writing-quarto/scripts/verifying-content.py +12 -3
  70. package/skills/writing-quarto/steps/01-task.md +6 -6
  71. package/skills/writing-quarto/steps/02-structure.md +19 -19
  72. package/skills/writing-quarto/steps/03-blocks.md +40 -40
  73. package/skills/writing-quarto/steps/04-paragraphs.md +55 -55
  74. package/skills/writing-quarto/steps/05-sentences.md +42 -43
  75. package/skills/writing-quarto/steps/06-wording.md +9 -11
  76. package/skills/writing-quarto/steps/07-layout.md +21 -17
  77. package/skills/writing-quarto/steps/08-reread.md +9 -13
  78. package/templates/quarto-book-project/SKILL.md +1 -1
  79. package/skills/designing-theme/assets/theme/assets/brand-mark.svg +0 -4
  80. package/skills/designing-theme/assets/theme/assets/favicon.svg +0 -9
  81. package/skills/designing-theme/assets/theme/palettes/github/highlight-dark.theme +0 -213
  82. package/skills/designing-theme/assets/theme/palettes/github/highlight-light.theme +0 -213
  83. package/skills/designing-theme/assets/theme/palettes/github/meta.md +0 -38
  84. package/skills/designing-theme/assets/theme/palettes/github/theme-dark.scss +0 -35
  85. package/skills/designing-theme/assets/theme/palettes/github/theme-light.scss +0 -34
  86. package/skills/designing-theme/assets/theme/palettes/github/tokens.css +0 -160
@@ -1,10 +1,10 @@
1
1
  # 坐标轴网格图的生成约定
2
2
 
3
- 坐标轴类网格图(状态面板行列、二维数组下标)用共享绘图助手生成 SVG,不用 Mermaid 硬画网格。流程图与坐标图的分工、页面围栏写法、解释器与 CI 依赖都在本文件;token 预算的排除口径见`steps/02-structure.md`「计数口径」。
3
+ 坐标轴类网格图(状态面板行列、二维数组下标)用共享绘图助手生成 SVG,不用 Mermaid 硬画网格。流程图与坐标图的分工、页面围栏写法、解释器与 CI 依赖都在本文件;token 预算的排除口径见 `steps/02-structure.md`「计数口径」。
4
4
 
5
5
  ## 与 Mermaid 的分工
6
6
 
7
- - 默认图是 `{mermaid}` flowchart,表达调用链、分层与数据流(口径见`quarto/mermaid.md`)。
7
+ - 默认图是 `{mermaid}` flowchart,表达调用链、分层与数据流(口径见 `quarto/mermaid.md`)。
8
8
  - 坐标轴类网格图只走 `rendering-coords.py` 加 `{python}` 可执行单元;Mermaid 的节点文本排版不适合网格,禁止用它拼状态面板。
9
9
  - Agent 作图边界:默认只生成 Mermaid 流程图;坐标图仅当用户明确指定时生成,且只改助手调用参数,不内联第二套 SVG 逻辑。
10
10
 
@@ -17,9 +17,9 @@
17
17
 
18
18
  ## 上游代码与图的桥接
19
19
 
20
- 坐标图不孤立出现:引出图的代码块与图之间必须有桥接句,说明图核对代码的哪部分契约(如「下面的图标出每个数据项的 (row, col),与 `IsValid` 接受的范围一致」);图后先给从图带走的结论,再进入下一块;小节以图收尾时,从图带走的结论可并入桥接段(如 示例章先给 `row` 为 `3` 或 `col` 为 `-1` 这类反例再上图),不在图后孤悬一句。代码块与图之间只有空行视为堆叠,固定序列见 `writing-quarto` 技能 `quarto/authoring.md`「代码与图的桥接」与`steps/03-blocks.md`。
20
+ 坐标图不孤立出现:引出图的代码块与图之间必须有桥接句,说明图核对代码的哪部分契约(如「下面的图标出每个数据项的 (row, col),与 `IsValid` 接受的范围一致」);图后先给从图带走的结论,再进入下一块;小节以图收尾时,从图带走的结论可并入桥接段(如 示例章先给 `row` 为 `3` 或 `col` 为 `-1` 这类反例再上图),不在图后孤悬一句。代码块与图之间只有空行视为堆叠,固定序列见 `writing-quarto` 技能 `quarto/authoring.md`「代码与图的桥接」与 `steps/03-blocks.md`。
21
21
 
22
- 坐标图单元计入盒子密度(口径见`steps/03-blocks.md`):同一 `###` 内坐标图与代码块相邻出现时,桥接句就是盒子之间的承接正文;`verifying-content.py` 对两围栏之间无正文给出 WARN 提示,人审与对照案例仍是主检查。
22
+ 坐标图单元计入盒子密度(口径见 `steps/03-blocks.md`):同一 `###` 内坐标图与代码块相邻出现时,桥接句就是盒子之间的承接正文;`verifying-content.py` 对两围栏之间无正文给出 WARN 提示,人审与对照案例仍是主检查。
23
23
 
24
24
  ## 助手 API 与主题适配
25
25
 
@@ -0,0 +1,35 @@
1
+ # 文件编码与行尾
2
+
3
+ > 速查:UTF-8 无 BOM · 文本文件 LF · `.bat`/`.cmd` CRLF · 机器规则以根 `.gitattributes` 与 `.editorconfig` 为准 · 不反向转码
4
+
5
+ ## 默认值
6
+
7
+ 书里的 `.qmd`、`.yml`、`.yaml`、`.scss`、`.css`、`.md`、`.lua`、`.py`、`.mjs` 一律满足三条:
8
+
9
+ - UTF-8 无 BOM。
10
+ - 行尾 LF。
11
+ - 文件末尾保留一个换行。
12
+
13
+ `.bat` 与 `.cmd` 用 CRLF;`.sh` 必须是 LF,否则在 Linux、WSL 与 CI 里会报 `bad interpreter`。
14
+
15
+ 二进制文件(图片、字体、PDF)不按文本规则处理,也不要让 Git 做行尾转换。
16
+
17
+ ## 权威与工具
18
+
19
+ - 仓库根的 `.gitattributes` 管提交与检出时的行尾,`.editorconfig` 管编辑器写入时的编码、行尾与空白。两份文件冲突时以 `.gitattributes` 为准,并同轮修正 `.editorconfig`。
20
+ - 新建文件前先看根 `.editorconfig` 是否已覆盖该扩展名;没有就用编辑器显式设成 UTF-8、LF。
21
+ - 提交前跑 `git diff --check`,它会拦下行尾空白与冲突标记;行尾本身由 `.gitattributes` 保证。
22
+ - 不要用 `git add --renormalize .` 批量改行尾:它会把无关文件一起带进提交。只改本次动到的文件。
23
+ - 不用 PowerShell 5.1 的 `Out-File`、`Set-Content -Encoding utf8` 写中文文件,它们会加 BOM;用编辑器或 Python 显式写 `encoding="utf-8", newline="\n"`。
24
+
25
+ ## 症状与处置
26
+
27
+ | 症状 | 先查 | 处置 |
28
+ |---|---|---|
29
+ | 中文变乱码特征串 | 文件是否被按错误编码重读 | 从 Git 可读版本恢复后重做修改,不对已乱码文本反向转码 |
30
+ | 文件头出现 `\ufeff` | 编辑器是否加了 BOM | 用无 BOM 方式重写整个文件 |
31
+ | 每行末尾多出 `^M` | 是否在 Windows 上按 CRLF 保存 | 统一转回 LF;`.bat`/`.cmd` 保持 CRLF |
32
+ | `bash: ...: /usr/bin/env: bad interpreter` | `.sh` 是否为 CRLF | 转成 LF 后重新提交 |
33
+ | `git diff` 整文件重写 | 行尾或 BOM 被批量改动 | 先恢复,再只改目标段落 |
34
+
35
+ 渲染侧的中文乱码排查见 `quarto/render.md`「5. 中文乱码/编码」。
@@ -2,7 +2,7 @@
2
2
 
3
3
  本文件记录 `content/**/*.qmd` 中 Mermaid 图表的渲染层约定;是否使用图表的门槛见 `writing-quarto` 技能的 P0 硬约束,主题侧取色与排版守卫见 `designing-theme` 技能的 `../designing-theme/assets/theme/css/mermaid.css`。
4
4
 
5
- Mermaid 只承担流程图、分层图与调用链;坐标轴类网格图(状态面板行列、二维下标)走 `rendering-coords.py` 加 `{python}` 可执行单元,分工与写法见`quarto/coords.md`,禁止用 Mermaid 硬画网格。
5
+ Mermaid 只承担流程图、分层图与调用链;坐标轴类网格图(状态面板行列、二维下标)走 `rendering-coords.py` 加 `{python}` 可执行单元,分工与写法见 `quarto/coords.md`,禁止用 Mermaid 硬画网格。
6
6
 
7
7
  ## 只使用 {mermaid} 围栏
8
8
 
@@ -0,0 +1,86 @@
1
+ # 中英混排与中文润色
2
+
3
+ > 速查:中文句用中文标点 · 英文句子内部保留英文标点 · 中西文之间一个半角空格 · 数字与单位之间一个空格 · 行内代码只标记要逐字识别的对象
4
+
5
+ 本文件是标点、空格、引号、数字和英文术语写法的唯一出处;句子结构与用词仍归 `steps/05-sentences.md` 与 `steps/06-wording.md`,版式列表与加粗归 `steps/07-layout.md`。标点依据 GB/T 15834—2011 与 W3C CLREQ,空格与润色取舍是本仓约定。
6
+
7
+ ## 一条主轴
8
+
9
+ 先保住事实、数字、条件、范围和归属,再改句子,最后才动标点。润色不是重写:原句已经自然准确就不改(叶圣陶「可改可不改则不改」);要改就改到读者能更快拿到动作与结果,不靠形容词抬高语气。
10
+
11
+ ## 标点
12
+
13
+ - 中文句子用全角标点:`,` `。` `;` `:` `?` `!` `、` `……` `——`。
14
+ - 完整英文句子、英文引文、代码、命令、URL 与文件路径内部保留半角标点,不改写。
15
+ - 中文句子里不混入半角 `,` `.` `;` `:` `?` `!`;版本号、时间、比例、坐标和代码例外。
16
+ - 中文引号先双后单:`“……”`,内层 `‘……’`;英文引文用英文引号;代码字符串保留源码引号。
17
+ - 中文内容的括号用全角 `()`;API、代码、英文缩写内部用半角 `()`;不中英括号混用。
18
+ - 破折号用 `——`,省略号用 `……`;不写 `--`、`...`。
19
+ - 书名号用 `《》`,内层用 `〈〉`。
20
+ - 冒号只用于引出列表、代码、图或结论;词条式冒号按 `steps/04-paragraphs.md`「散文伪标签冒号禁令」改写。
21
+
22
+ ## 空格
23
+
24
+ - 中文与拉丁字母、数字之间加一个半角空格:`使用 Quarto 渲染`、`共 9 格`。
25
+ - 中文与行内代码之间加一个半角空格;代码与中文标点之间不留空格:`调用 \`ApplyMove\`,返回 \`kRejected\`。`
26
+ - 中文标点前后不加空格;行首、行尾不留空格。
27
+ - 数字与单位之间加一个半角空格:`10 GB`、`3 s`;百分号紧贴数字:`20%`。
28
+ - 英文缩写与中文之间同样加空格:`使用 API 时`。
29
+ - 不为凑空格拆行,也不手写 ` ` 或不换行空格字符。
30
+
31
+ ## 引号与术语
32
+
33
+ - 术语首次出现写「中文译名(English original)」,后文统一用中文或原文,全书只选一种。
34
+ - API、类型、函数、参数、命令、路径和取值一律用行内代码,不翻译、不改大小写。
35
+ - 英文句子独立成句时,句末用英文标点;中文句子里夹一个英文词时,句末仍用中文标点。
36
+ - 不用全角拉丁字母或数字;不用中文引号包代码;不在术语中间插入空格。
37
+
38
+ ## 数字、单位与范围
39
+
40
+ - 数据用阿拉伯数字;概数与成语用汉字(`三四个`、`九宫格`)。
41
+ - 范围用 `~` 或「到」:`10~20`;不用半角连字符连接中文数字范围。
42
+ - 版本号、坐标、代码里的数字保持源码形式,不补空格、不换全角。
43
+ - 单位符号与数字之间加空格;角度、百分比按行业习惯,同一本书内保持一致。
44
+
45
+ ## 去套话
46
+
47
+ - 删「进行/作出+名词」「值得注意的是」「不难发现」「综上所述」「首先、其次、最后」的堆叠。
48
+ - 少用「被」和长「的」链;一句一个动作,主语尽量是领域对象,不用「我们」代替读者。
49
+ - 不写「本文将介绍」「下面我们来看」;直接给读者要做的动作和看得见的结果。
50
+ - 同一事实只留一处:标题、段首、块后不互相复述。
51
+ - 英文术语不堆叠;能用中文说清就不夹英文,必须夹时首次给原文。
52
+
53
+ ## 让句子有信息量
54
+
55
+ 润色要的「灵性」不靠形容词,靠三件事:主语是具体对象,动词是具体动作,读完能看见结果。
56
+
57
+ - 删掉章节行程,直接给对象和它回答的问题。
58
+ - 原句:这一章介绍棋盘类的设计,首先看成员,然后看落子,最后看胜负判定。
59
+ - 改写:棋盘只保存九个格子。落子、满盘、成线与赢家都由它回答。
60
+ - 把「进行校验」「负责计算」换成调用方看得见的动作与返回值。
61
+ - 原句:程序会对输入进行校验,如果坐标不合法就会返回错误。
62
+ - 改写:坐标越界、格子被占用或对局已结束时,`TryPlace` 返回 `kRejected`,棋盘不变。
63
+ - 主语落在领域对象上,不落在「我们」「本章」。
64
+ - 原句:这个函数负责计算当前局面下电脑应该落子的位置。
65
+ - 改写:`Choose` 收下当前对局,交出一个 `Move`。
66
+ - 一段里留一句短句(20 字以内);连续三句长度相近就拆开或合并,让节奏有起伏。
67
+ - 比喻只在能缩短解释时用一次,不叠加形容词。
68
+
69
+ ## 检查表
70
+
71
+ - 中文句里是否混入半角标点;英文句子里是否被改成全角。
72
+ - 中西文边界是否正好一个半角空格;中文标点前后是否多了空格。
73
+ - 引号、括号、书名号是否成对;代码与标点之间是否留了多余空格。
74
+ - 一句是否只做一件事;40 字以上是否该拆;删掉修饰词后信息是否不变。
75
+ - 段首是否用「这一章」「接下来」「首先」代替了具体对象。
76
+ - 是否出现「进行」「负责」「完成」加名词的空心动作,能换成具体动词吗。
77
+ - 段内是否至少有一句 20 字以内的短句。
78
+ - 首次出现的英文术语是否给了中文,后文是否统一。
79
+
80
+ ## 依据
81
+
82
+ - W3C《中文排版需求》(CLREQ):https://www.w3.org/TR/clreq/
83
+ - GB/T 15834—2011《标点符号用法》
84
+ - 中文文案排版指北:https://github.com/sparanoid/chinese-copywriting-guidelines
85
+ - 中文技术文档的写作规范:https://github.com/ruanyf/document-style-guide
86
+ - 叶圣陶《评改两篇作文》、朱光潜《谈文学》的修改观
@@ -4,7 +4,7 @@
4
4
 
5
5
  > 速查:外观选项集中在根目录配置的格式块下 · 目录收至三级标题放右侧 · 本书不用行号、代码块不折叠。自测答案使用 `.answer` 并渲染为原生 details
6
6
 
7
- 选项语义、作用域层级与生效边界的唯一出处是本文件与`steps/02-structure.md`(宽度与节奏);本文件只留本书的取值和写作口径:
7
+ 选项语义、作用域层级与生效边界的唯一出处是本文件与 `steps/02-structure.md`(宽度与节奏);本文件只留本书的取值和写作口径:
8
8
 
9
9
  ### 本书的现行取值
10
10
 
@@ -12,8 +12,8 @@
12
12
 
13
13
  | 选项 | 取值 | 备注 |
14
14
  |---|---|---|
15
- | `theme` | `light: [cosmo, palettes/github/theme-light.scss]` + `dark: [darkly, …]` | 内置主题与项目样式叠加,顺序决定覆盖关系 |
16
- | `highlight-style` | `light:`/`dark:` 指向 `palettes/github/highlight-light.theme` / `highlight-dark.theme` 两份主题文件路径 | 明暗分别指定,与 `palettes/github/meta.md` 同步,语义颜色交给主题文件,CSS 不覆盖 token |
15
+ | `theme` | `light: [cosmo, theme/palettes/flexoki/theme-light.scss]` + `dark: [darkly, theme/palettes/flexoki/theme-dark.scss]` | 内置主题与项目样式叠加,顺序决定覆盖关系;Flexoki 是编译默认 |
16
+ | `highlight-style` | `light:`/`dark:` 指向 `theme/palettes/flexoki/highlight-light.theme` / `highlight-dark.theme` | 明暗分别指定,与 `palettes/flexoki/meta.md` 同步;Solarized 的语法色由 `theme/palettes/solarized/syntax.css` 在 `html[data-palette="solarized"]` 下覆盖,不改这里 |
17
17
  | `filters` | `scripts/answering-disclosure.lua`(顶层 `filters:`) | 将正文 `.answer` 转为默认收起的原生 `details` |
18
18
  | `toc` / `toc-depth` / `toc-location` | `true` / `3` / `right` | 右侧目录最多到 H3,窄屏会折叠,不作唯一定位手段 |
19
19
  | `number-sections` | `false` | 因此标题不手填序号,见 `quarto/basics.md` |
@@ -28,12 +28,12 @@
28
28
  1. 改 `format: html:` 任何取值都属于主题级改动,会触发整本渲染,先确认代价再走 `quarto render`。
29
29
  2. 新增或删减主题样式表(`.agents/skills/designing-theme/assets/theme/css/**` 或书内 `theme/css/**`)时,同步修改配置里的样式表清单,否则新样式不参与渲染。
30
30
  3. 页面视觉问题(提示符配色、文件名条、术语色)改 `.agents/skills/designing-theme/assets/theme/**` 或书内 `theme/**` 与设计令牌,不在文档里内联样式,也不改高亮配置。主题系统详见 `../designing-theme/references/theme-system.md`。
31
- 4. 流程图使用 `{mermaid}` 属性围栏,配色由主题样式控制。配置里不指定图表主题名;围栏与 init 指令细则见`quarto/mermaid.md`。
31
+ 4. 流程图使用 `{mermaid}` 属性围栏,配色由主题样式控制。配置里不指定图表主题名;围栏与 init 指令细则见 `quarto/mermaid.md`。
32
32
  5. 拿不准选项名、默认值或嵌套层级时查官方参考页,不凭记忆写 YAML(入口见本文件 #8)。
33
33
 
34
34
  ### 验证
35
35
 
36
- 渲染后确认:目录深度与位置符合预期、明暗两套高亮都可读。渲染产物结构由 `checking-output.py` 与 `checking-callouts.py`自动核对;页面宽度与视觉依据见`steps/02-structure.md`。主题或目录看起来没生效时先硬刷新排除缓存,再核对选项嵌套层级。
36
+ 渲染后确认:目录深度与位置符合预期、明暗两套高亮都可读。渲染产物结构由 `checking-output.py` 与 `checking-callouts.py` 自动核对;页面宽度与视觉依据见 `steps/02-structure.md`。主题或目录看起来没生效时先硬刷新排除缓存,再核对选项嵌套层级。
37
37
 
38
38
  ## 渲染与发布排查索引
39
39
 
@@ -67,6 +67,7 @@
67
67
  - **症状**:中文变成乱码特征串,或文件带 BOM、行尾变 CRLF。
68
68
  - **处置**:改 `.qmd` 或规范文档后先跑 `verifying-content.py`。失败时从 Git 可读版本恢复再重做修改,**不要**对已乱码文本反向转码。用 `verifying-content.py` 复查结构,并在编辑器里确认 UTF-8 无 BOM。
69
69
  - **注意**:PowerShell 5.1 的 `Out-File`/`Set-Content -Encoding utf8` 会附带 BOM,需显式无 BOM 或改用 Python 写入。
70
+ - 编码与行尾的完整规则见 `quarto/encoding.md`;本文件只处理渲染后的症状。
70
71
 
71
72
  ### 6. 渲染失败排查顺序
72
73
 
@@ -113,17 +114,17 @@
113
114
  ### 13. `{{< include >}}` 引用代码文件未加属性围栏 → 乱码式排版、目录被污染
114
115
 
115
116
  - **症状**:渲染出的脚本失去高亮与等宽底色,`#` 注释行变成大号标题,含 `*`、`_` 的行变成斜体或粗体,右侧目录多出假标题。
116
- - **处置**:`{{< include >}}` 整体放进 `{.cpp filename="main.cpp"}` 形式的属性围栏,按扩展名选语言并把 `filename` 写成真实文件名短名,**没有一个例外**。规则见 `quarto/authoring.md`「代码与媒体」;include 的使用边界见`quarto/render.md`。
117
+ - **处置**:`{{< include >}}` 整体放进 `{.cpp filename="main.cpp"}` 形式的属性围栏,按扩展名选语言并把 `filename` 写成真实文件名短名,**没有一个例外**。规则见 `quarto/authoring.md`「代码与媒体」;include 的使用边界见 `quarto/render.md`。
117
118
 
118
119
  本文件记录本书 `content/**/*.qmd` 的渲染层约定,供 Agent 编写和评审章节时使用;写作层骨架与元素规则见 `steps/` 下的步骤文件。
119
120
 
120
121
  ## include 短代码必须包在围栏代码块内
121
122
 
122
- 展示源码默认**内联摘录片段**(片段规则见`steps/03-blocks.md`,生效);include 是可选手段,仅用于确实需要完整展示且很短的文件。仍在使用 include 时,必须包在围栏代码块内。
123
+ 展示源码默认**内联摘录片段**(片段规则见 `steps/03-blocks.md`,生效);include 是可选手段,仅用于确实需要完整展示且很短的文件。仍在使用 include 时,必须包在围栏代码块内。
123
124
 
124
125
  `{{< include <文件> >}}` 裸用(不包代码块)时,Quarto 把文件内容当作 Markdown 正文渲染——换行丢失、`#===` 横幅被解析为 Markdown 标记,最终在 HTML 中变成一串 `<p>` 段落,代码结构完全破坏。
125
126
 
126
- 正确写法是包在带语言标注的围栏代码块内([官方文档](https://quarto.org/docs/authoring/includes.html)给出了同样模式):
127
+ 正确写法是包在带语言标注的围栏代码块内([官方文档](https://quarto.org/docs/authoring/includes.html) 给出了同样模式):
127
128
 
128
129
  ````markdown
129
130
  ```python
@@ -140,26 +141,26 @@
140
141
 
141
142
  qmd 指向仓库内路径的链接仍**一律使用 GitHub 绝对链接**,不使用相对路径链接;锚文本与外链按下列规则执行。
142
143
 
143
- - 章节互引:用章节 title 作链接文字,`.qmd` 相对路径(规则见`steps/06-wording.md`);
144
+ - 章节互引:用章节 title 作链接文字,`.qmd` 相对路径(规则见 `steps/06-wording.md`);
144
145
  - 仓库内目录:`https://github.com/your-org/your-book/tree/main/<路径>`,锚文本用简短中文描述(如「最小工程目录」);
145
146
  - 仓库内文件:`https://github.com/your-org/your-book/blob/main/<路径>`,锚文本用中文描述或专名文件名(如「构建规则 CMakeLists.txt」「main.cpp」);
146
- - 锚文本不写路径结构:`src/` 这类层级不进锚文本;完整路径只出现在 GitHub URL、目录树和确需精确指路的行文里,不进代码块 filename(filename 一律短名,见`steps/03-blocks.md`);
147
+ - 锚文本不写路径结构:`src/` 这类层级不进锚文本;完整路径只出现在 GitHub URL、目录树和确需精确指路的行文里,不进代码块 filename(filename 一律短名,见 `steps/03-blocks.md`);
147
148
  - 行文叙述少用行内代码路径指代目录:正文指向仓库内目录或文件时,首次出现处用中文锚文本的 GitHub 链接,此后用中文短指称;行内代码路径只保留在目录树与目录映射表格,正文里的实现目录用 GitHub 链接(模板见 `quarto/authoring.md`);
148
149
  - 外部官方文档非必要不链接:命令与概念默认用行内代码加正文一句话讲清;引用第三方内容注明出处与章末参考资料清单是外链的合法位置;
149
150
  - 全路径在行文首次出现后改用中文短指称(工程目录、一键脚本、构建规则),不重复全路径;
150
151
  - 跨仓锚文本禁止「写法依据见 / 依据见 / 机制见 / 选型见 / 承诺见 / 用法见 / 陷阱见」式;默认不挂链,可选尾置用「若要系统阅读…」;细则见 `writing-quarto` 技能 `steps/01-task.md`「叙事范围(硬边界)」;
151
152
  - 新增链接后渲染检查 HTML:锚文本与 URL 对应、无相对路径仓库链接混入(章节互引除外);
152
- - 正文与代码块 filename 标注不引用 `.agents/` 内部路径:读者所需的解释就地写清,仓库内路径一律链 GitHub;内部知识路径的读者/作者分离依据见`steps/03-blocks.md`「内容块前后的闭环」;
153
+ - 正文与代码块 filename 标注不引用 `.agents/` 内部路径:读者所需的解释就地写清,仓库内路径一律链 GitHub;内部知识路径的读者/作者分离依据见 `steps/03-blocks.md`「内容块前后的闭环」;
153
154
  - 页面级 GitHub 入口只有「查看源码」:`_quarto.yml` 的 `book.repo-actions` 钉为 `[source]`,不开放编辑与议题按钮(取舍见 `quarto/render.md`)。
154
155
 
155
156
  ## 章节结构约定的归属
156
157
 
157
158
  章节骨架(无标题引言、任务序列、常见错误、自测问题、本章回顾)、标题字数与教学元素写法统一由 `steps/` 下的步骤文件维护,按下表查阅:
158
159
 
159
- - 见`steps/02-structure.md`:六段骨架、引言职责边界、H2/H3 门槛、术语策略;
160
- - 见`steps/02-structure.md`:title 与二三级标题的标题字数(动词短语、无冒号)与纵向承诺链;
161
- - 见`steps/03-blocks.md`:代码块 filename 标注、盒子密度、Callout、目录树、多命令块;
162
- - 见`examples/06-wording-cases.md`:措辞替换与术语节奏;句段对照见 `examples/05-sentence-frame.md`;
163
- - 见`steps/02-structure.md`:小节主线收束与信息分层。
160
+ - 见 `steps/02-structure.md`:六段骨架、引言职责边界、H2/H3 门槛、术语策略;
161
+ - 见 `steps/02-structure.md`:title 与二三级标题的标题字数(动词短语、无冒号)与纵向承诺链;
162
+ - 见 `steps/03-blocks.md`:代码块 filename 标注、盒子密度、Callout、目录树、多命令块;
163
+ - 见 `examples/06-wording-cases.md`:措辞替换与术语节奏;句段对照见 `examples/05-sentence-frame.md`;
164
+ - 见 `steps/02-structure.md`:小节主线收束与信息分层。
164
165
 
165
166
  本文件只维护 include 包裹与链接使用两条渲染层约定。
@@ -15,7 +15,7 @@
15
15
 
16
16
  后续命令依赖前一条命令的输出时,正文必须说明从输出中复制什么、如何用它完成占位符替换,以及什么时候执行下一条命令。不能只写「记下名称后再安装」,否则新手需要自行判断取值对象和替换位置。
17
17
 
18
- 恢复后的可观察状态本身需要拆解说明,并且其后没有必经动作时,可以用结果型 Callout 承接精确判据和说明列表。正文仍要先保留检查动作。结果型 Callout 的边界见`steps/03-blocks.md`。
18
+ 恢复后的可观察状态本身需要拆解说明,并且其后没有必经动作时,可以用结果型 Callout 承接精确判据和说明列表。正文仍要先保留检查动作。结果型 Callout 的边界见 `steps/03-blocks.md`。
19
19
 
20
20
  ## 代码块前的标点
21
21
 
@@ -37,7 +37,7 @@
37
37
 
38
38
  命令块只放能直接复制执行的命令,以及紧贴在命令上方的原生注释。不加 `$ ` 或 `PS>` 提示符,不在命令行末尾追加注释。每个代码块在首条命令上方写一条总注释,说明整块要做什么。只有单个依赖或用途不明显、容易误用时,才在该命令上方补一行子注释。输出放在紧随其后的 `text` 块中,命令块与输出块之间只留一个空行。
39
39
 
40
- 代码块注释一行只承担一个职责。总注释和子注释都用短句,不用中文冒号或分号串联多个动作。片段内注释硬限(每处 ≤2 行、单行 ≤100 列,与源文件 `ColumnLimit` 同一口径)见`steps/03-blocks.md`。代码块中不使用 Markdown 强调符号。
40
+ 代码块注释一行只承担一个职责。总注释和子注释都用短句,不用中文冒号或分号串联多个动作。片段内注释硬限(每处 ≤2 行、单行 ≤100 列,与源文件 `ColumnLimit` 同一口径)见 `steps/03-blocks.md`。代码块中不使用 Markdown 强调符号。
41
41
 
42
42
  标点规则只作用于正文、标题、表格和列表,行内代码与代码块内部照抄真实语法。把多条命令串进一句话,读者无法判断该复制哪一行,应当拆成独立的代码块或独立句子。留在同一块内的多条命令职责不同时,逐条写子注释说明各自用途;读者只需执行其中一条时,拆成独立代码块,并在正文写明先执行哪条、什么情况下改用另一条。多命令块后的逐条讲解用无序列表(格式见 `steps/07-layout.md`「列表选择」)。
43
43
 
@@ -81,7 +81,7 @@
81
81
 
82
82
  常见错误放在本章回顾之前,`## 常见错误` 负责导航。每个故障用一个描述现象的 `###`,标题后的第一句同时说明触发条件与可观察现象。条目按故障性质分两种形态:
83
83
 
84
- - **误用型条目**(接口或状态的用法错误,如传错枚举值、想绕开封装):默认一段成文,一句话写全「触发条件与现象:原因与正确做法」,验证信息并入现象句或做法句,不设加粗步骤;原因与做法各需一句完整交代时(如原因牵涉私有段的设计动机),改用症状句导语加两项引导词列表——首句只写触发条件与现象,列表项为「**出错的原因**」「**正确的做法**」,格式见 `steps/07-layout.md`「列表选择」(示例章绕过下标换算条目为对照);列表可作为节导语的合法收尾,三级导语预算只约束症状句。篇幅按`steps/02-structure.md` 的预算执行。
84
+ - **误用型条目**(接口或状态的用法错误,如传错枚举值、想绕开封装):默认一段成文,一句话写全「触发条件与现象:原因与正确做法」,验证信息并入现象句或做法句,不设加粗步骤;原因与做法各需一句完整交代时(如原因牵涉私有段的设计动机),改用症状句导语加两项引导词列表——首句只写触发条件与现象,列表项为「**出错的原因**」「**正确的做法**」,格式见 `steps/07-layout.md`「列表选择」(示例章绕过下标换算条目为对照);列表可作为节导语的合法收尾,三级导语预算只约束症状句。篇幅按 `steps/02-structure.md` 的预算执行。
85
85
  - **排查型故障**(环境或运行时问题,需要动手定位,如流状态、动态库加载失败):正文只保留「定位 → 修复 → 验证」三个有序步骤。
86
86
 
87
87
  排查型三步中,定位步骤只放收敛问题所需的最小检查,先确认执行位置与前置状态,再检查故障本身。确认执行位置用一条可观察的判据,例如用 `pwd` 确认当前目录以阶段目录结尾,或用 `ls CMakeLists.txt` 确认当前位于工程根目录。修复步骤必须复用定位得到的具体对象,并提供回到成功路径的动作。验证步骤给出一个可观察结果。修复动作必须与定位得到的故障对象一致:清理目标产物不能替代清除 CMake 配置缓存,排查缓存或工具链问题时也不顺带更换构建类型。
@@ -18,8 +18,8 @@
18
18
  否则移动端永远无法复制代码。
19
19
  C3 打印不隐藏代码:@media print 内不得对 .code-copy-outer-scaffold 设 display:none。
20
20
  (该层现在包裹代码本身,隐藏它 = 打印/PDF 时代码整块消失。)
21
- C4 站点图标:每个 HTML 的 <head> 必须含 rel="icon" 且指向 favicon.svg,
22
- 且该图标文件确实被发布到产物目录。
21
+ C4 站点图标:每个 HTML 的 <head> 必须含 rel="icon" 且指向 favicon-light.svg
22
+ 或 favicon-dark.svg(编译期默认是 light),且两个色板的明暗图标都已发布。
23
23
  C5 Mermaid 图表(按产物条件):产物没有 mermaid-js 占位符,说明正文本就不用图表,
24
24
  契约 N/A。一旦出现占位符,就必须同时包含 Quarto Mermaid 运行时,且不得退化为
25
25
  普通 sourceCode 代码块。浏览器加载脚本后,占位符会被转换成 SVG。
@@ -28,7 +28,8 @@
28
28
  C7 代码块视觉契约:普通文本代码块与语言代码块必须共用代码背景、边框、
29
29
  字体和布局令牌,避免两套代码块样式分叉。
30
30
  C8 代码来源标题:QMD 代码块必须由 .code-with-filename 包裹,且主题必须提供
31
- 标题背景、文字和间距令牌。标题条不能退化为普通代码块。
31
+ 标题背景、文字和间距令牌。标题条不能退化为普通代码块。自定义组件里的
32
+ <pre>(没有 <code> 子节点)不算代码来源块。
32
33
  C9 可折叠答案:产物中的 details.answer-disclosure 存在时,必须默认收起,
33
34
  摘要必须等于“查看答案”,且答案区不得混入标题层级;没有答案块时为 N/A。
34
35
 
@@ -300,11 +301,17 @@ def check_contracts(book_dir, htmls, css_pairs, root=None, require_favicon=True)
300
301
  missing = []
301
302
  for path, _tree, link_rels in htmls:
302
303
  rels = [(r, h) for r, h in link_rels if "icon" in r]
303
- if any("favicon.svg" in h for r, h in rels):
304
+ if any("favicon-light.svg" in h or "favicon-dark.svg" in h for r, h in rels):
304
305
  icon_pages += 1
305
306
  else:
306
307
  missing.append(str(path.relative_to(book_dir)))
307
- icon_file = any(p.name == "favicon.svg" for p in book_dir.rglob("favicon.svg"))
308
+ icon_files = [p for p in book_dir.rglob("favicon-*.svg")]
309
+ icon_names = {p.name for p in icon_files}
310
+ icon_palettes = {p.parent.name for p in icon_files}
311
+ icon_file = (
312
+ {"favicon-light.svg", "favicon-dark.svg"} <= icon_names
313
+ and {"flexoki", "solarized"} <= icon_palettes
314
+ )
308
315
  if not require_favicon:
309
316
  results.append((
310
317
  "C4", "站点图标已注入并发布", True,
@@ -313,15 +320,16 @@ def check_contracts(book_dir, htmls, css_pairs, root=None, require_favicon=True)
313
320
  ))
314
321
  else:
315
322
  c4 = icon_pages == len(htmls) and icon_file and bool(htmls)
316
- summary = "%d/%d 页含 icon 链接,图标已发布=%s" % (icon_pages, len(htmls), icon_file)
323
+ summary = "%d/%d 页含 icon 链接,四份色板图标已发布=%s" % (icon_pages, len(htmls), icon_file)
317
324
  if missing:
318
325
  summary += ";缺链接: " + ", ".join(missing[:3])
319
326
  if len(missing) > 3:
320
327
  summary += " …"
321
328
  results.append((
322
329
  "C4", "站点图标已注入并发布", c4, summary,
323
- ["每页 <head> 需 <link rel=\"icon\" … favicon.svg>;源文件见 theme/assets/favicon.svg,"
324
- "由 .agents/skills/agent-workspace/maintaining-python/scripts/maintenance/generating-favicon.py 生成"],
330
+ ["每页 <head> 需 <link rel=\"icon\" … favicon-light.svg 或 favicon-dark.svg>;"
331
+ "四份源文件见 theme/palettes/{flexoki,solarized}/favicon-{light,dark}.svg,"
332
+ "book.favicon 指 Flexoki light,另外三份随 resources 发布"],
325
333
  ))
326
334
 
327
335
  # ---------- C5 Mermaid ----------
@@ -436,6 +444,10 @@ def check_contracts(book_dir, htmls, css_pairs, root=None, require_favicon=True)
436
444
  continue
437
445
  if node.classes & {"mermaid", "mermaid-js"}:
438
446
  continue
447
+ # Pandoc 生成的源码块一定带 <code> 子节点;交互组件里的终端输出
448
+ # 直接把文本放进 <pre>,不是代码来源块,不该按 C8 判定。
449
+ if not any(child.tag == "code" for child in walk(node)):
450
+ continue
439
451
  untitled.append(str(path.relative_to(book_dir)))
440
452
  title_tokens = all(token in source_css_text for token in (
441
453
  "--code-title-bg", "--code-title-fg", "--code-title-font-size", "--code-title-padding",
@@ -91,11 +91,15 @@ def parse_frontmatter_title(front: str) -> str:
91
91
  def parse_chapters(quarto_yml: Path) -> list[str]:
92
92
  """Return chapter hrefs in declaration order.
93
93
 
94
- Supports the two forms Quarto Book uses:
94
+ Supports the forms Quarto Book uses:
95
95
  chapters:
96
96
  - index.qmd
97
97
  - href: content/part/01-intro.qmd
98
- It deliberately does not parse part titles as chapters.
98
+ - part: content/part/index.qmd
99
+ chapters:
100
+ - content/part/01-intro.qmd
101
+ `part:` 带标题时只是分组标题,不带 .qmd 后缀,因此不会被当成章节;带文件时,
102
+ 该文件是分组落地页,也要接受内容检查。嵌套的 `chapters:` 键本身不是章节。
99
103
  """
100
104
  if not quarto_yml.is_file():
101
105
  return []
@@ -114,7 +118,12 @@ def parse_chapters(quarto_yml: Path) -> list[str]:
114
118
  if not stripped.startswith("-"):
115
119
  continue
116
120
  item = stripped[1:].strip()
117
- href = re.sub(r"^href:\s*", "", item).strip().strip("'\"")
121
+ key, sep, value = item.partition(":")
122
+ if sep and re.fullmatch(r"[a-z_]+", key.strip()):
123
+ # 只接受会落到页面的键:href 与 part 的文件形式。
124
+ href = value.strip().strip("'\"") if key.strip() in {"href", "part"} else ""
125
+ else:
126
+ href = item.strip("'\"")
118
127
  if href.endswith(".qmd"):
119
128
  chapters.append(href)
120
129
  return chapters
@@ -47,13 +47,13 @@
47
47
 
48
48
  ### 定任务:先让新人完成任务
49
49
 
50
- - 开篇场景的写法见`steps/02-structure.md`「六段块序列」。
51
- - 每页一条成功路径与后置内容的判定见`steps/06-wording.md`;主线闭合见`steps/02-structure.md`。
52
- - 标准术语的首次解释与术语卡落点见`steps/02-structure.md`(写法见 `quarto/authoring.md`);缩写先写全称。
50
+ - 开篇场景的写法见 `steps/02-structure.md`「六段块序列」。
51
+ - 每页一条成功路径与后置内容的判定见 `steps/06-wording.md`;主线闭合见 `steps/02-structure.md`。
52
+ - 标准术语的首次解释与术语卡落点见 `steps/02-structure.md`(写法见 `quarto/authoring.md`);缩写先写全称。
53
53
  - 不假设读者知道工具名、命令参数、目录布局或错误输出代表的含义。
54
- - 目录式堆砌禁令与清单下沉判据见`steps/02-structure.md`。
55
- - 标题与引言的单事承诺、承诺用词与 title 变更同步见`steps/02-structure.md`。
56
- - 语言课禁令、否定式预告、不写「下一节」都在这一步判:它们决定本章能不能出现某句,不是措辞问题(细则见`steps/05-sentences.md`「句子规则」、本文件「叙事范围」)。
54
+ - 目录式堆砌禁令与清单下沉判据见 `steps/02-structure.md`。
55
+ - 标题与引言的单事承诺、承诺用词与 title 变更同步见 `steps/02-structure.md`。
56
+ - 语言课禁令、否定式预告、不写「下一节」都在这一步判:它们决定本章能不能出现某句,不是措辞问题(细则见 `steps/05-sentences.md`「句子规则」、本文件「叙事范围」)。
57
57
 
58
58
  ## 情况
59
59
 
@@ -37,12 +37,12 @@
37
37
 
38
38
  读者在正文里依次确认来对了地方、完成可验证的动作、理解关键关系并确认获得的能力。各段服务一个认知结果,顺序由「读者先要知道什么才能看懂下一步」决定。
39
39
 
40
- **章际衔接(定结构检查项)**:第 N 章的引言、任务节与自测题只用第 1..N-1 章已建立的名字与概念;本章新术语在首次真正使用处就近落术语卡或行内括号;术语卡的升级判据见 `writing-quarto` 技能 `quarto/authoring.md`「Callout 升级判据」,写法见`steps/03-blocks.md`。某概念接不上前章已建立的名字时,把它下沉回首次使用它的章建立,不在本章临时补课。
40
+ **章际衔接(定结构检查项)**:第 N 章的引言、任务节与自测题只用第 1..N-1 章已建立的名字与概念;本章新术语在首次真正使用处就近落术语卡或行内括号;术语卡的升级判据见 `writing-quarto` 技能 `quarto/authoring.md`「Callout 升级判据」,写法见 `steps/03-blocks.md`。某概念接不上前章已建立的名字时,把它下沉回首次使用它的章建立,不在本章临时补课。
41
41
 
42
- - **无标题引言**:第一个 `##` 之前,写成**连贯读者文**回答读者三问——从哪来(承接上一章已成立的结果)、这一章做什么(本章要解决的问题与读者将获得的能力,正面陈述;范围能并则并,不写否定式后章预告)、代码在哪(可选:若本章有主源文件,用**同段末句**自然语言点名并挂全章 blob 链接,不另起「代码写在…里」独立段)。第一句写出谁在什么情况下做本章这件事,类章同时写出类名;类型怎么实现放到后面的句子。不另开背景节。**形态硬限(用户决定)**:首选**恰好 1 个自然段**(通常 2–4 句);必要时允许 **1 个自然段 + 1 个列表**(列表前引导句写在同一段末,或段落后紧跟列表;列表不算第二散文段);**禁止**出现两个散文自然段并立,更禁止 ≥3 段、单句孤儿段、结尾导航段。列表仅用于并列范围/对象,任务细节下沉正文 `##`,不用顿号串交付物冒充散文。**摘录免责句永不写进读者正文**:「本章摘录源码服务于讲解」「片段不保证与源文件逐字一致」「不等于文件内顺序」类作者旁白一律删除(旧「示例位置句开口子」已废止),同源保证交给 `verifying-content.py`;摘录免责只保留在 技能的权威文件与检查脚本里。不放 Callout,不写后续章节内容,不用「后面的 X」式前向指称引入后续章节才建立的结构件(如「实现放在后面的编号目录里」)。引言容纳多个独立概念时**并段或改列表**,禁止拆成两个散文段;拆分判据见`steps/04-paragraphs.md`「拆分判据」。内容量硬限:token 预算见本文件「分层上限」;范围边界能并入承接段时不成列表。承接中引用其他章节一律用章节标题链接,不用「第 N 章」;本章回顾的下一章预告不写链接,直述预告一句(页面导航已有前进按钮),两者均见`steps/06-wording.md`。任务概览默认并入承接句,正文小节就是任务的展开;预览列表仅当任务没有对应正文小节时使用(示例章四项工作列表已按此删除)。原 front matter `description` 的定位信息并入引言承接句,信息只保留引言一处、不同义两存;章节 qmd 不写 `description`(字段出处见 basics.md)。着陆页 `index` 按 landing 规则组织,不硬套本契约。
43
- - **任务序列**:每节一个可验证结果。判定标准是任务结束时存在一个读者能自己复述的检查动作;只有「读完了解释」的内容并入相邻任务。概念 → 最小示例 → 操作 → 验证 → 边界,先让读者看到行为再解释规则。各章的任务节以该章标题里的对象为准,不把每一章都写成「目录、设计、构建、测试」四节。设计范围以这一章能在 `src/` 里核对的源文件收束。内容量硬限:任务级 `##` 通常不超过 4 个;`##` 与 `###` 开头的承接句数见本文件「分层上限」,写完直接进入代码、命令或列表;超出即为凑字数信号,禁令见`steps/04-paragraphs.md`「凑字数禁令」。有 `###` 子节时,二级标题(`##`)的引言须承接上文;恰好 2 个子节时一句点一个,3 个或 4 个时不再逐个点名,点名交给三级标题的句式见本文件「标题分层」,点名用读者已认识的词,不点后文才定义的类型名;一句之内禁止把两个子节对象配成「由 X 定位,并保存 Y」「分别交给」式的两组对应(对照见`examples/05-sentence-frame.md`「拉链句」)。交付清单或纯边界说明不单独设 `##`,并入引言或相邻工程总览节;同一头文件中连续的值类型优先按一个可验证结果归并到同一任务节。任务节内的讲述顺序按「类型 → 简单函数 → 更难的函数」排列,最难的组装放在最后,并满足先定义后调用:读者要跟着读懂的行内代码标识符,其行为必须已经出现过——上一章、上文,或同一小节里紧挨着的声明和一句行为——上一章已建立的名字视为已知;未定义名字的调用链、节首概览与编号步骤整段删除。`##` 导语只用白话,不点后文才定义的函数名。章内顺序的章内顺序的依据见 `SKILL.md`「九步」的定结构一条,本文件不复述。
42
+ - **无标题引言**:第一个 `##` 之前,写成**连贯读者文**回答读者三问——从哪来(承接上一章已成立的结果)、这一章做什么(本章要解决的问题与读者将获得的能力,正面陈述;范围能并则并,不写否定式后章预告)、代码在哪(可选:若本章有主源文件,用**同段末句**自然语言点名并挂全章 blob 链接,不另起「代码写在…里」独立段)。第一句写出谁在什么情况下做本章这件事,类章同时写出类名;类型怎么实现放到后面的句子。不另开背景节。**形态硬限(用户决定)**:首选**恰好 1 个自然段**(通常 2–4 句);必要时允许 **1 个自然段 + 1 个列表**(列表前引导句写在同一段末,或段落后紧跟列表;列表不算第二散文段);**禁止**出现两个散文自然段并立,更禁止 ≥3 段、单句孤儿段、结尾导航段。列表仅用于并列范围/对象,任务细节下沉正文 `##`,不用顿号串交付物冒充散文。**摘录免责句永不写进读者正文**:「本章摘录源码服务于讲解」「片段不保证与源文件逐字一致」「不等于文件内顺序」类作者旁白一律删除(旧「示例位置句开口子」已废止),同源保证交给 `verifying-content.py`;摘录免责只保留在 技能的权威文件与检查脚本里。不放 Callout,不写后续章节内容,不用「后面的 X」式前向指称引入后续章节才建立的结构件(如「实现放在后面的编号目录里」)。引言容纳多个独立概念时**并段或改列表**,禁止拆成两个散文段;拆分判据见 `steps/04-paragraphs.md`「拆分判据」。内容量硬限:token 预算见本文件「分层上限」;范围边界能并入承接段时不成列表。承接中引用其他章节一律用章节标题链接,不用「第 N 章」;本章回顾的下一章预告不写链接,直述预告一句(页面导航已有前进按钮),两者均见 `steps/06-wording.md`。任务概览默认并入承接句,正文小节就是任务的展开;预览列表仅当任务没有对应正文小节时使用(示例章四项工作列表已按此删除)。原 front matter `description` 的定位信息并入引言承接句,信息只保留引言一处、不同义两存;章节 qmd 不写 `description`(字段出处见 basics.md)。着陆页 `index` 按 landing 规则组织,不硬套本契约。
43
+ - **任务序列**:每节一个可验证结果。判定标准是任务结束时存在一个读者能自己复述的检查动作;只有「读完了解释」的内容并入相邻任务。概念 → 最小示例 → 操作 → 验证 → 边界,先让读者看到行为再解释规则。各章的任务节以该章标题里的对象为准,不把每一章都写成「目录、设计、构建、测试」四节。设计范围以这一章能在 `src/` 里核对的源文件收束。内容量硬限:任务级 `##` 通常不超过 4 个;`##` 与 `###` 开头的承接句数见本文件「分层上限」,写完直接进入代码、命令或列表;超出即为凑字数信号,禁令见 `steps/04-paragraphs.md`「凑字数禁令」。有 `###` 子节时,二级标题(`##`)的引言须承接上文;恰好 2 个子节时一句点一个,3 个或 4 个时不再逐个点名,点名交给三级标题的句式见本文件「标题分层」,点名用读者已认识的词,不点后文才定义的类型名;一句之内禁止把两个子节对象配成「由 X 定位,并保存 Y」「分别交给」式的两组对应(对照见 `examples/05-sentence-frame.md`「拉链句」)。交付清单或纯边界说明不单独设 `##`,并入引言或相邻工程总览节;同一头文件中连续的值类型优先按一个可验证结果归并到同一任务节。任务节内的讲述顺序按「类型 → 简单函数 → 更难的函数」排列,最难的组装放在最后,并满足先定义后调用:读者要跟着读懂的行内代码标识符,其行为必须已经出现过——上一章、上文,或同一小节里紧挨着的声明和一句行为——上一章已建立的名字视为已知;未定义名字的调用链、节首概览与编号步骤整段删除。`##` 导语只用白话,不点后文才定义的函数名。章内顺序的章内顺序的依据见 `SKILL.md`「九步」的定结构一条,本文件不复述。
44
44
  - **常见错误**:服务失败后回来的读者。每个症状一个 `###`,标题后第一句写触发条件和可观察现象。误用型条目一段成文写原因与正确做法;原因与做法各需一句完整交代时(如原因牵涉私有段的设计动机),用症状句导语加「出错的原因/正确的做法」引导词列表,列表可作为节导语的合法收尾,导语预算只约束症状句;排查型故障展开定位 → 修复 → 验证三步。形态分野与细则是 `writing-quarto` 技能 `quarto/terminal.md`「常见错误条目形态与三步诊断流」。入门章节只保留最可能遇到的 2-3 项,不是完整 FAQ。
45
- - **自测问题**:服务刚跑通主线、需要确认理解的读者。每章 0-7 道题,题目问本章已经写明的一件可观察结果(会怎样、是哪一个、从几开始),没有这种结果就不设题;只有本章写了原因、而且情景已经说全时,才用「为什么」。题面用本章已经用过的词说全,不用本章未定义的概念,不问「为什么不做成另一种」;题干是合上书的一问,只看本题题干、不看答案与上一题;题干代词的判法见`steps/05-sentences.md`「代词不能代替未写出的对象」,允许「什么」——它在要一个名字或一句文字,不是指上文没出现的东西;题面里每个细节都要改变答案,答案不受细节影响时不单点某一种情形。题面只描述一个自洽局面,每个事实都要能同时成立,禁止把互相矛盾的局面写成题干(同一句里先说轮到甲方、又说这一步的用户是 O,读者听到的是程序自相矛盾,不是一次非法调用)——「轮到谁」和「这一步的用户」若是同一个对象,只写一次。要考拒绝,用正文已经用过的那条规则问可观察结果(正例:「空状态面板开局,轮到甲方。没轮到的一方来操作时,状态面板会改变吗?」,答案首句「不会。操作的用户不是当前用户,`Place` 返回 `kRejected`,状态面板和轮次都保持原样。」);不为了出题制造正文没走过的矛盾局面。一道题只问一件可观察结果,不把两个观察捆进同一题(如「状态面板是空的吗」与「轮到谁」并列),拆开或删去一个。固定导语「不要展开答案,试着自己把回答完整说出来,写完之后展开对照;说不出来的部分,回到对应小节对照正文。」;答案写在 `::: {.answer}` 围栏 div 内,由 `scripts/answering-disclosure.lua` 渲染为默认收起的原生 `<details>`;答案只使用本章已讲过的概念。题目同样必须能由本章正文回答:答案依据须是正文已写明的内容,正文没讲的概念不设题;若问题值得问,先在正文补上依据再设题。答案先答所问:首句直接回答题面,一到两句,不补题面之外的对比、延伸或重复题面(对照与归属由正文承载)。问答中的文件、路径与标识符指称统一用行内代码,不挂链接(`verifying-content.py` 对自测节链接记 WARN);所属目录在答案前文已确立时,路径可省去重复的顶层前缀(如先写 `example/`,后文写 `include/state.h`)。
45
+ - **自测问题**:服务刚跑通主线、需要确认理解的读者。每章 0-7 道题,题目问本章已经写明的一件可观察结果(会怎样、是哪一个、从几开始),没有这种结果就不设题;只有本章写了原因、而且情景已经说全时,才用「为什么」。题面用本章已经用过的词说全,不用本章未定义的概念,不问「为什么不做成另一种」;题干是合上书的一问,只看本题题干、不看答案与上一题;题干代词的判法见 `steps/05-sentences.md`「代词不能代替未写出的对象」,允许「什么」——它在要一个名字或一句文字,不是指上文没出现的东西;题面里每个细节都要改变答案,答案不受细节影响时不单点某一种情形。题面只描述一个自洽局面,每个事实都要能同时成立,禁止把互相矛盾的局面写成题干(同一句里先说轮到甲方、又说这一步的用户是 O,读者听到的是程序自相矛盾,不是一次非法调用)——「轮到谁」和「这一步的用户」若是同一个对象,只写一次。要考拒绝,用正文已经用过的那条规则问可观察结果(正例:「空状态面板开局,轮到甲方。没轮到的一方来操作时,状态面板会改变吗?」,答案首句「不会。操作的用户不是当前用户,`Place` 返回 `kRejected`,状态面板和轮次都保持原样。」);不为了出题制造正文没走过的矛盾局面。一道题只问一件可观察结果,不把两个观察捆进同一题(如「状态面板是空的吗」与「轮到谁」并列),拆开或删去一个。固定导语「不要展开答案,试着自己把回答完整说出来,写完之后展开对照;说不出来的部分,回到对应小节对照正文。」;答案写在 `::: {.answer}` 围栏 div 内,由 `scripts/answering-disclosure.lua` 渲染为默认收起的原生 `<details>`;答案只使用本章已讲过的概念。题目同样必须能由本章正文回答:答案依据须是正文已写明的内容,正文没讲的概念不设题;若问题值得问,先在正文补上依据再设题。答案先答所问:首句直接回答题面,一到两句,不补题面之外的对比、延伸或重复题面(对照与归属由正文承载)。问答中的文件、路径与标识符指称统一用行内代码,不挂链接(`verifying-content.py` 对自测节链接记 WARN);所属目录在答案前文已确立时,路径可省去重复的顶层前缀(如先写 `example/`,后文写 `include/state.h`)。
46
46
  - **本章回顾**:服务已经成功的读者。1-2 句段落(不是 bullet 列表):「你已经能 <能力>」中的能力必须对应本章任务节交出的结果,可复用任务节关键词,不写正文没有的抽象总称(如「按输入、输出和终局」);「下一章 <预告>」不写链接,直述预告一句(页面导航已有前进按钮),预告不引入下一章才建立的术语。回顾的每个说法都要能在正文找到出处,禁止空泛能力句或只写预告;正文任务节变化时同步改写回顾。
47
47
 
48
48
  ### 有 class 的章的任务节
@@ -58,10 +58,10 @@
58
58
 
59
59
  ### 术语与验证策略
60
60
 
61
- - 术语 callout 就近放置的写法见`steps/03-blocks.md`;一个同位短语就能说清的(如 CTest(CMake 自带的测试运行工具))可保留行内括号。面向新人的正文不堆砌入门前置名词(walking skeleton 这类术语直接删除)。
61
+ - 术语 callout 就近放置的写法见 `steps/03-blocks.md`;一个同位短语就能说清的(如 CTest(CMake 自带的测试运行工具))可保留行内括号。面向新人的正文不堆砌入门前置名词(walking skeleton 这类术语直接删除)。
62
62
  - 页面写出的验证结论必须与证据强度匹配:命令能定位、版本能输出、程序能编译运行是不同层级,不能用弱观察替代强证明。
63
- - 涉及阶段目录结构的章节:先给目录树,再按树顺序逐项说明(链接格式见`quarto/render.md`)。
64
- - 全书统一术语与替换规则见`steps/06-wording.md`。
63
+ - 涉及阶段目录结构的章节:先给目录树,再按树顺序逐项说明(链接格式见 `quarto/render.md`)。
64
+ - 全书统一术语与替换规则见 `steps/06-wording.md`。
65
65
 
66
66
  ### 一章一个关键
67
67
 
@@ -86,10 +86,10 @@
86
86
  - 标题只用读者此刻已认识的词或字面自明的词,不使用正文之后才解释的术语。
87
87
  - 任务级 `##` 承担一个概念组或一项可独立交付的任务:单个类型、单个枚举或单个函数的小节不独占任务级 `##`,与相邻概念并成一组再按 `###` 分步(示例章反例:`定义坐标范围`、`保存格子状态` 曾各自独立成 `##`,粒度低于任务级;现行二级标题只记在本文件的对照里)。
88
88
  - 任务级 `##` 只保留读者能单独做完的一件事。只负责解释下一块代码、命令或图的,降为 `###`;短到没有独立观察步骤的,连 `###` 也不留,并进相邻正文。固定收尾「常见错误」「自测问题」「本章回顾」不合并、不降级,常见错误下面的症状继续用 `###`。
89
- - 一个任务级 `##` 下设 `###` 时至少两个:依据阮一峰[《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide)的标题原则,二级标题是文章的主要部分,三级标题是它下面的步骤,同级标题避免只出现一个;只有 `###` 时删去其标题归回 `##` 正文,或补出真正独立的同级小节。
89
+ - 一个任务级 `##` 下设 `###` 时至少两个:依据阮一峰 [《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide) 的标题原则,二级标题是文章的主要部分,三级标题是它下面的步骤,同级标题避免只出现一个;只有 `###` 时删去其标题归回 `##` 正文,或补出真正独立的同级小节。
90
90
  - `##` 导语的句数与 token 上限见本文件「分层上限」,只写这一节交出的结果,不放代码围栏;恰好 2 个 `###` 时一句点一个,3 到 7 个时不再逐个点名,点名交给三级标题(与「个数见本文件」收尾,取代旧「按顺序点名各子节对象」的概览句式)。连续值类型的任务节归并见本文件「任务序列」;一个三级标题可以只讲一个枚举、一个结构体或一个函数。紧挨着的两个值类型可以放在同一个三级标题里,各成一个短模块,示例章「操作与成败」是正例。
91
91
  - 标题与内容匹配:标题动词承诺的动作必须是本节正文实际让读者完成的动作——正文只要求观察的行为用「观察、查看、核对」类动词,不用「走完、完成」类只在真实操作节成立的动词;任务级标题不与页面 title 共用核心动词(如页面 title 用「明确」后,任务节不再以「明确」开头),页面 title 已承诺的动作由正文兑现,标题换用更具体的动词;二级标题的宾语要涵盖其下三级标题的宾语,读者从标题序列能看出各节分工,不写比正文更宽或更窄的承诺。改写对照见本文件「反例与改写」。
92
- - 层级结构遵循阮一峰[《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide)标题章:不跳级(一级标题下不直接出现三级标题)、避免孤立编号(同级标题只有一个时省略)、下级标题不重复上级标题的名字。
92
+ - 层级结构遵循阮一峰 [《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide) 标题章:不跳级(一级标题下不直接出现三级标题)、避免孤立编号(同级标题只有一个时省略)、下级标题不重复上级标题的名字。
93
93
  - 标题与导语不写拗口动宾,不用实现细节当主叙事:「得出胜负与平局」这类把两个结果硬拼成一个动宾的标题改写成交付对象(如「终局判定」);「三连算法」是实现细节,可一句带过,不作章节 title 或 `##` 标题的主叙事(示例章反例:原 `## 得出胜负与平局` 已更名为「终局判定」,正文改说「操作后判定流程是否结束」)。
94
94
 
95
95
  ### 标题字数
@@ -115,7 +115,7 @@
115
115
  - title 留下读者在侧栏里要找的对象:概念、数据、结果用名词;只有这一页的交付就是读者要执行的一个动作时,才用「动词 + 一个宾语」。修饰性定语留给正文,否则「示例项目」「工程」等限定在 title 与二三级标题里连续重复(用户决定:各章 title 收尾为对象名,如流程规则、工程目录、数据存储、一次操作、构建与运行、操作策略、局面快照)。
116
116
  - title 不用「并」串联两个动作、不用把字句;两个动作各有任务节承载时择主撰写对象,动作细节留给导语和任务节。
117
117
  - 标题与导航不使用行内代码(`CMakeLists.txt` 这类名字不进标题;标题写「构建规则」「一键脚本」等表达)。
118
- - 标题只用读者此刻已认识的词或字面自明的词,不使用正文之后才解释的术语(统称禁用清单见`steps/06-wording.md`)。
118
+ - 标题只用读者此刻已认识的词或字面自明的词,不使用正文之后才解释的术语(统称禁用清单见 `steps/06-wording.md`)。
119
119
  - 二级、三级标题用两组词:要么「限定语 + 对象」(数据项坐标、操作后的结果),要么「动词 + 具体宾语」(检查是否三连、放入一枚元素);同一个二级标题下的三级标题只用其中一种,数字见「标题字数」。指示(这一步、这次)、过程动词(记下、收进、用到)、方式(用数组、先…再…)、把字句与数量词(三种、四个、九个)不进标题,下放到导语或正文。组词是否带限定语由改标题时逐条对照,不新增正则。导语仍按现规则:恰好两个三级时一句点一个,三个或四个时不逐个点名。
120
120
  - 三级标题可以保留本章对象的完整名称(如「数据项坐标」),不拆成「行与列」「空格与标记」。
121
121
  - 固定收尾节名固定复用,见本文件。
@@ -175,14 +175,14 @@
175
175
  | 普通代码块(围栏内内容行) | 20 行 |
176
176
  | `{mermaid}` 图表块 | 40 行 |
177
177
  | `{python}` 可执行单元(坐标图等) | 30 行 |
178
- | 单个正文段落(代码块、表格、列表与标题之外的连续文本段) | 70–220 token;下限拦过短段(70 token ≈ 45 汉字当量),上限保持上限,写作舒适带 90–180。豁免下限:章引言段、`##`/`###` 节导语、紧邻代码/列表/表/图/盒子的单句块前导语、本章回顾、自测固定导语、Callout 盒子内段落;豁免类仍受 220 上限约束。低于下限的补法见`steps/05-sentences.md`「导语衔接」 |
178
+ | 单个正文段落(代码块、表格、列表与标题之外的连续文本段) | 70–220 token;下限拦过短段(70 token ≈ 45 汉字当量),上限保持上限,写作舒适带 90–180。豁免下限:章引言段、`##`/`###` 节导语、紧邻代码/列表/表/图/盒子的单句块前导语、本章回顾、自测固定导语、Callout 盒子内段落;豁免类仍受 220 上限约束。低于下限的补法见 `steps/05-sentences.md`「导语衔接」 |
179
179
  | `##` 节导语(标题后、首个代码块/列表/表格/引用/盒子前) | 120 token 且 ≤2 句,不放代码围栏;设 `###` 的任务级 `##` 导语不另设下限,导语点名的句式见本文件「标题分层」 |
180
180
  | `###` 节导语(同口径,到首个盒子/代码块/列表前) | 80 token 且 ≤1 句 |
181
181
  | 单个 `>` 引用块(连续引用行合并计) | 80 token |
182
- | 代码片段内注释 | 写法与限额见`steps/03-blocks.md`「代码块 filename 标注」 |
182
+ | 代码片段内注释 | 写法与限额见 `steps/03-blocks.md`「代码块 filename 标注」 |
183
183
  | 一章 Callout | 不设下限;超过 8 个失败。写作时常例是 1 到 3 个 |
184
184
 
185
- `{python}` 可执行单元应只含助手调用,绘图逻辑在共享助手库(见`quarto/coords.md`);超出 30 行说明把绘图逻辑内联进了正文,属于结构违规。
185
+ `{python}` 可执行单元应只含助手调用,绘图逻辑在共享助手库(见 `quarto/coords.md`);超出 30 行说明把绘图逻辑内联进了正文,属于结构违规。
186
186
 
187
187
  数字依据:没有规定章节字数的权威国标(GB/T 7713《科技报告编写规则》只管结构格式);技术写作社区实践是单节对应 3-5 分钟阅读(约 1500-3000 字)、单个功能模块 800-1200 字,超限优先拆分。按 CJK×1.5 换算,整章 5000 token 约合 3300 汉字的正文当量,是「一节一件事、一章四节左右」的自然边界。
188
188
 
@@ -191,20 +191,20 @@
191
191
  - `verifying-content.py` 第 3 查按上表逐文件、逐节、逐代码块、逐正文段落核对,超限即整体失败;限额调整只改该脚本的常量与本表,两处必须同步。
192
192
  - 根目录 `index.qmd` 与 `content/<game>/index.qmd`(YAML 含 `body-classes: index-page`)是着陆页:短引言与卡片网格不是章节引言,只核对整章总量与代码块限额;着陆页不套用标题与骨架限制,见本文件「六段块序列」。
193
193
  - 任务级 `##` 数量、固定收尾不计入、`###` 的使用条件与首章「常见错误」豁免的结构判断,见本文件「六段块序列」;数量口径以上表为准。
194
- - 结构性规则(引言构成、`###` 数量)同时受`steps/02-structure.md`「六段块序列」约束;本表提供量化兜底。
195
- - 接近上限不是目标:预算是上限,内容仍按凑字数禁令与密度规则精简(见`steps/04-paragraphs.md`「凑字数禁令」)。
194
+ - 结构性规则(引言构成、`###` 数量)同时受 `steps/02-structure.md`「六段块序列」约束;本表提供量化兜底。
195
+ - 接近上限不是目标:预算是上限,内容仍按凑字数禁令与密度规则精简(见 `steps/04-paragraphs.md`「凑字数禁令」)。
196
196
 
197
197
  ### 页面宽度与垂直节奏
198
198
 
199
199
  页面“紧凑”通常有两个来源:正文列太窄导致无谓换行,或块之间缺少承接留白。优先小幅放宽 Quarto HTML grid 的 `body-width`,再用共享 CSS 调整正文块间距;不要只放大字体,也不要用局部规则给每个块重复加 margin。正文列仍需保留 `max-width: 100%`,代码和宽表在窄屏上继续滚动或换行。
200
200
 
201
- 当前仓库采用 840px 的正文内容列和约 1.55rem 的普通块间距,代码块连续出现时保留更大的间隔。代码块与正文同宽:不再对代码做二次限宽(`--code-max-width` 已删除),宽屏两侧留白属主流文档站(VitePress 1440 壳/688 正文)正常行为,不按显示器拉满正文。872px/840px 的取值依据(100 列代码不折行)见`../designing-theme/knowledge/reading-surface.md`。评估重点是:每个任务是否有清晰的动作与结果、连续盒子之间是否有解释段、移动端是否出现横向溢出。这里不设置依赖浏览器截图的硬阈值,最终以 `quarto render` 后的 HTML 结构和实际阅读抽查为准。
201
+ 当前仓库采用 840px 的正文内容列和约 1.55rem 的普通块间距,代码块连续出现时保留更大的间隔。代码块与正文同宽:不再对代码做二次限宽(`--code-max-width` 已删除),宽屏两侧留白属主流文档站(VitePress 1440 壳/688 正文)正常行为,不按显示器拉满正文。872px/840px 的取值依据(100 列代码不折行)见 `../designing-theme/knowledge/reading-surface.md`。评估重点是:每个任务是否有清晰的动作与结果、连续盒子之间是否有解释段、移动端是否出现横向溢出。这里不设置依赖浏览器截图的硬阈值,最终以 `quarto render` 后的 HTML 结构和实际阅读抽查为准。
202
202
 
203
203
  Quarto 通过 HTML grid 控制正文、侧栏和目录列,代码块的 `filename`、换行和复制行为由代码块配置及 CSS 共同控制;页面宽度与代码标题过长是两个独立问题。
204
204
 
205
205
  ### 一图一事与同主题相邻
206
206
 
207
- 图是读者视觉负荷最高的盒子:一张图同时表达两条关系时,读者要同时在脑子里维护两个对照,图前正文与图后结论也各要写两遍才能闭环。因此一张图只核对一条已讲清的关系,需要两条就拆图或拆节;一图一事与主题错位拆 `###` 的边界见`steps/03-blocks.md`「代码与图的桥接」。代码与图相邻的前提是同一对象:图讲 B 而前后代码讲 A、C 时,读者被迫在三个对象间跳转,这正是「代码 A → 短句拐弯 → 图讲 B → 再贴代码 C」式堆叠的成因。主题错位时先用一句正文收束本对象,再另起 `###`。图中的每个框和箭头都应能在图前正文找到出处;图引入正文没有的概念时,读者只能靠猜。写法见 `writing-quarto` 技能 `quarto/authoring.md`「代码与图的桥接」。
207
+ 图是读者视觉负荷最高的盒子:一张图同时表达两条关系时,读者要同时在脑子里维护两个对照,图前正文与图后结论也各要写两遍才能闭环。因此一张图只核对一条已讲清的关系,需要两条就拆图或拆节;一图一事与主题错位拆 `###` 的边界见 `steps/03-blocks.md`「代码与图的桥接」。代码与图相邻的前提是同一对象:图讲 B 而前后代码讲 A、C 时,读者被迫在三个对象间跳转,这正是「代码 A → 短句拐弯 → 图讲 B → 再贴代码 C」式堆叠的成因。主题错位时先用一句正文收束本对象,再另起 `###`。图中的每个框和箭头都应能在图前正文找到出处;图引入正文没有的概念时,读者只能靠猜。写法见 `writing-quarto` 技能 `quarto/authoring.md`「代码与图的桥接」。
208
208
 
209
209
  ### 主线必须先闭合
210
210
 
@@ -212,7 +212,7 @@ Quarto 通过 HTML grid 控制正文、侧栏和目录列,代码块的 `filena
212
212
 
213
213
  主线闭合要求一节只有一个要闭合的目标:标题、第一句、动作和验收输出指向同一个结果,中途出现第二个独立动作时,读者就无法判断当前在等哪一个。任务粒度本身的判定标准属于页面结构,见本文件。
214
214
 
215
- 标题对齐同时排除离题辩白:操作小节里与标题无关的工程取舍长论(「为何不跳过某步 / 幂等 / 配置漂移」类)让读者在动作中途读辩白,主线被打断;执行规则见`steps/03-blocks.md`「小节标题与正文对齐」。
215
+ 标题对齐同时排除离题辩白:操作小节里与标题无关的工程取舍长论(「为何不跳过某步 / 幂等 / 配置漂移」类)让读者在动作中途读辩白,主线被打断;执行规则见 `steps/03-blocks.md`「小节标题与正文对齐」。
216
216
 
217
217
  当多个 `###` 共享同一阶段、环境或产物时,可以用父级 `##` 统摄,但父级只负责分组,不能把两个各自可验收的任务压成一个模糊标题。父标题要写清当前阶段或范围,子标题继续使用可执行、可观察的任务名。
218
218
 
@@ -220,7 +220,7 @@ Quarto 通过 HTML grid 控制正文、侧栏和目录列,代码块的 `filena
220
220
 
221
221
  长段的问题不在于占据多少行,而在于它要求读者同时记住多个职责。主线动作、成功判据和可跳过说明压在同一段时,只读必要内容的读者必须重新寻找下一步,逐字阅读的读者又无法判断哪些细节可以跳过。按职责拆成短段,能让首次执行和回看细节两条路径自然分开。
222
222
 
223
- 普通 Callout 不能成为细节垃圾桶。把可以跳过的内容集中进提示框后,读者仍要判断这段是否影响当前任务,而且视觉上独立的盒子容易像必经步骤。只有删除后不影响首次成功和验收的信息才适合下沉,并且一个最小模块最多一个 Callout,一章的个数见本文件;术语解释型 Callout 是就近放置的例外,写法与限制见`steps/03-blocks.md`。稳定界面判据与它的解释同框时,另见下节约束。
223
+ 普通 Callout 不能成为细节垃圾桶。把可以跳过的内容集中进提示框后,读者仍要判断这段是否影响当前任务,而且视觉上独立的盒子容易像必经步骤。只有删除后不影响首次成功和验收的信息才适合下沉,并且一个最小模块最多一个 Callout,一章的个数见本文件;术语解释型 Callout 是就近放置的例外,写法与限制见 `steps/03-blocks.md`。稳定界面判据与它的解释同框时,另见下节约束。
224
224
 
225
225
  合并与拆分都按信息职责判断,不按固定字数。同一状态内部的账号创建和正常现象可以合并。成功判据与后续执行范围进入下一个状态时另起一段,即使它们仍属于同一次首次启动流程。
226
226