🐛 fix(tsl-syntax-reference): check fence language per block identity
- `--check` now requires `反例 / 不可照写` in a text fence and `可直接照写示例` in a tsl fence; the AGENTS.md flow that extracts every ```tsl block and runs it would otherwise execute a counterexample as if it were a valid example, and an example hidden in a text fence would never be extracted for verification - 10 held the only counterexample in a tsl fence (a local function call with a trailing `with array(...)`); the rule and that fix cannot land in separate commits or --check fails in between - 配置片段 / 概念骨架 and 仅服务端可执行示例 stay unconstrained, since both languages are in use for them today Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -420,7 +420,7 @@ end;
|
|||||||
|
|
||||||
代码块身份:反例 / 不可照写
|
代码块身份:反例 / 不可照写
|
||||||
|
|
||||||
```tsl
|
```text
|
||||||
cached_result := Demo() with array("a": 11);
|
cached_result := Demo() with array("a": 11);
|
||||||
|
|
||||||
function Demo();
|
function Demo();
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ ALLOWED_IDENTITIES = {
|
|||||||
"配置片段 / 概念骨架",
|
"配置片段 / 概念骨架",
|
||||||
"仅服务端可执行示例",
|
"仅服务端可执行示例",
|
||||||
}
|
}
|
||||||
|
# 身份与围栏语言的固定对应。反例必须留在 text 围栏:批量抽取 ```tsl 块实跑的
|
||||||
|
# 流程会把 tsl 围栏里的反例当正例执行;反过来照写示例落进 text 围栏就永远不会
|
||||||
|
# 被抽出来验证。其余身份(概念骨架、仅服务端示例)按页面需要自行选择语言。
|
||||||
|
IDENTITY_FENCE_LANGUAGES = {
|
||||||
|
"反例 / 不可照写": "text",
|
||||||
|
"可直接照写示例": "tsl",
|
||||||
|
}
|
||||||
ROUTER_PHRASES = ("路由中心", "选择一个主专题", "候选页继续判断")
|
ROUTER_PHRASES = ("路由中心", "选择一个主专题", "候选页继续判断")
|
||||||
EXCLUDED_REFERENCE_FILES = {"index.md"}
|
EXCLUDED_REFERENCE_FILES = {"index.md"}
|
||||||
DUTY_HEADING = "本篇职责"
|
DUTY_HEADING = "本篇职责"
|
||||||
@@ -411,16 +418,30 @@ def _identity_problems(page: Path, lines: list[str]) -> list[ValidationProblem]:
|
|||||||
problems.append(ValidationProblem(page, index, f"未知身份:{identity}"))
|
problems.append(ValidationProblem(page, index, f"未知身份:{identity}"))
|
||||||
in_fence = False
|
in_fence = False
|
||||||
for index, line in enumerate(lines):
|
for index, line in enumerate(lines):
|
||||||
if FENCE_RE.match(line):
|
fence = FENCE_RE.match(line)
|
||||||
|
if fence:
|
||||||
if in_fence:
|
if in_fence:
|
||||||
in_fence = False
|
in_fence = False
|
||||||
else:
|
else:
|
||||||
if _associated_identity(lines, index) is None:
|
identity = _associated_identity(lines, index)
|
||||||
|
if identity is None:
|
||||||
problems.append(
|
problems.append(
|
||||||
ValidationProblem(
|
ValidationProblem(
|
||||||
page, index + 1, "每个代码围栏必须关联恰好一个代码块身份"
|
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
|
in_fence = True
|
||||||
continue
|
continue
|
||||||
if not in_fence and SUSPICIOUS_FENCE_RE.match(line):
|
if not in_fence and SUSPICIOUS_FENCE_RE.match(line):
|
||||||
|
|||||||
Reference in New Issue
Block a user