Skip to content

Commit df5ddb9

Browse files
committed
fix: handle !!python/name: tags in mkdocs.yml YAML parsing
1 parent 043add6 commit df5ddb9

2 files changed

Lines changed: 35 additions & 15 deletions

File tree

scripts/check_docs.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,22 @@ def collect_nav_files(node: Any, result: set[str]) -> None:
125125
result.add(node)
126126

127127

128+
class _IgnoreUnknownTags(yaml.SafeLoader):
129+
"""SafeLoader 扩展:遇到 !!python/name: 等自定义标签时忽略而非报错。"""
130+
pass
131+
132+
133+
def _ignore_tag_constructor(loader, tag_suffix, node):
134+
return loader.construct_scalar(node)
135+
136+
137+
_IgnoreUnknownTags.add_multi_constructor('', _ignore_tag_constructor)
138+
139+
128140
def validate_mkdocs_nav(mkdocs_path: Path, docs_dir: Path) -> int:
129141
errors = 0
130142
try:
131-
config = yaml.safe_load(mkdocs_path.read_text(encoding='utf-8')) or {}
143+
config = yaml.load(mkdocs_path.read_text(encoding='utf-8'), Loader=_IgnoreUnknownTags) or {}
132144
except Exception as e:
133145
gha_error(str(mkdocs_path).replace('\\', '/'), f'mkdocs.yml 解析失败: {e}')
134146
return 1

scripts/generate_readme.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -262,30 +262,38 @@ def generate_mkdocs_nav(articles, dir_order):
262262

263263

264264
def update_mkdocs_nav(nav):
265-
"""把 nav 写回 mkdocs.yml,保留 nav 以外的所有配置"""
265+
"""把 nav 写回 mkdocs.yml,保留 nav 以外的所有配置。
266+
267+
策略:用正则定位 nav: 块的起止位置做字符串替换,
268+
避免 yaml.dump 破坏 !!python/name: 等自定义标签。
269+
"""
270+
import re as _re
266271
mkdocs_path = Path('mkdocs.yml')
267272
if not mkdocs_path.exists():
268273
print('error: mkdocs.yml does not exist')
269274
return False
270275

271-
# 用 yaml 解析全文,只替换 nav 字段,其余保持原样
272-
content = mkdocs_path.read_text(encoding='utf-8')
273-
try:
274-
config = yaml.safe_load(content) or {}
275-
except Exception as e:
276-
print(f'error: cannot parse mkdocs.yml: {e}')
277-
return False
278-
279-
config['nav'] = nav
280-
281-
# 用 yaml.dump 回写,保留中文、不转义 unicode
282-
new_content = yaml.dump(
283-
config,
276+
# 生成新的 nav YAML 片段
277+
nav_yaml = yaml.dump(
278+
{'nav': nav},
284279
allow_unicode=True,
285280
default_flow_style=False,
286281
sort_keys=False,
287282
width=4096,
288283
)
284+
285+
content = mkdocs_path.read_text(encoding='utf-8')
286+
287+
# 用正则找到 nav: 块:从 ^nav: 开始,到下一个顶层 key 或文件末尾
288+
nav_pattern = _re.compile(
289+
r'^nav:.*?(?=^[a-z_]|\Z)',
290+
_re.MULTILINE | _re.DOTALL,
291+
)
292+
if nav_pattern.search(content):
293+
new_content = nav_pattern.sub(nav_yaml, content, count=1)
294+
else:
295+
new_content = content.rstrip('\n') + '\n\n' + nav_yaml
296+
289297
mkdocs_path.write_text(new_content, encoding='utf-8')
290298
print('mkdocs.yml nav updated')
291299
return True

0 commit comments

Comments
 (0)