# -*- coding: utf-8 -*- """ 阶段5:将 docs 内 .md 对旧结构路径的引用改写为新结构路径。 映射来源(全部已验证): - A类 content_dup: old -> new - B1类 name_diff(排除b2): old -> new - b2: docs_repair_b2.py 的 MOVES(改名迁入目标) - C类: docs_repair_c.py 的 M(逐文件归类目标) 旧路径统一用 '/' 匹配,替换也用 '/'。 """ import os, json, re, sys ROOT = "docs" DRY = "--go" not in sys.argv # ---- 复用已验证的映射 ---- def load_mod(path, stop_marker): src = open(path, encoding='utf-8').read() seg = src.split(stop_marker)[0] ns = {} exec(compile(seg, path, 'exec'), ns) return ns b2ns = load_mod('docs_repair_b2.py', 'ok, skip = [], []') MOVES = {k: v for k, v in b2ns['MOVES']} cns = load_mod('docs_repair_c.py', 'print("映射条目') M_C = cns['M'] d = json.load(open('docs_cmp_result2.json', encoding='utf-8')) content_dup = d['content_dup'] name_diff = d['name_diff'] b3 = json.load(open('docs_cmp_result3.json', encoding='utf-8')) b2_old = set(row[0] for row in b3.get('b2', [])) full = {} for old, new in content_dup: full[old] = new for row in name_diff: old, new = row[0], row[3] if old in b2_old: continue full[old] = new for old, new in MOVES.items(): full[old] = new for old, new in M_C.items(): full[old] = new # 统一成 '/' 分隔的键 norm_map = {} for old, new in full.items(): ko = old.replace('\\', '/') kn = new.replace('\\', '/') norm_map[ko] = kn # 按键长降序,避免短键先匹配导致部分替换 keys = sorted(norm_map.keys(), key=len, reverse=True) def rewrite_text(text): total = 0 for ko in keys: kn = norm_map[ko] # 同时匹配 / 与 \ 两种分隔 for variant in (ko, ko.replace('/', '\\')): if variant in text: cnt = text.count(variant) text = text.replace(variant, kn) total += cnt return text, total # 扫描所有 .md md_files = [] for root, _, fs in os.walk(ROOT): for f in fs: if f.endswith('.md'): md_files.append(os.path.join(root, f)) changed_files = [] total_repl = 0 samples = [] for fp in md_files: with open(fp, encoding='utf-8') as fh: text = fh.read() new_text, cnt = rewrite_text(text) if cnt: changed_files.append(fp) total_repl += cnt if len(samples) < 8: # 找一处样例 for ko in keys: if ko.replace('\\','/') in text or ko.replace('/','\\') in text: samples.append((fp, ko, norm_map[ko])) break print("映射条目:", len(norm_map)) print("扫描 .md 文件:", len(md_files)) print("将修改文件数:", len(changed_files)) print("替换引用处数:", total_repl) print("\n样例:") for fp, ko, kn in samples: print(" %s\n %s -> %s" % (fp, ko, kn)) if DRY: print("\n[DRY] 未写入。") else: for fp in changed_files: with open(fp, encoding='utf-8') as fh: text = fh.read() new_text, _ = rewrite_text(text) with open(fp, 'w', encoding='utf-8') as fh: fh.write(new_text) print("\n已写入", len(changed_files), "个文件。")