-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck_inline_links.py
More file actions
executable file
·61 lines (49 loc) · 2.42 KB
/
Copy pathcheck_inline_links.py
File metadata and controls
executable file
·61 lines (49 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3
"""Check inline links in example prose resolve to real pages.
`render_inline` (src/textfmt.py) renders [text](/examples/slug) and
[text](/journeys/slug) as anchors and leaves every other [text](target)
literal. This gate fails the build for:
- link syntax whose target is not an internal /examples or /journeys
path (it would ship as literal bracket text);
- internal links pointing at a slug that does not exist;
- a page linking to itself.
"""
from __future__ import annotations
import re
from _common import EXAMPLES_DIR, fail, load_catalog
LINK_RE = re.compile(r"\[([^\[\]]+)\]\(([^()\s]+)\)")
INTERNAL_RE = re.compile(r"^/(examples|journeys)/([a-z0-9-]+)$")
def journey_slugs() -> set[str]:
from src.app import JOURNEYS_BY_SLUG
return set(JOURNEYS_BY_SLUG)
def main() -> int:
_, examples = load_catalog()
example_slugs = {example["slug"] for example in examples}
journeys = journey_slugs()
errors: list[str] = []
for example in examples:
slug = example["slug"]
path = EXAMPLES_DIR / f"{slug}.md"
surfaces: list[tuple[int, str]] = [(1, paragraph) for paragraph in example["explanation"]]
surfaces += [(1, note) for note in example.get("notes", [])]
for cell in example["cells"]:
surfaces += [(cell.get("line", 1), paragraph) for paragraph in cell.get("prose", [])]
for line, text in surfaces:
for match in LINK_RE.finditer(text):
label, target = match.group(1), match.group(2)
internal = INTERNAL_RE.match(target)
if not internal:
errors.append(
f"{path}:{line}: link [{label}]({target}) is not an internal "
f"/examples or /journeys path and would render as literal text"
)
continue
kind, target_slug = internal.group(1), internal.group(2)
known = example_slugs if kind == "examples" else journeys
if target_slug not in known:
errors.append(f"{path}:{line}: link [{label}]({target}) points at an unknown {kind} slug")
if kind == "examples" and target_slug == slug:
errors.append(f"{path}:{line}: page links to itself: [{label}]({target})")
return fail(errors, f"Inline-link check OK ({len(examples)} examples).")
if __name__ == "__main__":
raise SystemExit(main())