@chengzhao-dev/dsh-quarto-book 0.6.14 → 0.6.15

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.
package/README.en.md CHANGED
@@ -29,7 +29,7 @@ Both skills are discovered from the package's `skills/` directory and loaded on
29
29
  2. Open a session in the book repository. `_quarto.yml` needs a standalone `type: book` line, and the book needs at least one `.qmd` or `.md` chapter source; only then do both skill names appear.
30
30
  3. Call a skill: `writing-quarto` for prose, `designing-theme` for the theme.
31
31
 
32
- Replace `--profile` with the profile you actually run. The desktop app always runs the `desktop` profile, and that profile is owned by the app, so `dsh --profile desktop` is rejected; install or upgrade with `dsh plugin --profile desktop add <package>`, and use the app's Settings → Plugins → Add plugin only if the app refuses that write. To pin a version, write `npm:@chengzhao-dev/dsh-quarto-book@0.6.14`; to follow a GitHub tag, write `github:chengzhao-dev/dsh-quarto-book#v0.6.14`.
32
+ Replace `--profile` with the profile you actually run. The desktop app always runs the `desktop` profile, and that profile is owned by the app, so `dsh --profile desktop` is rejected; install or upgrade with `dsh plugin --profile desktop add <package>`, and use the app's Settings → Plugins → Add plugin only if the app refuses that write. To pin a version, write `npm:@chengzhao-dev/dsh-quarto-book@0.6.15`; to follow a GitHub tag, write `github:chengzhao-dev/dsh-quarto-book#v0.6.15`.
33
33
 
34
34
  Upgrading from the old unscoped package `dsh-quarto-book` (removed from npm with 0.3.4, so this only affects profiles that installed it earlier): remove it from the same profile first with `dsh plugin --profile <profile> remove dsh-quarto-book`, then add the scoped package. Keeping both installed registers `writing-quarto` and `designing-theme` twice at the same rank 550.
35
35
 
package/README.md CHANGED
@@ -29,7 +29,7 @@
29
29
  2. 在书仓库里打开会话。`_quarto.yml` 要有独立一行的 `type: book`,书根至少有一个 `.qmd` 或 `.md` 章节源文件;两个技能名这时才会出现。
30
30
  3. 调用技能:写正文用 `writing-quarto`,改主题用 `designing-theme`。
31
31
 
32
- `--profile` 换成你实际运行的那个 profile。桌面应用固定跑 `desktop` profile,且该 profile 由应用独占管理,`dsh --profile desktop` 直接启动会被拒绝;安装或升级用 `dsh plugin --profile desktop add <包>`,应用拒绝写入时再走「设置 → 插件 → 添加插件」。需要固定版本时写 `npm:@chengzhao-dev/dsh-quarto-book@0.6.14`,跟 GitHub 标签时写 `github:chengzhao-dev/dsh-quarto-book#v0.6.14`。
32
+ `--profile` 换成你实际运行的那个 profile。桌面应用固定跑 `desktop` profile,且该 profile 由应用独占管理,`dsh --profile desktop` 直接启动会被拒绝;安装或升级用 `dsh plugin --profile desktop add <包>`,应用拒绝写入时再走「设置 → 插件 → 添加插件」。需要固定版本时写 `npm:@chengzhao-dev/dsh-quarto-book@0.6.15`,跟 GitHub 标签时写 `github:chengzhao-dev/dsh-quarto-book#v0.6.15`。
33
33
 
34
34
  从旧的无作用域包 `dsh-quarto-book` 升级(该包已随 0.3.4 从 npm 删除,只影响之前装过它的 profile):先在同一个 profile 里 `dsh plugin --profile <profile> remove dsh-quarto-book`,再装新包。两个包同时留着会以相同的 rank 550 各注册一遍 `writing-quarto` 和 `designing-theme`。
35
35
 
