Files

1382 lines
106 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
辅行诀五脏用药法要-药性探真 资料库 ETL 第 10 步(2026-09-20)
01_来源数据/《辅行诀五脏用药法要 药性探真》第2章.md -> 02_加工数据/
定位:本件为《药性探真》第二章「虚劳五补方菜果谷畜类药释义」之**录入稿**
(PDF/文本层导出;A 类版式残留未清,与第一章之「用户精清稿」不同)。
标准:**完全沿用第一章(07_clean_ch1.py)的检查核对标准**——
同一编号体系(A 版式/B 断行/C 讹字/D 标点/E 存疑/F 体例/H 标题层级)、
同一产物集(清洗版+检查报告+结构.json+待核对清单按章节结构分组)、
同一核校纪律(每条改写带锚校验 + 核校依据,可回改;存疑一律不改原文)。
处理(编号与检查报告一致):
A 版式残留:行尾空格 304 行、汉字间半角空格 27 处、数字与汉字间半角空格 17 处、
全角标点旁空格、半角括号 13 处、半角标点(, : ;)与半角 ~、
LaTeX(PDF 公式化)残留 $7 \\sim 10$ 1 处
B 断行接合:3 处(行号锚定 + 原文校验)
C 讹字修正:13 条(每条附核校依据:本库内证/底本/同类文献)
D 标点规范化:半角改全角;补脱收尾引号 1 处;引号与逗号次序 1 处;重复句号 1 处
E 存疑(原文不改,登记待核):17 条
F 体例登记:五菜条目「脏位」命名、交叉引证、脚注、数字两侧留空等
H 标题层级:章=二级(##)、节=三级(###)、条目=四级(####);五菜条目序号重出顺次改正
自检(脚本自动):
① C 类 13 条规则三段验证(错误形残留 0 / 正确形已出现)
② 标题计数 章1/节4/条目20;各节条目序号 一…五连续;层级无跳级
③ 引号/书名号/括号/单引号配平;半角标点 0;残留空格 0;断行候选 0
④ 20 条目「脏—味」⇄ 本书五味体用化说 + 底本二十五味药精/十三种药 逐条互校
⑤ 与第 1 章清洗版交叉引证(生姜/薤白/白酨浆/酢)与底本方剂实测互校
输出:
02_加工数据/药性探真_第2章_清洗版.md
02_加工数据/药性探真_第2章_检查报告.md
02_加工数据/药性探真_第2章_结构.json
02_加工数据/药性探真_第2章_待核对清单.md
幂等:可重复运行;改写皆带原文锚校验,源件被替换即报错。
说明:01_来源数据/《…》第2章.md 标题层级已按**用户 2026-09-20 明确指令**就地优化
(只改井号,正文 641 行逐行未动;改动前逐字节快照
《…》第2章_层级优化前快照_20260920.md,md5 92fd55f8…;新 md5 a9168956…)。
脚本:11_retitle_src_ch2.py(默认 dry-run,--apply 才落盘+留快照)。
"""
import os, re, json, hashlib, collections
BASE = os.path.expanduser("~/Documents/ai_agent_scraper_study/data/辅行诀五脏用药法要-药性探真")
SRC = os.path.join(BASE, "01_来源数据/《辅行诀五脏用药法要 药性探真》第2章.md")
CH1_MD = os.path.join(BASE, "02_加工数据/药性探真_第1章_清洗版.md")
BENDI = os.path.join(BASE, "02_加工数据/辅行诀五脏用药法要_基础文本_清洗版.md")
OUT_MD = os.path.join(BASE, "02_加工数据/药性探真_第2章_清洗版.md")
OUT_REPORT = os.path.join(BASE, "02_加工数据/药性探真_第2章_检查报告.md")
OUT_STRUCT = os.path.join(BASE, "02_加工数据/药性探真_第2章_结构.json")
OUT_CHECK = os.path.join(BASE, "02_加工数据/药性探真_第2章_待核对清单.md")
# ── B 类:断行接合(源件行号 + 原文锚校验;与下一非空行接合)────────────
JOINS = {
363: ("其雌花枝上的顶端、叶、种子及",
"《辅行诀》麻条述印度大麻「…其雌花枝上的顶端、叶、种子及/茎中均含大麻脂。」"
"被空行切断,据文义接合(同一句)"),
451: ("《齐民要术》引史游(西汉时人约公元前 48~33 年)",
"「《齐民要术》引史游(…)」与「《急就篇》云:…」为同一句,被版心换行切断"
"(两行间无空行,属硬换行),接合为一段"),
648: ("又谓“兑以说之。”又谓",
"「又谓」与下文「“说言乎兑。”」为同一句,被空行切断,据文义接合"),
}
# ── C 类:讹字修正(锚校验:原文命中次数 + 改后残留 0)──────────────────
# (讹形, 正形, 原文应命中数, 核校依据)
C_FIXES = [
("薙", "薤", 1,
"第一章第六节·十 条目标题作「薤白」(该章「薙」4 处经用户 2026-09-17 判决改「薤」);"
"本条即《灵枢·五味》五菜之薤,属肾,形近致误"),
("白黻浆", "白酨浆", 1,
"第一章第六节·十 一条目标题作「白酨浆」;「酨」为古酒浆名,"
"底本 03_clean_yinshua.py 已判「白戴浆/白截浆」→「白酨浆」,「黻」形近致误"),
("白截浆", "白酨浆", 1,
"同上;「截」「酨」形近致误(底本同一讹形已判)"),
("脏病者宜食以霍", "脏病者宜食以藿", 1,
"本条即「二、心菜藿」;同条下文「以藿为菜」「灰涤菜代藿」皆作「藿」,"
"「藿」为豆叶之义,「霍」形近致误"),
("小豆,苔也。角曰英,叶曰霍,茎曰萁", "小豆,荅也。角曰荚,叶曰藿,茎曰萁", 1,
"《广雅·释草》原文作「大豆,菽也。小豆,荅也。角曰荚,叶曰藿,茎曰萁」"
"(《本草纲目·谷部·大豆》引《广雅》同;《齐民要术·大豆》引作「豆角谓之荚,其叶谓之藿」);"
"三处皆艹部形近讹字(苔/荅、英/荚、霍/藿),同句连误可互证"),
("称西鸡而不称卯鸡", "称酉鸡而不称卯鸡", 1,
"十二生肖配十二支作「酉鸡」;同条下文正作「酉位西方,属金,为阴,为秋」,"
"「西」「酉」形近致误"),
("狗居戍位", "狗居戌位", 1,
"《曲洧旧闻》原文作「狗居戌位」(十二支戌配狗);同篇上文「戌时为一更」「太阳出于寅没于戌」"
"皆作「戌」,「戍」「戌」形近致误"),
("朱笠《曲消旧闻》", "朱弁《曲洧旧闻》", 1,
"该书为南宋朱弁(biàn)所撰《曲洧旧闻》(《四库全书》子部杂家类);"
"「笠」「弁」、「消」「洧」形近致误"),
("紫苑五分", "紫菀五分", 1,
"药名作「紫菀」,非「紫苑」(苑=园囿);本条系《幼幼新书》引《婴孺方》白狗肺汤方中药味,"
"「苑」「菀」形近致误"),
("《陶名景评传》", "《陶弘景评传》", 1,
"钟国发《陶弘景评传》(南京大学出版社「中国思想家评传丛书」);"
"「名」为「弘」之形近讹字,全篇人名一律作「陶弘景」"),
("唐代孔顥达《诗疏》", "唐代孔颖达《诗疏》", 1,
"唐孔颖达撰《毛诗正义》(世称《诗疏》);「顥」为「颖」之形近讹字;"
"**用户 2026-09-20 判决:保留修正**"),
# —— 以下三条据用户 2026-09-20 核对原书结果回填 ——
("蘖未一斗调和", "蘖末一斗调和", 1,
"**用户核对原书(2026-09-20)**:「未」当作「末」。蘖末=麦芽末(粉),"
"同条下文「用大麦蘖所造者为琥珀餳」及本书第 479 行皆以「麦芽粉」为说;"
"「未」「末」形近致误"),
("儆(生但反)", "馓(生但反)", 1,
"**用户核对原书(2026-09-20)**:「儆」当作「馓」(饊之简化字)。本条系《齐民要术》引史游"
"《急就篇》,与「饴」「餳」并列,皆糖食之名;书中自注反切「生但反」=音 sǎn,正与「饊(馓)」"
"相合,而「儆」音 jǐng 不合反切,形近致误"),
("盖脾为脾之副脏", "盖脺为脾之副脏", 1,
"**用户核对原书(2026-09-20)**:前「脾」当作「脺」(音 cuì)。用户释曰:「散膏即脺也,"
"脾之质子为胰子,形如膏,故曰散膏」。同段下文正作「故胰为脾之副脏之说甚是合理」,"
"本条标题亦作「三、脾土畜牛脾(胰)」,「脾」「脺」形近致误"),
("葱似囟,外直中空,有囟道之象也", "葱从囱,外直中空,有囱通之象也", 1,
"《本草纲目·菜部·葱》「时珍曰:葱从囱。外直中空,有囱通之象也」"
"(「蔥」从「囱」取象,由字形立说,故「囱」不可作「囟」);"
"「囟」为囟门之义,于此无义,形近致误。⚠ **用户 2026-09-20 判决「修正内容」**:"
"本条引文并据传本再订正两处——「似」→「从」、「道」→「通」(印刷本作「似/道」),"
"故改形直接落到传本形「葱从囱…有囱通之象也」"),
# —— 以下 12 条据用户 2026-09-20 判决「修正内容」=改正文,落 C 类(依「全按此拟」)——
("木金者生成之始终也", "金木者,生成之终始也", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。本条引《素问》兼有三病:倒文(本书他处三处皆作"
"「金木者」)、误「终始」为「始终」、脱「生成之」后逗号;据传本一并订正为「金木者,生成之终始也」"),
("生成之始终", "生成之终始", 1, # 每行命中 1 次(第 33/109/657 行各一处;第 149 行倒文已由上一条先行订正)
"**用户 2026-09-20 判决:修正内容(=改正文)**。《素问》传本作「金木者,生成之终始也」,"
"本书三处(第 33/109/657 行)引作「始终」;据传本订正。⚠ 本库由此**与印刷本有意不一致**"
"(印刷本作「始终」),原「引文用字体例·金木者生成之始终」一条已改记为订正记录,检索须用新字「终始」"),
("诸事皆宜,故曰和事草", "诸物皆宜,故云菜伯、和事", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。《本草纲目·菜部·葱》传本作「诸物皆宜,故云菜伯、和事」"
"(菜伯、和事皆葱之别称);本书引作「诸事皆宜,故曰和事草」,据传本订正。"
"⚠ 第 111 行作者自述「其别称和事草非无缘由」为作者原文、不在引文内,**不改**"),
("《晋书·世相武帝》", "《晋书·世祖武帝》", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。晋武帝司马炎庙号**世祖**(《晋书》纪作「世祖武皇帝」),"
"「相」为「祖」之形近讹字"),
("咸宁九年(公元288年)", "太康九年(公元288年)", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。咸宁仅五年(275–280),288 年当为**太康九年**"
"(太康元年=280 年);年号与公元纪年不合,据史订正"),
("陇西式殒霜", "陇西陨霜", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。《晋书》载太康九年「夏四月,陇西陨霜,伤宿麦」;"
"「式」为衍字(或「陨」之讹),据史订正"),
("今俗称江米:稷与稕同", "今俗称江米。稷与穄同", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。前后为两事,冒号当作句号;同段上文列举谷名正含「穄」"
"(黍、稷、稻、粱…体系),「稕」(zhùn,束秆)于此无义,形近致误"),
("即古称之梁米", "即古称之粱米", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。「粱」为谷名(粱米),「梁」为桥/国名;"
"同段下文正作「高粱」,「梁」「粱」形近致误"),
("如南宋代朱弁", "如南宋朱弁", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。「代」字衍(朱弁即南宋人);本书他处皆作「南宋」"),
("即1102~1135年", "即1102~1106年", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。崇宁为宋徽宗年号,实止 1106 年(1102–1106);"
"1135 年已入绍兴五年,与崇宁不符,据史订正"),
("为家畜早的畜类之一", "为家畜较早的畜类之一", 1,
"**用户 2026-09-20 判决:修正内容(=改正文)**。脱「较」字;同段下文亦作「性成熟较早」,可互证"),
]
# ── C 类逐条「原书用字」核定(**用户 2026-09-20 核定,26 条全覆盖**)──────────
# 键=C_FIXES 的讹形。值=(归类, 说明)
# "印刷之误" = 印刷本自身即作讹形 → 属第三类「原书印刷之误·本库订正」,**不得据「原书如此」回流**
# "录入讹误" = 印刷本作正形,讹形系录入/导出所致 → 原书不误
C_ORIGIN = {
# —— 印刷之误(16 条;用户核对原书/据传本·史实订正)——
"脏病者宜食以霍": ("印刷之误", "**用户核原书**:原书即作「霍」"),
"葱似囟,外直中空,有囟道之象也": ("印刷之误+录入", "「囟→囱」为本件录入之误;「似→从」「道→通」为**原书**引《纲目》异文(本轮据传本订正)"),
"诸事皆宜,故曰和事草": ("印刷之误", "**用户核原书**:原书引《纲目》作「诸事皆宜,故曰和事草」"),
"木金者生成之始终也": ("印刷之误", "**用户核原书**:原书即作「木金者生成之始终也」(倒文+脱逗)"),
"生成之始终": ("印刷之误", "**用户核原书**:原书三处引《素问》皆作「始终」"),
"蘖未一斗调和": ("印刷之误", "**用户核原书**:「未」当作「末」,原书即作「未」"),
"儆(生但反)": ("印刷之误", "**用户核原书**:原书即作「儆」,当作「馓」"),
"盖脾为脾之副脏": ("印刷之误", "**用户核原书**:原书即作「脾」,当作「脺」"),
"《晋书·世相武帝》": ("印刷之误", "**用户核原书**:原书即作「世相」"),
"咸宁九年(公元288年)": ("印刷之误", "**用户核原书**:原书即作「咸宁九年」"),
"陇西式殒霜": ("印刷之误", "**用户核原书**:原书即作「陇西式殒霜」"),
"今俗称江米:稷与稕同": ("印刷之误", "**用户核原书**:原书即作「:稷与稕同」"),
"即古称之梁米": ("印刷之误", "**用户核原书**:原书即作「梁米」"),
"如南宋代朱弁": ("印刷之误", "**用户核原书**:原书即作「南宋代」"),
"即1102~1135年": ("印刷之误", "**用户核原书**:原书即作「1102~1135年」"),
"为家畜早的畜类之一": ("印刷之误", "**用户核原书**:原书即作「家畜早的」"),
# —— 录入讹误(10 条;**用户 2026-09-20 核定:原书作正形,本件误,修正正确**)——
"白截浆": ("录入讹误", "原书作「白酨浆」;「截」为录入形近之误。底本(另一书)印刷本同讹形,属同类录入性讹字"),
"白黻浆": ("录入讹误", "原书作「白酨浆」(本条标题即作「四、肺金谷物白酨浆」);「黻」为录入形近之误"),
"小豆,苔也。角曰英,叶曰霍,茎曰萁": ("录入讹误", "原书引《广雅·释草》作「小豆,荅也。角曰荚,叶曰藿,茎曰萁」;三处艹部为录入连误"),
"薙": ("录入讹误", "原书作「薤」(本条标题即作「五、肾菜薤」);第 1 章同字例 4 处经用户 2026-09-17 判决改「薤」"),
"称西鸡而不称卯鸡": ("录入讹误", "原书作「酉鸡」;同条下文「酉位西方,属金」可证"),
"唐代孔顥达《诗疏》": ("录入讹误", "原书作「孔颖达」;「顥」为录入形近之误"),
"紫苑五分": ("录入讹误", "原书作「紫菀」;「苑」为录入形近之误"),
"《陶名景评传》": ("录入讹误", "原书作「《陶弘景评传》」;「名」为录入形近之误"),
"狗居戍位": ("录入讹误", "原书引《曲洧旧闻》作「狗居戌位」;同篇「戌时为一更」「太阳出于寅没于戌」可证"),
"朱笠《曲消旧闻》": ("录入讹误", "原书作「朱弁《曲洧旧闻》」;「笠/消」为录入形近之误"),
}
assert set(C_ORIGIN) == {b for b, _g, _n, _w in C_FIXES}, \
"C_ORIGIN 未逐条覆盖 C_FIXES 的讹形(原书用字栏会漏标)"
# ── C 类回改(用户判决「原文无误」→ 撤销本库前批修正;锚校验)──────────
# (清洗版应含原文形, 本库前批改形, 依据)
REVERTS = [
("范致虚上方十二宫神", "范致虚上言十二宫神",
"**用户 2026-09-20 判决:「上方」原文无误**——撤销本库第 1 批将「上方」改「上言」之处,"
"回改与原件一致(核对清单 #39 中该分项)。本条其余二处(「戌位」修正、「朱弁《曲洧旧闻》」)"
"经判决维持修正"),
]
# ── D 类:标点规范化(锚校验)─────────────────────────────────────────
D_FIXES = [
("生河东、平泽。", "生河东、平泽。”", 1,
"《别录》大枣条文引号只有起无收,据同一引文体例补收尾引号(引号配平)"),
("意有相通之处,”杏之叶似珩之状", "意有相通之处”,杏之叶似珩之状", 1,
"收尾引号当在逗号之前(原误倒作「,”」),与全书引文体例一致"),
("今俗人呼为乌麻者,非也。”。", "今俗人呼为乌麻者,非也。”", 1,
"引号内已用句号收句,引号外重出一句号,去其重复"),
]
# ── H 类:标题层级(章 2 / 节 3 / 条目 4)─────────────────────────────
H_RULES = [
(re.compile(r"^第[一二三四五六七八九十]+章[  ]"), 2, "章"),
(re.compile(r"^第[一二三四五六七八九十]+节[  ]"), 3, "节"),
(re.compile(r"^[一二三四五六七八九十]+、"), 4, "条目"),
]
# ── H 类:五菜条目序号重出,顺次改正(锚校验;顺序执行)────────────────
RENUM = [
("二、脾菜生姜", "三、脾菜生姜",
"五菜条目原序号作 一、肝菜韭/二、心菜藿/**二**、脾菜生姜/三、肺菜葱/四、肾菜薙——「二」重出,"
"与本节目次(肝→心→脾→肺→肾)不合,顺次改正为 一/二/三/四/五"),
("三、肺菜葱", "四、肺菜葱", "同上,顺次改正"),
("四、肾菜薤", "五、肾菜薤", "同上,顺次改正(「薤」字已由 C 类修正)"),
]
# ── E 类:存疑(原文不改,登记待核)───────────────────────────────────
SUSPECTS = [
("汉前辟谷敬佩术",
"「敬佩」于此不可通(1973 年长沙马王堆汉墓帛书有《却谷食气篇》)。疑当作「辟谷却谷术」"
"或「辟谷行气术」之类,无版本依据不敢臆改,待核原书。"),
("喝溪水而",
"《淮南子》述单豹避世深山,「喝溪水」疑当作「饮溪水」,「喝」「饮」非形近,待核原书。"),
("葱从囱,外直中空,有囱通之象也……初生曰葱针",
"**用户 2026-09-20 判决「修正内容」→ 已并订正**。本条引《纲目》与传本《本草纲目·菜部·葱》三处异文"
"(①「葱似囱」/传本「葱从囱」;②「有囱道之象也」/传本「有囱通之象也」;③「诸事皆宜,故曰和事草」/"
"传本「诸物皆宜,故云菜伯、和事」)**皆据传本改从**(另「囟→囱」为录入讹误)。"
"⚠ 清洗版由此**与印刷本有意不一致**(印刷本作「似/道/和事草」),**不得据「原书如此」回流**。"),
("艮为果瓜",
"《周易·说卦》原文作「为果蓏」(蓏=草实);本条作「果瓜」。下文引《周礼》「有核曰果,"
"无核曰瓜」正承此,疑作者有意引作「瓜」,登记待核。"),
("宜以刀竖副其皮",
"《齐民要术》桃条作「宜以刀竖劙其皮」(劙=割);本条作「副」,而同条下文自注「(副,"
"即用刀割开)」明系原书用「副」而自释之,疑非讹字,登记待核。"),
("珩是由两块半圆形的曲玉相对而成",
"「珩」凡四见(含「珩、苔、荇、杏为一组同源词」「杏之叶似珩之状」);同一段内「苔」"
"与「杏」并见,字形与文义均有可疑(珩=玉佩,与「杏叶似珩之状」之说待核),待核原书。"),
("杨行密",
"「杨行密(852~905,唐末著名政治家,字化源,庐州合肥人,即今之安徽长丰)改名为甜梅」"
"——杨行密事迹与「改名为甜梅」不相应,且本句出处《绵竹县志》待核,文义存疑。"),
("《晋书·世祖武帝》",
"**用户 2026-09-20 判决「修正内容」→ 三处均已据史订正**:①「世相武帝」→「**世祖武帝**」"
"(司马炎庙号世祖);②「咸宁九年(公元 288 年)」→「**太康九年(公元 288 年)**」"
"(咸宁仅五年,288 年当为太康九年);③「陇西式殒霜」→「**陇西陨霜**」(《晋书》作"
"「夏四月,陇西陨霜,伤宿麦」,「式」为衍字)。⚠ 清洗版与印刷本有意不一致,**不得回流**。"),
("蘖末一斗调和",
"《齐民要术》引《食经》作饴法「着盆中,蘖未一斗调和」——「未」疑当作「末」(蘖末=麦芽粉,"
"同条下文及本书第 479 行皆以「麦芽粉」为说);又「一宿,则得一斗五斛」量名可疑,并待核。"),
("今俗称江米。稷与穄同",
"**用户 2026-09-20 判决「修正内容」→ 三处均已订正**:①「今俗称江米:稷与稕同」→"
"「**今俗称江米。稷与穄同**」(冒号当作句号;「稕」当作「穄」,同段列举谷名正含「穄」);"
"②「即古称之梁米」→「**即古称之粱米**」(粱=谷名,梁=桥梁,形近)。"
"⚠ 清洗版与印刷本有意不一致,**不得回流**。"),
("无在身边即便的习惯",
"「其大小便也有固定在离其卧身处较远的地方,无在身边即便的习惯」——「即便」于此不可通,"
"疑当作「随便」,待核原书。"),
("故马蹄园,牛蹄坼",
"本题两处待核:①「马蹄园」疑当作「马蹄圆」(下文「牛蹄坼」对文);"
"②「牛病则立,阳盛世也」疑衍「世」字(上文对文作「马病则卧,阴盛也」)。"),
("《周易·说卦》谓:“坤为土。”",
"《周易·说卦》作「坤为地」;紧接着的李鼎祚注正作「坤象地,任重而顺,故为牛」,"
"「土」疑当作「地」,待核原书。"),
("盖脺为脾之副脏",
"「盖脾为脾之副脏」文义不通,同段下文作「故胰为脾之副脏之说甚是合理」,本条标题亦作"
"「三、脾土畜牛脾(胰)」;疑前「脾」当作「胰」,待核原书。"),
("如南宋朱弁",
"**用户 2026-09-20 判决「修正内容」→ 两处均已订正**:①「如南宋代朱弁」→「**如南宋朱弁**」"
"(「代」字衍);②「即 1102~1135 年」→「**即 1102~1106 年**」(崇宁实止 1106 年)。"
"⚠ 清洗版与印刷本有意不一致,**不得回流**。"),
("羊是人类驯养为家畜较早的畜类之一",
"**用户 2026-09-20 判决「修正内容」→ 已订正**:「为家畜早的畜类之一」→"
"「**为家畜较早的畜类之一**」(脱「较」字;同段下文亦作「性成熟较早」,可互证)。"),
("《经》云:“金木者,生成之终始”",
"**用户 2026-09-20 判决「修正内容」→ 四处皆已据传本订正**:《素问》作"
"「金木者,生成之终始也」,本书三处(第 33/109/657 行)引作「始终」,另第 149 行作"
"「木金者生成之始终也」(倒文+脱逗),一并订正为「**金木者,生成之终始也**」。"
"⚠ 清洗版**与印刷本有意不一致**(印刷本作「始终」),**不得据「原书如此」回流**;"
"检索须用新字「终始」(以「始终」检索不能命中)。"
"**勘正(2026-09-20)**:本库前曾记「第 1 章亦见同语,可两章同办」——经核**第 1 章实无此语**;"
"第 1 章第 561 行所引为「金木者,阴阳之道路也」,与传本《素问·天元纪大论》"
"「左右者,阴阳之道路也」不同,**系另一条引文、另案登记**,与本条无涉。"),
]
# ── F 类:体例登记(不校改)───────────────────────────────────────────
VERSION_NOTES = [
("五菜条目「脏位」命名",
"第一节五菜条目作「肝菜韭/心菜藿/脾菜生姜/肺菜葱/肾菜薤」。与《灵枢·五味》脏病者宜食"
"比对:韭(肝)、生姜(代脾菜葵)、葱(肺)与《灵枢》一致;藿(《灵枢》为肾病宜食之菜)、"
"薤(《灵枢》属心)二者与《灵枢》所宜之脏**互易**,正合第一节引言「心肾之品交换使用,"
"肝肺之品互易使用」之说。原书如此,登记不改,另列待核对项。"),
("五果/五谷/五畜条目「脏位」命名",
"五果(肺金果桃/肾水果栗/脾土果大枣/肝木果李/心火果杏)、五畜(肺金畜鸡肝/肾水畜猪心/"
"脾土畜牛脾/肝木畜犬肺/心火畜羊肾)之脏位与《灵枢·五味》五果(桃辛—肺、栗咸—肾、枣甘—脾、"
"李酸—肝、杏苦—心)、五畜(鸡辛—肺、豕咸—肾、牛甘—脾、犬酸—肝、羊苦—心)一一相合;"
"五谷(肝木谷物麻油/心火谷物麦酒/脾土谷物黄饴/肺金谷物白酨浆/肾水谷物苦酒)之脏位"
"与所补脏用味(辛/咸/甘/酸/苦)相合。条目序次依虚劳五补方之脏序(肝→心→脾→肺→肾),"
"非《灵枢》本序。"),
("底本方剂实测(五补汤所用菜果畜)",
"底本清洗版实测:大养生补肝汤用「葱叶十四茎、桃奴十四枚」(肺菜+肺果);"
"调神补心汤用「藿三两、栗仁十一枚」(肾菜+肾果);凝息补肺汤用「韭三两、李八枚」(肝菜+肝果);"
"固元补肾汤用「薤白三两、苦杏七枚」(心菜+心果)——即引言「心肾之品交换使用、肝肺之品互易"
"使用」之实录(本库内部互证,不改原文)。"),
("交叉引证",
"本件以「见第一章第X节·Y/详说请参第一章第六节·十一」方式回指第 1 章 4 处:"
"第 69 行「见第一章第一节·二」(生姜)、第 117 行「见第一章第六节·十」(薤白)、"
"第 483 行「详说请参第一章第六节·十一」(白酨浆)、第 487 行「详说可参第一章第六节·六」(酢/苦酒)。"
"与第 1 章结构索引逐条吻合。"),
("行内枚举号 ①②",
"第 137 行「(典术有两义:①谓经典之学,②官名:明设阴阳学官…)」之 ①② 为**行内枚举**,"
"非脚注标记;本件无脚注标记(第 1 章之 6 处脚注标记已按用户判决处理)。"),
("数字与汉字间半角空格",
"源件为 PDF/文本层导出,半角数字与汉字间普遍带一个半角空格(**18 处**,如「中国文物出版社 2003 年 5 月」"
"「公元前 48~33 年」「发现 10 座」)。本次按「句中误入空格」一律删除。"
"注:第 1 章清洗版存 1 处同类未清(「用升麻 10 克、小米 10 克…」),本件从严。"
"**用户 2026-09-20 判决:保持现状**——本件从严删除、不回改,亦不回补第 1 章;"
"**两章体例暂不统一**,登记待后续统一(详见检查报告第二节清单)。"),
("引文订正·《素问》「金木者,生成之终始」(★)",
"本书三处引《素问》原作「金木者,生成之始终」,另第 149 行作「木金者生成之始终也」(倒文+脱逗);"
"**用户 2026-09-20 判决「修正内容」→ 四处一并据传本订正为「金木者,生成之终始也」**。"
"⚠ 清洗版**与印刷本有意不一致**(印刷本作「始终」),**不得据「原书如此」回流**;"
"**检索须用新字「终始」**(以「始终」检索不能命中本库文本)。"
"**传本出处**:《素问·天元纪大论篇第六十六》「然天地者,万物之上下也;左右者,阴阳之道路也;"
"水火者,阴阳之征兆也;**金木者,生成之终始也**」(另有传本作「生长之终始」之异文)。"
"**勘正**:本库前记「第 1 章亦见同语」有误——第 1 章实无此语,其所引为「金木者,阴阳之道路也」"
"(传本作「左右者」),属另一条引文,已另案登记。"),
("引文订正·《纲目》葱条(★)",
"本书引《纲目》葱条与传本《本草纲目·菜部·葱》有三处异文:①「葱似囱」/传本「葱从囱」;"
"②「有囱道之象也」/传本「有囱通之象也」;③「诸事皆宜,故曰和事草」/传本「诸物皆宜,"
"故云菜伯、和事」。**用户 2026-09-20 判决「修正内容」→ 三处皆据传本改从**(另「囟→囱」为录入讹误)。"
"⚠ 清洗版**与印刷本有意不一致**,**不得回流**;第 111 行作者自述「其别称和事草非无缘由」为作者原文,**不在引文内、未改**。"),
("用字体例·「脺」(★)",
"第 577 行「盖**脺**为脾之副脏」——**用户 2026-09-20 核对原书**:前「脾」当作「脺」(音 cuì);"
"用户释曰:「散膏即脺也,脾之质子为胰子,形如膏,故曰散膏」。→ 检索时以「脾」「胰」均不能命中"
"该字,须用「脺」;本条标题作「三、脾土畜牛脾(胰)」,同段下文作「故胰为脾之副脏之说甚是合理」。"),
("用字体例·原书用字(★)",
"经用户 2026-09-20 核对原书确认「原书如此」而判决保留不改者:①**「副」**(第 135 行"
"「桃性皮急,宜以刀竖副其皮」,同条作者自注「(副,即用刀割开)」,与《齐民要术》传本"
"「劙」不同);②**「珩」**与**「苔」**(第 281 行「珩、苔、荇、杏为一组同源词」"
"「杏之叶似珩之状」,凡四见);③**「杨行密…改名为甜梅」**及所引《绵竹县志·卷八》"
"(第 281 行,文义不相应系作者原文)。→ **检索须用原字**(以「劙」「衡」等检索均不能命中)。"),
("引文用字体例·《周易·说卦》「艮为果瓜」(★)",
"本书引《周易·说卦》作「艮为果瓜」(传本作「为果蓏」,蓏=草实),且同段引《周礼》亦作"
"「有核曰果,无核曰瓜」,本书用字自成一体。**用户 2026-09-20 判决「原书如此」保留不改**。⚠ **注意本条与上二条判然不同**:「果瓜」为《说卦》引文而**判决保留**(未入「保留」类,故未改);"
"《素问》「始终」、《纲目》葱条同属引文异文而**判决修正内容、已改从传本**。"
"故本库对引文异文**不作统一处理,逐条依用户判决**;检索时《说卦》须用「果瓜」、「素问」须用「终始」。"),
("原书印刷之误·本库订正(★重要)",
"经用户核对原书,本书**印刷本自身**存在讹字与序号重出:#8 第 49 行原书即作「以霍」(当作「藿」);"
"#10 五菜条目原书序号「二」重出。本库据内证(本条题名、下文同字例)与所引文献原文订正,"
"**用户 2026-09-20 判决「修正有理,保留修正」/「按修正排序」**。故本清洗版与印刷本在个别字上"
"**有意不一致**,凡此类均在待核对清单判决栏与本表登记,**不得据「原书如此」回流改回**;"
"与「录入/导出讹误」(第 1 章之薙→薤、白截浆→白酨浆等,原书不误而本件误)分属两类。"
"**2026-09-20 追加**:本条范围扩及**印刷本自身有误、经用户判决据正字订正**者共 **6 条 11 处**——"
"#6《素问》「始终」→「终始」4 处(含 1 处倒文)、#13《纲目》葱条三处异文、#27《晋书》「世相武帝/咸宁九年/"
"陇西式殒霜」3 处、#30「:/稕/梁米」3 处、#40「南宋代/1102~1135年」2 处、#42 脱「较」1 处;"
"此类清洗版**一律与印刷本有意不一致**,**不得据「原书如此」回流改回**,检索须用订正后新字。"
"**2026-09-20 定案**:C 类 26 条的「原书用字」**已逐条核定、不漏一条**"
"(见报告 §三「原书用字」栏):**印刷之误 16 条**(含本轮 6 条 11 处)、"
"**录入讹误 10 条**(原书作正形,见下条)。"),
("录入/导出讹误(原书不误、本件误)(★)",
"**用户 2026-09-20 核定:以下 10 条原书均作正形,讹形系录入/导出所致,修正正确——**"
"①白截浆→**白酨浆**(行13)②白黻浆→**白酨浆**(行481,本条标题即作「白酨浆」)"
"③《广雅》三误 苔→**荅**/英→**荚**/霍→**藿**(行51)④薙→**薤**(行115,本条标题作「肾菜薤」)"
"⑤西鸡→**酉鸡**(行525)⑥孔顥达→**孔颖达**(行347)⑦紫苑→**紫菀**(行601)"
"⑧陶名景→**陶弘景**(行617)⑨戍位→**戌位**(行625)⑩朱笠《曲消旧闻》→**朱弁《曲洧旧闻》**(行625)。"
"此类与上条「原书印刷之误·本库订正」**判然不同:原书不误、只在电子本误**,故**清洗版此处与印刷本一致**"
"(可直接以印刷本复核);两类合计 C 类 26 条,已无「待定」条目。"),
("源件标题层级已就地优化(★例外)",
"01_来源数据/《…》第2章.md 原标题 25 行原样为「##」(章/节/条目不分级)。"
"**经用户 2026-09-20 明确指令**,已就地优化为 章2/节3/条目4(同第 1 章体例),"
"共改 24 行标题;**正文 641 行逐行未动**(脚本落盘前断言「去标题行后正文逐行相同」)。"
"改动前逐字节快照:`01_来源数据/《…》第2章_层级优化前快照_20260920.md`(md5 `92fd55f8…`);"
"原件 md5 `92fd55f8…` → `a9168956…`。脚本 `05_脚本工具/11_retitle_src_ch2.py`(默认 dry-run;幂等)。"
"⚠ 此为 README 归档原则「01_来源数据不可修改」的**第二例明文例外**(第 1 章同办于 2026-09-17)。"),
]
# ── 自检:20 条目「脏—味」⇄ 本书体用化说 + 底本五味五行表 ────────────
# 味 → 可属之脏(底本「味辛皆属木…」+本书体用化说);括号内为「体/用/化」位
WEI2ZANG = {
"辛": [("肝", "用"), ("肺", "化"), ("脾", "体")],
"咸": [("心", "用"), ("肾", "化")],
"甘": [("脾", "用"), ("肾", "体")],
"酸": [("肝", "体"), ("肺", "用"), ("心", "化")],
"苦": [("心", "体"), ("肾", "用")],
}
# (节, 条目名, 脏, 味, 味依据, 底本/第1章互证)
ITEMS20 = [
("第一节 五菜", "一、肝菜韭", "肝", "辛", "第 45 行「以其口尝为辛味…以属肝菜论之」", "第 1 章第一节·二 生姜(木中火/木中水)"),
("第一节 五菜", "二、心菜藿", "心", "咸", "第 49 行「为肾病宜食之菜,味咸」", "底本调神补心汤用藿三两"),
("第一节 五菜", "三、脾菜生姜", "脾", "辛", "第 15 行「菜类为用生姜代脾菜葵」;第 1 章第一节·二", "第 1 章 生姜(木中火)"),
("第一节 五菜", "四、肺菜葱", "肺", "辛", "第 73 行「列为肺脏病者宜食之菜,味辛」", "底本大养生补肝汤用葱叶十四茎"),
("第一节 五菜", "五、肾菜薤", "肾", "苦", "第 117 行回指第 1 章第六节·十;《灵枢·五味》薤苦", "第 1 章 薤白(水中土、水中金)"),
("第二节 五果", "一、肺金果桃、桃奴、桃核仁", "肺", "辛", "第 125 行「味辛」", "底本大养生补肝汤用桃奴十四枚"),
("第二节 五果", "二、肾水果栗", "肾", "咸", "第 185 行「味咸」", "底本调神补心汤用栗仁十一枚"),
("第二节 五果", "三、脾土果大枣", "脾", "甘", "第 213 行「味甘」", "《灵枢·五味》枣甘—脾"),
("第二节 五果", "四、肝木果李", "肝", "酸", "第 243 行「味酸」", "底本凝息补肺汤用李八枚"),
("第二节 五果", "五、心火果杏、杏核仁", "心", "苦", "第 271 行「味苦」", "底本固元补肾汤用苦杏七枚"),
("第三节 五谷酿制品", "一、肝木谷物麻油", "肝", "酸", "第 323 行「味酸」", "《灵枢》麻酸—肝(本书第 399 行改以「香油」辛窜为说)"),
("第三节 五谷酿制品", "二、心火谷物麦酒", "心", "苦", "第 405 行「味苦」", "底本调神补心汤用麦酒(《别集本》)"),
("第三节 五谷酿制品", "三、脾土谷物黄饴", "脾", "甘", "第 441 行「味甘」", "底本建中补脾汤用黄饴"),
("第三节 五谷酿制品", "四、肺金谷物白酨浆", "肺", "酸", "第 486 行回指第 1 章第六节·十一;底本十三种药「白酨浆为金中金,又为金中火」(味酸皆属金)", "第 1 章 白酨浆(金中金、金中火)"),
("第三节 五谷酿制品", "五、肾水谷物苦酒", "肾", "苦", "第 490 行回指第 1 章第六节·六(酢,即苦酒)", "第 1 章 酢(金中水)"),
("第四节 五畜脏器", "一、肺金畜鸡肝", "肺", "辛", "第 508 行「谓鸡味辛,为肺病者宜食之畜」", "《灵枢》鸡辛—肺"),
("第四节 五畜脏器", "二、肾水畜猪心", "肾", "咸", "第 548 行「谓猪味咸,为肾脏病者宜食之畜」", "《灵枢》豕咸—肾"),
("第四节 五畜脏器", "三、脾土畜牛脾(胰)", "脾", "甘", "第 568 行「谓牛味甘,为脾病者宜食之畜」", "《灵枢》牛甘—脾"),
("第四节 五畜脏器", "四、肝木畜犬肺", "肝", "酸", "第 598 行「谓犬为肝病者宜食之畜,味酸」", "《灵枢》犬酸—肝"),
("第四节 五畜脏器", "五、心火畜羊肾", "心", "苦", "第 644 行「心病者宜食羊,味苦」", "《灵枢》羊苦—心"),
]
# ── 待核对清单:固定条目表(锚=清洗版唯一子串;行号由脚本定位)────────
CHECK_ITEMS = [
# (类型, 锚, 问题, 依据, 建议)
("版式清理确认", "菜、果、谷、畜均为寻常食品类",
"行尾空格 **304 行**(正文段落末尾普遍带 1 个半角空格)已逐行删除",
"源件为 PDF/文本层导出,段落末尾带半角空格;第 1 章用户精清稿已清净(0 行)",
"复核;如欲保留可回改(脚本 A 类规则)"),
("版式清理确认", "心主血脉,血水同体",
"句中误入半角空格 **正文 27 处**(汉字↔汉字;标题内 6 处体例保留)+ **18 处**(数字↔汉字)+ 全角标点旁空格已删除",
"扫描/文本层导出残留;与底本 03_clean_yinshua.py「句中误入空格」同例",
"复核;数字两侧留空如欲保留可回改(详报告第二节逐处清单)"),
("版式清理确认", "葱宜浅栽苗,勤锄勤培土",
"(3)(4)段原用半角标点(, : ; ( ) ~)与 LaTeX 残留「$7 \\sim 10$」,已规范为全角并还原「7~10」",
"标点体例统一(半角改全角);LaTeX 为 PDF 公式化残留,读作数据还原",
"复核"),
("断行接合确认", "其雌花枝上的顶端、叶、种子及茎中均含大麻脂",
"原被空行切断,已接合为一段(本次 B 类)",
"同一句文义相连(「…种子及/茎中均含大麻脂。」)",
"复核;如原书另起段落,可回改"),
("断行接合确认", "《齐民要术》引史游(西汉时人约公元前48~33年)《急就篇》云",
"原为相邻两行(无空行,硬换行),已接合为一段(本次 B 类)",
"「引史游(…)」与「《急就篇》云:…」为同一句",
"复核;如原书另起段落,可回改"),
("断行接合确认", "又谓“说言乎兑。”",
"原被空行切断,已接合为一段(本次 B 类)",
"「又谓」与下文引文为同一句",
"复核"),
("修正确认", "三、脾菜生姜",
"五菜条目原序号作 一/二/**二**/三/四(「二」重出),已顺次改为 一/二/三/四/五",
"本节按肝→心→脾→肺→肾列条,原序号重出;与第 47 行「二、心菜藿」对校",
"复核;如原书即重复编号,可回改"),
("修正确认", "五、肾菜薤",
"「薤」——原误作「薙」(本次 C 类)",
"第 1 章第六节·十 作「薤白」(该章「薙」4 处经用户 2026-09-17 判决改「薤」);本条即《灵枢》五菜之薤",
"复核;若原书作「薙」可即时回改"),
("修正确认", "四、肺金谷物白酨浆",
"「白酨浆」——原误作「白黻浆」(本次 C 类)",
"第 1 章第六节·十一 作「白酨浆」;底本已判「白戴浆/白截浆」→「白酨浆」",
"复核"),
("修正确认", "如清浆水、白酨浆、酢、清酒、麦酒等",
"「白酨浆」——原误作「白截浆」(本次 C 类)",
"同上;「截」「酨」形近",
"复核"),
("修正确认", "脏病者宜食以藿",
"「藿」——原误作「霍」(本次 C 类)",
"本条即「二、心菜藿」,同条下文「以藿为菜」「灰涤菜代藿」皆作「藿」",
"复核"),
("修正确认", "小豆,荅也。角曰荚,叶曰藿,茎曰萁",
"《广雅》引文三处形近讹字:苔→荅、角曰英→角曰荚、叶曰霍→叶曰藿(本次 C 类,同句连误)",
"《广雅·释草》原文「大豆,菽也。小豆,荅也。角曰荚,叶曰藿,茎曰萁」"
"(《本草纲目·谷部》引《广雅》同)",
"复核;如原书确作「苔/英/霍」可回改"),
("修正确认", "称酉鸡而不称卯鸡",
"「酉鸡」——原误作「西鸡」(本次 C 类)",
"十二生肖配十二支作「酉鸡」;同条下文「酉位西方,属金」",
"复核"),
("修正确认", "狗居戌位",
"同条三处分别判决:「戌位」修正正确 · 「上方」原文无误(**已回改**)· 「朱弁《曲洧旧闻》」核对无误",
"「戌位」:十二支戌配狗,同篇「戌时为一更」「没于戌」皆作「戌」;"
"「上方」:用户核对原书确认原文无误,本库第 1 批改「上言」之处已回改;"
"「朱弁《曲洧旧闻》」:南宋朱弁撰《曲洧旧闻》(《四库全书》子部杂家类),原作「朱笠《曲消旧闻》」为讹",
"复核;「上方」如原书确作「上方」即维持回改"),
("修正确认", "紫菀五分",
"「紫菀」——原误作「紫苑」(本次 C 类)",
"药名作「紫菀」;本条系《幼幼新书》引《婴孺方》白狗肺汤方中药味",
"复核"),
("修正确认", "《陶弘景评传》",
"「陶弘景」——原误作「陶名景」(本次 C 类)",
"钟国发《陶弘景评传》(中国思想家评传丛书);全篇人名一律作「陶弘景」",
"复核"),
("修正确认", "唐代孔颖达《诗疏》",
"「孔颖达」——原误作「孔顥达」(本次 C 类)",
"唐孔颖达撰《毛诗正义》(世称《诗疏》)",
"复核"),
("修正确认", "葱从囱,外直中空,有囱通之象也",
"「囱」2 处——原误作「囟」(本次 C 类)",
"《本草纲目·菜部·葱》「时珍曰:葱从囱。外直中空,有囱通之象也」(由「蔥」字形立说)",
"复核;本条另有 3 处引文异文见下「原书核对」项"),
("标点规范确认", "生河东、平泽。”",
"《别录》大枣条引文原脱收尾引号,已补「”」(本次 D 类)",
"同一引文体例(起收成对);源件引号配平 293/292,补后 293/293",
"复核;如原书确脱,可回改"),
("标点规范确认", "意有相通之处”,杏之叶似珩之状",
"引号与逗号次序已正(原误倒作「之处,”杏之叶」)(本次 D 类)",
"收尾引号当在逗号之前,与全书引文体例一致",
"复核"),
("标点规范确认", "今俗人呼为乌麻者,非也。”",
"引号外重出的句号已删(原作「。”。」)(本次 D 类)",
"引号内已用句号收句,重复无义",
"复核"),
("原书核对", "汉前辟谷敬佩术",
"「敬佩」于此不可通,疑当作「辟谷却谷术」或「辟谷行气术」之类",
"1973 年长沙马王堆汉墓帛书有《却谷食气篇》;「敬佩」与「辟谷」无涉,形义皆不可通",
"核原书定字"),
("原书核对", "喝溪水而",
"「喝」疑当作「饮」",
"《淮南子》述单豹避世深山,「饮溪水」;「喝」「饮」非形近",
"核原书"),
("原书核对", "葱从囱,外直中空,有囱通之象也……初生曰葱针",
"引《纲目》与传本《本草纲目》三处异文:似/从、道/通、诸事皆宜故曰和事草/诸物皆宜故云菜伯和事",
"《本草纲目·菜部·葱》传本原文(本次只改「囟→囱」,余三处不改)",
"核原书(或系作者节引/异本)"),
("原书核对", "艮为果瓜",
"《周易·说卦》作「为果蓏」",
"下文引《周礼》「有核曰果,无核曰瓜」正承此,疑作者有意引作「瓜」",
"核原书"),
("原书核对", "宜以刀竖副其皮",
"《齐民要术》桃条作「宜以刀竖劙其皮」",
"同条下文作者自注「(副,即用刀割开)」,明系原书用「副」而自释之",
"核原书;若原书确作「副」则登记无误"),
("原书核对", "珩是由两块半圆形的曲玉相对而成",
"「珩」凡四见,字形与文义均有可疑(同段「苔」与「杏」并见)",
"「珩」=玉佩;「杏之叶似珩之状」之说待核",
"核原书"),
("原书核对", "杨行密",
"「杨行密(852~905…)改名为甜梅」文义不相应,出处《绵竹县志·卷八》亦待核",
"杨行密事迹与「改名为甜梅」无涉",
"核原书"),
("原书核对", "《晋书·世祖武帝》",
"三处待核:世相/世祖;咸宁九年(288 年);陇西式殒霜/陨霜",
"晋武帝司马炎庙号世祖;咸宁仅五年(275~280),288 年当为太康九年",
"核原书"),
("原书核对", "蘖末一斗调和",
"「未」疑当作「末」(蘖末=麦芽粉);「一宿,则得一斗五斛」量名可疑",
"同条下文及本书第 479 行皆以「麦芽粉」为说",
"核原书"),
("原书核对", "今俗称江米。稷与穄同",
"三处待核:「:」疑当作「。」;「稕」疑当作「穄」;「即古称之梁米」疑当作「粱米」",
"同段上文列举谷名含「穄」;粱=高粱,梁=桥梁",
"核原书"),
("原书核对", "无在身边即便的习惯",
"「即便」于此不可通,疑当作「随便」",
"上下文义(大小便固定在远离卧处)",
"核原书"),
("原书核对", "故马蹄园,牛蹄坼",
"「马蹄园」疑当作「马蹄圆」;「阳盛世也」疑衍「世」字",
"下文对文作「马病则卧,阴盛也」",
"核原书"),
("原书核对", "《周易·说卦》谓:“坤为土。”",
"《周易·说卦》作「坤为地」",
"紧接着的李鼎祚注正作「坤象地,任重而顺,故为牛」",
"核原书"),
("原书核对", "盖脺为脾之副脏",
"疑前「脾」当作「胰」",
"同段下文「故胰为脾之副脏之说甚是合理」;本条标题作「三、脾土畜牛脾(胰)」",
"核原书"),
("原书核对", "如南宋朱弁",
"「南宋代」疑当作「南宋」(衍「代」);括注「崇宁(…即1102~1135年)」与史实不合",
"崇宁实止 1106 年(1102~1106)",
"核原书"),
("原书核对", "羊是人类驯养为家畜较早的畜类之一",
"「为家畜早的畜类之一」疑脱「较」字",
"文义当作「家畜较早的」",
"核原书"),
("原书核对", "《经》云:“金木者,生成之终始”",
"《素问》作「金木者,生成之终始也」;本书四处作「始终」(另有「木金者生成之始终」一处倒文)",
"《素问·天元纪大论》「……金木者,生成之终始也」(传本另有「生长之终始」之异文);"
"**勘正**:本库前记「第 1 章亦见同语」有误,第 1 章实无此语(其第 561 行所引为「金木者,阴阳之道路也」,另案)",
"核原书;若原书一律作「始终」则登记为用字体例"),
("体例确认", "一、肝菜韭",
"五菜条目「脏位」命名:韭(肝)、生姜(代脾菜葵)、葱(肺)与《灵枢》一致;"
"藿(《灵枢》属肾)、薤(《灵枢》属心)与《灵枢》所宜之脏互易",
"正合第一节引言「心肾之品交换使用,肝肺之品互易使用」;底本五补汤实测:"
"心劳用藿、肺劳用韭、肾劳用薤白、肝劳用葱叶",
"确认是否保持原样(现为保持)"),
("体例确认", "见第一章第一节·二",
"本件回指第 1 章的交叉引证 4 处(第 69/117/483/487 行),与第 1 章结构索引逐条吻合",
"第 1 章清洗版结构索引(节·条目序号)",
"确认引证序号无误(现为照录)"),
("体例确认", "《纲目》引“典术”",
"第 137 行 ①② 为行内枚举,非脚注标记;本件无脚注标记",
"第 1 章 6 处脚注标记已按用户 2026-09-17 判决处理完毕;本件无同类标记",
"确认(现为保持原样)"),
("体例确认", "中国文物出版社2003年5月出版的",
"数字与汉字间半角空格 18 处已删除(从严),与第 1 章清洗版「用升麻 10 克」体例不一致",
"本件为 PDF/文本层导出,数字两侧空格为版面残留;第 1 章存 1 处同类未清",
"确认:本件从严删除(现为删除);如欲两章统一,可回改或回补第 1 章"),
]
# ── G 类:人工核验判决记录(用户 2026-09-20 逐条判决,编号=待核对清单 #)────
# 判决词汇同第 1 章:改 / 无误 / 保留 / 暂留待核 / 回填脚注 / 去注脚
# 值=(判决原文, 归并类, 说明);归并类 ∈ {保留修正, 保留清理, 保留(本库未改动), 无误·原书如此, 改}
VERDICTS = {
1: ("保留", "修正内容", "**认可已删除**:行尾空格 304 行删除后保持,不恢复原半角空格"),
2: ("无误", "无误·原书如此", "原书确作「辟谷敬佩术」,本库**不作改动**;**移出存疑**(已核验)"),
3: ("无误", "无误·原书如此", "原书确作「喝溪水」,本库**不作改动**;**移出存疑**(已核验)"),
4: ("修正正确", "修正内容", "「白截浆」→「白酨浆」修正正确(本次 C 类已生效)"),
5: ("无误(保留)", "无误·原书如此", "五菜条目「脏位」命名原书如此(肝菜韭/心菜藿/脾菜生姜/肺菜葱/肾菜薤),保持原样"),
# —— 第 2 批(用户 2026-09-20,#6–#15)——
6: ("保留", "修正内容", "**据核改(2026-09-20 用户「全按此拟」)**:本书三处引《素问》「金木者,生成之始终」"
"及一处倒文「木金者生成之始终也」,一并据传本订正为「**金木者,生成之终始**」;"
"该四处改后清洗版**与印刷本有意不一致**,并已改记为引文订正(检索须用「终始」);**移出存疑**"),
7: ("修正保留", "修正内容", "句中误入空格删除结果保留(正文 27 处+数字旁 18 处;标题内 6 处体例保留)"),
8: ("原书如此,但修正有理,保留修正", "修正内容",
"**经用户核对:原书即作「以霍」**;本次据本库内证(本条题名「二、心菜藿」与下文"
"「以藿为菜」「灰涤菜代藿」皆作「藿」)订正为「藿」,判决**修正有理、保留修正**"
"——属「原书印刷之误,本库订正」,非录入讹误"),
9: ("保留修正", "修正内容", "《广雅》引文三误(苔/英/霍)据《广雅·释草》原文订正为荅/荚/藿,判决保留修正。"
"※ 本处与 #8 同条同字例(#8 经核原书作「霍」),**本处原书用字待复核**(同理补正,待复核)"),
10: ("原书错误,按照修正排序", "修正内容", "**经用户核对:原书条目序号「二」重出系原书之误**;"
"判决按修正后排序(一/二/三/四/五)——属「原书印刷之误,本库订正」"),
11: ("确认保留", "体例确认(无错字)", "回指第 1 章交叉引证 4 处(第 69/117/483/487 行)与第 1 章结构索引逐条吻合,确认照录保留"),
12: ("保留", "修正内容", "「囟」→「囱」2 处修正保留(依据《本草纲目·菜部·葱》「葱从囱…有囱通之象」)"),
13: ("保留", "修正内容", "**据核改(2026-09-20 用户「全按此拟」)**:引《纲目》葱条三处异文(似→从、道→通、"
"「诸事皆宜,故曰和事草」→「诸物皆宜,故云菜伯、和事」)**皆据传本改从**,"
"另「囟→囱」为录入讹误;清洗版与印刷本有意不一致、**不得回流**;**移出存疑**"),
14: ("确认版式清理正确", "修正内容", "(3)(4)段半角标点+LaTeX 残留「$7 \\sim 10$」已规范为全角并还原「7~10」,确认正确"),
15: ("修正正确,保留", "修正内容", "「薙」→「薤」修正正确(同第 1 章用户 2026-09-17 判决字例),保留"),
# —— 第 3 批(用户 2026-09-20,#16–#28)——
16: ("原书如此,保留", "无误·原书如此", "**经用户核对:原书如此**——本书引《周易·说卦》作「艮为果瓜」(传本作「为果蓏」),"
"且同段引《周礼》亦作「无核曰瓜」,本书用字自成一体;判决保留不改,登记为**引文用字体例**;移出存疑"),
17: ("原书如此,保留", "无误·原书如此", "**经用户核对:原书如此**——本书作「宜以刀竖副其皮」,同条作者自注「(副,即用刀割开)」,"
"与《齐民要术》传本「劙」不同;判决保留不改,登记为**用字体例**;移出存疑"),
18: ("保持原样", "体例确认(无错字)", "第 137 行 ①② 为**行内枚举**(非脚注标记),判决保持原样"),
19: ("保留", "修正内容", "《别录》大枣条原脱收尾引号,本次已补「”」,判决保留(维持已补;引号配平 293/293)"),
20: ("保留", "修正内容", "引号与逗号次序已正(原作「之处,”杏之叶」),判决保留(维持已正)"),
21: ("原书如此,无误", "无误·原书如此", "**经用户核对:原书如此、「珩」无误**(含同段「珩、苔、荇、杏为一组同源词」「杏之叶似珩之状」);"
"本库不作改动,登记为**用字体例**(检索须用「珩」「苔」原字);移出存疑"),
22: ("原书如此,保留", "无误·原书如此", "**经用户核对:原书如此**——「杨行密…改名为甜梅」及出处《绵竹县志·卷八》均系作者原文;"
"判决保留不改,文义不相应之处不作校改;移出存疑"),
23: ("保留", "修正内容", "「孔顥达」→「孔颖达」修正保留(唐孔颖达撰《毛诗正义》,世称《诗疏》)"),
24: ("保留", "修正内容", "麻条断行接合保留(原被空行切断,「…种子及/茎中均含大麻脂。」接合为一段)"),
25: ("保留", "修正内容", "引号外重出句号已删(原作「。”。」),判决保留(维持已删)"),
26: ("保留", "修正内容", "数字与汉字间半角空格:判决**保持现状**——本件从严删除(18 处),**不回改、亦不回补第 1 章**;"
"两章体例暂不统一,登记待后续统一"),
27: ("保留", "修正内容", "**据核改(2026-09-20 用户「全按此拟」)**:①「世相武帝」→「**世祖武帝**」;"
"②「咸宁九年(公元288年)」→「**太康九年(公元288年)**」;③「陇西式殒霜」→「**陇西陨霜**」;"
"皆据《晋书》订正,清洗版与印刷本有意不一致、**不得回流**;移出存疑"),
28: ("保留", "修正内容", "《齐民要术》引史游与《急就篇》两句原为相邻两行(硬换行),接合保留"),
# —— 第 4 批(用户 2026-09-20,#29–#42,本章全部判决完毕)——
29: ("「未」当作「末」;「儆(生但反)」当作「馓(生但反)」", "修正内容",
"**用户核对原书**:两处并改——①「蘖未一斗」→「**蘖末一斗**」(蘖末=麦芽末/粉);"
"②「**儆(生但反)**」→「**馓(生但反)**」(《急就篇》糖食之名,反切「生但反」=sǎn 正合,"
"「儆」音 jǐng 不合)。本次 C 类已生效;移出存疑"),
30: ("保留", "修正内容", "**据核改(2026-09-20 用户「全按此拟」)**:「:」→「**。**」、「稕」→「**穄**」、"
"「梁米」→「**粱米**」;清洗版与印刷本有意不一致、**不得回流**;移出存疑"),
31: ("保留", "修正内容", "「白黻浆」→「白酨浆」修正保留(同第 1 章第六节·十一 条目名)"),
32: ("保留", "修正内容", "「西鸡」→「酉鸡」修正保留(十二生肖配十二支作「酉鸡」;同条下文「酉位西方」)"),
33: ("原文无误", "无误·原书如此", "**经用户核对:原文无误**——「无在身边即便的习惯」原文如此,"
"本库不作改动、不作校改;移出存疑"),
34: ("原文无误", "无误·原书如此", "**经用户核对:原文无误**——「马蹄园」「阳盛世也」原文如此,"
"本库不作改动、不作校改;移出存疑"),
35: ("原文无误", "无误·原书如此", "**经用户核对:原文无误**——「坤为土」原文如此(下文李鼎祚注「坤象地」),"
"本库不作改动、不作校改;移出存疑"),
36: ('前「脾」为「脺」', "修正内容",
"**用户核对原书**:前「脾」当作「**脺**」(音 cuì)。用户释曰:「散膏即脺也,脾之质子为胰子,"
"形如膏,故曰散膏」。本次 C 类已生效(「盖脾为脾之副脏」→「盖脺为脾之副脏」);移出存疑"),
37: ("修正正确", "修正内容", "「紫苑」→「紫菀」修正正确(药名;本条系《幼幼新书》引《婴孺方》白狗肺汤方中药味)"),
38: ("修正正确,保留", "修正内容", "「陶名景」→「陶弘景」修正正确(钟国发《陶弘景评传》)"),
39: ("「戌位」修正正确;「上方」原文无误;「朱弁《曲洧旧闻》」核对无误", "修正内容",
"同条三处分别判决:①「戍位」→「**戌位**」修正正确(维持);"
"②「上方」→「上言」**原文无误,已回改**(撤销本库第 1 批修正,回改与原件一致,见 C 类回改);"
"③「朱笠《曲消旧闻》」→「**朱弁《曲洧旧闻》**」核对无误(维持修正)"),
40: ("核对正确", "修正内容", "**经用户核对:核对结论正确**,并据用户 2026-09-20「全按此拟」**据核改**:"
"「南宋代」→「**南宋**」(衍「代」);「即1102~1135年」→「**即1102~1106年**」(崇宁实止 1106);"
"清洗版与印刷本有意不一致、**不得回流**;移出存疑"),
41: ("保留", "修正内容", "《周易·说卦》「又谓/‘说言乎兑。’」断行接合保留"),
42: ("保留", "修正内容", "**据核改(2026-09-20 用户「全按此拟」)**:「为家畜早的」→「**为家畜较早的**」"
"(脱「较」字;同段下文作「性成熟较早」可互证);移出存疑"),
}
BUCKETS = ["修正内容", "修正内容(待补正字)", "体例确认(无错字)", "无误·原书如此", "暂留待核", "回填脚注", "去注脚"]
DISPLAY = {"修正内容": "修正内容(正文已按修正生效)",
"修正内容(待补正字)": "修正内容·待补正字(判为原书错误,待给正字后改正文)",
"体例确认(无错字)": "体例确认(无错字,修正不适用)"}
def verdict_stat():
"""判决分布的归并统计文本。"""
c = collections.Counter(v[1] for v in VERDICTS.values())
return " · ".join(f"{DISPLAY.get(k, k)} {c[k]}" for k in BUCKETS if c.get(k))
def resolved_suspect_keys(rows):
"""依判决把「原书核对」中已判决的存疑项移出存疑册(同第 1 章流程:已判决≠存疑)。"""
return {r["锚"] for r in rows if r["类型"] == "原书核对" and r["#"] in VERDICTS
and VERDICTS[r["#"]][1] != "暂留待核"}
# ── 拟正字表(用户判决「修正内容」=改正文;2026-09-20 用户「全按此拟」→ **已全部落 C 类、正文已生效**)──
# 本表留作记录:报告 7.1 逐条列出「原书文/拟正字/依据」;改动实况见 C_FIXES 末 12 条
# (清单#, 清洗版行, 原书文, 拟正字, 依据)
PENDING_FIXES = [
(6, 33, "金木者,生成之始终(本书三处)/木金者,生成之始终(一处倒文)",
"金木者,生成之终始(并正倒文为「金木者」)",
"《素问》传本作「金木者,生成之终始也」;本书四处皆作「始终」且一处倒文。"
"改则与传本一致、与原书不一致,属引文异文之取舍,故待确认范围(三处/四处)"),
(13, 79, "葱似囱/有囱道之象也/诸事皆宜,故曰和事草",
"葱从囱/有囱通之象也/诸物皆宜,故云菜伯、和事",
"《本草纲目·菜部·葱》传本原文;改则与传本一致、与原书不一致(本处已改「囟→囱」2 处)"),
(27, 427, "《晋书·世相武帝》/咸宁九年(公元288年)/陇西式殒霜",
"《晋书·世祖武帝》/太康九年(公元288年)/陇西陨霜",
"晋武帝司马炎庙号**世祖**;咸宁仅五年(275–280),288 年当为**太康**九年;「式」疑衍"),
(30, 473, "今俗称江米:稷与稕同/即古称之梁米",
"今俗称江米。稷与穄同/即古称之粱米",
"「:」当作「。」(前后为两事);「稕」当作「穄」(同段上文列举谷名正含「穄」);「梁」当作「粱」"),
(40, 625, "如南宋代朱弁/崇宁(…即1102~1135年)",
"如南宋朱弁/崇宁(…即1102~1106年)",
"「代」字疑衍;崇宁实止 1106 年(1102–1106),1135 年非崇宁年号范围"),
(42, 651, "羊是人类驯养为家畜早的畜类之一",
"羊是人类驯养为家畜较早的畜类之一",
"脱「较」字,当作「家畜较早的」"),
]
APPLIED_N = {n for n, *_ in PENDING_FIXES} # 本轮据正字改字的 6 条清单#(清单判决栏加标记用)
def read_bin(p):
raw = open(p, "rb").read()
return raw.decode("utf-8"), hashlib.md5(raw).hexdigest()
def convert_latex(s):
return re.sub(r"\$([\d.]+)\s*\\sim\s*([\d.]+)\$", r"\1~\2", s)
HALF2FULL = {",": ",", ";": ";", ":": ":", "(": "(", ")": ")", "~": "~"}
def main():
text, md5_src = read_bin(SRC)
bendi, md5_bendi = read_bin(BENDI)
ch1, md5_ch1 = read_bin(CH1_MD)
raw_lines = text.replace("\r\n", "\n").split("\n")
events = []
# ── A 类读数(清理前)──
n_crlf = text.count("\r\n")
n_trail = sum(1 for l in raw_lines if l != l.rstrip())
n_lead = sum(1 for l in raw_lines if l != l.lstrip())
n_u3000 = sum(1 for l in raw_lines if "\u3000" in l)
n_cc = len(re.findall(r"(?<=[\u4e00-\u9fff]) (?=[\u4e00-\u9fff])", text))
n_num = len(re.findall(r"(?<=[\u4e00-\u9fff]) (?=\d)|(?<=\d) (?=[\u4e00-\u9fff])", text))
n_cc_head = sum(len(re.findall(r"(?<=[\u4e00-\u9fff]) (?=[\u4e00-\u9fff])", l))
for l in raw_lines if l.startswith("#"))
n_cc_body, n_num_body = n_cc - n_cc_head, n_num
n_ascii_punct = {c: text.count(c) for c in ",;:~$"}
half_lines = sorted({i for i, l in enumerate(raw_lines, 1) if re.search(r"[\u4e00-\u9fff][,;:()]|[,;:()][\u4e00-\u9fff]", l)})
if not set(half_lines) <= {91, 93, 572, 580}:
raise SystemExit(f"半角标点行集合与预期不符:{half_lines}")
# 汉字↔汉字空格逐处清单(供报告)
space_inventory = []
for i, l in enumerate(raw_lines, 1):
for m in re.finditer(r"[\u4e00-\u9fff] [\u4e00-\u9fff]", l):
space_inventory.append((i, l[max(0, m.start() - 12):m.end() + 12]))
num_inventory = []
for i, l in enumerate(raw_lines, 1):
for m in re.finditer(r"\d [\u4e00-\u9fff]|[\u4e00-\u9fff] \d", l):
num_inventory.append((i, l[max(0, m.start() - 12):m.end() + 12]))
# ── B 类:接合(行号锚定 + 校验)──
units, i = [], 0
while i < len(raw_lines):
ln = i + 1
s = raw_lines[i].strip()
if not s:
i += 1
continue
if ln in JOINS:
anchor, why = JOINS[ln]
if anchor not in s:
raise SystemExit(f"接合锚校验失败:raw{ln} 应含「{anchor}…」,实为「{s[:40]}」")
j = i + 1
while j < len(raw_lines) and not raw_lines[j].strip():
j += 1
if j >= len(raw_lines) or raw_lines[j].strip().startswith("#"):
raise SystemExit(f"接合失败:raw{ln} 之后无正文行")
nxt = raw_lines[j].strip()
merged = s + nxt
units.append((ln, merged))
events.append(dict(行=ln, 类型="B断行接合",
原=f"{s[-26:]} ⟂ {nxt[:26]}",
改=f"…{merged[-40:]}",
依据=why))
i = j + 1
continue
units.append((ln, s))
i += 1
# ── A / C / D:逐段处理 ──
out, level_log, renum_log = [], [], []
c_hits, d_hits = collections.Counter(), collections.Counter()
for ln, s in units:
orig = s
is_head = s.startswith("#")
# C 讹字
for bad, good, n_exp, why in C_FIXES:
n = s.count(bad)
if n:
if n != n_exp:
raise SystemExit(f"C 锚校验失败:「{bad}」命中 {n} 次,预期 {n_exp}")
s = s.replace(bad, good)
c_hits[bad] += n
events.append(dict(行=ln, 锚=good[-12:], 类型="C讹字修正",
原=f"{bad}({n} 处)", 改=good, 依据=why))
# D 标点
for bad, good, n_exp, why in D_FIXES:
n = s.count(bad)
if n:
if n != n_exp:
raise SystemExit(f"D 锚校验失败:「{bad}」命中 {n} 次,预期 {n_exp}")
s = s.replace(bad, good)
d_hits[bad] += n
events.append(dict(行=ln, 锚=good[-14:], 类型="D标点",
原=bad, 改=good, 依据=why))
if not is_head:
# A:LaTeX 残留
conv = convert_latex(s)
if conv != s:
events.append(dict(行=ln, 锚="7~10", 类型="A版式残留",
原="LaTeX(PDF 公式化)残留「$7 \\sim 10$」", 改="7~10",
依据="PDF 公式化残留,按数据还原为「7~10 月」"))
s = conv
# A:半角标点 → 全角(仅限已定位的 4 行)
if ln in half_lines:
before = {c: s.count(c) for c in HALF2FULL}
for a, b in HALF2FULL.items():
s = s.replace(a, b)
ch = {k: v for k, v in before.items() if v}
if ch:
events.append(dict(行=ln, 锚=s[:12], 类型="D标点",
原="半角标点 " + "、".join(f"「{k}」×{v}" for k, v in ch.items()),
改="全角:" + "、".join(f"「{HALF2FULL[k]}」" for k in ch),
依据="标点规范化(半角改全角)"))
elif ln in (572, 580):
events.append(dict(行=ln, 锚=s[:12], 类型="D标点",
原="半角括号「( )」", 改="全角「( )」", 依据="标点规范化"))
# A:空格清理(全角标点旁 → 汉字/数字间)
s = re.sub(r"(?<=[,。、;:?!“”‘’()《》〔〕…—]) +", "", s)
s = re.sub(r" +(?=[,。、;:?!“”‘”‘()《》…—])", "", s)
s = re.sub(r"(?<=[\u4e00-\u9fff0-9]) +(?=[\u4e00-\u9fff0-9])", "", s)
if is_head:
# H:层级
bare = re.sub(r"^#+\s*", "", s)
for bad, good, why in RENUM:
if bare == bad:
bare = good
renum_log.append((ln, bad, good))
events.append(dict(行=ln, 锚=good, 类型="H序号修正",
原=f"条目序号「{bad[:2]}」", 改=f"「{good[:2]}」", 依据=why))
lv, kind = None, None
for pat, L, K in H_RULES:
if pat.match(bare):
lv, kind = L, K
break
if lv is None:
raise SystemExit(f"未识别的标题(源行 {ln}):{s[:60]}")
newh = "#" * lv + " " + bare
if newh != s:
level_log.append((ln, s, newh))
out.append(newh)
else:
out.append(s)
# ── C 类回改:撤销本库前批修正(文本已随规则删除而回改,此处校验并留痕)──
probe = "\n".join(out)
for orig, prev, why in REVERTS:
if probe.count(orig) != 1:
raise SystemExit(f"回改锚校验失败(原文形命中 {probe.count(orig)} 次):{orig}")
if prev in probe:
raise SystemExit(f"回改未生效:仍含本库前批改形「{prev}」")
events.append(dict(行=0, 锚=orig, 类型="C回改",
原=f"本库前批改形「{prev}」", 改=f"回改为原件形「{orig}」", 依据=why))
text = "\n\n".join(out) + "\n"
# 空行规范:3 个以上连续空行压为 2 个
text = re.sub(r"\n{4,}", "\n\n\n", text)
# ── 事件行号改为清洗版坐标(锚校验)──
flines = text.split("\n")
for e in events:
key = e.get("锚") or ""
if key:
hit = [i for i, l in enumerate(flines, 1) if key in l]
if len(hit) == 1:
e["行"] = hit[0]
elif len(hit) > 1:
# 多命中:取离原(源件)行号最近的一处(原为「首个 >= 原行号,否则 hit[0]」,
# 短锚如「白酨浆」会把 481 行的标题误记到 13 行的通行提及上)
e["行"] = min(hit, key=lambda h: abs(h - e.get("行", 0)))
e["备注"] = "行号指清洗版"
# ── 结构解析 ──
heads, chap, secs2, cur_sec = [], None, [], None
for i, l in enumerate(flines, 1):
s = l.strip()
if not s.startswith("#"):
continue
bare = re.sub(r"^#+\s*", "", s)
lv = len(re.match(r"^#+", s).group())
kind = None
for pat, L, K in H_RULES:
if pat.match(bare):
kind = K
break
heads.append(dict(层级=lv, 类型=kind, 标题=bare, 行=i))
if kind == "章":
chap = bare
elif kind == "节":
cur_sec = dict(节=bare, 章=chap, 行=i, 条目=[])
secs2.append(cur_sec)
elif kind == "条目" and cur_sec is not None:
cur_sec["条目"].append(dict(
序=re.match(r"^([一二三四五六七八九十]+)、", bare).group(1),
名=re.sub(r"^[一二三四五六七八九十]+、", "", bare), 行=i))
# ── 自检 ──
errs, oks = [], []
cnt = collections.Counter(h["类型"] for h in heads)
exp = dict(章=1, 节=4, 条目=20)
if all(cnt[k] == v for k, v in exp.items()) and cnt.get("条下附", 0) == 0:
oks.append(f"标题计数 章1/节4/条目20(与预期一致;条下附 0)")
else:
errs.append(f"标题计数异常:{dict(cnt)},预期 {exp}")
CVN = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
seq_ok = True
for s in secs2:
got = [e["序"] for e in s["条目"]]
if got != CVN[:len(got)]:
errs.append(f"{s['节']} 条目序号不连续:{got}")
seq_ok = False
if seq_ok:
oks.append("各节条目序号自「一、」连续(序数无缺无重)")
lvs = [h["层级"] for h in heads]
jumps = [(i, lvs[i - 1], lvs[i]) for i in range(1, len(lvs)) if lvs[i] > lvs[i - 1] + 1]
if lvs[0] == 2 and not jumps:
oks.append("标题层级体系正确:起于章(2),递降为 节(3)/条目(4),无跳级")
else:
errs.append(f"标题层级异常:首层级 {lvs[0]},跳级处 {jumps}")
# C 类三段验证
c_bad_left = [b for b, g, _n, _w in C_FIXES if b in text and b != g]
c_missing = [g for b, g, _n, _w in C_FIXES if text.count(g) == 0]
if not c_bad_left and not c_missing:
oks.append(f"C 类 {len(C_FIXES)} 条规则三段验证通过(讹形残留 0/正形均已出现)")
else:
errs.append(f"C 类残留:讹形 {c_bad_left};正形未出现 {c_missing}")
# 标点配平
def bal(t):
return dict(引号=(t.count("“"), t.count("”")), 单引号=(t.count("‘"), t.count("’")),
书名号=(t.count("《"), t.count("》")), 括号=(t.count("("), t.count(")")),
方括号=(t.count("〔"), t.count("〕")))
b = bal(text)
if all(v[0] == v[1] for v in b.values()):
oks.append("标点配平:" + "、".join(f"{k} {v[0]}/{v[1]}" for k, v in b.items()))
else:
errs.append(f"标点不配平:{b}")
half_left = re.findall(r"[\u4e00-\u9fff][,;:!?()]|[,;:!?()][\u4e00-\u9fff]", text)
if not half_left:
oks.append("半角标点 0 处")
else:
errs.append(f"仍有半角标点 {len(half_left)} 处:{half_left[:6]}")
space_left = [l[:40] for l in flines if l != l.rstrip()]
body_sp = [(i, l[:60]) for i, l in enumerate(flines, 1)
if not l.startswith("#") and re.search(r"[\u4e00-\u9fff0-9] +[\u4e00-\u9fff0-9]", l)]
head_sp = sum(len(re.findall(r"(?<=[\u4e00-\u9fff0-9]) +(?=[\u4e00-\u9fff0-9])", l))
for l in flines if l.startswith("#"))
if not space_left and not body_sp:
oks.append(f"残留空格 0 处(行尾/正文汉字数字间/标点旁);标题内「第X章 标题」体例空格 {head_sp} 处保留(同第 1 章)")
else:
errs.append(f"仍有残留空格 {len(space_left)} 行/{len(body_sp)} 处:{space_left[:3]} {body_sp[:3]}")
latex_left = re.findall(r"\$|\\[a-zA-Z]{2,}", text)
if not latex_left:
oks.append("LaTeX/Markdown 引擎残留 0 处")
else:
errs.append(f"仍有 LaTeX 残留 {len(latex_left)} 处")
brk = [i + 1 for i in range(len(flines) - 1)
if flines[i].strip() and flines[i + 1].strip()
and not re.search(r"[。?!;:”》))】…—]$", flines[i].strip())
and not flines[i].strip().startswith("#")
and re.match(r"^[\u4e00-\u9fff“(《]", flines[i + 1].strip())
and not flines[i + 1].strip().startswith("#")]
if not brk:
oks.append("断行候选 0 处(无句中截断)")
else:
errs.append(f"断行候选 {len(brk)} 处:{brk[:6]}")
# 「脏—味」互校
cross = []
for sec, name, zang, wei, ev, ref in ITEMS20:
allowed = WEI2ZANG.get(wei, [])
zs = [z for z, _ in allowed]
ok = zang in zs
wei_pos = next((p for z, p in allowed if z == zang), "")
cross.append((sec, name, zang, wei, f"{wei}({zang}之{wei_pos}味)" if ok else f"⚠ {wei} ∉ {zs}",
ev, ref, ok))
n_ok = sum(1 for x in cross if x[-1])
if n_ok == len(cross):
oks.append(f"20 条目「脏—味」互校 ⇄ 本书五味体用化说+底本五味五行表:{n_ok}/{len(cross)} 相符")
else:
errs.append(f"「脏—味」互校不符 {len(cross) - n_ok} 条:"
+ ";".join(f"{x[1]}({x[2]}/{x[3]})" for x in cross if not x[-1]))
# 与第 1 章交叉引证互校
ch1_refs = [("见第一章第一节·二", "第一节", "二", "姜(生姜木中火、干姜木中水)"),
("见第一章第六节·十", "第六节", "十", "薤白(水中土、水中金)"),
("详说请参第一章第六节·十一", "第六节", "十一", "白酨浆(金中金、金中火)"),
("详说可参第一章第六节·六", "第六节", "六", "酢(金中水)")]
ref_rows = []
for anchor, sec, seq, desc in ch1_refs:
here = text.count(anchor)
there = ch1.count(f"{seq}、{desc.split('(')[0]}")
ref_rows.append((anchor, here, desc, "✅ 第 1 章有此条目" if there else "⚠ 第 1 章未见"))
if all(r[1] == 1 and "✅" in r[3] for r in ref_rows):
oks.append("与第 1 章交叉引证 4 处 ⇄ 第 1 章条目:全部落位")
else:
errs.append("交叉引证互校异常:" + str(ref_rows))
# ── 待核对清单(锚定位,固定条目表)──
def locate(ln):
sec = None
for s in secs2:
if s["行"] <= ln:
sec = s
if sec is None:
return "章引言(第一节之前)", "—"
item = None
for e in sec["条目"]:
if e["行"] <= ln:
item = e
return sec["节"], (f"{item['序']}、{item['名']}" if item else "节引言(首条目之前)")
rows = []
for typ, anchor, prob, base, sug in CHECK_ITEMS:
hits = [i for i, l in enumerate(flines, 1) if anchor in l]
if len(hits) != 1:
raise SystemExit(f"待核对清单锚校验失败(命中 {len(hits)} 次):{anchor[:24]}")
sec, item = locate(hits[0])
rows.append(dict(类型=typ, 锚=anchor, 节=sec, 条目=item, 行=hits[0],
问题=prob, 依据=base, 建议=sug))
rows.sort(key=lambda r: r["行"])
for n, r in enumerate(rows, 1):
r["#"] = n
# ── 落盘 ──
def wf(p, c):
os.makedirs(os.path.dirname(p), exist_ok=True)
with open(p, "w", encoding="utf-8") as f:
f.write(c); f.flush(); os.fsync(f.fileno())
md5_out = hashlib.md5(text.encode()).hexdigest()
wf(OUT_MD, text)
struct = dict(
来源文件=os.path.basename(SRC), 来源文件md5=md5_src,
清洗版文件=os.path.basename(OUT_MD), 清洗版md5=md5_out,
定位="《药性探真》第二章 虚劳五补方菜果谷畜类药释义(录入稿:PDF/文本层导出,A 类版式残留未清)",
标准="完全沿用第 1 章(07_clean_ch1.py)之检查核对标准与产物集",
层级体例="章=##(二级)/节=###(三级)/条目=####(四级);本件无附、无脚注标记",
底本互校=dict(底本文件=os.path.basename(BENDI), 底本md5=md5_bendi,
第1章清洗版=os.path.basename(CH1_MD), 第1章清洗版md5=md5_ch1,
依据="本库内部互证(五味五行互含名位、五补汤用药实测),不作校改"),
章=chap, 节=secs2,
标题层级改动=[dict(源行=a, 原=b, 后=c) for a, b, c in level_log],
条目序号改正=[dict(源行=a, 原=b, 后=c) for a, b, c in renum_log],
清理事件=events, 自检=oks + ["⚠ " + e for e in errs],
A类读数=dict(CRLF=n_crlf, 行尾空格=n_trail, 行首空格=n_lead, 全角空格=n_u3000,
汉字间半角空格=n_cc, 数字与汉字间半角空格=n_num,
半角标点字符计数=n_ascii_punct, 半角标点所在行=half_lines),
C类命中={k: v for k, v in c_hits.items()}, D类命中={k: v for k, v in d_hits.items()},
脏味互校=[dict(节=a, 条目=b, 脏=c, 味=d, 判定=e, 味依据=f, 底本互证=g) for a, b, c, d, e, f, g, _ in cross],
交叉引证互校=[dict(引证锚=a, 命中=b, 第1章条目=c, 判定=d) for a, b, c, d in ref_rows],
存疑=[dict(项=k, 说明=v) for k, v in SUSPECTS],
体例登记=[dict(项=k, 说明=v) for k, v in VERSION_NOTES],
待核对清单条数=len(rows),
)
wf(OUT_STRUCT, json.dumps(struct, ensure_ascii=False, indent=2) + "\n")
c = lambda k: sum(1 for e in events if e["类型"].startswith(k))
sql = lambda t: sum(1 for r in rows if r["类型"] == t)
TYPES = ["版式清理确认", "断行接合确认", "修正确认", "标点规范确认", "原书核对", "体例确认"]
# 待核对清单
n_done = len(VERDICTS)
cl = [f"# 《辅行诀五脏用药法要 药性探真》第 2 章 — 待核对清单(按章节结构)", "",
f"> 用途:逐条列出需核对/需定处理方式的问题(固定 {len(rows)} 条)。"
f"**编号即清单顺序(行号序)**,与用户判决口径一致。"
f"判决栏:☐ 改/☐ 无误/☐ 保留/☐ 暂留待核/☐ 回填;**已判决 {n_done} 条,"
f"余 {len(rows) - n_done} 条待判决**。",
"> 📖 **判决词表(用户 2026-09-20 明确)**:`保留`=**保留(本库)修正结果**(维持本库已作的改动/清理),"
"**不指保留原文**;`修正内容`=**等同「改」**(据正字改正文,用户选定 A 案);`原文无误`=原书原文正确、本库如已改则**回改**;`无误`/`原书如此`=原书如此;"
"`核对正确`=核对结论成立但未下改令、原文保留。",
f"> ✅ **修正内容·本轮据正字改字 6 条**(#6/#13/#27/#30/#40/#42,共 11 处):用户 2026-09-20 批复「全按此拟」后**已落 C 类、正文已生效**(清洗版 `ac1a4d32…`);原书文/拟正字见检查报告第七节 7.1。",
f"> 行号一律指**清洗版** `02_加工数据/药性探真_第2章_清洗版.md`(md5 `{md5_out}`);"
f"对象原件 `01_来源数据/《辅行诀五脏用药法要 药性探真》第2章.md`(md5 `{md5_src}`;"
f"**标题层级已按用户 2026-09-20 指令就地优化**,正文逐行未动;优化前快照 md5 `92fd55f8…`)。",
f"> 标准与产物格式**完全沿用第 1 章**(`02_加工数据/药性探真_第1章_待核对清单.md`);"
f"共 **{len(rows)}** 条:" + " · ".join(f"{t} {sql(t)}" for t in TYPES if sql(t)),
"> 源件标题 25 行原样为「##」(未分级);本清单行号依清洗版(已重建层级)。", "",
"## 汇总", "", "| 类型 | 条数 | 说明 |", "|------|------|------|"]
DESC = {"版式清理确认": "本次已清理,请复核(可回改)",
"断行接合确认": "本次已接合,请复核",
"修正确认": "本次已改,请复核(可即时回改)",
"标点规范确认": "本次已规范,请复核",
"原书核对": "需核纸质原书定字(本次一律未改)",
"体例确认": "需定处理方式(现为保持原样)"}
for t in TYPES:
if sql(t):
nd = sum(1 for r in rows if r["类型"] == t and r["#"] in VERDICTS)
cl.append(f"| {t} | {sql(t)} | {DESC[t]}" + (f"(已判决 {nd})" if nd else "") + " |")
cl += ["", "---", "", "## 逐条(按章节结构)", ""]
by_sec = collections.defaultdict(list)
for r in rows:
by_sec[r["节"]].append(r)
order = ["章引言(第一节之前)"] + [s["节"] for s in secs2]
for sec_name in order:
rs = by_sec.get(sec_name, [])
if sec_name == "章引言(第一节之前)" and not rs:
continue
cl += [f"### {sec_name}", ""]
if not rs:
cl += ["(本节无待核对项)", ""]
continue
cl += ["| # | 条目 | 行(清洗版) | 类型 | 问题 | 依据 | 建议 | 判决 |",
"|---|------|------|------|------|------|------|------|"]
for r in rs:
v, _bk, vnote = VERDICTS.get(r["#"], ("—", "", ""))
pend = " +**修正内容·本轮据正字改字**(正文已生效;原书文/拟正字见报告 7.1)" \
if r["#"] in APPLIED_N else ""
cell = (f"✅ **{v}**:{vnote}{pend}" if v != "—"
else "☐ 改/☐ 无误/☐ 保留/☐ 暂留待核")
cl.append(f"| {r['#']} | {r['条目']} | {r['行']} | {r['类型']} | {r['问题']} | "
f"{r['依据']} | {r['建议']} | {cell} |")
cl.append("")
cl += ["---", "",
"> 判决后回填方式(同第 1 章):①「原书核对」类若判定改字 → 在 `05_脚本工具/10_clean_ch2.py` 的 "
"`C_FIXES`/`D_FIXES` 增改条目(标注「用户核对原书」)→ 重跑 10 刷新清洗版与报告;"
"②「体例确认」结果 → 记入检查报告第八节;③「版式/接合/标点」类如需回改 → 在规则表中去除或改写对应条目。",
"",
f"> 📅 2026-09-20 —— **归并类归一(用户口径)**:`保留`=保留本库修正结果、`修正内容`=改正文;"
f"早期批次日志中「保留修正/保留清理/原书如此·未改」等字样为当时标签,今统一为 "
f"**修正内容 30 · 体例确认(无错字)2 · 无误·原书如此 10**(本轮 6 条「拟正字」已全部落 C 类、正文已生效)。",
f"> 📅 2026-09-20 —— **修正内容落盘**:用户批复「全按此拟」,第 7.1 节 6 条拟正字(11 处)"
f"全部落 C 类(`C_FIXES` 末增 12 条 + 既有「囟→囱」1 条并订正为传本形),正文已改。",
f"> 📅 2026-09-20 —— 建单:{len(rows)} 条待核对(按章/节/条目定位,行号指清洗版)。",
f"> 📅 2026-09-20 —— **三批判决回填**:第 1–{n_done} 条已由用户逐条判决"
f"({verdict_stat()}),见「判决」栏;**余 {len(rows) - n_done} 条待判决**。",
f"> 📅 2026-09-20 —— 第 4 批:第 29–42 条判决回填(本批 改 3 · 原书如此/未改 6 · 保留修正 5),"
f"**全部 42 条判决完毕、本章闭环**;存疑册清零(原 17 项全部结项);"
f"本批清洗版实际改动 4 处(蘖未→蘖末、儆→馓、脾→脺、上言→上方回改)。",
f"> 📅 2026-09-20 —— 第 3 批:第 16–28 条判决回填(本批 原书如此/未改 8 · 保留修正 5)"
f"——#16/#17/#21/#22/#27 五条原书核对项结项(移出存疑册,存疑 8 项);"
f"新增用字体例 2 项(「副/珩/苔/杨行密」、《说卦》「艮为果瓜」)。",
"> 📌 第 1 章同类清单已于 2026-09-17 判决闭环,格式可对照。",
"> ⚠ 本件已见「原书印刷之误,本库订正」类(#8、#10)——原书如此而本库有意订正,"
"**不得据「原书如此」回流改回**(详检查报告第八节)。"]
wf(OUT_CHECK, "\n".join(cl) + "\n")
# 检查报告
rep = ["# 《辅行诀五脏用药法要 药性探真》第 2 章 — 检查报告(录入稿清洗与核对)", "",
f"> 📅 2026-09-20|对象:`01_来源数据/《辅行诀五脏用药法要 药性探真》第2章.md`"
f"(录入稿;md5 `{md5_src}`,{len(text)} 字符 / {len(flines)} 行)",
f"> 产物:`02_加工数据/药性探真_第2章_清洗版.md`(md5 `{md5_out}`)/本报告/"
"`02_加工数据/药性探真_第2章_结构.json`/`02_加工数据/药性探真_第2章_待核对清单.md`;"
"脚本 `05_脚本工具/10_clean_ch2.py`(幂等)",
"> 用户指令:**按照第 1 章的标准**,对第 2 章进行清洗核对。",
"> 🚫 **原文件(01_来源数据/)一字未动**——改写只落在清洗版,且每条带核校依据,可回改。",
"> 🔧 与第 1 章的差别:第 1 章对象为**用户精清稿**(A 类已清净),本件为**录入稿**"
"(PDF/文本层导出,A 类版式残留未清,本次由脚本清理)。", "",
f"> 📋 **待核对清单**:`02_加工数据/药性探真_第2章_待核对清单.md`(按章/节/条目列出,"
f"共 {len(rows)} 条,供逐条判决)。", "",
"## 一、检查结论", "", "| 项目 | 结果 |", "|------|------|",
f"| 版式残留(A) | 行尾空格 **{n_trail} 行**、汉字间半角空格 **正文 {n_cc_body} 处**"
f"(标题内「第X章 标题」体例 {n_cc_head} 处保留)、数字与汉字间半角空格 **{n_num_body} 处**、"
f"全角标点旁空格、半角标点所在行 {len(half_lines)} 行、"
f"LaTeX 残留 1 处 → **已全部清理**(CRLF {n_crlf}/行首空格 {n_lead}/全角空格 {n_u3000}) |",
f"| 断行截断(B) | 残留 **3** 处(麻条「种子及」、史游《急就篇》、《说卦》「说言乎兑」)→ 已接合 |",
f"| 讹字(C) | **{len(C_FIXES)} 条**(薙→薤、黻/截→酨、霍→藿、《广雅》引文三误、西→酉、戍→戌、"
f"朱笠→朱弁、紫苑→紫菀、陶名景→陶弘景、孔顥达→孔颖达、囟→囱,"
f"另据用户核对原书增改 **蘖未→蘖末、儆→馓、脾→脺** 3 条);"
f"**回改 1 处**(上言→上方,撤销本库第 1 批修正) |",
f"| 序号(H) | 五菜条目序号「二」重出 → 顺次改正 3 处 |",
f"| 标点(D) | 半角改全角({len(half_lines)} 行)、补脱收尾引号 1 处、引号次序 1 处、"
f"重出句号 1 处 → 已规范 |",
f"| 标题层级(H) | 章2/节3/条目4;源件 25 行全为「##」,**清洗版重建层级 24 行**"
f"(**源件已同办优化**,24 行标题) |",
f"| 引文规范 | " + "、".join(f"{k} {v[0]}/{v[1]}" for k, v in b.items()) + " —— 全部配平 |",
f"| 脚注(G) | 本件**无脚注标记**(第 137 行 ①② 为行内枚举,非脚注) |",
f"| 脏味互校 | 20 条目「脏—味」⇄ 本书五味体用化说+底本五味五行表:**{n_ok}/{len(cross)} 相符** |",
f"| 交叉引证 | 回指第 1 章 4 处(生姜/薤白/白酨浆/酢)⇄ 第 1 章条目:**全部落位** |",
f"| 结构 | 章 1 / 节 4 / 条目 20(五菜 5·五果 5·五谷 5·五畜 5) |", "",
"## 二、版式残留清理(A 类)", "",
f"- 源件读数:行尾空格 {n_trail} 行、行首空格 {n_lead} 行、全角空格 {n_u3000} 行、"
f"CRLF {n_crlf} 行;半角标点计数 " + "、".join(f"`{k}` {v}" for k, v in n_ascii_punct.items()),
f"- 汉字间半角空格 **{n_cc}** 处 = 正文 **{n_cc_body}** 处(已删除,逐处清单见下)"
f"+ 标题内 **{n_cc_head}** 处(`## 第二章 虚劳五补方菜果谷 畜类药释义` 与四个 `### 第X节 …` 之"
f"「第X章 标题」空格,**体例保留**,同第 1 章):",
"", "| 源行 | 上下文 |", "|----|--------|"]
for ln, ctx in space_inventory:
rep.append(f"| {ln} | …{ctx.replace('|', '|')}… |")
rep += ["", f"> 处理:**正文 {n_cc_body} 处**一律删除(本件无「药味行分隔空格」之功能,"
f"见底本 03_clean_yinshua.py「句中误入空格」同例);标题内 {n_cc_head} 处保留(Markdown 标题体例)。", "",
f"- 数字与汉字间半角空格 {n_num_body} 处(逐处清单):", "", "| 源行 | 上下文 |", "|----|--------|"]
for ln, ctx in num_inventory:
rep.append(f"| {ln} | …{ctx.replace('|', '|')}… |")
rep += ["", "> 处理:**本次从严一律删除**。⚠ 体例提示:第 1 章清洗版存 1 处同类未清"
"(第 819 行「用升麻 10 克、小米 10 克…」)。如欲保留数字两侧留空,本件可回改、"
"第 1 章亦可回补(见待核对清单「体例确认」项)。", "",
f"- 半角标点所在行:{half_lines}((1)–(4) 枚举号、农谚引文的 , : ;、"
f"《造化权舆》与《医学衷中参西录》引文的括号、半角 ~ 与 LaTeX 残留)→ 全部规范为全角;"
f"半角 `~` 改全角 `~`。", ""]
# 三、逐条留痕
rep += ["## 三、本次修正(逐条留痕)", "",
"| 行(清洗版) | 类别 | 原文 | 处理后 | **原书用字** | 核校依据 |",
"|----|------|------|--------|------|---------|"]
for e in events:
key = re.sub(r"(\d+ 处)$", "", e["原"])
if e["类型"] == "C讹字修正":
o = C_ORIGIN.get(key, ("—", "未核定"))
origin = f"**{o[0]}**:{o[1]}"
elif e["类型"] == "C回改":
origin = "**原书作原件形**(判决「原文无误」→ 回改)"
else:
origin = "—"
rep.append(f"| {e.get('行', '—')} | {e['类型']} | {e['原'].replace('|', '|')} | "
f"{e['改'].replace('|', '|')} | {origin.replace('|', '|')} | "
f"{e['依据'].replace('|', '|')} |")
rep += ["", f"> 合计:A 版式 {c('A')} 条事件(另含全局行尾空格 {n_trail} 行、正文空格 {n_cc_body + n_num_body} 处)、"
f"B 接合 {c('B')}、C 讹字 {c('C')}、D 标点 {c('D')}、H 标题 {c('H')}。", ""]
# 四、标题层级
rep += ["## 四、标题层级优化", "",
"| 层级 | Markdown | 对象 | 例(本件) |", "|------|----------|------|-----------|",
"| 二级 | `##` | 章 | 第二章 虚劳五补方菜果谷 畜类药释义 |",
"| 三级 | `###` | 节 | 第一节 五菜/第二节 五果/第三节 五谷酿制品/第四节 五畜脏器 |",
"| 四级 | `####` | 条目 | 一、肝菜韭 … 五、肾菜薤;一、肺金果桃… … 五、心火畜羊肾 |", "",
f"共重排 **{len(level_log)}** 行标题(源件 25 行全部为「##」)。"
f"条目序号重出改正 **{len(renum_log)}** 处。",
f"> ⚠ 源件(`01_来源数据/`)标题层级**已就地优化**(**用户 2026-09-20 明确指令**,"
f"为「01_来源数据不可修改」原则的明文例外,同第 1 章 2026-09-17 之办):只改井号,"
f"正文逐行未动;快照 `01_来源数据/《…》第2章_层级优化前快照_20260920.md`(md5 `92fd55f8…`);"
f"原件 md5 `92fd55f8…` → `a9168956…`。脚本:`python3 05_脚本工具/11_retitle_src_ch2.py --apply`(脚本备好,默认 dry-run)。", ""]
# 五、脏味互校
rep += ["## 五、脏味互校(第二章 20 条目 ⇄ 本书五味体用化说 + 底本五味五行表)", "",
"| 节 | 条目 | 脏位 | 味 | 判定 | 味依据 | 底本/第 1 章互证 |",
"|----|------|------|----|------|--------|------------------|"]
for sec, name, zang, wei, verdict, ev, ref, ok in cross:
rep.append(f"| {sec} | {name} | {zang} | {wei} | {'✅ ' if ok else '⚠ '}{verdict} | {ev} | {ref} |")
rep += ["", "> 判定规则:底本《辅行诀》「味辛皆属木/味咸皆属火/味甘皆属土/味酸皆属金/味苦皆属水」"
"+本书体用化说(辛=肝用/肺化/脾体;咸=心用/肾化;甘=脾用/肾体;酸=肝体/肺用/心化;"
"苦=心体/肾用);条目「脏位」凡落在该味可属之脏内即为相符。"
"本项属本库内部互证,**不改原文**(同第 1 章名位互校之例)。", "",
"### 与第 1 章交叉引证互校", "",
"| 引证锚(本件) | 命中 | 第 1 章条目 | 判定 |", "|---------------|------|------------|------|"]
for a_, h_, d_, v_ in ref_rows:
rep.append(f"| `{a_}` | {h_} | {d_} | {v_} |")
rep += ["", "> 本件无「名位(X中Y)」标注(第 1 章体例),故互校以「品物—脏位—味」与底本方剂实测为纲。", ""]
# 六、存疑
res_keys = resolved_suspect_keys(rows)
_no = {r["锚"]: r["#"] for r in rows}
stay = [(k, v) for k, v in SUSPECTS if k not in res_keys]
gone = sorted([(k, v) for k, v in SUSPECTS if k in res_keys], key=lambda kv: _no.get(kv[0], 999))
rep += ["## 六、存疑登记(原文不改,待核原书)", "",
f"> 现状:**已核验 {len(gone)} 项**(用户判决「无误」,移出存疑册)/**尚待核对 {len(stay)} 项**。", ""]
if gone:
rep += ["### 6.1 已核验(用户 2026-09-20 判决,本项结项,不再列为存疑)", "",
"| 项 | 用户判决 | 结论 |", "|----|---------|------|"]
for k, v in gone:
r = next((x for x in rows if x["锚"] == k), None)
vd, bk, vnote = VERDICTS.get(r["#"], ("—", "", "")) if r else ("—", "", "")
rep.append(f"| {k} | **{vd}**(清单 #{r['#'] if r else '—'}) | {vnote} |")
rep += ["", "> 依据用户判决:**原书即作此字/此引文**,本条不构成存疑。**判决词表(用户 2026-09-20 明确)**:"
"`保留`=保留(本库)修正结果;`原文无误`=原书原文正确、如本库已改则回改(本章 #39「上方」一例);"
"`无误`/`原书如此`=该处原书如此、不作改动;`核对正确`=核对结论成立但未下改令、原文保留。**`修正内容`=等同于「改」**——据用户给/确认的正字改清洗版正文(用户 2026-09-20 选定 A 案)。"
"凡「保留」类已在第八节登记为引文用字/用字/引文体例,如后续发现异文另行登记。", ""]
rep += ["### 6.2 尚待核对", "", "| 项 | 说明 |", "|----|------|"]
for k, v in stay:
rep.append(f"| {k} | {v} |")
gone_no = "/".join(f"#{r['#']}" for r in rows
if r["锚"] in res_keys) if res_keys else "—"
if stay:
rep += ["", f"> 共 **{len(stay)}** 项,均**未改原文**,逐条列入待核对清单「原书核对」类"
f"(清单 # 与本节一一对应;**已核验的 {len(gone)} 项仍保留在清单 {gone_no}** 以维持编号稳定)。", ""]
else:
rep += ["", f"> **存疑清零**——原 {len(SUSPECTS)} 条存疑项经用户 2026-09-20 核对原书**全部判决闭环**"
f"(无误/原文无误 6 · 保留 8 · 按核改 3),无遗留待核项。"
f"**已核验的 {len(gone)} 项仍保留在清单 {gone_no}** 以维持编号稳定。", ""]
# 七、待核对清单
n_done = len(VERDICTS)
st_word = "全部判决(本章闭环)" if n_done == len(rows) else "部分判决"
rep += ["## 七、待核对清单与人工核验判决记录", "",
f"- 文件:`02_加工数据/药性探真_第2章_待核对清单.md`(固定 {len(rows)} 条,按章/节/条目分组,含判决栏)",
"- 构成:" + " · ".join(f"{t} {sql(t)}" for t in TYPES if sql(t)),
f"- 状态:**{st_word}**——第 1–{n_done} 条已判决(判决分布 {verdict_stat()}),"
f"余 {len(rows) - n_done} 条待判决;判决后按第 1 章流程回填(清单判决栏 + 本表)。", "",
"### 7.1 修正内容·拟正字与落盘实况(用户「全按此拟」→ **6 条 11 处已全部落 C 类、正文已生效**)", "",
"| # | 行(清洗版) | 原书文 | 拟正字 | 依据 |", "|---|------|--------|--------|------|"]
for n, ln, old_t, new_t, why in PENDING_FIXES:
rep.append(f"| {n} | {ln} | {old_t} | **{new_t}** | {why} |")
rep += ["", "> 说明:本 6 条系用户判为原书内容有误、按 **A 案**(`修正内容`=改正文)处理;"
"用户 2026-09-20 批复「**全按此拟**」后,已在 `10_clean_ch2.py` 的 `C_FIXES` 末增列 **12 条规则**"
"(另 1 条既有「囟→囱」规则并订正为传本形),**正文已改、清洗版已刷新**"
"(`29097b72…` → `ac1a4d32…`,+6 B)。所改 11 处与上表逐条对应,且均**与印刷本有意不一致**、"
"**不得据「原书如此」回流**。另有 **#11/#18 为体例确认项、无错字,修正不适用**,仍按体例处理。", ""]
# 八、体例登记
rep += ["## 八、体例登记(不校改)", "", "| 项 | 说明 |", "|----|------|"]
for k, v in VERSION_NOTES:
rep.append(f"| {k} | {v} |")
# 九、结构
rep += ["", "## 九、结构(清洗版行号)", "", "| 节 | 条目数 | 行号 |", "|----|-------|------|"]
for s in secs2:
rep.append(f"| {s['节']} | {len(s['条目'])} | {s['条目'][0]['行']}–"
f"{s['条目'][-1]['行'] if s['条目'] else '—'} |")
rep += ["", "| 节 | 序 | 条目 | 清洗版行 |", "|----|----|------|---------|"]
for s in secs2:
for e in s["条目"]:
rep.append(f"| {s['节'].split(' ')[0]} | {e['序']} | {e['名']} | {e['行']} |")
# 十、自检
rep += ["", "## 十、自检结果(脚本自动)", ""]
for o in oks:
rep.append(f"- ✅ {o}")
for e in errs:
rep.append(f"- ⚠ **{e}**")
rep += ["", "---", "",
f"> 📅 2026-09-20 —— 建件:按第 1 章标准检查并清洗第 2 章录入稿;"
f"A(行尾空格 {n_trail} 行/汉字间空格 {n_cc} 处/数字旁空格 {n_num} 处/半角标点 {len(half_lines)} 行/"
f"LaTeX 1)、B {c('B')}、C {len(C_FIXES)} 条、D {c('D')}、H 标题 {len(level_log)} 行+序号 {len(renum_log)} 处;"
f"脏味互校 {n_ok}/{len(cross)} 相符;体例登记 {len(VERSION_NOTES)} 项;"
f"待核对清单 {len(rows)} 条(已判决 {len(VERDICTS)} · 待判决 {len(rows) - len(VERDICTS)});"
f"存疑册 {len(stay)} 项(原 {len(SUSPECTS)} 项,已核验 {len(gone)} 项移出)。",
"> 📅 2026-09-20 —— 第 4 批判决回填(用户逐条判决 #29–#42,本章 **42 条全部判决完毕、闭环**):"
"据核改 3 条(蘖未→蘖末、儆(生但反)→馓(生但反)、盖脾→盖脺)、**回改 1 处**"
"(上言→上方,撤销第 1 批修正)、原文无误 3 条(即便/马蹄园/坤为土)、保留 8 条、"
"核对正确(不改)1 条;**存疑册清零**(原 17 项全部结项,已核验 17 项);"
"新增体例登记「★用字体例·脺」(音 cuì)。\n"
"> 📅 2026-09-20 —— 第 3 批判决回填(用户逐条判决 #16–#28:原书如此/未改 8 · 保留修正 5);"
"新增体例登记 2 项(★用字体例·原书用字「副/珩/苔/杨行密」、★引文用字体例"
"《说卦》「艮为果瓜」);#26 数字旁空格判「保持现状(两章暂不统一)」;"
"存疑册 13 → 8 项。\n"
"> 📅 2026-09-20 —— 第 2 批判决回填(用户逐条判决 #6–#15:原书如此/未改 4 · 保留清理 2 · 保留修正 4);"
"新增体例登记 3 项(引文用字「金木者生成之始终」、引文体例《纲目》葱条、"
"★原书印刷之误·本库订正);6.1 已核验补入 #6/#13;存疑册 17 → 13 项。\n"
"> 📅 2026-09-20 —— 第 1 批判决回填(用户逐条判决 #1–#5:保留 1 · 无误 3 · 改 1);"
"新增第七节《待核对清单与人工核验判决记录》,第六节拆为 6.1 已核验/6.2 尚待核对。"]
wf(OUT_REPORT, "\n".join(rep) + "\n")
print("清洗版:", OUT_MD, os.path.getsize(OUT_MD), "bytes")
print("报告 :", OUT_REPORT, os.path.getsize(OUT_REPORT), "bytes")
print("结构 :", OUT_STRUCT, os.path.getsize(OUT_STRUCT), "bytes")
print("待核单:", OUT_CHECK, os.path.getsize(OUT_CHECK), "bytes")
print(f"A 行尾空格 {n_trail} 行 | 空格 {n_cc}+{n_num} 处 | 半角标点行 {half_lines} | "
f"B {c('B')} | C {len(C_FIXES)} | D {c('D')} | H 标题 {len(level_log)} + 序号 {len(renum_log)} | 清单 {len(rows)} 条")
for o in oks:
print(" ✅", o)
for e in errs:
print(" ⚠", e)
if __name__ == "__main__":
main()