Files
yuegong/old/脚本/generate_line_diff.py
klarkxy 6a2ea7d7b5 ♻️ refactor(设定): 重构1.1为4月新canon并归档旧资产
- 将历史档案整体迁移至 `old/`,包含旧大纲、人物卡、世界书、参考资料与脚本
- 重写 `AGENTS.md` 为全书创作约束,去除剧情进度管理
- 重写 `世界书.md`,时间锚点由 1945 年 3 月改为 1945 年 4 月 26 日
- 重写 `伏笔与承诺.md` 与 `资产索引.md`,建立新旧设定权威顺序
- 重写宁诚、古米、赫默、铃兰、朱文晋五张人物卡;朱文晋改为带队指挥员而非被藏匿伤员
- 新增 `资料-1945年越南政治势力图谱.md` 作为历史写作资料层
- 重写 `项目总览.md`,明确五条长期叙事引擎与已确认边界
- 重写 1.1 五章正文:001《弃船》、002《事已至此,先吃饭吧》、003《蝗军来了》、004《狐火渺然》、005《越南救国军》;删除旧版 001—003 正文
2026-07-16 23:06:07 +08:00

106 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""Generate line-by-line diff between two markdown files."""
from __future__ import annotations
import argparse
import difflib
from pathlib import Path
def read_lines(path: Path) -> list[str]:
text = path.read_text(encoding="utf-8-sig")
return text.splitlines()
def generate_line_diff(src: Path, dst: Path) -> str:
src_lines = read_lines(src)
dst_lines = read_lines(dst)
src_name = src.as_posix()
dst_name = dst.as_posix()
diff = difflib.unified_diff(
src_lines,
dst_lines,
fromfile=src_name,
tofile=dst_name,
lineterm="",
)
return "\n".join(diff)
def generate_compact_line_diff(src: Path, dst: Path, context: int = 2) -> str:
"""Generate a compact diff showing only changed lines with a little context."""
src_lines = read_lines(src)
dst_lines = read_lines(dst)
src_name = src.as_posix()
dst_name = dst.as_posix()
sm = difflib.SequenceMatcher(None, src_lines, dst_lines)
output = [f"--- {src_name}", f"+++ {dst_name}", ""]
for tag, i1, i2, j1, j2 in sm.get_opcodes():
if tag == "equal":
# Show only a few context lines around changes
if context > 0:
ctx = src_lines[i1:i2]
if len(ctx) <= context * 2 + 1:
for line in ctx:
output.append(f" {line}")
else:
for line in ctx[:context]:
output.append(f" {line}")
output.append(" ...")
for line in ctx[-context:]:
output.append(f" {line}")
elif tag == "replace":
output.append(f"@@ -{i1 + 1},{i2 - i1} +{j1 + 1},{j2 - j1} @@")
for line in src_lines[i1:i2]:
output.append(f"-{line}")
for line in dst_lines[j1:j2]:
output.append(f"+{line}")
elif tag == "delete":
output.append(f"@@ -{i1 + 1},{i2 - i1} +{j1 + 1},0 @@")
for line in src_lines[i1:i2]:
output.append(f"-{line}")
elif tag == "insert":
output.append(f"@@ -{i1 + 1},0 +{j1 + 1},{j2 - j1} @@")
for line in dst_lines[j1:j2]:
output.append(f"+{line}")
return "\n".join(output)
def main() -> int:
parser = argparse.ArgumentParser(description="Generate line-by-line diff for markdown files.")
parser.add_argument("--input-dir", type=Path, required=True, help="Directory containing source files.")
parser.add_argument("--output-dir", type=Path, required=True, help="Directory containing polished files.")
parser.add_argument("--out-diff-dir", type=Path, required=True, help="Directory to write diff files.")
parser.add_argument("--compact", action="store_true", help="Show only changed lines with context.")
parser.add_argument("--context", type=int, default=2, help="Number of context lines around changes (compact mode).")
args = parser.parse_args()
args.out_diff_dir.mkdir(parents=True, exist_ok=True)
for src in sorted(args.input_dir.glob("*.md")):
dst = args.output_dir / src.name
if not dst.exists():
print(f"Skip {src.name}: no matching polished file.")
continue
if args.compact:
diff_text = generate_compact_line_diff(src, dst, context=args.context)
suffix = "-compact.diff"
else:
diff_text = generate_line_diff(src, dst)
suffix = "-line.diff"
out_path = args.out_diff_dir / (src.stem + suffix)
out_path.write_text(diff_text, encoding="utf-8")
print(f"Wrote {out_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())