@@ -247,7 +247,7 @@ const RESULT_SCHEMA = {
247
247
  export function registerPassReportTool(tools) {
248
248
  tools.register({
249
249
  name: 'quarto_pass_report',
250
- description: '一次写作或主题润色收尾时调用一次,出一张短回执卡片:执行了哪个技能、什么模式、改了哪些文件与步骤、未改项、检查结论。入参是闭集:skill、mode、files(最多 8 个,每条带 path 与 edits)、steps(写作 1-9,主题用定表面/定字体/定尺度/定颜色/定组件/通过检查,各带 edits,合计必须等于 files 的 edits 合计)、held、checks、skip_reason。没改也传 0;不适用时 executed:false、mode:skipped、给 skip_reason。卡片就是回执,不要在回复里再复述。',
250
+ description: '一次写作或主题润色收尾时调用一次,生成短回执卡;卡片即回执,不在回复里重复。参数是闭集:skill、mode、files(每条带 path 与 edits)、steps(各步 edits 合计等于 files 合计)、held、checks、skip_reason。没改动时传空 files、steps 与 0;不适用时 executed:false、mode:skipped,并写 skip_reason。',
251
251
  parameters: {
252
252
  type: 'object',
253
253
  additionalProperties: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chengzhao-dev/dsh-quarto-book",
3
- "version": "0.6.14",
3
+ "version": "0.6.15",
4
4
  "description": "把一份 Quarto Book 写成可读、可查、可发布的中文技术书:九步章节写作、结构/链接/图表检查、统一主题与渲染验收。 · Write, check, and publish a Chinese Quarto Book: nine-step chapter writing, structure/link/figure checks, a consistent theme, and render acceptance.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -37,7 +37,7 @@
37
37
 
38
38
  ## 字体栈与字形来源(定字体)
39
39
 
40
- 正文与标题各一面。**正文**用 `LXGW Bright Medium`(Klee One 中笔画 + Ysabeau Office 西文,登记 `font-weight: 400`,`font-synthesis: none` 下不合成粗体);**代码**用 `LXGW Bright Code`(Klee + Monaspace Argon);**标题**(h1–h6、导航书名、首页卡片小标题)用 `--heading-font` 的系统黑体栈(`Noto Sans SC` → 思源黑体 → `PingFang SC` → `Microsoft YaHei` → system-ui),请求 600/700 时由系统字面真正加粗。理由:单字面的楷体在 24px 以上笔画偏细、600 又不合成,标题与正文层级只靠字号,层级弱;对照实测 h2 换黑体后层级立刻清楚,且不新增字体文件、不影响正文观感。中文正文保持霞鹜楷体路线;文楷 Screen 与 Fixel 已移除。候选对比、授权与字面实测(数字等宽、标点宽度、`+` 墨迹 0.23em)见 `docs/research/font-selection.md`。西文来源依据:文楷仓库点名 Ysabeau;Bright 用齐线数字的 Ysabeau Office;文楷 Screen 的 Medium 笔画标 Regular、度量对齐 Roboto,不适合中西文都自托管的站点。
40
+ 正文与标题各一面。**正文**用 `LXGW Bright Medium`(Klee One 中笔画 + Ysabeau Office 西文,登记 `font-weight: 400`,`font-synthesis: none` 下不合成粗体);**代码**用 `LXGW Bright Code`(Klee + Monaspace Argon);**标题**(h1–h6、导航书名、首页卡片小标题)用 `--heading-font` 的系统黑体栈(`Noto Sans SC` → 思源黑体 → `PingFang SC` → `Microsoft YaHei` → system-ui),请求 600/700 时由系统字面真正加粗。理由:单字面的楷体在 24px 以上笔画偏细、600 又不合成,标题与正文层级只靠字号,层级弱;对照实测 h2 换黑体后层级立刻清楚,且不新增字体文件、不影响正文观感。中文正文保持霞鹜楷体路线;文楷 Screen 与 Fixel 已移除。候选对比、授权与字面实测属于开发期记录,不再入库;这里只留可执行结论。西文来源依据:文楷仓库点名 Ysabeau;Bright 用齐线数字的 Ysabeau Office;文楷 Screen 的 Medium 笔画标 Regular、度量对齐 Roboto,不适合中西文都自托管的站点。
41
41
 
42
42
  - 文件与预算:`assets/theme/assets/fonts/` 每字体一个 `*-common.woff2`(共 2 个),单页合计 ≤ 1.6 MB、≤ 5 个文件。
43
43
  - 子集:沿用常用字表并覆盖全书正文与终端输出;生成方式 `pyftsubset --flavor=woff2 --no-hinting`。改结果文案或新增字符后,用 fontTools 读 woff2 cmap 复核(起因:子集共用字符表漏「胜」,结果行末字落到宋体);`checking-layout.py` 的覆盖断言在未声明 unicode-range 时直接读 cmap。新增字符时,按同版本上游 TTF(Bright 5.528、Bright Code 2.922)保留现 cmap 并入新码位后重建,输出到插件与书内两份;跑页面矩阵时用 `NODE_PATH` 指向插件的 `node_modules`。
@@ -7,7 +7,7 @@ metadata:
7
7
 
8
8
  # Skill: writing-quarto
9
9
 
10
- 承载 `.qmd` 写法与 Book 结构约定。正文九步:增量任务只开对应一步;全章重构才走九步。判不准才开步骤点名的 `examples/` 案例,排图与查渲染开 `quarto/`;研究目录 `docs/research/` 只供开发。
10
+ 承载 `.qmd` 写法与 Book 结构约定。正文九步:增量任务只开对应一步,全章重构走九步,只读审查只报告不改文件。判不准才开步骤点名的 `examples/` 案例,排图与查渲染开 `quarto/`;插件开发资料不属读者正文。
11
11
 
12
12
  ## 适用场景
13
13
 
@@ -31,11 +31,11 @@ metadata:
31
31
 
32
32
  单章与整书共用同一套九步,不另造一套章节规则;项目有章节表时以项目表为准。技能文件体量受 `references/token-budget.md` 约束,新增整书规则只写进 `book-journey.md`。
33
33
 
34
- ## 两种走法
34
+ ## 三种走法
35
35
 
36
- 增量任务只走对应步骤,只改判为不合格的地方;全章重构仍走九步,但第 1–2 步先定删留、不动句子,第 3–4 步只拆块和段,第 5–7 步才逐句改。
36
+ 增量任务只走对应步骤,只改不合格处。全章重构走九步:第 1–2 步定删留,第 3–4 步拆块段,第 5–7 步逐句改。只读审查不改文件,按九步逐条报告行号、规则出处与改法。
37
37
 
38
- 两条走法共守同一组不变量,写在这里,不重复进各步:不新增原文没有的事实、数字、命令、性能结论、引文和出处;不把「可能」「通常」「在本书里」这类留有余地的说法改成确定说法;保留否定、条件、范围、时间和归属;围栏里的代码、命令、路径、URL 与 YAML 不改。增量润色只删除和换词,不扩写、不补论证;全章重构可删可换序,但不能发明事实,也不能把限定说成确定。
38
+ 三种走法共守:不新增原文没有的事实、数字、命令、性能结论、引文和出处;不把「可能」「通常」「在本书里」改成确定说法;保留否定、条件、范围、时间和归属;围栏里的代码、命令、路径、URL 与 YAML 不改。增量润色只删除和换词;全章重构可删可换序,但不能发明事实。
39
39
 
40
40
  ## 九步
41
41
 
@@ -65,3 +65,4 @@ metadata:
65
65
  - [ ] 混排自查通过:`scripts/checking-prose.py --root <book>` 无高置信问题。
66
66
  - [ ] 调 `quarto_render_check`:`dry_run: true` 最多 2 次,确认 `safe_to_render`;`dry_run: false` 最多 1 次,确认 `html_report.usable` 为 true。不手跑 `quarto render`,也不截图 PNG。
67
67
  - [ ] 收尾调用一次 `quarto_pass_report`:`skill` 填 `writing-quarto`,`mode` 填 `polish` 或 `rewrite`,文件与步骤的改动次数、未改项、检查结论照实填。卡片就是回执,回复里不再复述;没改也传 0,当前文件不是章节时传 `executed: false`。
68
+ - [ ] 只读审查:不改文件,不调 `quarto_render_check`、`quarto_pass_report`,报告写清行号、规则出处与改法。
@@ -233,7 +233,7 @@
233
233
  ```text
234
234
  不佳(标题数条目,一节混讲坐标表、算法和归谁用):
235
235
  ### 八条线
236
- 八条线的坐标写在 board.cpp 里,存成一张 constexpr 常量表。HasLine 与 IsLineComplete 共用它。
236
+ 八条线的坐标写在 board.cpp 里,存成一张 constexpr 常量表。HasLine 与 PreviewWin 的推演共用它。
237
237
  Game 和 Ai 调用查询,不读它,所以不放进 Board 类里:
238
238
  (kLines 围栏)
239
239
  (算法旁白与 HasLine 围栏)
@@ -36,6 +36,15 @@
36
36
  - 主题用 `.book-figure` 统一居中、限制最大宽度,并让 `figcaption` 落在图下;不要另写行内样式。
37
37
  - 图注内需要行内代码时写 `<code>`,不要写 Markdown 反引号——`{=html}` 围栏按原样输出。
38
38
 
39
+ ## 无障碍文本
40
+
41
+ 图注给视觉读者,替代文本给读屏软件;两者不互相复制:
42
+
43
+ - Markdown 图片用 `fig-alt` 写替代文本,一句话说明图的用途与读图结论,不重复图注原文:`![…](board.png){fig-alt="棋盘坐标:3 行 3 列,左上角为 (0, 0)"}`。
44
+ - 只有装饰作用、正文已完整说明的图才留空替代文本:`{fig-alt=""}`;不要省略属性后让文件名充当替代文本。
45
+ - 原生 SVG 已用 `role="img"` 与 `aria-label` 承担替代文本,`aria-label` 与 `figcaption` 各写各的,不要求逐字相同。
46
+ - 替代文本里不写“图片”“下图”这类载体词,直接写图承载的信息。
47
+
39
48
  ## 与其他图类的关系
40
49
 
41
50
  - Mermaid 的方向、节点预算与线型约定见 `quarto/mermaid.md`;它的 `fig-cap` 同样遵守本文件。
@@ -47,3 +56,4 @@
47
56
  - 图前是否还有“下图 / 图中 / 本图”这类只交代图面的句子?有就移入图注或删除。
48
57
  - 图注是否重复了图后正文?重复就删正文或删图注,只留一处。
49
58
  - 原生 SVG 是否在 `figure` 内,`figcaption` 是否在 `svg` 之后、`</figure>` 之前?
59
+ - 内容图是否有不复制图注的 `fig-alt`;装饰图是否显式留空。
@@ -47,7 +47,7 @@ mermaid 用 init 指令中的字体测量标签宽度,页面 CSS 按 `--ui-fon
47
47
 
48
48
  ## 类图成员写法
49
49
 
50
- - 成员行用 `+`/`-` 标出可见性,类型写在名字前,参数只保留名字:`+bool CompletesLine(position, cell_type)`;
50
+ - 成员行用 `+`/`-` 标出可见性,类型写在名字前,参数只保留名字:`+bool HasLine(cell_type)`;
51
51
  - 一行只写一个成员,不把多个方法压进同一行;
52
52
  - 只列本章用到的成员;完整声明留在代码块和章节正文里,图内不补空成员,也不在图后写“其余成员见某章”;
53
53
  - 空类、接口和派生类只写类名与 `<<interface>>` 一类注解,不补空成员占位;
@@ -79,6 +79,7 @@
79
79
  - 少用「被」和长「的」链;一句一个动作,主语尽量是领域对象,不用「我们」代替读者。
80
80
  - 不写「本文将介绍」「下面我们来看」;直接给读者要做的动作和看得见的结果。
81
81
  - 同一事实只留一处:标题、段首、块后不互相复述。
82
+ - 交叉引用写章节标题或链接,不写「上图」「下表」;读者可能先读正文再回看图表,方位词会失效。
82
83
  - 英文术语不堆叠;能用中文说清就不夹英文,必须夹时首次给原文。
83
84
 
84
85
  ## 让句子有信息量
@@ -113,6 +114,10 @@
113
114
 
114
115
  - W3C《中文排版需求》(CLREQ):https://www.w3.org/TR/clreq/
115
116
  - GB/T 15834—2011《标点符号用法》
117
+ - GB/T 15835—2011《出版物上数字用法》
118
+ - GB/T 10112—2019《术语工作 原则与方法》;规范译名查术语在线:https://www.termonline.cn/
119
+ - Microsoft 写作风格指南:https://learn.microsoft.com/en-us/style-guide/welcome/
120
+ - O'Reilly 风格指南:https://oreillymedia.github.io/production-resources/styleguide/
116
121
  - 中文文案排版指北:https://github.com/sparanoid/chinese-copywriting-guidelines
117
122
  - 中文技术文档的写作规范:https://github.com/ruanyf/document-style-guide
118
123
  - 叶圣陶《评改两篇作文》、朱光潜《谈文学》的修改观
@@ -25,7 +25,7 @@
25
25
 
26
26
  1. 声明围栏 + 实现文字(本节讲机制,读者手上却只有接口)。
27
27
  2. 声明围栏 + 「完整实现见源文件」这类指路句:读者在书里看不到,等于没给。
28
- 3. 正文出现围栏里不存在的函数名或表达式(正文讲 `GetWinner`,围栏只有 `IsWin` 的声明)。
28
+ 3. 正文出现围栏里不存在的函数名或表达式(正文讲 `GetWinner`,围栏只有 `IsFull` 的声明)。
29
29
  4. 声明与定义之间隔了整段机制解释,读者翻到围栏时讲解已经结束。
30
30
  5. 定义不平凡却只写契约,再在「常见错误」或 Callout 里补一段机制。
31
31
 
@@ -34,7 +34,7 @@
34
34
  - 平凡:单次比较、单个 `return`、两行赋值、纯委托(`return Other();`)、只做一次边界检查后返回。
35
35
  - 不平凡:含循环或分支组合、更新状态、与别的类型协作、需要解释「为什么不用另一种写法」。
36
36
 
37
- 平凡判例:`IsInRange` 的 `return row >= 0 && row < kRows && col >= 0 && col < kCols;`、`IsWin` 的 `return GetWinner().has_value();`。
37
+ 平凡判例:`IsInRange` 的 `return row >= 0 && row < kRows && col >= 0 && col < kCols;`、`IsFull` 的 `none_of` 一行。
38
38
 
39
39
  ## 正反例(棋盘章的真实片段)
40
40
 
@@ -42,23 +42,30 @@
42
42
 
43
43
  ```markdown
44
44
  ```{.cpp filename="board.h"}
45
- /// @return 是否有任意一枚棋子连成一条线。
46
- [[nodiscard]] bool IsWin() const;
45
+ /// @return 任一方形成三连时该棋子类型;没有赢家时返回空。
46
+ [[nodiscard]] std::optional<CellType> GetWinner() const;
47
47
  ```
48
48
 
49
- `IsWin` 复用 `GetWinner` 的三连判定,不再单独扫描棋盘。
49
+ `GetWinner` 扫描全部整行、整列与两条对角线,命中就返回赢家。
50
50
  ```
51
51
 
52
52
  改后——组合围栏,正文对着代码讲组合:
53
53
 
54
54
  ```markdown
55
- ```{.cpp filename="board.cpp"}
56
- bool Board::IsGameOver() const { return IsWin() || IsDraw(); }
57
- bool Board::IsWin() const { return GetWinner().has_value(); }
58
- bool Board::IsDraw() const { return IsFull() && !IsWin(); }
55
+ ```{.cpp filename="game.cpp"}
56
+ GameResult Game::JudgeAfterPlace(const Board& board, Player player) {
57
+ const auto winner = board.GetWinner();
58
+ if (winner.has_value() && *winner == PlayerToCellType(player)) {
59
+ return PlayerToWinResult(player);
60
+ }
61
+ if (board.IsFull()) {
62
+ return GameResult::kDraw;
63
+ }
64
+ return GameResult::kInProgress;
65
+ }
59
66
  ```
60
67
 
61
- `IsGameOver` 把两个判断用 `||` 连起来;`IsWin` 与 `IsDraw` 各自只回答一个问题,真正的扫描都在别处。
68
+ `JudgeAfterPlace` 先看赢家再看满盘;`Board` 只回答有没有三连、是否满盘,结束与否由对局层组合。
62
69
  ```
63
70
 
64
71
  ## 与其它规则的关系
@@ -15,6 +15,7 @@
15
15
  - **更短 vs 更完整**:删掉条件、范围、失败出口换来的短,不算润色;先补回事实,再压句子。
16
16
  - **统一格式 vs 准确表达**:统一句式不能把不同的行为写成同一句话;先让每句准确,再统一能统一的部分。
17
17
  - **强调语言 vs 讲清内容**:消息先说来源、条件、实际值和限度;用哪种自然语言由项目约定,不由润色规则决定。
18
+ - **结论 vs 前提**:只写「终局后空格仍在」而不写「一方已三连且棋盘未满」,读者会把特例当通例。先补成立条件,再压句子;删掉前提换来的短不算润色(见第 6 步)。
18
19
  - **视觉整齐 vs 可读**:表格先保证表头、行列关系和表尾闭合,再谈斑马纹、色块和装饰。
19
20
 
20
21
  ## 执行顺序
@@ -1,7 +1,7 @@
1
1
  # 规则卡
2
2
 
3
3
  研究结论的压缩版。每张卡一行规则、一个正例、一个反例和所属步骤;写正文时按需打开一张,不要整份读完。
4
- 来源编号见 `docs/research/synthesis.md` 的表格;卡号写进步骤文件末尾,便于追溯。
4
+ 卡号写进步骤文件末尾,便于在技能内互相指认;来源不随包分发。
5
5
 
6
6
  ## 句子
7
7
 
@@ -26,7 +26,7 @@
26
26
  - 步骤:`steps/06-wording.md`
27
27
 
28
28
  **C05 删复述句。** 代码已经说明的,不要再写一遍。
29
- - 正:`PlaceCell 返回 false 有两种原因:越界,或格子已被占用。`
29
+ - 正:`PlaceCell 被拒绝有两种原因:越界,或格子已被占用。`
30
30
  - 反:`上面的代码中,if 判断 position.row 是否越界,如果越界就 return false。`
31
31
  - 步骤:`steps/08-reread.md`
32
32
 
@@ -1,228 +1,226 @@
1
1
  # 第 2 步:定结构
2
2
 
3
3
  产出:章内页面骨架和二级标题清单。
4
- 这一步只定删留和标题,不改句子;全章重构也先停在这一步。
4
+
5
+ 边界:这一步只定删留和标题,不改句子;全章重构也先停在这里。页面宽度归 `designing-theme`,图与代码的桥接归第 3 步,段落节奏归第 4 步。
5
6
 
6
7
  ## 通用情况
7
8
 
9
+ 绝大多数章按下面的六段块序列展开;类章、能力章与着陆页的差异见「情况」。本步的规则默认按这一通用形状判断。
10
+
11
+ ### 章节骨架
12
+
13
+ 六段块序列是骨架的默认顺序。
14
+
8
15
  ### 六段块序列
9
16
 
10
17
  ```text
11
18
  无标题引言 → 按独立任务划分的任务级 ## → ## 常见错误 → ## 自测问题 → ## 本章回顾
12
19
  ```
13
20
 
14
- 正文首章和末章也套这个序列,全书各章的页面骨架都是它:任务级 `##` 按独立读者任务和可验证结果划分;2–4 个只是常见预算,不是必须凑足的配额。固定收尾节不计入任务数量,着陆页不套用任务级标题上限。上限用于防止页面失控,不要求把独立任务机械降为 `###`。**两处骨架豁免(用户决定)**:① 首章可以没有「常见错误」节,入门章只保留最可能遇到的 2–3 项;② 示例章(工程目录)没有可独立复现的失败症状,允许整节缺省,不必为凑骨架硬写一条。两者都只在确实无可写内容时成立,不是默认省略。
21
+ - 任务级 `##` 按独立读者任务和可验证结果划分;通常 2–4 个,是上限不是配额。固定收尾不计入任务数;着陆页不套用本骨架。
22
+ - 两处豁免只在确实无可写内容时成立:首章「常见错误」可只留最可能的 2–3 项;工程目录章没有可独立复现的失败症状时,可整节缺省。
23
+ - 读者沿正文依次确认:来对了地方、完成一个可验证动作、理解关键关系、确认获得的能力。各段服务一个认知结果,顺序由「读者先要知道什么」决定。
24
+ - 章际衔接:第 N 章的引言、任务节与自测只用第 1..N-1 章已建立的名字与概念;本章新术语在首次真正使用处就近落术语卡或行内括号。接不上前章已建立名字的概念,下沉回首次使用它的章,不在本章临时补课。
15
25
 
16
- 读者在正文里依次确认来对了地方、完成可验证的动作、理解关键关系并确认获得的能力。各段服务一个认知结果,顺序由「读者先要知道什么才能看懂下一步」决定。
26
+ ### 无标题引言
17
27
 
18
- **章际衔接(定结构检查项)**:第 N 章的引言、任务节与自测题只用第 1..N-1 章已建立的名字与概念;本章新术语在首次真正使用处就近落术语卡或行内括号;术语卡的升级判据见 `writing-quarto` 技能 `quarto/authoring.md`「Callout 升级判据」,写法见 `steps/03-blocks.md`。某概念接不上前章已建立的名字时,把它下沉回首次使用它的章建立,不在本章临时补课。
28
+ 第一个 `##` 之前是连贯读者文,回答三问:
19
29
 
20
- - **无标题引言**:第一个 `##` 之前,写成**连贯读者文**回答读者三问——从哪来(承接上一章已成立的结果)、这一章做什么(本章要解决的问题与读者将获得的能力,正面陈述;范围能并则并,不写否定式后章预告)、代码在哪(可选:若本章有主源文件,用**同段末句**自然语言点名并挂全章 blob 链接,不另起「代码写在…里」独立段)。第一句写出谁在什么情况下做本章这件事,类章同时写出类名;类型怎么实现放到后面的句子。不另开背景节。**形态硬限(用户决定)**:首选**恰好 1 个自然段**(通常 2–4 句);必要时允许 **1 个自然段 + 1 个列表**(列表前引导句写在同一段末,或段落后紧跟列表;列表不算第二散文段);**禁止**出现两个散文自然段并立,更禁止 ≥3 段、单句孤儿段、结尾导航段。列表仅用于并列范围/对象,任务细节下沉正文 `##`,不用顿号串交付物冒充散文。**摘录免责句永不写进读者正文**:「本章摘录源码服务于讲解」「片段不保证与源文件逐字一致」「不等于文件内顺序」类作者旁白一律删除(旧「示例位置句开口子」已废止),同源保证交给 `verifying-content.py`;摘录免责只保留在 技能的权威文件与检查脚本里。不放 Callout,不写后续章节内容,不用「后面的 X」式前向指称引入后续章节才建立的结构件(如「实现放在后面的编号目录里」)。引言容纳多个独立概念时**并段或改列表**,禁止拆成两个散文段;拆分判据见 `steps/04-paragraphs.md`「拆分判据」。陈述范围跟页面一样大:部分页只说这一部分的对局与代码,只有书首页可以写「这本书」;第一句写读者要做成的事,不用「本章将…」「下面介绍…」开场。内容量硬限:导语 60–140 个可见字符(链接只算标签文字,空白不计;超过先删下一块已经摆出来的内容,不足补本章要解决什么);项目可在 `.agents/skills/quarto-book-project/checks.json` 用 `"lead_chars": [60, 140]` 声明,`verifying-content.py` 按此检查,着陆页不受限;token 预算见本文件「分层上限」;范围边界能并入承接段时不成列表。承接中引用其他章节一律用章节标题链接,不用「第 N 章」;**链接预算**:引言只挂承接上一章的那 1 个章节链接和本章主源文件的 blob 链接,其余章节链接下沉到正文真正用到它的句子,每处只挂当下需要的那个目标,同一段不堆多个章节链接(Google 技术写作指南把每个链接视为一次读者可能离开当前页的机会,链接越多,认知负担越重);本章回顾的下一章预告不写链接,直述预告一句(页面导航已有前进按钮),两者均见 `steps/06-wording.md`。任务概览默认并入承接句,正文小节就是任务的展开;预览列表仅当任务没有对应正文小节时使用(示例章四项工作列表已按此删除)。原 front matter `description` 的定位信息并入引言承接句,信息只保留引言一处、不同义两存;章节 qmd 不写 `description`(字段出处见 basics.md)。着陆页 `index` 按 landing 规则组织,不硬套本契约。
21
- - **任务序列**:每节一个可验证结果。判定标准是任务结束时存在一个读者能自己复述的检查动作;只有「读完了解释」的内容并入相邻任务。概念 → 最小示例 → 操作 → 验证 → 边界,先让读者看到行为再解释规则;单次操作按「做什么 → 执行什么 → 看到什么 → 简短说明」推进。各章的任务节以该章标题里的对象为准,不把每一章都写成「目录、设计、构建、测试」四节。设计范围以这一章能在 `src/` 里核对的源文件收束。内容量硬限:任务级 `##` 通常不超过 4 个;`##` 与 `###` 开头的承接句数见本文件「分层上限」,写完直接进入代码、命令或列表;超出即为凑字数信号,禁令见 `steps/04-paragraphs.md`「凑字数禁令」。有 `###` 子节时,二级标题(`##`)的引言须承接上文;恰好 2 个子节时一句点一个,3 个或 4 个时不再逐个点名,点名交给三级标题的句式见本文件「标题分层」,点名用读者已认识的词,不点后文才定义的类型名;一句之内禁止把两个子节对象配成「由 X 定位,并保存 Y」「分别交给」式的两组对应(对照见 `examples/05-sentence-frame.md`「拉链句」)。交付清单或纯边界说明不单独设 `##`,并入引言或相邻工程总览节;同一头文件中连续的值类型优先按一个可验证结果归并到同一任务节。任务节内的讲述顺序按「类型 → 简单函数 → 更难的函数」排列,最难的组装放在最后,并满足先定义后调用:读者要跟着读懂的行内代码标识符,其行为必须已经出现过——上一章、上文,或同一小节里紧挨着的声明和一句行为——上一章已建立的名字视为已知;未定义名字的调用链、节首概览与编号步骤整段删除。`##` 导语只用白话,不点后文才定义的函数名。章内顺序的依据见 `SKILL.md`「九步」的定结构一条,本文件不复述。
22
- - **常见错误**:服务失败后回来的读者。每个症状一个 `###`,标题后第一句写触发条件和可观察现象。误用型条目一段成文写原因与正确做法;原因与做法各需一句完整交代时(如原因牵涉私有段的设计动机),用症状句导语加「出错的原因/正确的做法」引导词列表,列表可作为节导语的合法收尾,导语预算只约束症状句;排查型故障展开定位 → 修复 → 验证三步。形态分野与细则是 `writing-quarto` 技能 `quarto/terminal.md`「常见错误条目形态与三步诊断流」。入门章节只保留最可能遇到的 2-3 项,不是完整 FAQ。
23
- - **自测问题**:服务刚跑通主线、需要确认理解的读者。每章 0-7 道题,题目问本章已经写明的一件可观察结果(会怎样、是哪一个、从几开始),没有这种结果就不设题;只有本章写了原因、而且情景已经说全时,才用「为什么」。题面用本章已经用过的词说全,不用本章未定义的概念,不问「为什么不做成另一种」;题干是合上书的一问,只看本题题干、不看答案与上一题;题干代词的判法见 `steps/05-sentences.md`「代词不能代替未写出的对象」,允许「什么」——它在要一个名字或一句文字,不是指上文没出现的东西;题面里每个细节都要改变答案,答案不受细节影响时不单点某一种情形。题面只描述一个自洽局面,每个事实都要能同时成立,禁止把互相矛盾的局面写成题干(同一句里先说轮到甲方、又说这一步的用户是 O,读者听到的是程序自相矛盾,不是一次非法调用)——「轮到谁」和「这一步的用户」若是同一个对象,只写一次。要考拒绝,用正文已经用过的那条规则问可观察结果(正例:「空状态面板开局,轮到甲方。没轮到的一方来操作时,状态面板会改变吗?」,答案首句「不会。操作的用户不是当前用户,`Place` 返回 `kRejected`,状态面板和轮次都保持原样。」);不为了出题制造正文没走过的矛盾局面。一道题只问一件可观察结果,不把两个观察捆进同一题(如「状态面板是空的吗」与「轮到谁」并列),拆开或删去一个。固定导语「不要展开答案,试着自己把回答完整说出来,写完之后展开对照;说不出来的部分,回到对应小节对照正文。」;答案写在 `::: {.answer}` 围栏 div 内,由书内 `filters/answering-disclosure.lua` 渲染为默认收起的原生 `<details>`;答案只使用本章已讲过的概念。题目同样必须能由本章正文回答:答案依据须是正文已写明的内容,正文没讲的概念不设题;若问题值得问,先在正文补上依据再设题。答案先答所问:首句直接回答题面,一到两句,不补题面之外的对比、延伸或重复题面(对照与归属由正文承载)。问答中的文件、路径与标识符指称统一用行内代码,不挂链接(`verifying-content.py` 对自测节链接记 WARN);所属目录在答案前文已确立时,路径可省去重复的顶层前缀(如先写 `example/`,后文写 `include/state.h`)。
24
- - **本章回顾**:服务已经成功的读者。1-2 句段落(不是 bullet 列表):「你已经能 <能力>」中的能力必须对应本章任务节交出的结果,可复用任务节关键词,不写正文没有的抽象总称(如「按输入、输出和终局」);「下一章 <预告>」不写链接,直述预告一句(页面导航已有前进按钮),预告不引入下一章才建立的术语。回顾的每个说法都要能在正文找到出处,禁止空泛能力句或只写预告;正文任务节变化时同步改写回顾。
30
+ - 从哪来:承接上一章已成立的结果;引用其他章一律用章节标题链接,不用「第 N 章」。
31
+ - 这一章做什么:本章要解决的问题与读者将获得的能力,正面陈述;范围能并则并,不写否定式后章预告。
32
+ - 代码在哪(可选):有主源文件时,用同段末句自然语言点名并挂全章 blob 链接,不另起「代码写在…里」。
25
33
 
26
- ### 有 class 的章的任务节
34
+ 形态:首选恰好 1 个自然段(2–4 句);必要时 1 段 + 1 个列表,列表只放并列范围/对象,前置引导句写在同一段末。禁止两个散文段并立、单句孤儿段、结尾导航段。不放 Callout,不写后续章节内容,不用「后面的 X」引入后文才建立的结构件。
27
35
 
28
- 任务级正文里有 `class` 定义的章(示例项目是「状态面板」的 `Board` 与「流程」的 `Game`),任务级 `##` 按下面的次序排列,没有下一种内容就停,不为凑数加节:
36
+ 内容:60–140 个可见字符(链接只算锚文本,空白不计),超过先删下一块已经摆出来的内容,不足补「本章要解决什么」。项目可在 `checks.json` 用 `"lead_chars": [60, 140]` 覆盖。陈述范围与页面一样大:部分页只说这一部分,只有书首页可以写「这本书」。第一句写读者要做成的事,不用「本章将…」「下面介绍…」开场。
29
37
 
30
- 1. **类型**:先讲这一章要用到的值类型(枚举与结构体),一节一个可验证结果,可下分三级标题。
31
- 2. **成员变量**:成员变量单独一节。读取这些成员的函数用三级标题。不读取成员、只判断坐标是否落在下标区间内的检查,也用三级标题放在这一节,不单独占一个二级标题。类说明、构造函数与数据成员拼进**同一个围栏**,禁止拆成类头一个、成员另一个围栏;存放方式写在第二节正文里,不单独做标题。
32
- 3. **最重要的函数**:这个类最重要的那一个函数,以及它的配套函数。
33
- 4. **其余重要函数**:除此以外还有的重要函数,有一组才再加第四节、第五节,没有就停。
38
+ 链接预算:引言只挂承接上一章的那 1 个章节链接和本章主源文件的 blob 链接;其余章节链接下沉到正文真正用到它的句子。同一段不堆多个章节链接——每个链接都是读者离开当前页的一次机会。
34
39
 
35
- 没有 `class` 的章不套这个次序,按「先类型、再使用这些类型的函数」重排。每个二级标题下三级标题的个数见本文件。超过上限时合并同前缀的函数,或把最难的组装并入相邻节。
40
+ 摘录免责句(「本章摘录源码服务于讲解」「片段不保证与源码逐字一致」)不写进读者正文,同源保证交给 `verifying-content.py`。
36
41
 
37
- ### 术语与验证策略
42
+ ### 任务序列
38
43
 
39
- - 术语 callout 就近放置的写法见 `steps/03-blocks.md`;一个同位短语就能说清的(如 CTest(CMake 自带的测试运行工具))可保留行内括号。面向新人的正文不堆砌入门前置名词(walking skeleton 这类术语直接删除)。
40
- - 页面写出的验证结论必须与证据强度匹配:命令能定位、版本能输出、程序能编译运行是不同层级,不能用弱观察替代强证明。
41
- - 涉及阶段目录结构的章节:先给目录树,再按树顺序逐项说明(链接格式见 `quarto/render.md`)。
42
- - 全书统一术语与替换规则见 `steps/06-wording.md`。
44
+ - 每节一个可验证结果:任务结束时存在读者能自己复述的检查动作;只有「读完了解释」的内容并入相邻任务。
45
+ - 节内顺序:概念 → 最小示例 → 操作 → 验证 → 边界;先让读者看到行为,再解释规则。单次操作按「做什么 → 执行什么 → 看到什么 → 简短说明」推进。
46
+ - 任务节以该章标题里的对象为准,不把每章都写成「目录、设计、构建、测试」。
47
+ - 交付清单或纯边界说明不单独设 `##`,并入引言或相邻总览节;同一头文件中连续的值类型优先并成一个可验证结果。
48
+ - 任务节内按「类型 → 简单函数 → 更难的函数」排列,最难的组装放在最后,满足先定义后调用:读者要读懂的行内标识符,其行为必须已在上文或紧邻声明中出现;未定义名字的调用链、节首概览与编号步骤整段删除。
49
+ - `##` 导语只用白话,不点后文才定义的函数名;有 `###` 时导语承接上文。
43
50
 
44
- ### 一章一个关键
51
+ ### 有 class 的章的任务节
45
52
 
46
- 每一章只有一个关键,标题、二级标题、三级标题、导语和自然段都是这个关键的部分或对它的核对。关键分两类:
53
+ 有 `class` 定义的章,任务级 `##` 按下面次序排;没有下一种内容就停,不为凑数加节:
47
54
 
48
- - 类章:头文件的主要类型是拥有数据的类。YAML `title` 用这个类的读者名,2 到 6 个汉字,不写英文类名,不把成员函数写成章标题。章首第一句按本文件「无标题引言」写出,类章同时写出类名。二级标题是类的一部分:类要用的类型、类里的成员变量、类最重要的函数、其余重要函数。成员函数可以做三级标题,不能做章标题。没有数据成员的类同样可以是类章:不写成员节,其余仍按要用的类型、类本身、类对外做的事排列。
49
- - 能力章:这一章没有这样的类。关键是这一章交给读者的那一件事。函数、文件和步骤是这件事的部分。源文件只有一个函数、而且这个函数就是交付物时,关键可以是这个函数。`main` 属于这一种。
55
+ 1. 类型:本章用到的值类型(枚举与结构体),一节一个可验证结果,可下分三级标题。
56
+ 2. 成员变量:单独一节;读取成员的函数用三级标题。只判断下标区间的检查也用三级标题放在这一节,不单独占二级标题。类说明、构造函数与数据成员拼进同一个围栏,不拆成两个围栏。
57
+ 3. 最重要的函数:这个类最重要的一个函数及配套函数。
58
+ 4. 其余重要函数:还有一组就再加一节,没有就停。
50
59
 
51
- 固定收尾 `常见错误`、`自测问题`、`本章回顾` 不改名,不升成关键。
60
+ 没有 `class` 的章不套这个次序,按「先类型,再使用这些类型的函数」重排。
52
61
 
53
- ### 源文件与编译顺序
62
+ ### 常见错误
54
63
 
55
- 章的关键与头文件里声明的物理顺序冲突时,以编译要求为准:语言要求被用到的类型先声明,被依赖的类型留在使用它的类前面。头文件不把类挪到它依赖的类型之上。叙述上的主次由章首和横幅承担,不由声明的物理顺序承担。
64
+ 服务失败后回来的读者。每个症状一个 `###`,标题后第一句写触发条件和可观察现象。
56
65
 
57
- ### 标题分层
66
+ - 误用型:一段成文写原因与正确做法;两者各需完整交代时,用症状句导语加「出错的原因/正确的做法」引导词列表。
67
+ - 排查型:按定位 → 修复 → 验证三步展开。
68
+ - 入门章只保留最可能遇到的 2–3 项,不是完整 FAQ。
58
69
 
59
- - `##` 承担大任务,且要让读者看出它承担本章 title 中的哪部分:标题应描述本页当前交付的读者结果;布局页不使用「配置并运行」作为标题,除非该页确实让读者完成并验证这些动作。
60
- - `###` 承担 `##` 内部可独立执行、观察或验证的子任务(源码阅读、产物检查、具体故障症状);一个 `##` 内含多个连续子流程时用 `###` 分步。
61
- - 只有解释或一两句结论的内容不升级为标题;正文最多保留到 H3,不写 `####`。
62
- - 每个任务级 `##` 的可验证结果判定见本文件「六段块序列」;标题写成宽泛主题时读者无法判断做到什么程度才算完。
63
- - `##` 出现多个连续子流程、或篇幅触达 token 预算(见本文件「分层上限」)时,强制拆分为 `###` 子小节,不整块下压。
64
- - 标题只用读者此刻已认识的词或字面自明的词,不使用正文之后才解释的术语。
65
- - 任务级 `##` 承担一个概念组或一项可独立交付的任务:单个类型、单个枚举或单个函数的小节不独占任务级 `##`,与相邻概念并成一组再按 `###` 分步(示例章反例:`定义坐标范围`、`保存格子状态` 曾各自独立成 `##`,粒度低于任务级;现行二级标题只记在本文件的对照里)。
66
- - 任务级 `##` 只保留读者能单独做完的一件事。只负责解释下一块代码、命令或图的,降为 `###`;短到没有独立观察步骤的,连 `###` 也不留,并进相邻正文。固定收尾「常见错误」「自测问题」「本章回顾」不合并、不降级,常见错误下面的症状继续用 `###`。
67
- - 一个任务级 `##` 下设 `###` 时至少两个:依据阮一峰 [《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide) 的标题原则,二级标题是文章的主要部分,三级标题是它下面的步骤,同级标题避免只出现一个;只有 `###` 时删去其标题归回 `##` 正文,或补出真正独立的同级小节。
68
- - `##` 导语的句数与 token 上限见本文件「分层上限」,只写这一节交出的结果,不放代码围栏;恰好 2 个 `###` 时一句点一个,3 到 7 个时不再逐个点名,点名交给三级标题(与「个数见本文件」收尾,取代旧「按顺序点名各子节对象」的概览句式)。连续值类型的任务节归并见本文件「任务序列」;一个三级标题可以只讲一个枚举、一个结构体或一个函数。紧挨着的两个值类型可以放在同一个三级标题里,各成一个短模块,示例章「操作与成败」是正例。
69
- - 标题与内容匹配:标题动词承诺的动作必须是本节正文实际让读者完成的动作——正文只要求观察的行为用「观察、查看、核对」类动词,不用「走完、完成」类只在真实操作节成立的动词;任务级标题不与页面 title 共用核心动词(如页面 title 用「明确」后,任务节不再以「明确」开头),页面 title 已承诺的动作由正文兑现,标题换用更具体的动词;二级标题的宾语要涵盖其下三级标题的宾语,读者从标题序列能看出各节分工,不写比正文更宽或更窄的承诺。改写对照见本文件「反例与改写」。
70
- - 层级结构遵循阮一峰 [《中文技术文档写作风格指南》](https://github.com/ruanyf/document-style-guide) 标题章:不跳级(一级标题下不直接出现三级标题)、避免孤立编号(同级标题只有一个时省略)、下级标题不重复上级标题的名字。
71
- - 标题与导语不写拗口动宾,不用实现细节当主叙事:「得出胜负与平局」这类把两个结果硬拼成一个动宾的标题改写成交付对象(如「终局判定」);「三连算法」是实现细节,可一句带过,不作章节 title 或 `##` 标题的主叙事(示例章反例:原 `## 得出胜负与平局` 已更名为「终局判定」,正文改说「操作后判定流程是否结束」)。
70
+ 细则是 `quarto/terminal.md`「常见错误条目形态与三步诊断流」。
72
71
 
73
- ### 标题字数
72
+ ### 自测问题
74
73
 
75
- 标题二选一与层级约定的通用 how 见 `writing-quarto` 技能 `quarto/basics.md`;本节保留本书标题三层数字与反例。目录、侧栏和页内 TOC 需要的是对象名,不是把导语缩进标题;四家文档只取这一层:learncpp 课内小节用概念名,C++ Primer 节名是对象,cppreference 节名只留实体、不留过程,中文技术文档标题收成两组词:「限定语 + 对象」,或「动词 + 具体宾语」。
74
+ 服务刚跑通主线、需要确认理解的读者。每章 0–7 道;没有可观察结果就不设题。
76
75
 
77
- | 层级 | 长度 | 形式 |
78
- | --- | --- | --- |
79
- | YAML `title` | 2-6 个汉字 | 读者在侧栏里要找的对象:概念、数据、结果用名词(流程规则、数据存储、局面快照);只有这一页的交付就是读者要执行的一个动作时,才用「动词 + 一个宾语」 |
80
- | `##` 二级标题 | 2-10 个汉字 | 这一阶段交出的对象,或读者必须动手的一个短任务:要么「限定语 + 对象」(流程数据、数据项坐标),要么「动词 + 具体宾语」(执行脚本、输入坐标) |
81
- | `###` 三级标题 | 2-10 个汉字 | 该阶段里的一个实体或一步具体动作,组词同二级(数据项坐标、检查是否三连);「常见错误」下的症状标题可到 12 个汉字,以便认出故障(找不到动态库) |
76
+ - 题目问本章已写明的一件可观察结果(会怎样、是哪一个、从几开始);只有正文写了原因且情景完整时才用「为什么」。
77
+ - 题干用本章已用过的词说全,只看题干就能作答;每个细节都要改变答案,答案不受细节影响时不单点某情形。
78
+ - 题干只描述一个自洽局面,不把矛盾事实写进同句。
79
+ - 一道题只问一件可观察结果,不把两个观察捆进同一题。要考拒绝,用正文已用过的规则问可观察结果,不为出题制造正文没走过的局面。
80
+ - 固定导语:「不要展开答案,试着自己把回答完整说出来,写完之后展开对照;说不出来的部分,回到对应小节对照正文。」
81
+ - 答案写在 `::: {.answer}` 内,由 `filters/answering-disclosure.lua` 渲染为默认收起的 `<details>`;首句直接回答,一到两句,不补题面之外的对比或延伸,只用本章讲过的概念。
82
+ - 答案里的文件、路径与标识符用行内代码,不挂链接;所属目录已在答案前文确立时,路径可省顶层前缀。
82
83
 
83
- - **同级同句式**:二级、三级标题只用两组词——要么「限定语 + 对象」(数据项坐标、操作后的结果),要么「动词 + 具体宾语」(检查是否三连、放入一枚元素);同一个二级标题下的三级标题只用其中一种。不收成「格子定义」「三连」这类看不出对象的短词。
84
- - **能单独看懂才省略**:下级不重复上级里已经说清的词;省略后在侧栏里看不懂的,保留区分词(「类型」单独不够,「流程类型」可以)。
85
- - 汉字计数只计汉字,英文和标点不计;JSON 这类读者已认识的词可以留在症状标题里,但不靠英文把标题撑长。
84
+ ### 本章回顾
86
85
 
87
- ### 形式规则
86
+ 1–2 句段落,不用列表。
88
87
 
89
- - 一律**不加冒号、破折号、括号补充说明**;并列结构可用顿号或逗号连接(如「区分声明、初始化与赋值」)。
90
- - 不堆「教程」「详解」「学习」「验证:」等泛化或解释性后缀;标题让读者预先知道这一页/节要完成什么,而不是只知道宽泛主题。
91
- - 标题不用「看懂、读懂、弄清」类口语领会词,也不预设读者的领悟结果;标题写读者要在目录里找的对象,陈述本页交付的内容(用户决定:`看懂一次完整流程` 改 `流程规则`;自动化由 `writing-quarto` 技能 `scripts/verifying-content.py` 词表承担)。
92
- - 标题不用人称、劝诱和口语动词:不写「自己走一局」「跟我做」「动手试试」这类第一人称或劝诱式;标题只留对象名或「动词 + 具体宾语」(`对局演示`、`启动对局`),不把读者本人写进标题。`scripts/verifying-content.py` 检查人称与标题里的行内代码。
93
- - 标题不以时间或过程从句起头:不把「输入之后」「看完之后」「下一步」压成 `输入之后的回应` 这类标题;从句还原成对象或短任务(`程序回应`、`查看回应`),时间关系留给导语。
94
- - 同一章的任务级 `##` 用同一种句式:类章与流程章统一收成「限定语 + 对象」名词短语(`终局判定`、`落子入口`、`棋盘还原`),同章混用「动词 + 宾语」与名词短语判为不合格;动作交给正文。
95
- - 标题不用视图隐喻和英文类名:`程序全图` 改 `程序结构`,`Ai 落子` 改 `电脑落子`;标题写读者在侧栏里查找的中文对象,类名留给正文与代码。
96
- - 标题禁元叙述与抽象空心题:不写「本节说明…」「本章规划…」类讲章节安排的标题,也不写读不出动作对象的空心名词短语(「确认依赖方向」类),一律改成「动作 + 对象」或读者已认识的对象。
97
- - title 留下读者在侧栏里要找的对象:概念、数据、结果用名词;只有这一页的交付就是读者要执行的一个动作时,才用「动词 + 一个宾语」。修饰性定语留给正文,否则「示例项目」「工程」等限定在 title 与二三级标题里连续重复(用户决定:各章 title 收尾为对象名,如流程规则、工程目录、数据存储、一次操作、构建与运行、操作策略、局面快照)。
98
- - title 不用「并」串联两个动作、不用把字句;两个动作各有任务节承载时择主撰写对象,动作细节留给导语和任务节。
99
- - 标题与导航不使用行内代码(`CMakeLists.txt` 这类名字不进标题;标题写「构建规则」「一键脚本」等表达)。
100
- - 标题只用读者此刻已认识的词或字面自明的词,不使用正文之后才解释的术语(统称禁用清单见 `steps/06-wording.md`)。
101
- - 二级、三级标题用两组词:要么「限定语 + 对象」(数据项坐标、操作后的结果),要么「动词 + 具体宾语」(检查是否三连、放入一枚元素);同一个二级标题下的三级标题只用其中一种,数字见「标题字数」。指示(这一步、这次)、过程动词(记下、收进、用到)、方式(用数组、先…再…)、把字句与数量词(三种、四个、九个)不进标题,下放到导语或正文。组词是否带限定语由改标题时逐条对照,不新增正则。导语仍按现规则:恰好两个三级时一句点一个,三个或四个时不逐个点名。
102
- - 三级标题可以保留本章对象的完整名称(如「数据项坐标」),不拆成「行与列」「空格与标记」。
103
- - 固定收尾节名固定复用,见本文件。
104
- - 过程节不承载回顾职责:`### 本章实现边界` 一类「本章做到哪、哪章再讲」的标题一律不设,边界话并入 `## 本章回顾`;开篇的目标节只陈述本章可交付产物(如 `确认本章产物`),标题与回顾分工见本文件「六段块序列」。
105
- - 英文文件名承担稳定路径职责,多词形态见本文件;中文 title 承担理解职责,两者不必逐字翻译。
106
- - 例外:part 落地页(`_quarto.yml` 中 part 引用的 index.qmd)title 即 part 名(如「示例项目」),不受 2-6 汉字硬限;副题信息只放落地页引言,章节与落地页 qmd 一律不写 `description`(front matter 出处见 basics.md),后续其他 part 同样处理。
107
-
108
- - **实体标题而不是条目数**:标题若是集合的数量(`八条线`、`三种类型`、`四个入口`),说明这一节在数条目。先看条目能否各自成为实体;能,就拆成实体标题(`八条线` 拆成 `线坐标表`、`成线判断`);不能,就改成承载它们的对象。标题不替读者数个数。对照见 `examples/02-structure-shape.md`「八条线拆成两个实体标题」。
109
-
110
- ### 定语「的」的取舍
111
-
112
- 标题(YAML `title` 与 `##`、`###` 同规)里的定语「的」按定语与中心语的关系取舍,不默认加、也不默认省:
113
-
114
- - **加「的」**:定语与中心语是两个各自成立的名词性概念,直连会长串名词堆叠或产生切分歧义(如「明确流程约定」:示例项目 与 流程约定 各自成词,去掉「的」后定语加中心语直连成七字名词串;「识别流程的进行与结束」的「的」标出领属边界)。
115
- - **省「的」**:定语与中心语合成一个单一名称或紧密概念,加「的」反而把名称拆散(如「认识示例工程布局」:示例工程 是一个整体名称)。
116
- - 判定法:把定语与中心语拆开各说一遍,两个都是完整概念就用「的」相连;合起来才是一个名称就不用。加「的」后标题超出标题字数时先改写对象词,不靠删「的」压字数。
117
-
118
- ### 纵向承诺链
119
-
120
- 写章第 2 步(定结构)逐条对照,不新开第 10 步。检查顺序固定为下面 9 条;每条的要求都是「下一层必须兑现上一层对象」:
121
-
122
- 1. part 落地页那一句引言的范围等于该部分全部章的 YAML `title` 集合。根首页卡片不把示例项目收成其中几章。
123
- 2. 章引言里「这一章做什么」那一句的宾语等于 YAML `title` 的对象。引言点名的源文件必须是本章摘录实际来自的文件。
124
- 3. 每个任务级 `##` 的中心名词是章 title 对象的一部分。有 `class` 的章按「类型、成员变量、最重要的函数、其余重要函数」的次序排任务节,形状见本文件「有 class 的章的任务节」,没有下一种内容就停在当前一种。
125
- 4. 每个 `###` 的中心名词能被父级 `##` 的宾语盖住,或是这一结果里的一步。恰好 2 个 `###` 时,`##` 导语一句点一个;3 个或 4 个时导语只写共同结果,不逐个点名。
126
- 5. `###` 那一句导语的宾语等于该 `###` 的对象。其下每个自然段的段首句保持这个对象;换对象就换 `###`,或把句子挪到已经拥有该对象的 `###`。导语点名标题里的对象,不用「这三种类型」代替还没写出的取值名。
127
- 6. `##` 下没有 `###` 是允许的,条件是这一节只有一个函数或一个结果。禁止为了「有下级」补出一个孤立 `###`。
128
- 7. 「本章回顾」里「下一章」后面的名字等于 `_quarto.yml` 中下一章的 YAML `title`,不写链接。回顾里的能力用本章 title 的对象。最后一章不写「下一章」。任务节不解释下一章才建立的术语。
129
- 8. 有 `class` 的章的任务节顺序,见本文件「有 class 的章的任务节」。任务章的 `###` 顺序与 `src/run-build.sh` 的步骤顺序一致。目录章里「有几个目录」的句子与该节目录树的项数一致,口径见本文件。
130
- 9. 章题一致:YAML `title` 的对象与本章的主对象相同。把引言第一句、各任务级 `##` 的中心名词、`## 本章回顾` 的能力句并排看;三处指向的对象与 title 不同,说明正文写成了另一章,先改 title 或重排任务节,不写导语把 title 拉回来。标题写 `对局规则`、正文多数节却在讲程序回应的,按章题脱节处理;`输入之后的回应` 这类时间从句标题是同一处的信号。项目技能有章节表时,同轮同步表的 `title` 与 `##` 顺序;表与正文不一致按章题脱节处理。
131
-
132
- ### 命名检查
133
-
134
- 改 title 不改文件名,除非主题边界或页面职责变化;改动后用 `quarto_render_check` 检查右侧目录与书内导航显示。页面 title 变化时,part 落地页的卡片标题与一句话描述同步改为新 title 的承诺,一句话仍概括该章交付,不沿用旧措辞。
88
+ - 「你已经能 <能力>」对应本章任务节交出的结果,可复用任务节关键词;不写正文没有的抽象总称。
89
+ - 「下一章 <预告>」不写链接,直述一句;预告不引入下一章才建立的术语。
90
+ - 每个说法都要能在正文找到出处,禁止空泛能力句或只写预告;任务节变化时同步改写。
135
91
 
136
- ### 计数口径
92
+ ## 一章一个关键
137
93
 
138
- 估算 token = 中日韩字符数 × 1.5 + 其他字符数 ÷ 4。公式对主流分词器(GLM、Claude、GPT)取保守上界,只用于预算比较,不声称等于真实 token 数。
94
+ 每一章只有一个关键,标题、各级标题、导语和自然段都是它的部分或核对。关键分两类:
139
95
 
140
- - **计入**:正文、标题、列表、表格、Callout 与链接锚文本。
141
- - **不计入**:YAML frontmatter、链接目标、代码围栏(`{.cpp}`、`{.text}`、bash 等)全文、`{mermaid}` 图表全文、`{python}` 可执行单元全文。逐字代码与图表是机器寻址或视觉对象,读者扫读时整体跳过;token 预算度量的是读者逐句读过的正文当量。
142
- - 代码与图表不计 token 不等于免检:它们仍受分层的行数上限与注释连续行检查约束(见「分层上限」)。
143
- - **任何链接只计读者看见的锚文本,不计目标**(计数口径收紧):`[锚]` 与 `(目标)` 组成的行内链接、`[锚][ref]` 引用式链接只计锚(锚内可含行内代码);`<https://…>` 与裸 URL 计 0。GitHub 绝对链接的 URL 是机器寻址字符串,相对链接目标是页面地址,计入都会挤占正文预算;`verifying-content.py` 在计数前把整段链接替换为锚文本,再进入统计。
144
- - 字符数按 Unicode 字符计:汉字、全角标点各算 1 个字符,归入中日韩一侧。
145
- - 节导语口径:标题之后、首个代码块/列表/表格/引用/盒子(div)之前的连续正文;空行只分段,不结束导语。导语内链接只计锚文本。
146
- - 引用块口径:连续 `>` 行合并为一块计数,链接只计锚文本;Callout 盒子(`:::`)不是引用块,按其自身层级计入所属分节。
96
+ - 类章:头文件的主要类型是拥有数据的类。YAML `title` 用类的读者名(2–6 个汉字,不写英文类名);章首第一句同时写出类名。二级标题是类的一部分:要用的类型、成员变量、最重要的函数、其余函数。成员函数可做三级标题,不能做章标题。没有数据成员的类同样可以是类章:不写成员节,其余按「要用的类型 → 类本身 → 对外做的事」排列。
97
+ - 能力章:没有这样的类,关键是这一章交给读者的那一件事;函数、文件和步骤都是它的部分。源文件只有一个函数且这个函数就是交付物时,关键可以是这个函数(`main` 属于这一种)。
147
98
 
148
- ### 分层上限
99
+ 固定收尾「常见错误」「自测问题」「本章回顾」不改名,不升成关键。
149
100
 
150
- | 层级 | 上限 |
151
- | --- | --- |
152
- | 整章(frontmatter 外全部内容,只含计入部分) | 5000 token |
153
- | 无标题引言(首个 `##` 之前) | 400 token |
154
- | 每个 `##` 正文(不含代码和图表) | 400–1200 token;一章只有一个任务级 `##` 时该节 200–1200(下限只约束任务级,固定收尾不设下限)。区间按现有章节的正文当量定,低于下限合并或降级,不补空话 |
155
- | 任务级 `###` 正文(不含代码和图表) | 有代码、表或图时下限 40 token,没有这些块时下限 120 token;上限 640 token |
156
- | 「常见错误」的症状 `###`(不含代码和图表) | 60–240 token,不套任务级 `###` 的 120 下限 |
157
- | 「自测问题」与「本章回顾」 | 不设新的上下限,本章回顾保持短 |
158
- | 任务级 `##` 数量 | 通常不超过 4 个;按独立任务划分的原则见本文件「六段块序列」 |
159
- | 每个 `##` 下 `###` 数量 | 2 到 7 个;只有 1 个时并入 `##` 正文或补同级 |
160
- | 普通代码块(围栏内内容行) | 20 行 |
161
- | `{mermaid}` 图表块 | 40 行 |
162
- | `{python}` 可执行单元(坐标图等) | 30 行 |
163
- | 单个正文段落(代码块、表格、列表与标题之外的连续文本段) | 70–220 token;下限拦过短段(70 token ≈ 45 汉字当量),上限保持上限,写作舒适带 90–180。豁免下限:章引言段、`##`/`###` 节导语、紧邻代码/列表/表/图/盒子的单句块前导语、本章回顾、自测固定导语、Callout 盒子内段落;豁免类仍受 220 上限约束。低于下限的补法见 `steps/05-sentences.md`「导语衔接」 |
164
- | `##` 节导语(标题后、首个代码块/列表/表格/引用/盒子前) | 120 token 且 ≤2 句,不放代码围栏;设 `###` 的任务级 `##` 导语不另设下限,导语点名的句式见本文件「标题分层」 |
165
- | `###` 节导语(同口径,到首个盒子/代码块/列表前) | 80 token 且 ≤1 句 |
166
- | 单个 `>` 引用块(连续引用行合并计) | 80 token |
167
- | 代码片段内注释 | 写法与限额见 `steps/03-blocks.md`「代码块 filename 标注」 |
168
- | 一章 Callout | 不设下限;超过 8 个失败。写作时常例是 1 到 3 个 |
101
+ ### 术语与验证策略
169
102
 
170
- `{python}` 可执行单元应只含助手调用,绘图逻辑在共享助手库(见 `quarto/coords.md`);超出 30 行说明把绘图逻辑内联进了正文,属于结构违规。
103
+ - 标题、导语与任务节只用读者在前文已认识的名字;本章新术语在首次真正使用处就近定义,不在标题里抢先出现。
104
+ - 每个任务节交付一个可观察结果;章末「本章回顾」只复述这些结果,不引入新承诺。项目有章节表时,关键、`title` 与二级标题同轮同步。
171
105
 
172
- 数字依据:没有规定章节字数的权威国标(GB/T 7713《科技报告编写规则》只管结构格式);技术写作社区实践是单节对应 3-5 分钟阅读(约 1500-3000 字)、单个功能模块 800-1200 字,超限优先拆分。按 CJK×1.5 换算,整章 5000 token 约合 3300 汉字的正文当量,是「一节一件事、一章四节左右」的自然边界。
106
+ ### 源文件与编译顺序
173
107
 
174
- ### 执行方式
108
+ 章的关键与头文件里声明的物理顺序冲突时,以编译要求为准:被用到的类型先声明,被依赖的类型留在使用它的类前面。叙述主次由章首与横幅承担,不由声明顺序承担。
175
109
 
176
- - `verifying-content.py` 第 3 查按上表逐文件、逐节、逐代码块、逐正文段落核对,超限即整体失败;限额调整只改该脚本的常量与本表,两处必须同步。
177
- - 根目录 `index.qmd` 与 `content/<game>/index.qmd`(YAML 含 `body-classes: index-page`)是着陆页:短引言与卡片网格不是章节引言,只核对整章总量与代码块限额;着陆页不套用标题与骨架限制,见本文件「六段块序列」。
178
- - 任务级 `##` 数量、固定收尾不计入、`###` 的使用条件与首章「常见错误」豁免的结构判断,见本文件「六段块序列」;数量口径以上表为准。
179
- - 结构性规则(引言构成、`###` 数量)同时受本文件「六段块序列」约束;本表提供量化兜底。
180
- - 接近上限不是目标:预算是上限,内容仍按凑字数禁令与密度规则精简(见 `steps/04-paragraphs.md`「凑字数禁令」)。
110
+ ## 标题
181
111
 
182
- ### 页面宽度与垂直节奏
112
+ ### 标题分层
183
113
 
184
- 页面“紧凑”通常有两个来源:正文列太窄导致无谓换行,或块之间缺少承接留白。优先小幅放宽 Quarto HTML grid 的 `body-width`,再用共享 CSS 调整正文块间距;不要只放大字体,也不要用局部规则给每个块重复加 margin。正文列仍需保留 `max-width: 100%`,代码和宽表在窄屏上继续滚动或换行。
114
+ | 层级 | 长度 | 形式 |
115
+ | --- | --- | --- |
116
+ | YAML `title` | 2–6 个汉字 | 侧栏里要找的对象:概念、数据、结果用名词;整页交付就是一个动作时才用「动词 + 宾语」 |
117
+ | `##` | 2–10 个汉字 | 这一阶段交出的对象,或读者必须动手的短任务:「限定语 + 对象」或「动词 + 具体宾语」 |
118
+ | `###` | 2–10 个汉字 | 该阶段里的一个实体或一步具体动作;「常见错误」下的症状标题可到 12 个汉字 |
119
+
120
+ - `##` 承担大任务,要让读者看出它承担本章 title 的哪部分;`###` 承担可独立执行、观察或验证的子任务;正文最多到 H3,不写 `####`。
121
+ - 只有解释或一两句结论的内容不升级为标题;`##` 含多个连续子流程或篇幅触达预算时,拆 `###`,不整块下压。
122
+ - 一个 `##` 下设 `###` 时至少两个:同级只有一个时,删去标题归回正文,或补出真正独立的同级小节。
123
+ - 标题只用读者此刻已认识的词或字面自明的词,不用正文之后才解释的术语。
124
+ - 单个类型、单个枚举或单个函数的小节不独占任务级 `##`,与相邻概念并成一组再下分 `###`。
125
+ - 标题与内容匹配:标题动词承诺的动作必须是正文实际让读者完成的动作;只要求观察的用「观察、查看、核对」,不用「走完、完成」。任务级标题不与页面 title 共用核心动词;`##` 的宾语要涵盖其下 `###` 的宾语。
126
+ - 层级不跳级;下级标题不重复上级标题的名字;标题与导语不写拗口动宾,不用实现细节当主叙事。
185
127
 
186
- 当前仓库采用 840px 的正文内容列和约 1.55rem 的普通块间距,代码块连续出现时保留更大的间隔。代码块与正文同宽:不再对代码做二次限宽(`--code-max-width` 已删除),宽屏两侧留白属主流文档站(VitePress 1440 壳/688 正文)正常行为,不按显示器拉满正文。872px/840px 的取值依据(100 列代码不折行)见 `../designing-theme/knowledge/reading-surface.md`。评估重点是:每个任务是否有清晰的动作与结果、连续盒子之间是否有解释段、移动端是否出现横向溢出。这里不设置依赖浏览器截图的硬阈值,最终以 `quarto_render_check` 渲染出的 HTML 结构和实际阅读抽查为准。
128
+ ### 标题字数
187
129
 
188
- Quarto 通过 HTML grid 控制正文、侧栏和目录列,代码块的 `filename`、换行和复制行为由代码块配置及 CSS 共同控制;页面宽度与代码标题过长是两个独立问题。
130
+ YAML `title` 2–6 个汉字;`##` 与 `###` 2–10 个汉字,「常见错误」下的症状标题可到 12 个。按可见汉字计,英文、数字和标点不计入;part 落地页的 title 例外。
189
131
 
190
- ### 一图一事与同主题相邻
132
+ ### 句式
191
133
 
192
- 图是读者视觉负荷最高的盒子:一张图同时表达两条关系时,读者要同时在脑子里维护两个对照,图前正文与图后结论也各要写两遍才能闭环。因此一张图只核对一条已讲清的关系,需要两条就拆图或拆节;一图一事与主题错位拆 `###` 的边界见 `steps/03-blocks.md`「代码与图的桥接」。代码与图相邻的前提是同一对象:图讲 B 而前后代码讲 A、C 时,读者被迫在三个对象间跳转,这正是「代码 A → 短句拐弯 → 图讲 B → 再贴代码 C」式堆叠的成因。主题错位时先用一句正文收束本对象,再另起 `###`。图中的每个框和箭头都应能在图前正文找到出处;图引入正文没有的概念时,读者只能靠猜。写法见 `writing-quarto` 技能 `quarto/authoring.md`「代码与图的桥接」。
134
+ - 二级、三级标题只用两组词:要么「限定语 + 对象」(数据项坐标、操作后的结果),要么「动词 + 具体宾语」(检查是否三连、放入一枚元素)。同一个 `##` 下的 `###` 只用其中一种。
135
+ - 任务级 `##` 在同一章内用同一种句式;类章与流程章统一收成名词短语,动作交给正文。
136
+ - 标题若是集合的数量(`八条线`、`三种类型`),先看条目能否各自成为实体;能就拆成实体标题,不能就改成承载它们的对象。标题不替读者数个数。
137
+ - 标题不用人称、劝诱和口语动词(「自己走一局」「跟我做」),不把读者写进标题。
138
+ - 标题不以时间或过程从句起头(「输入之后的回应」还原成「程序回应」),时间关系留给导语。
139
+ - 标题不用视图隐喻和英文类名:`程序全图` 改 `程序结构`,`Ai 落子` 改 `电脑落子`。
140
+ - 标题禁元叙述与空心题:不写「本节说明…」「本章规划…」,不写读不出动作对象的短语。
141
+ - 标题与导航不使用行内代码;文件名承担路径职责,中文 title 承担理解职责,两者不必逐字翻译。
142
+ - 过程节不承载回顾职责:`### 本章实现边界` 一类标题不设,边界话并入 `## 本章回顾`。
143
+ - 例外:part 落地页的 title 即 part 名,不受 2–6 汉字硬限;章节与落地页一律不写 `description`。
193
144
 
194
- ### 主线必须先闭合
145
+ ### 形式规则
195
146
 
196
- 读者在教程中需要不断确认"我现在做什么"和"我是否做对了"。如果命令、输出、参数解释和下一步背景交错出现,读者必须频繁切换目标,无法判断哪一块是必经步骤。先给唯一动作和可见结果,再补解释,能把首次成功压缩成一条可回放的路径。
147
+ - 不加冒号、破折号、括号补充说明;并列结构可用顿号或逗号。
148
+ - 不堆「教程」「详解」「学习」「验证:」等泛化或解释性后缀。
149
+ - 不用「看懂、读懂、弄清」类口语领会词,不预设读者的领悟结果。
150
+ - 不用「并」串联两个动作,不用把字句;两个动作各有任务节承载时择主撰写对象。
151
+ - 指示(这一步、这次)、过程动词(记下、收进、用到)、方式(用数组、先…再…)与数量词(三种、四个)不进标题,下放导语或正文。
197
152
 
198
- 主线闭合要求一节只有一个要闭合的目标:标题、第一句、动作和验收输出指向同一个结果,中途出现第二个独立动作时,读者就无法判断当前在等哪一个。任务粒度本身的判定标准属于页面结构,见本文件。
153
+ ### 定语「的」
199
154
 
200
- 标题对齐同时排除离题辩白:操作小节里与标题无关的工程取舍长论(「为何不跳过某步 / 幂等 / 配置漂移」类)让读者在动作中途读辩白,主线被打断;执行规则见 `steps/03-blocks.md`「小节标题与正文对齐」。
155
+ 标题里的「的」按定语与中心语的关系取舍,不默认加也不默认省:
201
156
 
202
- 当多个 `###` 共享同一阶段、环境或产物时,可以用父级 `##` 统摄,但父级只负责分组,不能把两个各自可验收的任务压成一个模糊标题。父标题要写清当前阶段或范围,子标题继续使用可执行、可观察的任务名。
157
+ - 加「的」:定语与中心语是两个各自成立的名词性概念,直连会长串名词堆叠或切分歧义。
158
+ - 省「的」:两者合成一个单一名称或紧密概念,加「的」反而把名称拆散。
159
+ - 判定法:拆开各说一遍,两个都是完整概念就用「的」相连;合起来才是一个名称就不用。加「的」后超字数时先改写对象词,不靠删「的」压字数。
203
160
 
204
- ### 长段拆分的判断依据
161
+ ### 命名同步
205
162
 
206
- 长段的问题不在于占据多少行,而在于它要求读者同时记住多个职责。主线动作、成功判据和可跳过说明压在同一段时,只读必要内容的读者必须重新寻找下一步,逐字阅读的读者又无法判断哪些细节可以跳过。按职责拆成短段,能让首次执行和回看细节两条路径自然分开。
163
+ 改 title 不改文件名,除非主题边界或页面职责变化;改后跑 `quarto_render_check` 看右侧目录与导航。页面 title 变化时,part 落地页的卡片标题与一句话描述同步改为新承诺。项目技能有章节表时,同轮同步表的 `title` 与 `##` 顺序;表与正文不一致按章题脱节处理。
207
164
 
208
- 普通 Callout 不能成为细节垃圾桶。把可以跳过的内容集中进提示框后,读者仍要判断这段是否影响当前任务,而且视觉上独立的盒子容易像必经步骤。只有删除后不影响首次成功和验收的信息才适合下沉,并且一个最小模块最多一个 Callout,一章的个数见本文件;术语解释型 Callout 是就近放置的例外,写法与限制见 `steps/03-blocks.md`。稳定界面判据与它的解释同框时,另见下节约束。
165
+ ## 纵向承诺链
209
166
 
210
- 合并与拆分都按信息职责判断,不按固定字数。同一状态内部的账号创建和正常现象可以合并。成功判据与后续执行范围进入下一个状态时另起一段,即使它们仍属于同一次首次启动流程。
167
+ 定结构时逐条对照,不新开第 10 步。每条的要求都是「下一层必须兑现上一层对象」:
211
168
 
212
- ## 情况
169
+ 1. part 落地页那句引言的范围等于该部分全部章的 title 集合;根首页卡片不把项目收成其中几章。
170
+ 2. 章引言里「这一章做什么」的宾语等于 title 的对象;引言行名的源文件必须是本章摘录实际来自的文件。
171
+ 3. 每个任务级 `##` 的中心名词是章 title 对象的一部分;类章按「类型、成员、最重要函数、其余函数」排。
172
+ 4. 每个 `###` 的中心名词能被父级 `##` 的宾语盖住,或是这一结果里的一步;恰好 2 个 `###` 时导语一句点一个,3–4 个时只写共同结果。
173
+ 5. `###` 导语的宾语等于该 `###` 的对象;其下每段段首保持这个对象,换对象就换 `###` 或挪句。
174
+ 6. `##` 下没有 `###` 是允许的,条件是这一节只有一个函数或一个结果;禁止补孤立 `###`。
175
+ 7. 「本章回顾」里「下一章」的名字等于 `_quarto.yml` 中下一章的 title,不写链接;回顾的能力用本章 title 的对象;最后一章不写「下一章」。
176
+ 8. 类章任务节顺序按上文;任务章的 `###` 顺序与构建脚本步骤顺序一致;目录章的「有几个目录」与目录树项数一致。
177
+ 9. 章题一致:引言第一句、各 `##` 中心名词、回顾能力句并排看,三处对象必须与 title 相同;不同说明正文写成了另一章,先改 title 或重排任务节。
213
178
 
214
- ### 情况:类章或能力章
179
+ ## 分层上限
215
180
 
216
- 类章按「是什么、怎么用、边界在哪」排任务节;能力章按「做完什么、怎么做、怎么验」排。同一本书里两种章各自固定次序,不混排。
181
+ ### 计数口径
217
182
 
218
- ### 情况:标题归并
183
+ 估算 token = 中日韩字符数 × 1.5 + 其他字符数 ÷ 4;只用于预算比较,不声称等于真实 token 数。计入正文、标题、列表、表格、Callout 与链接锚文本;不计 YAML、链接目标、代码围栏、mermaid 与可执行单元全文。任何链接只计锚文本。
219
184
 
220
- 两个标题讲同一件事就并成一个,下层的句子跟着走,不重写。承诺链断开时先并标题,再动句子。
185
+ ### 上限表
221
186
 
222
- ### 情况:全章重构
187
+ | 层级 | 上限 |
188
+ | --- | --- |
189
+ | 整章(frontmatter 外,只含计入部分) | 5000 token |
190
+ | 无标题引言 | 400 token |
191
+ | 每个 `##` 正文(不含代码/图) | 400–1200 token;一章只有一个任务级 `##` 时 200–1200 |
192
+ | 任务级 `###` 正文 | 有代码/表/图时下限 40,没有时下限 120;上限 640 |
193
+ | 「常见错误」症状 `###` | 60–240 token,不套任务级下限 |
194
+ | 任务级 `##` 数量 | 通常不超过 4 个 |
195
+ | 每个 `##` 下 `###` 数量 | 2–7 个 |
196
+ | 普通代码块 | 20 行 |
197
+ | `{mermaid}` / `{python}` | 40 / 30 行 |
198
+ | 单个正文段落 | 70–220 token;写作舒适带 90–180。豁免下限:章引言、节导语、紧邻块的单句前导、回顾、自测固定导语、Callout 内段落 |
199
+ | `##` 节导语 | 120 token 且 ≤2 句 |
200
+ | `###` 节导语 | 80 token 且 ≤1 句 |
201
+ | 单个 `>` 引用块 | 80 token |
202
+ | 一章 Callout | 超过 8 个失败;常用 1–3 个 |
203
+
204
+ 数字依据:技术写作社区实践是单节 3–5 分钟阅读(1500–3000 字)、单个功能模块 800–1200 字;按 CJK×1.5 换算,整章 5000 token 约合 3300 汉字的正文当量,是「一节一件事、一章四节左右」的自然边界。
205
+
206
+ ## 执行与例外
207
+
208
+ - `verifying-content.py` 第 3 查按上表逐文件、逐节、逐代码块、逐段核对,超限即失败;调限额只改该脚本常量与本表,两处同步。
209
+ - 根 `index.qmd` 与 part 落地页(`body-classes: index-page`)只核对整章总量与代码块限额,不套标题与骨架限制。
210
+ - 接近上限不是目标:预算是上限,内容仍按第 4 步的凑字数禁令精简。
211
+ - 标题归并:两个标题讲同一件事就并成一个,下层句子跟着走,不重写。
212
+ - 全章重构:第 1–2 步只定删留和标题;发现某段要重写,记下来留给第 5–7 步。
213
+ - 判不准时打开 `examples/02-structure-shape.md`。
223
214
 
224
- 第 1–2 步只定删留和标题。发现某段要重写,记下来留给第 5–7 步,不在这里改。
215
+ ## 情况
216
+
217
+ - 类章按「类型 → 成员变量 → 最重要函数 → 其余函数」排任务节;没有 `class` 的章按「类型 → 使用这些类型的函数」排。
218
+ - 只有一项交付、没有可独立复现失败症状的工程章,可省「常见错误」,其余固定收尾保留。
219
+ - 着陆页与根首页不套六段骨架,只核对整章预算、标题层级与卡片承诺。
220
+ - 全章重构或跨章搬迁时,先按「章节骨架」定删留,再进入标题与句子步骤。
225
221
 
226
222
  ## 正反例
227
223
 
228
- 通用情况判得准就不打开。判不准时打开 `examples/02-structure-shape.md`。
224
+ 正例:章题「棋盘」→ 引言点明 3×3 棋盘 → 任务节「类型与坐标」「成员与接口」「写入与清空」「终局判定」→ 固定收尾;每个 `##` 都是「棋盘」的一部分。
225
+
226
+ 反例一:章题「棋盘」,任务节却按「打开文件、修改、编译、运行」排——把读者动作当结构,偏离本章关键。反例二:标题写成「进行棋盘的初始化操作」——空动词加关系词把对象挤到末尾,读者在目录里扫不到「棋盘」。
@@ -140,7 +140,7 @@ int main() {
140
140
 
141
141
  ### 盒子密度
142
142
 
143
- 盒子指代码块、表格、提示框、引用块、图表容器。密度阈值与权衡的唯一出处见本文件,本条不重写数字。
143
+ 盒子指代码块、表格、提示框、引用块、图表容器。密度按本节与「机械检查」的软门禁人工判断,不设硬阈值。
144
144
 
145
145
  ### 标题导语
146
146
 
@@ -163,7 +163,7 @@ int main() {
163
163
  | --- | --- | --- |
164
164
  | 标题 → 正文 | 标题下至少一句引导;禁止 `##` 后立刻 `###` 叠标题 | `steps/02-structure.md` 与本文件 |
165
165
  | 段 → 列表 | lead-in 含主谓、点名列表将展开的维度;完整句可用句号,明确「如下」时用冒号;列表项平行且字数带 | `steps/07-layout.md`「列表选择」 |
166
- | 段 → 代码 | 一句完整导语(对象标识符 + 谁调用/做什么)→ 围栏;禁块前半句 + 块后补半句;函数或枚举围栏前固定两句:第一句接住上一句的对象,第二句使用紧随围栏里 `///` 第一句的动词和对象,位置写成「定义在 `文件` 里」,不用「声明在」 |本文件「内容块前后的闭环」 |
166
+ | 段 → 代码 | 一句完整导语(对象标识符 + 谁调用/做什么)→ 围栏;禁块前半句 + 块后补半句;函数或枚举围栏前固定两句:第一句接住上一句的对象并点名函数或枚举,第二句写读者为什么要看它、它在调用链里的位置或与邻块的关系;可以沿用围栏 `///` 的术语,但不得同义复述注释;位置写成「定义在 `文件` 里」,不用「声明在」 |本文件「内容块前后的闭环」 |
167
167
  | 代码 → 图 | 代码 → 桥接句 → 图 → 图后结论;空行 ≠ 桥接 |本文件「代码与图的桥接」 |
168
168
  | 段 → 表 | 关系句引出 → 表 → 表后结论句 |本文件「短表与宽表」 |
169
169
  | 任意块 → Callout | Callout 只承载可跳过提示,不复述块内已写信息,不承载唯一成功判据 |本文件「元素边界」 |
@@ -31,6 +31,15 @@
31
31
 
32
32
  「只读」「只写」是读写性质的固定术语,保留;`const` 成员函数首次称「只读」时,写明它不改动对象。安全、协议或验收条件确实需要排他时,写成可核对的条件(「`PlaceCell` 在目标格子非空时返回 `false`」),不靠「只」承担论证。
33
33
 
34
+ ### 结论必须带成立条件
35
+
36
+ 写「终局后……」「完成后……」「结束后仍然……」这类状态结论时,先把成立条件写出来。没有前提的绝对句会让读者把特例当成通例。
37
+
38
+ - 不佳:终局后空格仍在。
39
+ - 改写:一方已经三连而棋盘尚未占满时,对局结束,空格仍然留着;平局时棋盘已满,没有空格。
40
+
41
+ 判定信号:句子里出现「终局 / 完成 / 结束 / 之后仍然 / 总是 / 都会」,却找不到「在……时」「当……时」「如果……」。历史原因或旧行为也要写清触发条件,不要只写结果。
42
+
34
43
  ### 表示、保存、记录,不用「承载」
35
44
 
36
45
  读者正文不把类型或字段写成「承载」某个值。「承载」是抽象能力或文档职责的说法,套到 `struct`、`enum`、字段上会让读者分不清它表示什么、运行时保存什么。
@@ -64,7 +64,7 @@
64
64
 
65
65
  ### 润色流程:沿着步骤走
66
66
 
67
- 润色任务沿 `SKILL.md` 的路由执行:增量任务只走与改动对应的步骤;新章、新阶段或用户明确要求全章重构才从定任务走到通过检查。判定标准见 `steps/06-wording.md`。书根 `README.md` 与 `README.en.md` 是仓库说明页,按 `SKILL.md` 的例外只走第 5–8 步,这个例外优先于本步的跳步判定。两种走法共用 1–9:**增量润色**保持最小改动,只改判为不合格的句子,不做风格重塑;**全章重构**按 `SKILL.md`「两种走法」走——章级(1–2)先定删留不动句子,节级(3–4)只拆块和段,句级(5–7)逐句拆开再写回去,该层全部重组,不走最小改动。执行时遵守定段落节的既有判定:分句骨架在定句子判为不合格,不在定段落里顺手改句子。
67
+ 润色任务沿 `SKILL.md` 的路由执行:增量任务只走与改动对应的步骤;新章、新阶段或用户明确要求全章重构才从定任务走到通过检查。判定标准见 `steps/06-wording.md`。书根 `README.md` 与 `README.en.md` 是仓库说明页,按 `SKILL.md` 的例外只走第 5–8 步,这个例外优先于本步的跳步判定。三种走法共用同一套九步:**增量润色**保持最小改动,只改判为不合格的句子,不做风格重塑;**全章重构**按 `SKILL.md`「三种走法」走——章级(1–2)先定删留不动句子,节级(3–4)只拆块和段,句级(5–7)逐句拆开再写回去,该层全部重组,不走最小改动;**只读审查**按同一套九步核对,逐条报告,不改文件。执行时遵守定段落节的既有判定:分句骨架在定句子判为不合格,不在定段落里顺手改句子。
68
68
 
69
69
  同一处同时命中多条规则时,先按 `references/priority.md` 排级:事实与读者任务 > 结构 > 清晰 > 一致 > 风格。高层没有解决,不先做低层润色;低层改动碰到高层事实,停手退回。
70
70