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

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.13`; to follow a GitHub tag, write `github:chengzhao-dev/dsh-quarto-book#v0.6.13`.
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`.
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.13`,跟 GitHub 标签时写 `github:chengzhao-dev/dsh-quarto-book#v0.6.13`。
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`。
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
 
@@ -774,11 +774,12 @@ export function registerRenderCheckTool(tools) {
774
774
  if (typeof cwd !== 'string' || cwd.trim() === '') {
775
775
  return refusedResult('当前会话没有 cwd;quarto_render_check 只在 Quarto Book 项目的会话 cwd 内工作。');
776
776
  }
777
- const root = await findBookRoot(cwd);
777
+ const qmdPath = path.resolve(cwd, args.qmd_path);
778
+ const root = (await findBookRoot(cwd)) ?? (await findBookRoot(path.dirname(qmdPath)));
778
779
  if (!root) {
779
780
  return refusedResult('当前会话不在 Quarto Book 项目内:需要 git checkout、_quarto.yml 的 type: book,以及至少一个 .qmd 或 .md 源文件。');
780
781
  }
781
- return runRenderCheck({ root, qmdPath: path.resolve(cwd, args.qmd_path), dryRun: args.dry_run, signal: exec?.signal });
782
+ return runRenderCheck({ root, qmdPath, dryRun: args.dry_run, signal: exec?.signal });
782
783
  },
783
784
  presentCall(args) {
784
785
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chengzhao-dev/dsh-quarto-book",
3
- "version": "0.6.13",
3
+ "version": "0.6.14",
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",
@@ -61,6 +61,7 @@
61
61
  "dsh",
62
62
  "deepseek-harness",
63
63
  "dsh-plugin",
64
+ "cordis",
64
65
  "quarto",
65
66
  "quarto-book",
66
67
  "technical-writing",
@@ -13,7 +13,7 @@
13
13
  | 3 定尺度 | 字号台阶、行长与栏宽;视口不够时不改字号,只让代码块横向滚动 | `references/theme-system.md`「字号、行长与页面尺度(定尺度)」+ `assets/theme/css/tokens.css` |
14
14
  | 4 定颜色 | 正文、强调、链接、次要文字、代码标题在 `body` 与 `body.quarto-dark` 各写一套;Solarized 覆盖层写 `html[data-palette="solarized"]`,山光覆盖层写 `html[data-palette="hill-light"][data-mode="…"] body`;代码语法色默认改 `palettes/flexoki/highlight-light.theme` / `highlight-dark.theme` 两份主题文件,Solarized 与山光的语法色写各自 `palettes/<name>/syntax.css`;切换后核对加粗、链接、链接里的加粗、列表小标题和代码文件名没有串色 | `references/theme-system.md`「令牌与色板(定颜色)」+ `assets/theme/palettes/flexoki/tokens.css` + `assets/theme/palettes/flexoki/highlight-*.theme` + `assets/theme/palettes/solarized/syntax.css` |
15
15
  | 5 定组件 | 只打开要改的那一个 `assets/theme/css/*.css`;导航字重、答案折叠、行内代码、复制按钮、打印换行属于这一步,不在定颜色里顺手改 | `references/theme-system.md`「组件约定(定组件)」对应条目 |
16
- | 6 通过检查 | `scripts/checking-layout.py`,然后整本 `render`;只检查,不在这一步发明新的字号或颜色 | `scripts/checking-layout.py`;检查项回到本步骤表与 `theme-system.md`「组件约定」 |
16
+ | 6 通过检查 | `scripts/checking-layout.py`,然后整本 `render`;需要无障碍交叉验证时在 `format.html` 打开 `axe: true`(Quarto 内置 axe-core);只检查,不在这一步发明新的字号或颜色 | `scripts/checking-layout.py`;检查项回到本步骤表与 `theme-system.md`「组件约定」 |
17
17
 
18
18
  ## 增量链(改规则)
19
19
 
@@ -7,7 +7,7 @@ metadata:
7
7
 
8
8
  # Skill: writing-quarto
9
9
 
10
- 承载 `.qmd` 章节的写法流程与 Book 结构约定。正文只有九步:增量任务只打开与这次改动对应的一个 `steps/` 文件;九步同走只用于新章、新阶段,或用户明确要求全章重构。判不准才打开步骤点名的那一个 `examples/` 案例;要排图、查渲染才打开 `quarto/`。不读插件包内的 `docs/`,也不读书里的旧通用副本。
10
+ 承载 `.qmd` 写法与 Book 结构约定。正文九步:增量任务只开对应一步;全章重构才走九步。判不准才开步骤点名的 `examples/` 案例,排图与查渲染开 `quarto/`;研究目录 `docs/research/` 只供开发。
11
11
 
12
12
  ## 适用场景
13
13
 
@@ -37,8 +37,6 @@ metadata:
37
37
 
38
38
  两条走法共守同一组不变量,写在这里,不重复进各步:不新增原文没有的事实、数字、命令、性能结论、引文和出处;不把「可能」「通常」「在本书里」这类留有余地的说法改成确定说法;保留否定、条件、范围、时间和归属;围栏里的代码、命令、路径、URL 与 YAML 不改。增量润色只删除和换词,不扩写、不补论证;全章重构可删可换序,但不能发明事实,也不能把限定说成确定。
39
39
 
40
- 后一步发现前一步没做完,退回那一步改一次;同一文件第二次仍失败就停在检查输出上,不重走整段。
41
-
42
40
  ## 九步
43
41
 
44
42
  九步按四个写作域分:写作 1–2,布局 3–4 与 7,润色 5–6 与 8,排版归主题技能;第 9 步是检查与渲染。跨域改动按「写作 → 布局 → 润色」的顺序推进,前一步落定再进下一步。
@@ -54,6 +52,10 @@ metadata:
54
52
  8. 回读并退回:按现象判断属于哪一步,先按 `references/priority.md` 判冲突,再退回那一步改。规则在 `steps/08-reread.md`。
55
53
  9. 检查与渲染:先核对内容与链接,再调 `quarto_render_check` 渲染并检查 HTML。规则在 `steps/09-check.md`。
56
54
 
55
+ ## 规则卡
56
+
57
+ 改句子、改块、改标题时,按需打开 `references/rules-cards.md` 的一张卡(C01–C30)查正例与反例,不整份读。卡是结论的紧凑副本,步骤文件仍是权威;两者冲突时以步骤为准。
58
+
57
59
  ## 完成判据
58
60
 
59
61
  - [ ] 本轮点名的文件走完它对应的步骤,改动落在正文里;不要求九步全走。
@@ -43,7 +43,7 @@
43
43
 
44
44
  ## 混排自查
45
45
 
46
- `python <skill>/scripts/checking-prose.py --root <book>` 检查中文与拉丁字母、数字、行内代码之间的空格,以及中文句里的半角标点。脚本只报高置信项,不替代人工回读。
46
+ `python <skill>/scripts/checking-prose.py --root <book>` 检查中文与拉丁字母、数字、行内代码之间的空格,以及中文句里的半角标点。脚本只报高置信项,不替代人工回读。环境里只有 `python3` 时,把命令里的 `python` 换成 `python3`。
47
47
 
48
48
  ## 依据
49
49
 
@@ -0,0 +1,164 @@
1
+ # 规则卡
2
+
3
+ 研究结论的压缩版。每张卡一行规则、一个正例、一个反例和所属步骤;写正文时按需打开一张,不要整份读完。
4
+ 来源编号见 `docs/research/synthesis.md` 的表格;卡号写进步骤文件末尾,便于追溯。
5
+
6
+ ## 句子
7
+
8
+ **C01 段首给结论。** 第一句写这段要读者记住的事,背景放后面。
9
+ - 正:`棋盘用固定大小的二维数组保存,行和列都是 0 到 2。`
10
+ - 反:`在开始介绍棋盘之前,我们先来了解一下背景。`
11
+ - 步骤:`steps/04-paragraphs.md`
12
+
13
+ **C02 一段只推进一个动作。** 说明、举证、划界、收口四选一;出现第二个动作就分段。
14
+ - 正:一段说清 `PlaceCell` 的职责,下一段再说它拒绝哪些输入。
15
+ - 反:一段里既讲职责、又讲实现细节、又讲历史原因。
16
+ - 步骤:`steps/04-paragraphs.md`
17
+
18
+ **C03 句子有预算。** 中文单句不超过 40 字,英文不超过 25 词;超了先拆。
19
+ - 正:`落子前先检查坐标是否越界。越界时返回 false,不修改棋盘。`
20
+ - 反:`落子前先检查坐标是否越界并在越界时返回 false 且不修改棋盘以及不记录日志。`
21
+ - 步骤:`steps/05-sentences.md`
22
+
23
+ **C04 术语首次出现给中英。** 中文在前,英文括注一次,之后只用中文。
24
+ - 正:`棋盘格子(cell)只有三种状态。`
25
+ - 反:`cell 有三种状态,后面我们有时也叫它格子。`
26
+ - 步骤:`steps/06-wording.md`
27
+
28
+ **C05 删复述句。** 代码已经说明的,不要再写一遍。
29
+ - 正:`PlaceCell 返回 false 有两种原因:越界,或格子已被占用。`
30
+ - 反:`上面的代码中,if 判断 position.row 是否越界,如果越界就 return false。`
31
+ - 步骤:`steps/08-reread.md`
32
+
33
+ **C06 删元叙述。** 不写「本节将」「下面我们来看」「值得注意的是」。
34
+ - 正:`判断胜负要扫描四条线。`
35
+ - 反:`下面我们来看一下如何判断胜负。`
36
+ - 步骤:`steps/08-reread.md`
37
+
38
+ **C07 示例先于术语。** 先给能跑的最小例子,再解释机制。
39
+ - 正:先给 `Board b; b.PlaceCell({0,0}, CellType::kX);` 与输出,再讲存储布局。
40
+ - 反:先讲「采用行优先的连续存储」,再给例子。
41
+ - 步骤:`steps/03-blocks.md`
42
+
43
+ **C08 反例紧随正例。** 错误写法放在正例之后一段,不埋进注里。
44
+ - 正:正例后一段写「如果漏掉越界检查,会……」,附代码。
45
+ - 反:把反例塞进 `::: {.callout-note}` 的折叠块。
46
+ - 步骤:`steps/04-paragraphs.md`
47
+
48
+ ## 结构
49
+
50
+ **C09 标题用名词短语。** 不用问句,不用「关于……」。
51
+ - 正:`胜负判定`
52
+ - 反:`我们如何判断胜负?`
53
+ - 步骤:`steps/02-structure.md`
54
+
55
+ **C10 章节按五步走。** 现象 → 最小例子 → 机制 → 边界 → 自测。
56
+ - 正:`03-board.qmd` 依次讲空棋盘、落子、越界、判胜、自测。
57
+ - 反:先给完整类声明,再逐行解释。
58
+ - 步骤:`steps/02-structure.md`
59
+
60
+ **C11 表格只放同构信息。** 叙述内容仍写自然段。
61
+ - 正:三种格子类型一行一个,列固定。
62
+ - 反:把一段因果解释塞进表格的「说明」列。
63
+ - 步骤:`steps/03-blocks.md`
64
+
65
+ **C12 一节一个关键。** 一章只解决一个问题,多出来的挪到下一章。
66
+ - 正:03 章只讲棋盘;游戏流程留给 04 章。
67
+ - 反:03 章顺手把 `Game` 的状态机也讲了。
68
+ - 步骤:`steps/02-structure.md`
69
+
70
+ **C13 章首导语 60–146 字。** 一段说清这章解决什么、读者读完能做什么。
71
+ - 正:`这一章把棋盘写成类……读完后你能判断任意坐标是否合法。`
72
+ - 反:三段历史回顾加一张架构图。
73
+ - 步骤:`steps/01-task.md`
74
+
75
+ ## 代码块与图
76
+
77
+ **C14 代码块前一句导语,后一段解说。** 导语说这块代码要证明什么,解说只讲没写在代码里的。
78
+ - 正:`下面这段是判胜的核心循环:` + 代码 + `两层 any_of 在第一次命中时短路。`
79
+ - 反:导语写「代码如下」,解说把代码逐行翻译。
80
+ - 步骤:`steps/03-blocks.md`
81
+
82
+ **C15 围栏属性只写必要项。** 需要文件名才写 `filename`,需要行号才写 `start-from`。
83
+ - 正:` ```{.cpp filename="board.h"} `
84
+ - 反:每个代码块都堆 `filename`、`code-link`、`start-from`。
85
+ - 步骤:`steps/03-blocks.md`
86
+
87
+ **C16 图示有替代文本。** 图必须有 `alt` 或 `aria-label`,说明图在讲什么,不写「示意图」。
88
+ - 正:`aria-label="三行三列的棋盘,行列都从 0 编号"`
89
+ - 反:`alt="图 1"`
90
+ - 步骤:`steps/07-layout.md`
91
+
92
+ **C17 交叉引用用锚点。** 引用其他章节写 `@fig-`、`@tbl-` 或 `[](){#...}`,不写「见上文」。
93
+ - 正:`判胜规则见 @fig-board-lines。`
94
+ - 反:`判胜规则见上面的图。`
95
+ - 步骤:`steps/07-layout.md`
96
+
97
+ ## 用词与排版
98
+
99
+ **C18 称呼读者用「你」。** 不写「我们」「大家」「读者」。
100
+ - 正:`你可以先用空棋盘试一次落子。`
101
+ - 反:`我们接下来让大家试着落子。`
102
+ - 步骤:`steps/06-wording.md`
103
+
104
+ **C19 中英混排加空格。** 中文与英文、数字之间留一个空格;全角标点只用于中文语境。
105
+ - 正:`C++23 的 std::array 固定长度。`
106
+ - 反:`C++23的std::array固定长度。`
107
+ - 步骤:`steps/07-layout.md`
108
+
109
+ **C20 数字与单位写全。** 行列编号写「第 0 行」,范围写「0 到 2」,不写「0~2」。
110
+ - 正:`行和列的取值都是 0 到 2。`
111
+ - 反:`行列取值 0~2。`
112
+ - 步骤:`steps/07-layout.md`
113
+
114
+ **C21 链接文字要自述。** 链接文字说明目标是什么,不写「这里」「点击」。
115
+ - 正:`参见 [Google C++ 风格指南](https://google.github.io/styleguide/cppguide.html)。`
116
+ - 反:`参见[这里](https://google.github.io/styleguide/cppguide.html)。`
117
+ - 步骤:`steps/09-check.md`
118
+
119
+ **C22 列表只列同构项。** 列表项长度相近;出现完整句子就改自然段。
120
+ - 正:三条各一行的「越界、占用、终局」检查项。
121
+ - 反:列表第一项一句话,第二项三行解释。
122
+ - 步骤:`steps/07-layout.md`
123
+
124
+ ## 节奏与收尾
125
+
126
+ **C23 长文分小节。** 一节 60–90 行,超过就拆;拆出来的小节标题写名词短语。
127
+ - 正:`棋盘存储`、`落子`、`判胜` 三个小节。
128
+ - 反:一个 300 行的「实现」小节。
129
+ - 步骤:`steps/02-structure.md`
130
+
131
+ **C24 排障写成可跟做步骤。** 失败现象、检查项、修法各一行,命令可直接复制。
132
+ - 正:`报错 EADDRINUSE:先运行 lsof -i :3000,再结束占用进程。`
133
+ - 反:`如果端口被占用,可能需要检查一下相关进程。`
134
+ - 步骤:`steps/09-check.md`
135
+
136
+ **C25 每章末尾给三句回顾。** 只回顾结论,不引入新概念。
137
+ - 正:`棋盘用二维数组保存;落子前检查越界与占用;判胜扫描四条线。`
138
+ - 反:回顾里补一个前面没讲过的 `std::optional` 用法。
139
+ - 步骤:`steps/08-reread.md`
140
+
141
+ **C26 自测问题不引入新概念。** 问题只用本章讲过的内容,答案放折叠块。
142
+ - 正:`如果省略越界检查,传入 {-1, 0} 会发生什么?`
143
+ - 反:`请用 std::variant 重写棋盘。`
144
+ - 步骤:`steps/08-reread.md`
145
+
146
+ **C27 术语表只收本书自造词。** 通用 C++ 术语不收;收「棋盘格子」「落子」这类本书固定叫法。
147
+ - 正:`棋盘格子:棋盘上的一个位置,取值见 CellType。`
148
+ - 反:把 `std::array` 也收进术语表。
149
+ - 步骤:`steps/06-wording.md`
150
+
151
+ **C28 代码注释不复述正文。** 正文讲契约,注释讲代码里看不出的取舍;同一句不写两遍。
152
+ - 正:注释写「不用编号求和,和相等不代表同色」,正文讲判胜算法。
153
+ - 反:注释把正文的判胜步骤抄一遍。
154
+ - 步骤:`steps/03-blocks.md`
155
+
156
+ **C29 渲染后朗读一遍。** 出声读,卡住的地方就是句子太长或指代不清。
157
+ - 正:读不顺的句子拆成两句。
158
+ - 反:只看渲染截图就交付。
159
+ - 步骤:`steps/09-check.md`
160
+
161
+ **C30 改完就校验。** 每改完一节跑一次 `verifying-content.py`,不攒到最后。
162
+ - 正:`python scripts/verifying-content.py --root . --strict`
163
+ - 反:整章改完再跑,报错定位到整章。
164
+ - 步骤:`steps/09-check.md`
@@ -56,6 +56,13 @@ CARRIER_RE = re.compile("承载")
56
56
  NEXT_SECTION_RE = re.compile(r"(?:下一节|上一节)")
57
57
  CALLOUT_OPEN_RE = re.compile(r"^\s*:::\s*\{?\s*\.callout-")
58
58
  OPENING_CLICHE_RE = re.compile(r"^(?:本章|本节|这一章|这一节)(?:将|会|要)|^下面(?:介绍|讲)")
59
+ # 元叙述与清点句:读者不需要作者交代「接下来讲什么」;一句里排到两个序列词,
60
+ # 说明这句话在报清单而不是在讲因果。规则卡见 references/rules-cards.md 的 C06、C02。
61
+ META_NARRATION_RE = re.compile(
62
+ r"本节将|本章将|这一节将|接下来(?:我们|将|会|介绍|讲)|下面(?:我们)?(?:先|来|看)|"
63
+ r"值得我们|值得注意的是|需要说明的是|如上所述|如前所述"
64
+ )
65
+ ENUMERATION_RE = re.compile(r"首先|其次|再次|然后|最后|其一|其二|其三|第[一二三四五]是|第[一二三四五],")
59
66
  LADDER_RE = re.compile(r"(?:分别交给|各说一层)")
60
67
  SKILL_TONE_RE = re.compile(r"这里不定义|测试也不必|不必为[^。;\n]{0,20}再记|不写双层循环")
61
68
  INLINE_NAME_RE = re.compile(r"`([A-Za-z_][A-Za-z0-9_]*)`")
@@ -246,6 +253,20 @@ def check_prose_block(
246
253
  issues.append(Issue(path, start_line, "第 N 章式编号指称(用章节标题或链接)"))
247
254
  if SKILL_TONE_RE.search(compact):
248
255
  issues.append(Issue(path, start_line, "技能腔:只约束作者的选择,整句删掉"))
256
+ if META_NARRATION_RE.search(compact):
257
+ issues.append(Issue(
258
+ path, start_line,
259
+ "元叙述:删掉「本节将 / 下面我们看」这类句子,直接从内容写起",
260
+ ))
261
+ if CJK_RE.search(compact):
262
+ for sentence in re.split(r"(?<=[。!?])", compact):
263
+ markers = ENUMERATION_RE.findall(sentence)
264
+ if len(markers) >= 2:
265
+ issues.append(Issue(
266
+ path, start_line,
267
+ f"清点句:一句里出现 {len(markers)} 个序列词,改成列表或自然衔接",
268
+ ))
269
+ break
249
270
  if not is_list and CJK_RE.search(compact):
250
271
  names = {
251
272
  match.group(1)
@@ -117,3 +117,5 @@
117
117
  ## 正反例
118
118
 
119
119
  通用情况判得准就不打开。判不准时打开 `examples/08-appendix.md`。
120
+
121
+ 定稿前对照 `references/rules-cards.md` 的 C05、C06、C25、C26:删复述句与元叙述,补三句回顾,自测题只用本章内容。
@@ -14,7 +14,7 @@
14
14
 
15
15
  ### 渲染与 HTML
16
16
 
17
- 内容核对通过后,调 `quarto_render_check`。参数只有两个:
17
+ 内容核对通过后,调 `quarto_render_check`。工具先按会话工作目录找书根;会话不在书内时,从 `qmd_path` 所在目录向上找 `_quarto.yml`,两处都找不到才拒绝并返回「当前会话不在 Quarto Book 项目内」。被拒绝时把工作目录切到书根再调用;仍不行就停住并说明,不改用手跑 `quarto render` 顶替。参数只有两个:
18
18
 
19
19
  - `qmd_path`:正在改的 `.qmd` 路径。
20
20
  - `dry_run`:`true` 只做输出目录安全检查,`false` 才启动渲染。
@@ -76,3 +76,5 @@
76
76
  ## 正反例
77
77
 
78
78
  第 9 步不设例子文件。检查结果本身就是判据。
79
+
80
+ 自查时按 `references/rules-cards.md` 逐条对照,只打开当前段落涉及的卡片;卡片编号写在动手记录里,便于回溯。