MCPcopy Create free account
hub / github.com/Qinbf/groundmap / list_broken_refs

Function list_broken_refs

scripts/k.py:1859–1920  ·  view source on GitHub ↗

扫描 wiki/ 所有页面里带 ^anchor 的双链,列出失效的引用。 覆盖两类目标: - [[raw/...#^anchor]] — raw 文件不存在 / anchor 不存在(raw 有 outline,但 anchor 集合直接从 .md 扫,与 wiki 同路) - [[wiki/...#^anchor]] — wiki 文件不存在 / anchor 不存在(wiki 页无 outline.json, 用 _collect_anchors_in_md 直扫目标 .md 的锚点集合判断) 无 ^anch

(pages)

Source from the content-addressed store, hash-verified

1857
1858
1859def list_broken_refs(pages) -> list[dict]:
1860 """扫描 wiki/ 所有页面里带 ^anchor 的双链,列出失效的引用。
1861
1862 覆盖两类目标:
1863 - [[raw/...#^anchor]] — raw 文件不存在 / anchor 不存在(raw 有 outline,但
1864 anchor 集合直接从 .md 扫,与 wiki 同路)
1865 - [[wiki/...#^anchor]] — wiki 文件不存在 / anchor 不存在(wiki 页无 outline.json,
1866 用 _collect_anchors_in_md 直扫目标 .md 的锚点集合判断)
1867
1868 无 ^anchor 的纯页面链接([[wiki/concepts/X]])不在此检查——那属于孤儿 / 出链
1869 维度,由 list-orphans / outlinks 覆盖。
1870 """
1871 out = []
1872 # 目标 .md 路径(rel)→ 其锚点集合,避免重复扫盘
1873 anchor_cache: dict[str, set[str]] = {} # raw 目标:内联锚点集合
1874 resolvable_cache: dict[str, tuple] = {} # wiki 目标:read_block 同口径的可解析索引
1875
1876 for page in pages:
1877 # 跳过反引号包裹的字面占位(如周报里写 `[[raw/...#^anchor]]` 当格式示例)
1878 scan_text = mask_code_spans(page.raw_content)
1879 for m in WIKILINK_RE.finditer(scan_text):
1880 target = m.group(1)
1881 anchor = m.group(2)
1882 if not anchor or not anchor.startswith("^"):
1883 continue
1884 target_norm = normalize_link_target(target)
1885 is_raw = bool(RAW_REF_PREFIX_RE.match(target_norm))
1886 is_wiki = bool(WIKI_REF_PREFIX_RE.match(target_norm))
1887 if not is_raw and not is_wiki:
1888 continue
1889 # 拒绝越界目标([[raw/../etc/passwd]])——既不打开也不报告
1890 doc_path = _safe_join_under_root(target_norm)
1891 if doc_path is None:
1892 continue
1893 anchor_id = anchor.lstrip("^")
1894 line = page.raw_content[: m.start()].count("\n") + 1
1895 kind_label = "raw" if is_raw else "wiki"
1896 reason = None
1897 if not doc_path.exists():
1898 reason = f"{kind_label} 文件不存在"
1899 elif is_wiki:
1900 # wiki 页:与 read_block 同口径(计算块锚点 + hash6 容错)判断锚点是否真能解析,
1901 # 避免旧的内联扫描被正文裸锚点文本骗过而漏报坏块引用。
1902 if target_norm not in resolvable_cache:
1903 resolvable_cache[target_norm] = _resolvable_anchor_index(doc_path)
1904 if not _anchor_resolvable(anchor_id, resolvable_cache[target_norm]):
1905 reason = "anchor 不存在"
1906 else:
1907 if target_norm not in anchor_cache:
1908 anchor_cache[target_norm] = _collect_anchors_in_md(doc_path)
1909 if anchor_id not in anchor_cache[target_norm]:
1910 reason = "anchor 不存在"
1911 if reason:
1912 out.append({
1913 "from_path": page.path,
1914 "from_title": page.title,
1915 "line": line,
1916 "target": target_norm,

Callers 2

health_reportFunction · 0.70
_main_implFunction · 0.70

Calls 6

mask_code_spansFunction · 0.85
normalize_link_targetFunction · 0.85
_safe_join_under_rootFunction · 0.85
_resolvable_anchor_indexFunction · 0.85
_anchor_resolvableFunction · 0.85
_collect_anchors_in_mdFunction · 0.85

Tested by

no test coverage detected