Files
Viper_Wiki/MergeWiki.py
T
TermiNexus d7a4012b20 docs(lang): 修正 cif/defined() 条件编译、值引用注解与 assert 语义口径
07-control-flow / 08-c-operations / 10-imports / README:cif-celif-celse 成套语法与 defined() 谓词改写条件编译章节;值引用注解 &T / &temp T 取代 t.CNeedPtr;assert 自动导入 testcheck 并改译 testcheck.check(cond, None, msg)。MergeWiki.py 仅微调合并快照横幅措辞。
2026-10-07 19:02:43 +08:00

147 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""MergeWiki.py - 把 wiki 目录下的 Markdown 快速合并成可发送给 AI 的快照
用法(在本目录下执行):
python MergeWiki.py # → WikiAi0.md(若超块大小则 WikiAi0.md, WikiAi1.md, ...)
python MergeWiki.py 输出前缀 # 自定义输出前缀
python MergeWiki.py 输出前缀 200 # 自定义输出前缀 + 每块大小(KB)
特点:
* 递归收集本目录(脚本所在目录)下所有 *.md / *.MD(跳过 .git 与自身产出);
* 按路径排序合并,结果可复现;
* 每个文件前后插入 `<!-- ===== BEGIN/END FILE: <相对路径> ===== -->` 边界标记;
* 每块开头插入文件头,含用途与【弱时效性】声明;
* 默认每块 199KB(与 Tools/sendaiandsplit.py 口径一致)。
【弱时效性声明】
wiki 会持续修订,本脚本产出的是**生成时刻的快照**。发送给 AI 前请重新生成,
分析结论请以 wiki 目录下的**实时文件**为准,不要固化。
"""
import os
import sys
import time
DEFAULT_PREFIX = "WikiAi"
DEFAULT_CHUNK_KB = 199
HERE = os.path.dirname(os.path.abspath(__file__))
def CollectMarkdown(Dir: str, Prefix: str):
"""递归收集 *.md / *.MD(跳过 .git 与以 Prefix 开头的自身产出),返回排序后的路径列表。"""
Matched = []
LowPrefix = Prefix.lower()
for Root, Dirs, Files in os.walk(Dir):
Dirs[:] = [d for d in Dirs if d != ".git"]
for F in Files:
Lower = F.lower()
if not (Lower.endswith(".md")):
continue
if Lower.startswith(LowPrefix):
continue
Matched.append(os.path.join(Root, F))
Matched.sort()
return Matched
def Banner(Title: str, SrcDir: str, FileCount: int, Total: int,
ChunkIndex: int, ChunkTotal: int, OutName: str) -> str:
"""生成面向 AI 分析的文件头(含【弱时效性】声明)。"""
Stamp = time.strftime("%Y-%m-%d %H:%M:%S")
return (
"<!-- ============================================================ -->\n"
f"<!-- {Title} -->\n"
"<!-- 用途:把 wiki 全部章节合并为的快照。 -->\n"
"<!-- 【弱时效性】本文件是生成时刻的快照,wiki 会持续修订;请以目录下实时文件为准, -->\n"
"<!-- 结论不要固化;需要最新内容请重新运行 MergeWiki.py。 -->\n"
f"<!-- 生成时间:{Stamp} -->\n"
f"<!-- 源目录 :{SrcDir} -->\n"
f"<!-- 文件数 :{FileCount} -->\n"
f"<!-- 内容字节:{Total} -->\n"
f"<!-- 分块  :第 {ChunkIndex + 1}/{ChunkTotal} 块 → {OutName} -->\n"
"<!-- ============================================================ -->\n\n"
)
def MergeWiki(Dir: str, Prefix: str, ChunkKb: int) -> int:
"""合并 Dir 下所有 Markdown,带边界标记与【弱时效性】文件头,按 ChunkKb 分块输出。"""
if not os.path.isdir(Dir):
print(f"错误: 目录 {Dir} 不存在", file=sys.stderr)
return 1
Matched = CollectMarkdown(Dir, Prefix)
if not Matched:
print(f"错误: {Dir} 下没有可合并的 Markdown", file=sys.stderr)
return 1
Parts = []
Total = 0
try:
for Path in Matched:
Rel = os.path.relpath(Path, Dir).replace("\\", "/")
with open(Path, "r", encoding="utf-8") as Fh:
Content = Fh.read()
Total += len(Content)
Parts.append(f"<!-- ===== BEGIN FILE: {Rel} ===== -->\n")
Parts.append(Content)
if not Content.endswith("\n"):
Parts.append("\n")
Parts.append(f"<!-- ===== END FILE: {Rel} ===== -->\n\n")
except OSError as Exc:
print(f"错误: 读取源文件失败: {Exc}", file=sys.stderr)
return 1
Body = "".join(Parts)
ChunkSize = max(1, ChunkKb) * 1024
ChunkTotal = max(1, (len(Body) + ChunkSize - 1) // ChunkSize)
Title = "Viper wiki 快照(AI 分析用)"
for i in range(ChunkTotal):
Chunk = Body[i * ChunkSize:(i + 1) * ChunkSize]
OutName = f"{Prefix}{i}.md"
OutPath = os.path.join(Dir, OutName)
try:
with open(OutPath, "w", encoding="utf-8") as Out:
Out.write(Banner(Title, Dir, len(Matched), Total, i, ChunkTotal, OutName))
Out.write(Chunk)
except OSError as Exc:
print(f"错误: 写入 {OutName} 失败: {Exc}", file=sys.stderr)
return 1
print(f"{OutName}: {len(Chunk)} 字节")
print(f"wiki 合并完成: {len(Matched)} 个文件 → {ChunkTotal} 块(前缀 {Prefix},每块 {ChunkKb}KB)")
print("【弱时效性】以上为生成时刻快照,请以 wiki 目录下实时文件为准。")
return 0
def PrintUsage() -> None:
print("用法: python MergeWiki.py [输出前缀] [块大小KB]", file=sys.stderr)
print(f" 默认: 前缀 {DEFAULT_PREFIX},块大小 {DEFAULT_CHUNK_KB}KB", file=sys.stderr)
print(" 合并本目录下所有 *.md/*.MD → <前缀>0.md, <前缀>1.md, ...", file=sys.stderr)
print("【弱时效性】产出为生成时刻快照,分析结论请以实时文件为准。", file=sys.stderr)
def main() -> int:
Args = sys.argv[1:]
Prefix = DEFAULT_PREFIX
ChunkKb = DEFAULT_CHUNK_KB
if len(Args) >= 1 and Args[0] not in ("-h", "--help"):
Prefix = Args[0]
if len(Args) >= 2:
try:
ChunkKb = int(Args[1])
except ValueError:
print(f"错误: 块大小 '{Args[1]}' 不是整数", file=sys.stderr)
PrintUsage()
return 1
if len(Args) > 2 or (len(Args) >= 1 and Args[0] in ("-h", "--help")):
PrintUsage()
return 1
return MergeWiki(HERE, Prefix, ChunkKb)
if __name__ == "__main__":
sys.exit(main())