@chengzhao-dev/dsh-quarto-book 0.3.4 → 0.4.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.
- package/LICENSE +20 -20
- package/README.en.md +35 -4
- package/README.md +35 -4
- package/cordis.patch.yml +2 -2
- package/docs/plugin-flow.md +15 -4
- package/docs/versioning.md +9 -9
- package/lib/index.js +3 -1
- package/lib/tools/pass-report.js +332 -0
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +10 -2
- package/skills/designing-theme/SKILL.md +1 -0
- package/skills/designing-theme/assets/theme/css/base.css +368 -368
- package/skills/designing-theme/assets/theme/includes/footer.html +63 -63
- package/skills/designing-theme/assets/theme/palettes/github/meta.md +38 -38
- package/skills/designing-theme/knowledge/reading-surface.md +68 -68
- package/skills/designing-theme/scripts/measuring-pages.mjs +309 -309
- package/skills/writing-quarto/SKILL.md +44 -43
- package/skills/writing-quarto/scripts/checking-callouts.py +102 -102
- package/skills/writing-quarto/scripts/checking-dom.py +577 -577
- package/skills/writing-quarto/scripts/diagrams/rendering-coords.py +250 -250
- package/skills/writing-quarto/scripts/testing-check-ascii-names.py +71 -71
- package/skills/writing-quarto/scripts/testing-content.py +149 -149
- package/skills/writing-quarto/scripts/verifying-content.py +378 -378
- package/skills/writing-quarto/steps/09-check.md +13 -1
- package/templates/quarto-book-project/writing/chapter-map.md +22 -22
|
@@ -1,43 +1,44 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: writing-quarto
|
|
3
|
-
description: 编写和修改 Quarto Book 的 .qmd 章节,覆盖中文技术写作、Book 结构、代码与图表、渲染验证;不用于改 CSS、字体或主题颜色
|
|
4
|
-
metadata:
|
|
5
|
-
short-description: 编写中文 Quarto 图书章节
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Skill: writing-quarto
|
|
9
|
-
|
|
10
|
-
承载 `.qmd` 章节的写法流程与 Book 结构约定。正文只有九步:每一步只打开 `steps/` 里同号的一个文件;判不准才打开 `examples/` 里同号的案例;要排图、查渲染或全仓重构才打开 `quarto/`。不读插件包内的 `docs/`,也不读书里的旧通用副本。
|
|
11
|
-
|
|
12
|
-
## 适用场景
|
|
13
|
-
|
|
14
|
-
- 新建或修改 `content/**/*.qmd` 章节、`index.qmd` 或 `_quarto.yml`;内容与链接核对走本技能 `scripts/` 下的脚本,HTML 是否可用走 `quarto_render_check` 工具。
|
|
15
|
-
- **不适用**:改主题样式、颜色或字体(转 `designing-theme`);讲解书里项目的业务领域知识(那是项目正文的职责,不是本技能)。
|
|
16
|
-
- 项目带有 `.agents/skills/quarto-book-project/SKILL.md` 时,读完本技能再读它,并只按它指向的 `writing/` 文件读章节对照;没有就跳过,不要凭猜测补书名、章节名和术语。书内 `context/` 下的旧通用副本不再打开,写法以本技能为准。
|
|
17
|
-
- 书仓库根目录的 `README.md` 只走第 5–8 步:它是仓库说明页,不是章节;不套第 1–4 步的任务与结构骨架,不写「常见错误」「自测问题」,不调 `quarto_render_check`。第 8 步发现问题只退回第 5、6、7 步。`README.en.md` 同样处理;`CHANGELOG.md`、`LICENSE`、`AGENTS.md` 不在写作范围。这条只在书仓库里适用(技能本身由 Book 门禁触发)。
|
|
18
|
-
|
|
19
|
-
## 两种走法
|
|
20
|
-
|
|
21
|
-
增量润色沿九步走,只改判为不合格的地方,其余保持原样。全章重构仍是这九步,但第 1–2 步先定删留、不动句子,第 3–4 步只拆块和段,第 5–7 步才逐句改。
|
|
22
|
-
|
|
23
|
-
两条走法共守同一组不变量,写在这里,不重复进各步:不新增原文没有的事实、数字、命令、性能结论、引文和出处;不把「可能」「通常」「在本书里」这类留有余地的说法改成确定说法;保留否定、条件、范围、时间和归属;围栏里的代码、命令、路径、URL 与 YAML 不改。增量润色只删除和换词,不扩写、不补论证;全章重构可删可换序,但不能发明事实,也不能把限定说成确定。
|
|
24
|
-
|
|
25
|
-
后一步发现前一步没做完,退回那一步重做,不跳到更后面的步骤补救。
|
|
26
|
-
|
|
27
|
-
## 九步
|
|
28
|
-
|
|
29
|
-
1. 定任务:写出读者做完能完成的那件事,再列这一章要覆盖的任务。规则在 `steps/01-task.md`。
|
|
30
|
-
2. 定结构:排页面骨架、二级标题和篇幅预算,只定删留和标题。规则在 `steps/02-structure.md`。
|
|
31
|
-
3. 排列内容块:导语、围栏、收束与 Callout 的次序,一个围栏只放正在讲的那一块。规则在 `steps/03-blocks.md`。
|
|
32
|
-
4. 定段落:一段一个对象,段间衔接落在话题切换处。规则在 `steps/04-paragraphs.md`。
|
|
33
|
-
5. 定句子:对象先行,一句一动作。规则在 `steps/05-sentences.md`。
|
|
34
|
-
6. 定用词:统一术语、主动语态和语气。规则在 `steps/06-wording.md`。
|
|
35
|
-
7. 定版式:标点、中英混排、列表和加粗。规则在 `steps/07-layout.md`。
|
|
36
|
-
8. 回读并退回:按现象判断属于哪一步,退回那一步改。规则在 `steps/08-reread.md`。
|
|
37
|
-
9. 检查与渲染:先核对内容与链接,再调 `quarto_render_check` 渲染并检查 HTML。规则在 `steps/09-check.md`。
|
|
38
|
-
|
|
39
|
-
## 完成判据
|
|
40
|
-
|
|
41
|
-
- [ ] 九步走完,每一步的产出都落在正文里。
|
|
42
|
-
- [ ] 内容与链接核对通过:项目技能存在时跑它列出的 `run.ps1 verify --changed`,否则跑本技能 `scripts/verifying-content.py` 与 `checking-links.py`。
|
|
43
|
-
- [ ] 调 `quarto_render_check`:`dry_run: true` 最多 2 次,确认 `safe_to_render`;`dry_run: false` 最多 1 次,确认 `html_report.usable` 为 true。不手跑 `quarto render`,也不截图 PNG。
|
|
1
|
+
---
|
|
2
|
+
name: writing-quarto
|
|
3
|
+
description: 编写和修改 Quarto Book 的 .qmd 章节,覆盖中文技术写作、Book 结构、代码与图表、渲染验证;不用于改 CSS、字体或主题颜色
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: 编写中文 Quarto 图书章节
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Skill: writing-quarto
|
|
9
|
+
|
|
10
|
+
承载 `.qmd` 章节的写法流程与 Book 结构约定。正文只有九步:每一步只打开 `steps/` 里同号的一个文件;判不准才打开 `examples/` 里同号的案例;要排图、查渲染或全仓重构才打开 `quarto/`。不读插件包内的 `docs/`,也不读书里的旧通用副本。
|
|
11
|
+
|
|
12
|
+
## 适用场景
|
|
13
|
+
|
|
14
|
+
- 新建或修改 `content/**/*.qmd` 章节、`index.qmd` 或 `_quarto.yml`;内容与链接核对走本技能 `scripts/` 下的脚本,HTML 是否可用走 `quarto_render_check` 工具。
|
|
15
|
+
- **不适用**:改主题样式、颜色或字体(转 `designing-theme`);讲解书里项目的业务领域知识(那是项目正文的职责,不是本技能)。
|
|
16
|
+
- 项目带有 `.agents/skills/quarto-book-project/SKILL.md` 时,读完本技能再读它,并只按它指向的 `writing/` 文件读章节对照;没有就跳过,不要凭猜测补书名、章节名和术语。书内 `context/` 下的旧通用副本不再打开,写法以本技能为准。
|
|
17
|
+
- 书仓库根目录的 `README.md` 只走第 5–8 步:它是仓库说明页,不是章节;不套第 1–4 步的任务与结构骨架,不写「常见错误」「自测问题」,不调 `quarto_render_check`。第 8 步发现问题只退回第 5、6、7 步。`README.en.md` 同样处理;`CHANGELOG.md`、`LICENSE`、`AGENTS.md` 不在写作范围。这条只在书仓库里适用(技能本身由 Book 门禁触发)。
|
|
18
|
+
|
|
19
|
+
## 两种走法
|
|
20
|
+
|
|
21
|
+
增量润色沿九步走,只改判为不合格的地方,其余保持原样。全章重构仍是这九步,但第 1–2 步先定删留、不动句子,第 3–4 步只拆块和段,第 5–7 步才逐句改。
|
|
22
|
+
|
|
23
|
+
两条走法共守同一组不变量,写在这里,不重复进各步:不新增原文没有的事实、数字、命令、性能结论、引文和出处;不把「可能」「通常」「在本书里」这类留有余地的说法改成确定说法;保留否定、条件、范围、时间和归属;围栏里的代码、命令、路径、URL 与 YAML 不改。增量润色只删除和换词,不扩写、不补论证;全章重构可删可换序,但不能发明事实,也不能把限定说成确定。
|
|
24
|
+
|
|
25
|
+
后一步发现前一步没做完,退回那一步重做,不跳到更后面的步骤补救。
|
|
26
|
+
|
|
27
|
+
## 九步
|
|
28
|
+
|
|
29
|
+
1. 定任务:写出读者做完能完成的那件事,再列这一章要覆盖的任务。规则在 `steps/01-task.md`。
|
|
30
|
+
2. 定结构:排页面骨架、二级标题和篇幅预算,只定删留和标题。规则在 `steps/02-structure.md`。
|
|
31
|
+
3. 排列内容块:导语、围栏、收束与 Callout 的次序,一个围栏只放正在讲的那一块。规则在 `steps/03-blocks.md`。
|
|
32
|
+
4. 定段落:一段一个对象,段间衔接落在话题切换处。规则在 `steps/04-paragraphs.md`。
|
|
33
|
+
5. 定句子:对象先行,一句一动作。规则在 `steps/05-sentences.md`。
|
|
34
|
+
6. 定用词:统一术语、主动语态和语气。规则在 `steps/06-wording.md`。
|
|
35
|
+
7. 定版式:标点、中英混排、列表和加粗。规则在 `steps/07-layout.md`。
|
|
36
|
+
8. 回读并退回:按现象判断属于哪一步,退回那一步改。规则在 `steps/08-reread.md`。
|
|
37
|
+
9. 检查与渲染:先核对内容与链接,再调 `quarto_render_check` 渲染并检查 HTML。规则在 `steps/09-check.md`。
|
|
38
|
+
|
|
39
|
+
## 完成判据
|
|
40
|
+
|
|
41
|
+
- [ ] 九步走完,每一步的产出都落在正文里。
|
|
42
|
+
- [ ] 内容与链接核对通过:项目技能存在时跑它列出的 `run.ps1 verify --changed`,否则跑本技能 `scripts/verifying-content.py` 与 `checking-links.py`。
|
|
43
|
+
- [ ] 调 `quarto_render_check`:`dry_run: true` 最多 2 次,确认 `safe_to_render`;`dry_run: false` 最多 1 次,确认 `html_report.usable` 为 true。不手跑 `quarto render`,也不截图 PNG。
|
|
44
|
+
- [ ] 收尾调用一次 `quarto_pass_report`:`skill` 填 `writing-quarto`,`mode` 填 `polish` 或 `rewrite`,文件与步骤的改动次数、未改项、检查结论照实填。卡片就是回执,回复里不再复述;没改也传 0,当前文件不是章节时传 `executed: false`。
|
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""校验渲染产物中的 callout 是否真的渲染成提示框(自定义类的静默退化在这里暴露)。
|
|
3
|
-
|
|
4
|
-
Quarto 只认内置 5 类 callout(note/tip/warning/important/caution)。未知的
|
|
5
|
-
`.callout-<name>` 类会被静默丢弃。callout 退化成带 <h2> 的 <section>。这个
|
|
6
|
-
<section> 没有提示框样式。它还混进右侧目录。本脚本在 _book/**/*.html 里抓这一回归。
|
|
7
|
-
|
|
8
|
-
用法:python checking-callouts.py [--root .] [--book-dir _book]
|
|
9
|
-
退出码:0 = 全部正常,1 = 发现退化的 callout。
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import argparse
|
|
13
|
-
import re
|
|
14
|
-
import sys
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
|
|
17
|
-
# Quarto 内置 callout 类型(唯一的合法集合,none 用于无类型 callout)
|
|
18
|
-
BUILTIN_TYPES = {"none", "note", "tip", "warning", "important", "caution"}
|
|
19
|
-
|
|
20
|
-
# <section ... class="level2 callout-xxx"> => callout 退化成了普通小节
|
|
21
|
-
DEGRADED_RE = re.compile(r'<section[^>]*class="[^"]*\bcallout-[a-z0-9-]+\b[^"]*"')
|
|
22
|
-
|
|
23
|
-
# callout 外层容器的开头标签:必带 callout-style-*(内层的 callout-body / callout-header
|
|
24
|
-
# 等结构 div 没有该类,据此排除它们,不会误判成「非内置类型」)
|
|
25
|
-
CALLOUT_DIV_RE = re.compile(r'<div[^>]*class="[^"]*\bcallout-style-[a-z]+[^"]*"[^>]*>')
|
|
26
|
-
CLASS_RE = re.compile(r'class="([^"]*)"')
|
|
27
|
-
|
|
28
|
-
# 外层容器上的结构性类(不是 callout 类型)
|
|
29
|
-
STRUCTURAL_CLASSES = {"callout", "callout-titled", "callout-empty-content", "no-icon"}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def check_file(path):
|
|
33
|
-
"""返回 (退化小节数, 非内置类型集合, 缺标题容器数)。"""
|
|
34
|
-
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
35
|
-
degraded = len(DEGRADED_RE.findall(text))
|
|
36
|
-
|
|
37
|
-
unknown = set()
|
|
38
|
-
missing_title = 0
|
|
39
|
-
matches = list(CALLOUT_DIV_RE.finditer(text))
|
|
40
|
-
for idx, m in enumerate(matches):
|
|
41
|
-
classes = CLASS_RE.search(m.group(0)).group(1).split()
|
|
42
|
-
for c in classes:
|
|
43
|
-
if c in STRUCTURAL_CLASSES or c.startswith("callout-style-"):
|
|
44
|
-
continue
|
|
45
|
-
if c.startswith("callout-") and c[len("callout-") :] not in BUILTIN_TYPES:
|
|
46
|
-
unknown.add(c[len("callout-") :])
|
|
47
|
-
# 标题容器应紧随本 div 出现。用下一个 callout div 的起点作为窗口边界。
|
|
48
|
-
if "callout-titled" in classes:
|
|
49
|
-
stop = matches[idx + 1].start() if idx + 1 < len(matches) else len(text)
|
|
50
|
-
window = text[m.start() : min(stop, m.start() + 3000)]
|
|
51
|
-
if "callout-title-container" not in window:
|
|
52
|
-
missing_title += 1
|
|
53
|
-
return degraded, unknown, missing_title
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def main():
|
|
57
|
-
try:
|
|
58
|
-
sys.stdout.reconfigure(encoding="utf-8")
|
|
59
|
-
sys.stderr.reconfigure(encoding="utf-8")
|
|
60
|
-
except Exception:
|
|
61
|
-
pass
|
|
62
|
-
|
|
63
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
64
|
-
parser.add_argument("--root", default=".", help="书根目录(默认当前目录)")
|
|
65
|
-
parser.add_argument("--book-dir", default="_book", help="渲染产物目录(默认 _book)")
|
|
66
|
-
args = parser.parse_args()
|
|
67
|
-
|
|
68
|
-
root = Path(args.root).resolve()
|
|
69
|
-
book_dir = Path(args.book_dir)
|
|
70
|
-
if not book_dir.is_absolute():
|
|
71
|
-
book_dir = root / book_dir
|
|
72
|
-
if not book_dir.is_dir():
|
|
73
|
-
print(f"未找到渲染产物目录:{book_dir};请先执行 quarto render。")
|
|
74
|
-
return 1
|
|
75
|
-
|
|
76
|
-
html_files = sorted(book_dir.rglob("*.html"))
|
|
77
|
-
bad_pages = 0
|
|
78
|
-
for path in html_files:
|
|
79
|
-
degraded, unknown, missing_title = check_file(path)
|
|
80
|
-
if not (degraded or unknown or missing_title):
|
|
81
|
-
continue
|
|
82
|
-
bad_pages += 1
|
|
83
|
-
rel = path.relative_to(book_dir)
|
|
84
|
-
print(f" FAIL {rel}")
|
|
85
|
-
if degraded:
|
|
86
|
-
print(f" {degraded} 处 callout 退化为 <section>(未渲染成提示框)")
|
|
87
|
-
if unknown:
|
|
88
|
-
print(f" 非内置 callout 类型:{sorted(unknown)}")
|
|
89
|
-
if missing_title:
|
|
90
|
-
print(f" {missing_title} 个带标题 callout 缺少 callout-title-container")
|
|
91
|
-
|
|
92
|
-
print()
|
|
93
|
-
if bad_pages:
|
|
94
|
-
print(f"{bad_pages} 个页面存在 callout 问题。")
|
|
95
|
-
print('修复:改用内置 5 类,并用 `title="中文标题"` 提供标题(见 quarto/rendering-and-output.md #12)。')
|
|
96
|
-
return 1
|
|
97
|
-
print(f"OK:{len(html_files)} 个页面的 callout 均正常渲染。")
|
|
98
|
-
return 0
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if __name__ == "__main__":
|
|
102
|
-
sys.exit(main())
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""校验渲染产物中的 callout 是否真的渲染成提示框(自定义类的静默退化在这里暴露)。
|
|
3
|
+
|
|
4
|
+
Quarto 只认内置 5 类 callout(note/tip/warning/important/caution)。未知的
|
|
5
|
+
`.callout-<name>` 类会被静默丢弃。callout 退化成带 <h2> 的 <section>。这个
|
|
6
|
+
<section> 没有提示框样式。它还混进右侧目录。本脚本在 _book/**/*.html 里抓这一回归。
|
|
7
|
+
|
|
8
|
+
用法:python checking-callouts.py [--root .] [--book-dir _book]
|
|
9
|
+
退出码:0 = 全部正常,1 = 发现退化的 callout。
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import re
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# Quarto 内置 callout 类型(唯一的合法集合,none 用于无类型 callout)
|
|
18
|
+
BUILTIN_TYPES = {"none", "note", "tip", "warning", "important", "caution"}
|
|
19
|
+
|
|
20
|
+
# <section ... class="level2 callout-xxx"> => callout 退化成了普通小节
|
|
21
|
+
DEGRADED_RE = re.compile(r'<section[^>]*class="[^"]*\bcallout-[a-z0-9-]+\b[^"]*"')
|
|
22
|
+
|
|
23
|
+
# callout 外层容器的开头标签:必带 callout-style-*(内层的 callout-body / callout-header
|
|
24
|
+
# 等结构 div 没有该类,据此排除它们,不会误判成「非内置类型」)
|
|
25
|
+
CALLOUT_DIV_RE = re.compile(r'<div[^>]*class="[^"]*\bcallout-style-[a-z]+[^"]*"[^>]*>')
|
|
26
|
+
CLASS_RE = re.compile(r'class="([^"]*)"')
|
|
27
|
+
|
|
28
|
+
# 外层容器上的结构性类(不是 callout 类型)
|
|
29
|
+
STRUCTURAL_CLASSES = {"callout", "callout-titled", "callout-empty-content", "no-icon"}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def check_file(path):
|
|
33
|
+
"""返回 (退化小节数, 非内置类型集合, 缺标题容器数)。"""
|
|
34
|
+
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
35
|
+
degraded = len(DEGRADED_RE.findall(text))
|
|
36
|
+
|
|
37
|
+
unknown = set()
|
|
38
|
+
missing_title = 0
|
|
39
|
+
matches = list(CALLOUT_DIV_RE.finditer(text))
|
|
40
|
+
for idx, m in enumerate(matches):
|
|
41
|
+
classes = CLASS_RE.search(m.group(0)).group(1).split()
|
|
42
|
+
for c in classes:
|
|
43
|
+
if c in STRUCTURAL_CLASSES or c.startswith("callout-style-"):
|
|
44
|
+
continue
|
|
45
|
+
if c.startswith("callout-") and c[len("callout-") :] not in BUILTIN_TYPES:
|
|
46
|
+
unknown.add(c[len("callout-") :])
|
|
47
|
+
# 标题容器应紧随本 div 出现。用下一个 callout div 的起点作为窗口边界。
|
|
48
|
+
if "callout-titled" in classes:
|
|
49
|
+
stop = matches[idx + 1].start() if idx + 1 < len(matches) else len(text)
|
|
50
|
+
window = text[m.start() : min(stop, m.start() + 3000)]
|
|
51
|
+
if "callout-title-container" not in window:
|
|
52
|
+
missing_title += 1
|
|
53
|
+
return degraded, unknown, missing_title
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def main():
|
|
57
|
+
try:
|
|
58
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
59
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
60
|
+
except Exception:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
64
|
+
parser.add_argument("--root", default=".", help="书根目录(默认当前目录)")
|
|
65
|
+
parser.add_argument("--book-dir", default="_book", help="渲染产物目录(默认 _book)")
|
|
66
|
+
args = parser.parse_args()
|
|
67
|
+
|
|
68
|
+
root = Path(args.root).resolve()
|
|
69
|
+
book_dir = Path(args.book_dir)
|
|
70
|
+
if not book_dir.is_absolute():
|
|
71
|
+
book_dir = root / book_dir
|
|
72
|
+
if not book_dir.is_dir():
|
|
73
|
+
print(f"未找到渲染产物目录:{book_dir};请先执行 quarto render。")
|
|
74
|
+
return 1
|
|
75
|
+
|
|
76
|
+
html_files = sorted(book_dir.rglob("*.html"))
|
|
77
|
+
bad_pages = 0
|
|
78
|
+
for path in html_files:
|
|
79
|
+
degraded, unknown, missing_title = check_file(path)
|
|
80
|
+
if not (degraded or unknown or missing_title):
|
|
81
|
+
continue
|
|
82
|
+
bad_pages += 1
|
|
83
|
+
rel = path.relative_to(book_dir)
|
|
84
|
+
print(f" FAIL {rel}")
|
|
85
|
+
if degraded:
|
|
86
|
+
print(f" {degraded} 处 callout 退化为 <section>(未渲染成提示框)")
|
|
87
|
+
if unknown:
|
|
88
|
+
print(f" 非内置 callout 类型:{sorted(unknown)}")
|
|
89
|
+
if missing_title:
|
|
90
|
+
print(f" {missing_title} 个带标题 callout 缺少 callout-title-container")
|
|
91
|
+
|
|
92
|
+
print()
|
|
93
|
+
if bad_pages:
|
|
94
|
+
print(f"{bad_pages} 个页面存在 callout 问题。")
|
|
95
|
+
print('修复:改用内置 5 类,并用 `title="中文标题"` 提供标题(见 quarto/rendering-and-output.md #12)。')
|
|
96
|
+
return 1
|
|
97
|
+
print(f"OK:{len(html_files)} 个页面的 callout 均正常渲染。")
|
|
98
|
+
return 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
sys.exit(main())
|