diff --git a/skills/tsl-syntax-reference/references/10_runtime_context_and_with.md b/skills/tsl-syntax-reference/references/10_runtime_context_and_with.md index b09260f5..a521c379 100644 --- a/skills/tsl-syntax-reference/references/10_runtime_context_and_with.md +++ b/skills/tsl-syntax-reference/references/10_runtime_context_and_with.md @@ -420,7 +420,7 @@ end; 代码块身份:反例 / 不可照写 -```tsl +```text cached_result := Demo() with array("a": 11); function Demo(); diff --git a/skills/tsl-syntax-reference/scripts/lookup.py b/skills/tsl-syntax-reference/scripts/lookup.py index ac5bcfe3..6c92f1c8 100644 --- a/skills/tsl-syntax-reference/scripts/lookup.py +++ b/skills/tsl-syntax-reference/scripts/lookup.py @@ -35,6 +35,13 @@ ALLOWED_IDENTITIES = { "配置片段 / 概念骨架", "仅服务端可执行示例", } +# 身份与围栏语言的固定对应。反例必须留在 text 围栏:批量抽取 ```tsl 块实跑的 +# 流程会把 tsl 围栏里的反例当正例执行;反过来照写示例落进 text 围栏就永远不会 +# 被抽出来验证。其余身份(概念骨架、仅服务端示例)按页面需要自行选择语言。 +IDENTITY_FENCE_LANGUAGES = { + "反例 / 不可照写": "text", + "可直接照写示例": "tsl", +} ROUTER_PHRASES = ("路由中心", "选择一个主专题", "候选页继续判断") EXCLUDED_REFERENCE_FILES = {"index.md"} DUTY_HEADING = "本篇职责" @@ -411,16 +418,30 @@ def _identity_problems(page: Path, lines: list[str]) -> list[ValidationProblem]: problems.append(ValidationProblem(page, index, f"未知身份:{identity}")) in_fence = False for index, line in enumerate(lines): - if FENCE_RE.match(line): + fence = FENCE_RE.match(line) + if fence: if in_fence: in_fence = False else: - if _associated_identity(lines, index) is None: + identity = _associated_identity(lines, index) + if identity is None: problems.append( ValidationProblem( page, index + 1, "每个代码围栏必须关联恰好一个代码块身份" ) ) + else: + expected = IDENTITY_FENCE_LANGUAGES.get(identity) + language = (fence.group(1) or "").strip() + if expected is not None and language != expected: + problems.append( + ValidationProblem( + page, + index + 1, + f"「{identity}」必须写在 ```{expected} 围栏里," + f"当前是 ```{language or '(无语言标注)'}", + ) + ) in_fence = True continue if not in_fence and SUSPICIOUS_FENCE_RE.match(line):