重构为函数式通用 Markdown 修改库
This commit is contained in:
@@ -1,225 +0,0 @@
|
||||
# data/ 五份论文 Markdown 审计报告(2026-08-21)
|
||||
|
||||
> 状态:scratch 草稿,供评审。清洗力度由师姐逐项决定,本报告只列问题、证据和可选处置,不做力度决策。
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
- 五份文件均为英文学术论文的 PDF→Markdown 转换产物,分属 5 个来源(JAMA、EJHF、Statistics in Medicine/arXiv、Springer/arXiv、Disaster Med Public Health Preparedness),噪声特征差异很大,不能用一套固定规则覆盖。
|
||||
- 最严重的问题不是格式噪声,而是**内容丢失**:2 份文件中途截断,1 份(JAMA)所有表格整体缺失。这类问题清洗无法恢复,只能重新转换或人工补录。
|
||||
- JAMA 文件的原始 PDF 是**未定稿的 Word 修订稿**,行号、审阅批注、修订残留词对全部泄漏进正文,是五份中污染最重的。
|
||||
- 格式类噪声(双重转义实体 31 处、孤行公式编号 12 处、空行断句、标题层级扁平、引用上标混用等)确定可清洗,风险低。
|
||||
- 少数问题涉及**语义改变**(数学公式被 OCR 改错、乱码替换专名),自动清洗有改错正文的风险,建议人工确认。
|
||||
|
||||
## 2. 审计范围与方法
|
||||
|
||||
- 对象:`data/*/markdowns/*.md` 共 5 份,逐行人工通读;行号均指 markdowns 下的 md 文件。
|
||||
- 辅助统计(本轮实际执行):标题层级计数、图片/表格/实体/批注/arXiv 戳的 grep 计数。
|
||||
- 判定原则:只把"转换管线引入的噪声"列为清洗对象;原文自身的写作瑕疵(如语法错误)不属于转换噪声,单独列出并标注"不建议清洗"。
|
||||
- 未验证项:未与原 PDF 逐页比对内容完整性,"缺失"结论基于文内自引用(如正文提到 Table 2 但全文无 Table 2)和文件截断位置。
|
||||
|
||||
## 3. 总体统计
|
||||
|
||||
| 文件(下文简称) | 行数 | H1 | H2 | H3+ | 图片 | HTML表格 | 双重转义 | 孤行编号 | 批注 | arXiv边栏戳 |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| dmp (Disaster Med) | 208 | 0 | 11 | 0 | 1 | 7 | 23 | 0 | 0 | 0 |
|
||||
| jama (JAMA 2024) | 349 | 2 | 10 | 0 | 0 | 0 | 0 | 0 | 2 | 0 |
|
||||
| ejhf (EJHF 2020) | 143 | 1 | 13 | 0 | 1 | 1 | 8 | 0 | 0 | 0 |
|
||||
| sim (Stat Med/arXiv) | 247 | 2 | 11 | 0 | 2 | 0 | 0 | 12 | 0 | 1 |
|
||||
| springer (ICU LSTM) | 154 | 1 | 12 | 0 | 4 | 1 | 0 | 1 | 0 | 1 |
|
||||
|
||||
补充:jama 有 128 行以"行号+空格"开头(手稿行号泄漏);springer 的 3 处 arXiv 字符串中 2 处是参考文献的正常引用,仅 1 处是边栏戳。
|
||||
|
||||
## 4. 问题清单
|
||||
|
||||
每项标注:【确定】= 确定是转换噪声,可安全清洗;【语义】= 涉及内容判断,建议人工确认;【丢失】= 内容缺失,清洗不可恢复。处置选项仅供师姐选择。
|
||||
|
||||
### A. 内容级问题(最严重)
|
||||
|
||||
**A1【丢失】两份文件中途截断**
|
||||
- ejhf 第 143 行在 Table 1 HTML 表格中间戛然而止("Medical history at randomization, no. (%)" 行后为空单元格)。Table 1 后半、Tables 2–4、全部图注、参考文献整体缺失。
|
||||
- sim 第 247 行止于方法 M5 描述中间,且结尾 URL 损坏(`https://cran.r-project.org/web/p6$^{10}$`)。第 3 节(结果)、4、5 节、参考文献、附录缺失。
|
||||
- 处置选项:a) 退回重新转换;b) 接受现状并在元数据标记"截断";c) 人工补录缺失部分。清洗管线本身无法解决。
|
||||
|
||||
**A2【丢失】jama 全部表格缺失**
|
||||
- 正文多处引用 Table、Box 1、eTables 1–3,但全文 0 个表格、0 张图片。摘要性内容(如各器官系统阈值表)完全丢失。
|
||||
- 处置选项:同 A1。
|
||||
|
||||
**A3【丢失】dmp 的 FIGURE 1 流程图被转成 HTML 表格**
|
||||
- 第 83 行:流程图(决策树)被输出为单行 HTML 表格,图形语义尽失,仅 FIGURE 2(第 111 行)保留为图片。
|
||||
- 处置选项:a) 保留现状(有总比没有好);b) 重新转换该页;c) 人工用图片替换。
|
||||
|
||||
**A4【丢失】sim 第 93 行句子开头缺失**
|
||||
- "/unpenalized) regression models" 以斜杠开头,前文整句丢失。
|
||||
- 处置选项:标记为损坏片段,或对照原文补录。
|
||||
|
||||
### B. 草稿/修订痕迹泄漏(仅 jama,原稿是 Word 修订稿)
|
||||
|
||||
**B1【确定】手稿行号泄漏(128 行)**
|
||||
- 正文行以行号开头:"25 increase in the Sequential..."(第 115 行)、"26 with suspected infection"(第 116 行)等;标题也带行号:"## 116 Results/recommandations"(第 149 行)、"## 117 Criteria..."(第 151 行)、"## 143 Organ dysfunction..."(第 165 行)。
|
||||
- 处置选项:a) 剥离行首行号(注意与正常编号列表、年份区分);b) 连同批注一起整体退回,要求提供定稿版。
|
||||
|
||||
**B2【确定】审阅批注泄漏(2 处)**
|
||||
- 第 155–157 行:"Commented [LS1]: Why highlighted?"、"Commented [SW2R1]: To make sure we use capital letters..."。
|
||||
- 处置选项:整段删除。注意第 292 行还有一句删除文字与保留文字混杂的句子("Appropriate process and balancing measures Efforts to enhance..."),需人工断句。
|
||||
|
||||
**B3【语义】Word 修订残留词对(约 7 处)**
|
||||
- "defined identified by as"(第 91 行)、"defined identified using by"(第 153 行)、"defined identified as in sepsis-septic patients"(第 116 行)、"defined indicate by as"(第 163 行)、"was were derived"(第 306 行)、"The new-Phoenix"(第 197 行)等——是"插入词+删除词"并存的痕迹。
|
||||
- 哪个词是最终保留词需要对照定稿判断,自动二选一有风险。处置选项:a) 人工逐处确认;b) 退回要定稿。
|
||||
|
||||
**B4【确定】未填占位符**
|
||||
- "XX societies"(第 101 行)、"XX-microbiological testing and YY-antibiotics"(第 302 行)、"Endorsing societies: To be populated after acceptance"(第 317 行)。
|
||||
- 处置选项:保留并标记待补,或等定稿填充后再清洗。
|
||||
|
||||
**B5【确定】日期损坏**
|
||||
- 第 85 行 "Revision date: December 3122, 2023"。
|
||||
- 处置选项:对照原文改为 2023 年内正确日期(人工)。
|
||||
|
||||
### C. 标题结构问题
|
||||
|
||||
**C1【确定】标题层级扁平**
|
||||
- dmp:0 个 H1,11 个 H2 全部同级(含 Introduction/Methods/Results 等,第 1,3,7,59,67,103,137,153 行)。
|
||||
- ejhf:主章节与子章节同为 H2("## Methods" 第 51 行、"## Study population" 第 53 行),无层级区分。
|
||||
- 处置选项:按章节编号/语义推断层级(2.1 → H3),或统一降级保持平级。前者需人工核对推断结果。
|
||||
|
||||
**C2【确定】标题被拆分成两行**
|
||||
- jama:标题拆成两个 H1(第 1–2 行 "International Consensus Criteria..." / "The Phoenix Pediatric Sepsis Criteria",实为正副标题)。
|
||||
- sim:主标题拆成两个 H1(第 3–4 行 "Conounder selection..." / "treatment effect estimators",且首词 "Conounder" 是 OCR 错字,原文应为 Confounder);2.2 节标题拆两行(第 183/185 行 "…full matching on the propensity" / "## score")。
|
||||
- 处置选项:合并为单标题;sim 主标题的 "Conounder" 拼写需对照原文确认(【语义】)。
|
||||
|
||||
**C3【语义】乱码标题**
|
||||
- dmp 第 47 行 `## ่วง`(泰文字符)。按位置推断应为 METHODS,但不能凭推断改写正文级内容。
|
||||
- 处置选项:人工对照 PDF 改回,或删除该标题。
|
||||
|
||||
**C4【确定】跑动页眉混入正文且被标为标题**
|
||||
- dmp 第 73、191 行 "## MSOFA Score for Critical Care Triage" 出现在句中和 REFERENCES 内;第 71→75 行一句话被它从中间切断。
|
||||
- 处置选项:删除页眉行并把被切断的句子接回。
|
||||
|
||||
### D. 表格问题
|
||||
|
||||
**D1【确定】表格压缩为单行 HTML**
|
||||
- 全部 9 个表格(dmp 7、ejhf 1、springer 1)都是 `<table>...</table>` 单行输出,diff、review、编辑都极难。
|
||||
- 处置选项:转 GFM 多行表格(简单表);对含 rowspan/colspan 的复杂表保留 HTML 但格式化缩进。
|
||||
|
||||
**D2【确定】HTML 实体双重转义(31 处)**
|
||||
- dmp 23 处(`&gt;400`、`&lt;1.2`、`MAP&lt;70`,第 27/33/39 行等);ejhf 8 处(`A1C&lt;7`、`7≤A1C&lt;8`,第 143 行)。
|
||||
- 处置选项:还原一层转义(`&gt;` → `>`)。这是最安全的清洗之一。
|
||||
|
||||
**D3【确定】合并单元格信息丢失**
|
||||
- dmp 第 33 行 Table 2 的 Liver 行出现空 `<td></td>`,跨行合并关系丢失,数值与表头对应断裂。
|
||||
- 处置选项:对照 PDF 人工修复合并结构,或标记为低可信表格。
|
||||
|
||||
**D4【确定】表格行错误合并**
|
||||
- dmp 第 39 行 Table 3:四个器官系统 "Respiratory Coagulation Liver Cardiovascular" 被挤进一个单元格。
|
||||
- 处置选项:人工拆分修复。
|
||||
|
||||
**D5【确定】表头 OCR 乱码**
|
||||
- springer 第 111 行 Table 1 表头 "Claesther"(应为 Classifier)。
|
||||
- 处置选项:人工改正(单处,低成本)。
|
||||
|
||||
### E. 文本级损坏
|
||||
|
||||
**E1【语义】跨脚本字符替换**
|
||||
- dmp 第 43 行 "atينS Hospital"、第 55 行 "ينDS Hospital"——阿拉伯字符 ين 替换了 "LD"(LDS Hospital 是机构专名)。
|
||||
- 处置选项:人工替换回 "LDS"。自动规则可检出非拉丁字符混入,但替换动作建议人工确认。
|
||||
|
||||
**E2【确定】跨页断词**
|
||||
- dmp:第 125 行结尾 "…at the relevant thresh" + 第 127 行 "olds of 8 and 11"(单词 thresholds 被页边界切开)。
|
||||
- sim:第 87/89 行 "except possi-" / "bly via treatment";第 217/219 行 "cre-" / "ated by permuting"。
|
||||
- 处置选项:拼接断词(去连字符合并)。需注意英语中合法的行尾连字符(如 "well-known")不能误合并,建议只合并"行尾连字符+下一行首为小写字母且拼出的词在词表内"的情况,其余保留待审。
|
||||
|
||||
**E3【确定】句内空行断句**
|
||||
- 大量段落被空行从句子中间切开:jama 第 103→105、113→115 行;ejhf 第 47–49、57–59、67–69、87–89、113–115、131–133 行;springer 第 16→20 行(中间还被 arXiv 戳隔开,见 H1)、42→44 行。
|
||||
- 处置选项:段内合并(前段末无句号且后段首为小写/连接词时拼接)。这是对 RAG 分块影响最大的问题之一。
|
||||
|
||||
**E4【确定】段落内容错位/孤立行**
|
||||
- springer 第 63 行孤立 "1"(公式编号漂移,见 F1);第 81–83 行 "…improve the simple Multilayer Perceptron… other deep models." 后接 "including RNNs and MLPs.",段落被错误切开。
|
||||
- 处置选项:结合上下文人工归位。
|
||||
|
||||
### F. 数学公式问题(sim 最重,springer 次之)
|
||||
|
||||
**F1【确定】公式编号漂移成孤行**
|
||||
- sim 12 处:第 63/70/81/107/117/133/145/153/161/171/179/197 行分别是 "1"、"2"、"(4)"…"(12)";springer 第 63 行 "1"。
|
||||
- 处置选项:并入对应公式块或删除(若公式本体已带编号)。需逐处对照,不宜盲目删除。
|
||||
|
||||
**F2【语义】公式内容被 OCR 改错**
|
||||
- sim 第 139 行 `$\exp(x) = \exp(x)/\{1+\exp(x)\}$`——这是 expit 函数定义(x↦e^x/(1+e^x)),左边的 $\exp(x)$ 应为 $x$ 或 expit(x)。OCR 错误改变了数学含义,且这种错误会误导下游读者。
|
||||
- 处置选项:人工对照原文修复;自动工具只能标记"公式与上下文不符",不宜自动改。
|
||||
- sim 第 119 行 "weights w k" 下标丢失,同类。
|
||||
|
||||
**F3【确定】LaTeX 冗余空格与风格不一**
|
||||
- sim 全文行内公式带前导空格(`$ \widehat{\psi}_{j} $`)、内部空格过多(`\widehat { \mathrm { E } } ( Y ^ { a } )`,第 150 行)。
|
||||
- 处置选项:规范化空格(不改变符号语义的前提下)。风险低但需保守,避免动 `\,` `\;` 等有意义的间距命令。
|
||||
|
||||
**F4【确定】公式 OCR 字符间距拉宽**
|
||||
- springer 第 72/78 行 cases 环境里 `\mathrm { s u r v i v o r s ~ g r o u p }` 逐字空格。
|
||||
- 处置选项:去除字母间空格(保守做法:只处理 `\mathrm{}` 内的单字母间距模式)。
|
||||
|
||||
### G. 格式不一致
|
||||
|
||||
**G1【确定】引用上标风格混用**
|
||||
- 同一文件内 LaTeX `$^{1,2}$` 与 Unicode 上标(¹²、²⁻⁴、⁴⁹ ⁵⁰,⁵¹)并存:jama(第 115–116 行 Unicode vs 第 107/187 行 `$\geq 2$`)、ejhf(第 45–49 行 LaTeX vs 第 133 行 Unicode)、springer(第 5–6 行 `$ ^{1} $` vs 第 20 行 [1,2,4,3] 方括号)。
|
||||
- 处置选项:统一为一种(选哪种由师姐定,取决于下游用途:RAG 检索倾向 Unicode 纯文本,渲染倾向 LaTeX)。
|
||||
|
||||
**G2【可能】数字格式不一致**
|
||||
- ejhf 第 55/57 行 "6068 patients" vs "4,091 patients";dmp 第 91 行 "0.81-.85"(小数点前缺 0)。
|
||||
- 注意:springer 的 "61.532"、"46.520" 是欧式千分位,可能是原文排版而非转换噪声,不能自动统一。
|
||||
- 处置选项:统一千分位与小数风格;欧式写法是否转换需师姐定。
|
||||
|
||||
**G3【确定】参考文献列表分隔不一致**
|
||||
- dmp:refs 1–18 空行分隔,19–33 连续堆叠(第 193–208 行);springer:refs 1–8 空行分隔,9–19 连续堆叠(第 140–154 行)。
|
||||
- 处置选项:统一为一条一空行。
|
||||
|
||||
### H. 非正文噪声与资产
|
||||
|
||||
**H1【确定】arXiv 边栏戳**
|
||||
- sim 第 1 行 "arXiv:2001.08971v3 [stat.ME] 10 Oct 2020";springer 第 18 行同类戳插在 Introduction 段落中间,把一段话切成三截(第 16/18/20 行)。
|
||||
- 处置选项:删除戳行并接回段落。注意别误删参考文献中的合法 "arXiv preprint arXiv:…"(springer 第 143/152 行)。
|
||||
|
||||
**H2【确定】机构仓库封面页**
|
||||
- ejhf 第 1–11 行:Glasgow eprints 引用说明、版本声明、`http://eprints.gla.ac.uk/213358/`、"Deposited on: 27 April 2020",以及封面图 ``(该图是仓库封面,不是论文插图)。
|
||||
- 处置选项:整体删除封面区;封面图一并删或移入元数据。对 RAG 是纯噪声。
|
||||
|
||||
**H3【可能】图片相对路径依赖**
|
||||
- 全部图片用 `../images/` 相对路径(dmp 第 111 行、ejhf 封面、sim 第 229/231 行、springer 第 65/115/117/119 行)。md 文件一旦脱离原目录结构,图片全部失效。
|
||||
- 处置选项:a) 保持现状(目录结构不变时无碍);b) 清洗时把路径改写为部署目标路径;c) 校验引用的图片文件是否存在并报告断链。sim 的 Figure 1 实为左右两个面板(sub0/sub1 两张图)共享一条图注(第 233 行),springer 的 Fig. 2 为三面板(sub1–sub3)——合并还是保持多图由师姐定。
|
||||
|
||||
## 5. 不建议清洗的内容(保真边界)
|
||||
|
||||
- **原文自身的写作瑕疵**:springer 论文语言明显不通("was went to describe"、"In the other hand"、"section 4 discuss"),这是作者问题不是转换噪声,清洗工具不得改写学术内容。
|
||||
- **欧式千分位**(springer "61.532"):疑似原文排版,自动统一有改数风险。
|
||||
- **专名与缩写的大小写、期刊缩写风格**:不属于转换噪声。
|
||||
- **A 类内容缺失**:不要试图用生成或推测内容"补全"缺失章节——宁可留空标记。
|
||||
|
||||
## 6. 决策清单(供师姐勾选力度)
|
||||
|
||||
| 编号 | 问题 | 涉及文件 | 建议决策点 |
|
||||
|---|---|---|---|
|
||||
| A1/A2/A4 | 截断与表格缺失 | ejhf, sim, jama | 重新转换 / 接受并标记 / 人工补录 |
|
||||
| A3 | 图转表格 | dmp | 保留 / 重转 / 换图 |
|
||||
| B1 | 行号剥离 | jama | 剥离 / 退回要定稿 |
|
||||
| B2 | 批注删除 | jama | 删(基本无争议) |
|
||||
| B3 | 修订词对 | jama | 人工定稿对照(不宜自动) |
|
||||
| B4/B5 | 占位符/坏日期 | jama | 保留标记 / 人工修 |
|
||||
| C1 | 层级重建 | dmp, ejhf | 推断层级 / 保持平级 |
|
||||
| C2 | 标题合并 | jama, sim | 合并(低风险) |
|
||||
| C3/C4 | 乱码标题/页眉 | dmp | 人工改 / 删 |
|
||||
| D1 | 表格展开 | 全部 | GFM / 缩进 HTML / 不动 |
|
||||
| D2 | 实体还原 | dmp, ejhf | 还原(低风险) |
|
||||
| D3/D4/D5 | 表格结构修复 | dmp, springer | 人工修 / 标记低可信 |
|
||||
| E1 | 乱码专名 | dmp | 人工替换 |
|
||||
| E2 | 断词拼接 | dmp, sim | 保守合并+白名单 |
|
||||
| E3 | 段内合并 | jama, ejhf, springer | 启用(对 RAG 影响大) |
|
||||
| E4 | 段落归位 | springer | 人工 |
|
||||
| F1 | 编号并入 | sim, springer | 对照处理 |
|
||||
| F2 | 公式纠错 | sim | 人工(含义级) |
|
||||
| F3/F4 | 公式空格 | sim, springer | 保守规范化 |
|
||||
| G1 | 上标统一 | jama, ejhf, springer | 定一种风格 |
|
||||
| G2 | 数字格式 | ejhf, dmp | 统一 / 保留原文 |
|
||||
| G3 | 参考文献分隔 | dmp, springer | 统一空行 |
|
||||
| H1 | arXiv 戳 | sim, springer | 删+接段(勿伤引文) |
|
||||
| H2 | 封面页 | ejhf | 删 |
|
||||
| H3 | 图片路径 | 全部 | 现状 / 改写 / 断链校验 |
|
||||
|
||||
## 7. 与既有审计的关系
|
||||
|
||||
`research-wiki/reference/GOVDOC_SAAS_CLEANING_SCOPE.md`(45 份政务文档审计,原名 MARKDOWN_CLEANING_AUDIT.md)中的幻觉、重复、页眉页脚等类别在本批论文中部分复现(C4/D2/H1 对应旧审计的 D001/L001 类),但本批新增了论文特有的类别:修订稿痕迹(B 类)、公式问题(F 类)、引用上标混用(G1)、截断缺失(A 类)。若后续建立通用清洗规则库,B/F/G 类需要论文 profile,不宜进默认规则。
|
||||
@@ -1,143 +0,0 @@
|
||||
# HTML 表格清洗专题调研:业界工具在 Markdown 清洗中如何处理 HTML 表格
|
||||
|
||||
> 状态:调研记录,尚未进入任何 design。
|
||||
>
|
||||
> 调研日期:2026-08-21。
|
||||
>
|
||||
> 定位:回答一个具体问题——Markdown 清洗中遇到 HTML 表格,业界工具实际怎么做。
|
||||
> 结论用于印证或修正 [`../reference/GOVDOC_SAAS_CLEANING_SCOPE.md`](../reference/GOVDOC_SAAS_CLEANING_SCOPE.md)
|
||||
> 中 T001/T002 的方向,不构成对任何方案的批准。
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
围绕“Markdown 里的 HTML 表格怎么办”,生态里的工具分成三种流派:
|
||||
|
||||
| 流派 | 做法 | 代表 |
|
||||
|---|---|---|
|
||||
| 生成端保真 | 复杂表格直接输出 HTML,不做管道表格 | MinerU、Docling(HTML/JSON 视图) |
|
||||
| 强行归一 | 全部转成管道表格,合并单元格静默损坏或内容重复 | Turndown + gfm 插件、Docling(Markdown 视图) |
|
||||
| 保真派 | 容错解析 → 校验网格 → 简单表转 GFM、复杂表保留 HTML/JSON | 本项目审计 T001 方向、Pandoc(grid tables / AST) |
|
||||
|
||||
支撑这张表的共同事实是:**GFM 管道表格语法在原理上表达不了合并单元格**。三种流派只是对这条约束的
|
||||
不同回答——绕开它、硬转它、或者按能力分流。
|
||||
|
||||
## 2. 语法能力边界:GFM 管道表格没有合并单元格写法
|
||||
|
||||
Pandoc 手册对各家 Markdown 表格方言的原文描述(2026-08-21 从官方 MANUAL 核实):
|
||||
|
||||
| 方言 | 合并单元格 | 单元格内块级元素 |
|
||||
|---|---|---|
|
||||
| pipe tables(≈GFM 表格) | 不支持(单元格不能跨多行) | 不能包含块级元素 |
|
||||
| multiline tables | 明确不支持跨行/跨列单元格 | 可以 |
|
||||
| grid tables | **支持**("Cells can span multiple columns or rows") | 可以 |
|
||||
| HTML `<table>` | 原生 `rowspan`/`colspan` | 可以 |
|
||||
|
||||
grid tables 是唯一支持合并单元格的 Markdown 表格语法,但它是 Pandoc 扩展,GitHub 不渲染,
|
||||
对“清洗后还要在 GFM 渲染器里查看”的场景不可用。所以在 GFM 方言内部,合并单元格没有任何无损写法;
|
||||
想保真只能保留 HTML,或存结构化 JSON。
|
||||
|
||||
Pandoc 手册同时警告:从表达能力更强的格式转换时"some document elements, such as complex tables,
|
||||
may not fit","can be expected to be lossy"。
|
||||
|
||||
来源:[Pandoc MANUAL - Tables](https://pandoc.org/MANUAL.html)
|
||||
|
||||
## 3. 生成端:PDF→Markdown 转换器为什么输出 HTML 表格
|
||||
|
||||
MD 文档里出现 HTML 表格,通常不是 bug,而是转换器面对合并单元格(`rowspan`/`colspan`)、
|
||||
多级表头等管道语法表达不了的结构时的标准回退。
|
||||
|
||||
| 工具 | 表格输出策略 | 依据 |
|
||||
|---|---|--- |
|
||||
| [MinerU](https://github.com/opendatalab/MinerU) | 所有表格一律输出 HTML 嵌在 Markdown 中,不做管道表格;支持跨页表格拼接 | 官方 README 功能列表 |
|
||||
| [Docling](https://docling.org/) | 内部 TableFormer 模型专门恢复合并单元格;同一文档可导出 HTML / Markdown / JSON 三种视图 | 官网能力页 + docling-core 2.92.0 源码 |
|
||||
|
||||
对本项目的含义:HTML 表格是合法的中间形态,不是待清除的垃圾。清洗目标不是“消灭 HTML 表格”,
|
||||
而是“识别哪些表格结构正确、哪些在转换中损坏”。
|
||||
|
||||
## 4. 反面教材一:Turndown 静默产出错位表格
|
||||
|
||||
[Turndown](https://github.com/mixmark-io/turndown) 是最流行的 HTML→Markdown 转换库之一,
|
||||
[turndown-plugin-gfm 的 tables.js](https://github.com/mixmark-io/turndown-plugin-gfm/blob/master/src/tables.js)
|
||||
(v1.0.2,2018 年发布后基本未改)只做两件事:
|
||||
|
||||
1. 首行不是全 `<th>`(无表头行)的表格:保留 HTML 不转;
|
||||
2. 其余表格:按 DOM 位置逐格输出管道符。
|
||||
|
||||
它**完全没有 `colspan`/`rowspan` 的处理代码**。合并单元格不触发上面的回退,直接按 DOM 位置压扁,
|
||||
转出列数不齐的坏表,且**不报任何错**。
|
||||
|
||||
对本项目的含义:
|
||||
|
||||
- “无表头就不转”是能力判断驱动的回退,这个思想是对的;但它的能力判断漏掉了合并单元格;
|
||||
- 连最流行的转换库在这里都会静默弄坏表格——审计要求“先建 DOM、校验网格、禁止正则替换”有真实事故支撑;
|
||||
- 选 HTML→Markdown 转换库时,“是否处理 span”必须列入验证项,不能信 README 宣称。
|
||||
|
||||
## 5. 反面教材二:Docling 的 Markdown 导出重复合并单元格内容
|
||||
|
||||
读了 docling-core 2.92.0 的源码(wheel 解包,2026-08-21):
|
||||
|
||||
- 内部 `TableCell` 带 `row_span`/`col_span` 和起止行列偏移;`TableData.grid` 属性把同一个 cell 对象
|
||||
**铺满**它覆盖的每个 (行, 列) 位置;
|
||||
- **HTML 序列化器**(`transforms/serializer/html.py`):遍历网格时跳过被覆盖的续位
|
||||
(`rowstart != i` 或 `colstart != j` 时 `continue`),只在起始位置输出,并正确带上
|
||||
`rowspan="N"`/`colspan="N"`——语义保真;
|
||||
- **Markdown 序列化器**(`transforms/serializer/markdown.py` 的 `MarkdownTableSerializer`):
|
||||
直接遍历铺满后的 grid,每个位置都输出 `col.text`——一个 `row_span=3` 的单元格内容在 Markdown
|
||||
输出里**重复出现 3 次**。转义只处理换行和管道符(`\n`→空格、`|`→`|`),再用
|
||||
tabulate `tablefmt="github"` 输出管道表格。
|
||||
|
||||
即 Docling 面对“Markdown 视图必须有合并单元格”的需求,选择了**内容重复**来保住矩形形状。
|
||||
这是“强行转管道表格会丢语义”的又一个实例,和 Turndown 的压扁是同一根源的两种表现。
|
||||
|
||||
对本项目的含义:
|
||||
|
||||
- “转 GFM”不是免费的格式变换,每一家实现都发明了自己的有损映射;
|
||||
- 如果未来用 Docling 做回源提取(调研报告第 6.1 节的候选方向),它的 Markdown 导出不能直接当作
|
||||
保真输出使用,需要用它的 `DoclingDocument` JSON 或 HTML 视图;
|
||||
- 审计 T001 说“强行转 GFM 会丢失语义”,这里的机制证据是:跨行列单元格要么被压扁(Turndown)、
|
||||
要么被重复(Docling)、要么失去合并关系本身(都失去 `rowspan`/`colspan` 语义)。
|
||||
|
||||
## 6. 清洗与格式化工具:主流选择是“不动 HTML 块”
|
||||
|
||||
| 工具 | 对 Markdown 内 HTML 表格的行为 | 来源 |
|
||||
|---|---|---|
|
||||
| remark / mdformat | raw HTML 当不透明块原样传递,不重新格式化、不转换 | [mdformat](https://mdformat.readthedocs.io/) 官方文档(核心保证是格式化前后 AST 一致,HTML 块不在处理范围) |
|
||||
| rumdl MD033(no-inline-html) | 报告 `<table>`(它有 Markdown 等价物),但 `fix` 只自动转 `em/strong/code/a/img/br/hr` 等行内简单标签,**不含表格**;`allowed-inside = ["table"]` 可整块豁免 | 本地 `reference/rumdl/docs/md033.md` |
|
||||
| rumdl MD056(table-column-count) | 校验每行列数与表头一致,自动修复方式是补/删空单元格 | 本地 `reference/rumdl/docs/md056.md` |
|
||||
| rumdl MD058(blanks-around-tables) | GFM 表格前后补空行 | 本地 `reference/rumdl/docs/md058.md` |
|
||||
|
||||
两点值得注意:
|
||||
|
||||
1. **没有主流工具自动把 HTML 表格转成 GFM 表格。** 连以“消灭 HTML”为目标的 MD033 都把表格留在
|
||||
“只报告、不修复”的范围里——因为工具作者知道这个转换会弄坏表格。
|
||||
2. **MD056 的自动修复方向与本项目审计相反。** 审计 T002 反对“补空单元格凑齐列数通过语法检查”,
|
||||
因为这可能掩盖静默丢列;MD056 恰恰把补空作为修复手段。借用这类规则时必须关掉它的自动修复,
|
||||
只取检测部分。
|
||||
|
||||
## 7. 与既有材料的关系
|
||||
|
||||
- 审计 T001(`../reference/GOVDOC_SAAS_CLEANING_SCOPE.md` 第 4.4 节)的五步法——容错解析建 DOM、
|
||||
展开 rowspan/colspan 校验二维网格、简单矩形表转 GFM / 复杂表保留 HTML 或 JSON、拆多行、
|
||||
回源确认幻觉——与本次调研的所有正面证据一致,未发现需要修正的点;
|
||||
- [`markdown-cleaning-ecosystem-research-2026-08-20.md`](markdown-cleaning-ecosystem-research-2026-08-20.md)
|
||||
第 5 节的推荐流程(html5lib 容错解析、禁正则、按合并单元格分流)同样得到印证;
|
||||
- 新增的证据是反面案例的具体机制:Turndown 的压扁路径、Docling Markdown 视图的重复路径、
|
||||
Pandoc 手册的方言能力原文、MD056 修复方向与审计相反。
|
||||
|
||||
## 8. 对本项目的待决问题(不是结论)
|
||||
|
||||
以下问题在对应 design 时需要回答,本调研只提供背景:
|
||||
|
||||
1. 简单/复杂表格的分界线,除了“有无合并单元格”,是否还要看单元格内块级元素、嵌套表格和表头层级;
|
||||
2. 复杂表保留的“规范 HTML”具体规范到什么程度(属性白名单?标签重排?缩进策略?);
|
||||
3. JSON grid 的格式是否对齐 Docling 的 `TableCell`(row_span/col_span/offset 字段),
|
||||
还是自定义 schema——涉及与未来回源 adapter 的成本权衡;
|
||||
4. 无表头表格(Turndown 的回退条件)按哪种流派处理:补合成表头转 GFM,还是保留 HTML。
|
||||
|
||||
## 9. 验证状态
|
||||
|
||||
- Pandoc 手册、Turndown 源码、MinerU README、Docling 官网:2026-08-21 通过网络核实;
|
||||
- docling-core 2.92.0:下载 wheel 解包读源码核实,涉及
|
||||
`MarkdownTableSerializer.serialize`、`TableData.grid`、HTML 序列化器的 span 处理;
|
||||
- rumdl 三条规则:读本地 `reference/rumdl/docs/`(该目录为镜像副本,以 rumdl 上游为准);
|
||||
- 未验证:各工具在本项目真实数据上的实际表现——需要等对应组件 design 批准后用受控样本测试。
|
||||
@@ -1,170 +0,0 @@
|
||||
# HTML 表格真实数据结构分析:45 份 GovDoc 测试 Markdown
|
||||
|
||||
> 状态:只读分析记录,尚未进入任何 design。文中"建议"部分是候选方向,不是批准的方案。
|
||||
>
|
||||
> 分析日期:2026-08-21。
|
||||
>
|
||||
> 定位:用真实数据回答"我们的 HTML 表格到底长什么样、损坏在哪",为未来表格清洗 design 提供测量依据,
|
||||
> 并修正 [`html-table-cleaning-ecosystem-research-2026-08-21.md`](html-table-cleaning-ecosystem-research-2026-08-21.md)
|
||||
> 第 8 节中可以用数据回答的待决问题。
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
按"展开 rowspan/colspan 后每行列数是否一致"给全部顶层表格分类,**剔除空 `<tr></tr>` 之后**的分布:
|
||||
|
||||
| 分类 | 定义 | 数量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| A 简单矩形表 | 无合并单元格、每行列数一致、无嵌套、无游离内容 | 2474 | 53% |
|
||||
| B 合法合并表 | 有 rowspan/colspan,展开后仍是完整矩形 | 356 | 8% |
|
||||
| C 损坏表 | 参差网格、标签截断、占位冲突等 | 1879 | 40% |
|
||||
|
||||
四个改变预期的发现:
|
||||
|
||||
1. **一半的"损坏"是空 `<tr></tr>` 造成的假象**——剔除后 C 类从 54% 降到 40%;
|
||||
2. **标签不闭合会吞掉半篇文档**——最极端的一个未闭合表格吞了 2.79MB、1294 个表格;
|
||||
3. **参差网格与合并单元格强相关**——六成以上参差表带 span 属性,指向转换器丢失 colspan 标注;
|
||||
4. **无表头是常态**(A 类中 96%),**表格内图片为零**,单元格内管道符为零。
|
||||
|
||||
## 2. 数据范围与方法
|
||||
|
||||
- 输入:`/home/lihaoze/gov_test_data/compare/*/uploads/*.md`,45 份,全程只读;
|
||||
本文只含聚合数字和结构事实,不含任何原文片段;
|
||||
- 分析脚本在会话级临时目录 `/tmp/table-analysis/analyze.py`,未入库(仓库处于文档治理阶段,无源码目录);
|
||||
本文第 2.1 节的规则描述是复现依据;
|
||||
- 解析器:lxml `HTMLParser(recover=True)`。本地未装 html5lib。
|
||||
|
||||
### 2.1 测量规则
|
||||
|
||||
1. **代码围栏遮蔽**:先标记 ```` ``` ````/`~~~` 围栏内的位置,围栏里的 `<table>` 不计入;
|
||||
2. **片段切分**:对围栏外的 `<table`/`</table>` 事件按嵌套深度配对出顶层片段;悬空的 `</table>`
|
||||
(无对应开启)单独计数并忽略;到文件尾仍未闭合的片段标记 `truncated`;
|
||||
3. **结构分析**:每个片段单独喂给 lxml 容错解析;对每个 `<table>` 展开 rowspan/colspan 建二维占位网格,
|
||||
检测占位冲突,计算每行展开后的列数,收集表头、嵌套、游离文本、块级子标签、空单元格、超长单元格、
|
||||
退化重复等特征;
|
||||
4. **分类谓词**(`truncated` 为片段级标记,其余为表格级):
|
||||
|
||||
```text
|
||||
A_simple : 非 truncated 且 span_cells=0 且无嵌套 且每行展开列数一致
|
||||
且无占位冲突 且无游离文本 且块级子标签 ⊆ {br}
|
||||
B_span_ok: 非 truncated 且无占位冲突 且每行展开列数一致 且无游离文本
|
||||
C_broken : 其余全部
|
||||
```
|
||||
|
||||
5. **空行修复复核**:把没有任何 `td`/`th` 子元素的 `<tr>` 整行剔除后重新跑同一分类,观察迁移。
|
||||
|
||||
## 3. 总量与原始分类
|
||||
|
||||
- 45 份文档共 7550 个 `<table` 开标签、7155 个闭标签,**缺口 395 个**;
|
||||
- 深度配对得到 4648 个顶层片段;容错解析后共 **4709 个表格元素**(缺口标签导致部分片段解析出多个表格);
|
||||
- `parse_fail=0`;lxml recover 模式记录 parser 错误的片段仅 30/4648——**recover 解析器的错误日志是弱信号,
|
||||
不能当损坏检测器用**,损坏要靠网格校验发现。
|
||||
|
||||
原始分类(4709 个表格):
|
||||
|
||||
| 分类 | 数量 | 占比 |
|
||||
|---|---|---|
|
||||
| A_simple | 1921 | 41% |
|
||||
| B_span_ok | 262 | 5% |
|
||||
| C_broken | 2526 | 54% |
|
||||
|
||||
结构特征(占 4709 的比例):含 span 属性 1891(40%)、参差网格 2506(53%)、有 `<th>` 259(5.5%)、
|
||||
单行表 157、截断片段 67、超长单元格(>500 字符)197、巨型片段(>10KB)70、退化重复内容 33、
|
||||
游离文本 27、占位冲突 14、嵌套表格 5、含块级标签 5、**含图片 0**。
|
||||
|
||||
## 4. 发现一:空 `<tr></tr>` 是最大的单一"假损坏"来源
|
||||
|
||||
完全没有 `td`/`th` 子元素的空行标签在参差表里出现 3000+ 行次。它们把"列数一致的好表"撑成
|
||||
"某些行 0 列"的参差表。
|
||||
|
||||
剔除空行后重新分类:
|
||||
|
||||
| 迁移路径 | 数量 |
|
||||
|---|---|
|
||||
| C_broken → A_simple | 553 |
|
||||
| C_broken → B_span_ok | 94 |
|
||||
|
||||
即分类变为 **A 2474(53%)/ B 356(8%)/ C 1879(40%)**,一条零风险修复救回 13% 的表。
|
||||
空行不含任何内容,剔除是无损的。
|
||||
|
||||
空行出现的位置:表中间 1151 处、表尾 385 处(对修复后仍为 C 的表统计),**没有出现在表头位置**——
|
||||
符合"转换器输出残留"而非"表头占位"的形态。
|
||||
|
||||
## 5. 发现二:标签不闭合会吞掉后续正文
|
||||
|
||||
最极端案例 `001-2/uploads/file_0_PDF.md`:全文件 1315 开 / 1124 闭;从第 1315 行开始的一个未闭合
|
||||
表格把后续 **2,789,092 字符、内部含 1294 个表格**的内容全部吞进一个"顶层片段"。
|
||||
|
||||
全库 395 个闭合缺口意味着:**清洗的第一步不是处理表格,而是安全切分片段**。深度配对在标签缺失时
|
||||
会把正文和后续完整表格归并进一个巨型片段,后续所有基于片段的统计和修改都会失真。
|
||||
|
||||
切分策略的可用锚点:相邻顶层表格之间,2943 对隔着真实文本、1661 对只隔空行——块边界
|
||||
(空行 + 后续正文)在实际数据中是可识别的。
|
||||
|
||||
## 6. 发现三:参差网格与 span 强相关,指向"丢 colspan 标注"
|
||||
|
||||
2506 个参差表中 **1624 个(65%)带 span 属性**——格子内容在、宽度信息没了,是转换器丢失
|
||||
colspan 标注的形态,不全是真缺内容。
|
||||
|
||||
剔除空行后仍参差的 1851 个表,参差发生位置:
|
||||
|
||||
| 位置 | 数量 | 推断成因 |
|
||||
|---|---|---|
|
||||
| 中间各行乱 | 780 | 真·结构损坏或逐行丢标注 |
|
||||
| 表头行比正文长 | 619 | 多级表头被拍平成一行、丢层级 |
|
||||
| 首行短 | 239 | 表头/首行缺格 |
|
||||
| 仅尾部截短 | 213 | 跨页截断尾巴 |
|
||||
|
||||
四类成因不同,修复策略应当不同,但**都不能靠补空单元格自动修**——那正是
|
||||
[`../reference/GOVDOC_SAAS_CLEANING_SCOPE.md`](../reference/GOVDOC_SAAS_CLEANING_SCOPE.md) T002
|
||||
明确反对、且 rumdl MD056 的 auto-fix 方向被本仓库否决的做法。
|
||||
|
||||
## 7. 发现四:无表头是常态,转换障碍集中在 `<br>`
|
||||
|
||||
对修复后仍是 A 类的 2474 个表,检查转 GFM 管道表格的内容障碍:
|
||||
|
||||
| 障碍 | 数量 | 占 A 类 |
|
||||
|---|---|---|
|
||||
| 无 `<th>` 表头 | 2393 | 96% |
|
||||
| 单元格含 `<br>` | 501 | 20% |
|
||||
| 单行表 | 176 | 7% |
|
||||
| 超长单元格(>500 字符) | 54 | 2% |
|
||||
| 单元格文本含 `\|` | 0 | 0% |
|
||||
| 表格内 `<img>` | 0 | 0% |
|
||||
|
||||
转义压力比预期小(管道符、图片都是零),压力集中在**合成表头**和 `<br>` 处理上。
|
||||
|
||||
## 8. 建议的处理策略(候选,未批准)
|
||||
|
||||
三步走,对齐审计 T001 的分流方向,用真实数据修正边界:
|
||||
|
||||
1. **切分**:容错定位 `<table>` 片段;未闭合的在块边界截断并标记 truncated,
|
||||
绝不让深度配对吞正文;
|
||||
2. **无损修复**:只做剔除空 `<tr>` 这一级别的零风险修复(实测救回 13% 的表);
|
||||
3. **分流**:
|
||||
- A 类(53%)→ 转 GFM:合成表头、`<br>` 转空格、管道符转义兜底;
|
||||
- B 类(8%)→ 保留 HTML,规范化输出;
|
||||
- C 类(40%)→ 不自动修,保留原样 + 按第 6 节四类成因报告分类原因,交人工确认或回源。
|
||||
|
||||
对生态调研第 8 节待决问题的数据回答:
|
||||
|
||||
- 问题 4(无表头表格怎么处理):数据表明无表头占绝对多数(96%),"补合成表头转 GFM"
|
||||
是主流路径;空表头还是首行充当表头仍是 design 待决;
|
||||
- 问题 1(简单/复杂分界线):分界线除了合并单元格,必须加"展开后网格是否矩形"——
|
||||
本数据中它是比 span 更强的损坏信号(53% 对 40%);
|
||||
- 问题 2、3(规范 HTML 程度、JSON schema)本次数据没有新增证据,维持开放。
|
||||
|
||||
## 9. 局限
|
||||
|
||||
- 全部数字只来自这 45 份文档,不得外推为一般结论(CLAUDE.md 第 5 节约束);
|
||||
- 53/8/40 依赖"剔除空 `<tr>`"这条规则被采纳;不采纳则为 41/5/54;
|
||||
- lxml recover 解析可能自行重排损坏片段,个别表格的行列统计是解析结果而非字节事实;
|
||||
- 巨型片段内部的表格统计(如 001-2/file_0 被吞的 1294 个)已计入总数,但它们在原文中的
|
||||
真实边界未经人工核对;
|
||||
- 参差位置的四分类用的是简单规则(与列数众数比较),是启发式归类,不是语义判断。
|
||||
|
||||
## 10. 验证状态
|
||||
|
||||
- 第 3 至 7 节所有数字:2026-08-21 由只读脚本在真实数据上实际运行得出,脚本未入库;
|
||||
- 分类谓词与第 2.1 节规则描述和脚本逻辑一致,可据此重建等价测量;
|
||||
- 未验证:任何修复或转换策略的实际效果——A/B/C 分流、空行剔除、块边界截断都还没有实现,
|
||||
需要等对应 design 批准后用受控样本测试。
|
||||
@@ -1,492 +0,0 @@
|
||||
# Markdown 清洗生态调研与通用架构建议
|
||||
|
||||
> 状态:调研草稿,尚未批准为项目设计。
|
||||
>
|
||||
> 调研日期:2026-08-20。
|
||||
>
|
||||
> 更新方式:候选工具、许可证、实测结果或项目范围变化时更新;形成实施决定后转写为下一编号 design。
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
这个项目不应该重新实现一个“正则表达式合集”,也不应该把 Prettier、mdformat、Unstructured 或某个
|
||||
PDF→Markdown 模型直接包装成最终产品。
|
||||
|
||||
现有工具各自只解决问题的一层:
|
||||
|
||||
- Markdown parser/formatter 能统一语法,但无法知道一句话是不是模型幻觉;
|
||||
- HTML 容错解析器能补齐标签,但无法保证补出的表格在业务上正确;
|
||||
- PDF/DOCX 提取器能回源重建,但仍可能 OCR 错误或生成幻觉;
|
||||
- PII 工具能提供候选实体,但无法自动决定跨文档伪名是否应该一致;
|
||||
- 文本质量过滤器能发现重复和低熵,却常以“整篇丢弃”为目标,不适合忠实修复文档。
|
||||
|
||||
因此建议把 `govdoc-md-cleaner` 定位为:
|
||||
|
||||
> **面向多项目的、可审计的文档规范化与派生框架。Markdown 是主要输入输出格式,但核心对象是带来源、
|
||||
> 结构、置信度和问题记录的文档,而不是一串待正则替换的文本。**
|
||||
|
||||
推荐的技术组合是:
|
||||
|
||||
| 层 | 首选候选 | 在本项目中的角色 |
|
||||
|---|---|---|
|
||||
| 核心语言 | Python | 与文档解析、OCR、隐私工具及现有下游生态衔接 |
|
||||
| Markdown 解析 | `markdown-it-py` + GFM 插件 | CommonMark/GFM 结构识别、块级行号映射;不负责语义修复 |
|
||||
| Markdown 输出 | 自有受控 renderer;`mdformat` 只作可选格式化后端 | 保证 profile 输出稳定,避免 formatter 越权改原文 |
|
||||
| 损坏 HTML | `html5lib`,必要时配合 `lxml` tree builder | 按浏览器规则恢复 DOM;恢复动作必须进入审计 |
|
||||
| 回源提取 | Docling 作为默认候选 adapter | PDF/DOCX/图片转结构化文档,保留页码、bbox 和 provenance |
|
||||
| 编码异常 | `ftfy` 作为候选建议器 | 识别/建议 mojibake 修复;默认不静默应用到法律文本 |
|
||||
| 隐私 | Presidio 可选 adapter + 中文自定义 recognizer | 检测、确定性伪名和图片脱敏;不是默认核心依赖 |
|
||||
| 重复/退化 | 自有 detector,参考 DataTrove 指标 | 长行、低熵、重复字符/n-gram、语言突变和固定幻觉模板 |
|
||||
| 多格式转换 | Pandoc 可选 adapter/对照 oracle | DOCX/HTML/Markdown 转换与 AST filter;不作为忠实度权威 |
|
||||
|
||||
`remark/unified` 是 Markdown 原生变换能力最完整的候选,但它会引入 Node.js/TypeScript 运行时;本项目的
|
||||
回源、OCR、中文隐私和下游环境更偏 Python,所以建议把 remark 作为设计参照和交叉验证器,而不是第一版核心。
|
||||
|
||||
这不是最终技术选型。下一步应以本报告为输入编写 design,并用小型 spike 验证关键假设后再批准依赖。
|
||||
|
||||
## 2. 审计告诉我们的真实问题
|
||||
|
||||
本报告以 [45 份 Markdown 清洗审计](../reference/MARKDOWN_CLEANING_AUDIT.md) 为本地事实来源。
|
||||
审计发现的不是单一格式问题,而是至少五个不同层次的问题:
|
||||
|
||||
1. **字节与字符层**:替换字符、私用区字符、NBSP、零宽字符、多余转义;
|
||||
2. **Markdown/HTML 语法层**:标题扁平、悬空链接、损坏 HTML/GFM 表格、极端长行;
|
||||
3. **文档结构层**:段落断裂、阅读顺序错误、页眉页脚混入、图片与表格丢失;
|
||||
4. **内容可信度层**:模型幻觉、退化重复、OCR 语义错误、无法凭 Markdown 恢复的缺失内容;
|
||||
5. **用途与合规层**:对比、RAG、受控忠实版、公开脱敏版对内容保留规则不同。
|
||||
|
||||
其中两个结论直接改变技术路线。
|
||||
|
||||
第一,Markdown parser 解析成功不能作为质量通过条件。CommonMark 明确规定任意字符序列都是合法文档,
|
||||
因此绝大多数“脏 Markdown”仍然可以无报错解析;我们必须建立额外的结构、内容和来源验证器
|
||||
([CommonMark 0.31.2](https://spec.commonmark.org/0.31.2/))。
|
||||
|
||||
第二,GFM parser 接受的表格也未必满足我们的忠实度要求。GFM 对正文行缺列会补空单元格,多出的单元格
|
||||
会被忽略;这对法律和金额表格可能造成静默丢失,所以项目必须在 parser 之上做严格矩形网格验证
|
||||
([GFM 表格规范](https://github.github.io/gfm/#tables-extension-))。
|
||||
|
||||
## 3. 为什么成熟 formatter 不能直接解决
|
||||
|
||||
### 3.1 Prettier、mdformat
|
||||
|
||||
[Prettier](https://prettier.io/docs/) 和 [mdformat](https://mdformat.readthedocs.io/) 都是成熟的确定性格式化器。
|
||||
它们通过“解析后重新打印”统一标题、列表、换行等书写风格。mdformat 使用 `markdown-it-py`,并提供语法扩展
|
||||
和代码围栏 formatter 插件([mdformat 插件文档](https://mdformat.readthedocs.io/en/stable/users/plugins.html))。
|
||||
|
||||
适合:
|
||||
|
||||
- 已经确认语义正确的 Markdown;
|
||||
- 统一输出风格;
|
||||
- 检查幂等性;
|
||||
- Wiki、README 和开发者手写文档。
|
||||
|
||||
不适合直接处理本审计数据:
|
||||
|
||||
- formatter 不知道 `The quick brown fox...` 是幻觉;
|
||||
- 重新打印会扩大 diff,使逐项审计更困难;
|
||||
- 对 raw HTML、损坏表格和未知扩展可能规范化或转义;
|
||||
- 它无法从缺失图片引用恢复资产,也无法回到 PDF bbox。
|
||||
|
||||
建议:只在结构和内容已经通过验证的节点上使用,或作为最终输出的可选 profile;永不直接覆盖原输入。
|
||||
|
||||
### 3.2 markdownlint、remark-lint
|
||||
|
||||
[remark-lint](https://github.com/remarkjs/remark-lint) 有约 70 条可组合规则,能检查标题跳级、硬换行、
|
||||
链接语法和行长等;markdownlint 也有成熟的规则集。这些工具适合开发文档质量门禁,但其规则主要面向
|
||||
作者书写风格,不认识 PDF 页、OCR 置信度、表格合并单元格或业务实体。
|
||||
|
||||
建议:用作本仓 Wiki/README 的 CI,或复用部分规则思想;不作为业务文档清洗引擎。
|
||||
|
||||
## 4. Markdown AST 候选
|
||||
|
||||
### 4.1 `remark` / `unified`
|
||||
|
||||
[remark](https://github.com/remarkjs/remark) 提供 Markdown→mdast→Markdown 的完整插件流水线;
|
||||
[mdast](https://github.com/syntax-tree/mdast) 对 CommonMark、GFM 表格、图片、raw HTML 等节点有稳定模型,
|
||||
unist 生态还提供位置、source extraction、遍历、lint 和 vfile 消息。它是本次调研中最完整的
|
||||
Markdown-native 变换生态。
|
||||
|
||||
优点:
|
||||
|
||||
- parser、AST、visitor、transformer、lint、stringifier 是同一生态;
|
||||
- 节点通常带行、列、offset,适合生成诊断;
|
||||
- GFM、frontmatter、数学、directives 等扩展成熟;
|
||||
- TypeScript 类型和插件边界清晰。
|
||||
|
||||
代价:
|
||||
|
||||
- 核心运行时是 Node.js/ESM;
|
||||
- PDF/DOCX/OCR、中文文本处理和当前下游大多仍在 Python;
|
||||
- 双运行时会增加部署、版本锁定和跨语言 IR 的维护成本。
|
||||
|
||||
判断:如果项目只清洗开发者 Markdown,remark 是首选;对当前“文档回源 + 多项目 profile”目标,第一版
|
||||
不建议为它引入第二套运行时。可把它用于 conformance 对照或以后提供 TypeScript 前端。
|
||||
|
||||
### 4.2 `markdown-it-py` + `mdformat`
|
||||
|
||||
[markdown-it-py](https://markdown-it-py.readthedocs.io/en/latest/) 遵循 CommonMark,支持插件、自定义规则和
|
||||
GFM 相关扩展;Token 的 `map` 字段提供块级起止行号
|
||||
([Token 文档](https://markdown-it-py.readthedocs.io/en/v4.2.0/_modules/markdown_it/token.html))。它活跃、
|
||||
MIT、Python 原生,适合本项目第一版。
|
||||
|
||||
局限也需要明确:
|
||||
|
||||
- 它主要是 parser/HTML renderer,不是完整的 Markdown transformation framework;
|
||||
- 行号映射主要在块级,细粒度字符 offset 和跨回源 bbox 仍需我们维护;
|
||||
- raw HTML 会成为特殊 token,表格恢复仍要交给 HTML parser;
|
||||
- CommonMark 合法不等于文档内容可信。
|
||||
|
||||
建议:把它用于“识别现有 Markdown 的结构和边界”,再投影到项目自己的 Document IR;不要直接在 token
|
||||
列表上堆满业务规则。`mdformat` 可为确认安全的 AST 提供稳定输出,但 renderer 行为必须通过回归样本冻结。
|
||||
|
||||
### 4.3 Pandoc
|
||||
|
||||
[Pandoc](https://pandoc.org/MANUAL.html) 使用 reader→AST→writer 架构,Lua/JSON filter 可以按顺序变换 AST
|
||||
([Pandoc filter 文档](https://pandoc.org/filters.html))。它的多格式覆盖和长期稳定性很强。
|
||||
|
||||
适合:
|
||||
|
||||
- DOCX、HTML、Markdown 等格式导入导出;
|
||||
- 做第二实现的转换对照;
|
||||
- 用户明确接受 Pandoc 方言规范化的 profile。
|
||||
|
||||
不适合担任忠实版核心:
|
||||
|
||||
- reader/writer round-trip 会改变原始 Markdown 表达;
|
||||
- Pandoc AST 不是为逐字符审计和 PDF bbox 设计的;
|
||||
- 外部二进制与 [GPL-2.0 许可证](https://github.com/jgm/pandoc/blob/main/COPYING.md)需要独立部署评估;
|
||||
- 不能修复不存在于输入中的图片和内容。
|
||||
|
||||
判断:可选 adapter,不作为唯一内部表示。
|
||||
|
||||
### 4.4 Marko、Mistune 等 Python parser
|
||||
|
||||
[Marko](https://marko-py.readthedocs.io/en/latest/) 提供纯 Python CommonMark AST 和扩展机制,Mistune 偏向
|
||||
高速渲染。它们都能用于特定场景,但相较 `markdown-it-py`,当前项目更看重现成插件、维护活跃度、
|
||||
生态采用以及块级 source map。第一轮 spike 不必同时维护三个 Python parser。
|
||||
|
||||
## 5. 损坏 HTML 与表格恢复
|
||||
|
||||
[html5lib](https://html5lib.readthedocs.io/en/stable/) 按 WHATWG 浏览器解析算法处理可能损坏的 HTML,
|
||||
可以输出 ElementTree 或使用 lxml tree builder;[lxml 的 HTML5 接口](https://lxml.de/4.5/apidoc/lxml.html.html5parser.html)
|
||||
也支持 fragment 解析。
|
||||
|
||||
推荐流程:
|
||||
|
||||
1. 从 Markdown AST 中只取 raw HTML fragment,不把整篇 Markdown 当 HTML;
|
||||
2. 保存原 fragment、source span 和哈希;
|
||||
3. 使用 html5lib 容错解析并收集 parser errors;
|
||||
4. 构建显式二维 table grid,展开 `rowspan`/`colspan`;
|
||||
5. 校验每个输出 cell 都能映射到原节点或 source 区域;
|
||||
6. 仅无合并单元格的简单矩形表格输出 GFM;
|
||||
7. 复杂表格输出规范 HTML,并并行保留 JSON grid;
|
||||
8. parser 自动补齐的标签只说明“语法可恢复”,不能自动标为“语义已验证”。
|
||||
|
||||
不能采用旧实现那样用正则匹配 `<table>...</table>`:审计已经证明大量闭合标签缺失,正则既无法正确嵌套,
|
||||
也会把后续正文吞入表格。
|
||||
|
||||
## 6. PDF、DOCX 和图片回源候选
|
||||
|
||||
### 6.1 Docling:默认候选 adapter
|
||||
|
||||
[Docling](https://docling.org/) 支持 PDF、Office、HTML、Markdown、图片等格式,能输出 Markdown 和结构化
|
||||
`DoclingDocument`;后者包含表格、层级、bbox 和 provenance
|
||||
([DoclingDocument 说明](https://github.com/docling-project/docling/blob/main/docs/concepts/docling_document.md))。
|
||||
项目是 Python/MIT,OCR 后端可插拔。
|
||||
|
||||
它与审计需求最匹配的不是“Markdown 看起来更漂亮”,而是能先保存结构化、带位置的中间结果,再由我们
|
||||
生成 fidelity/profile 输出。因此建议把 Docling 作为第一批回源 adapter 的基准候选。
|
||||
|
||||
但它仍不能成为无条件真值:OCR、阅读顺序和表格模型都会出错,VLM 路径也可能生成内容。必须在 001、003
|
||||
有原始 PDF 的受控样本上验证字符、数字、表格和图片,不以官方 demo 或总准确率代替本项目测试。
|
||||
|
||||
### 6.2 Unstructured
|
||||
|
||||
[Unstructured partition](https://docs.unstructured.io/open-source/core-functionality/partitioning) 能把多种格式切成
|
||||
`Title`、`NarrativeText`、`ListItem`、`Table` 等元素,一些格式保留页码、坐标和 table HTML,适合作为
|
||||
另一种 source adapter 或元素分类对照。
|
||||
|
||||
其 `cleaners` 不能整体照搬。例如官方实现中的 `clean_dashes` 会替换连字符,`clean_bullets` 会删除项目符号,
|
||||
`clean_non_ascii_chars` 会丢弃非 ASCII 字符;这对中文法律文本、项目编号和列表结构明显过于激进
|
||||
([cleaners 源码](https://github.com/Unstructured-IO/unstructured/blob/main/unstructured/cleaners/core.py))。
|
||||
|
||||
判断:可评估 partition/metadata;不采用通用 `clean(...)` 作为默认清洗策略。
|
||||
|
||||
### 6.3 MinerU、Marker、MarkItDown
|
||||
|
||||
- [MinerU](https://github.com/opendatalab/MinerU) 支持 PDF/Office/图片到 Markdown、JSON 和图片资产,能力覆盖广,
|
||||
但本地审计已经展示某些现有解析产物中的幻觉与退化;此外它当前是 Apache-2.0 加附加商业与署名条款,
|
||||
不是无条件的标准 Apache-2.0([MinerU 许可证](https://github.com/opendatalab/MinerU/blob/master/LICENSE.md))。
|
||||
- [Marker](https://github.com/datalab-to/marker) 能输出 Markdown、JSON、HTML 和 chunks,也暴露页/块结构;代码为
|
||||
Apache-2.0,但模型权重采用带商业门槛和用途限制的修改版 OpenRAIL-M,必须把代码与模型许可分开审查
|
||||
([Marker 模型许可证](https://github.com/datalab-to/marker/blob/master/MODEL_LICENSE))。
|
||||
- [Microsoft MarkItDown](https://github.com/microsoft/markitdown) 是轻量多格式→Markdown 工具,适合低成本文本提取,
|
||||
但它的目标不是页级 provenance、复杂表格忠实恢复或审计账本。
|
||||
|
||||
判断:三者都可成为 benchmark adapter,不应把任何一个输出直接标为 fidelity 真值。第一轮优先比较
|
||||
Docling、MinerU 和 Marker 的结构化 JSON,而不是只比较最终 Markdown 的视觉效果。
|
||||
|
||||
## 7. 编码、内容退化和隐私工具
|
||||
|
||||
### 7.1 `ftfy`
|
||||
|
||||
[ftfy](https://ftfy.readthedocs.io/en/latest/) 用保守启发式修复 Unicode mojibake,目标之一是避免把正常文本
|
||||
误改。它适合发现和建议典型 UTF-8/Windows-1252 误解码。
|
||||
|
||||
边界:
|
||||
|
||||
- 已经变成 `�` 的原字符信息不在字符串中,ftfy 无法凭空恢复;
|
||||
- 私用区字符需要字体或源文件映射;
|
||||
- 中文旧编码误解码和法律文本中的兼容字符仍需专门验证;
|
||||
- 即使候选看起来合理,也要保留 before/after、置信度和规则版本。
|
||||
|
||||
建议:作为 detector/candidate fixer;默认 profile 只自动应用有严格前置条件、通过实体保护检查的修复。
|
||||
|
||||
### 7.2 重复、低熵和幻觉模板
|
||||
|
||||
[DataTrove](https://github.com/huggingface/datatrove) 是大规模文本过滤/去重框架,已有行重复率、长行比例、
|
||||
标点比例、语言分数和 contamination 等统计。它的默认任务是筛掉低质量训练语料,而本项目需要定位并修复
|
||||
文档中的局部区域。
|
||||
|
||||
建议借鉴指标,不把 DataTrove 作为核心依赖:
|
||||
|
||||
- 最大行长与结构白名单;
|
||||
- 字符/短片段 run-length;
|
||||
- 唯一字符、token 和 n-gram 比例;
|
||||
- 压缩率与局部信息熵;
|
||||
- 相邻和非相邻重复块;
|
||||
- 文档主要语言与局部语言突变;
|
||||
- 已知转换器/模型幻觉签名。
|
||||
|
||||
detector 只产生 issue 和范围。没有可信来源时,默认隔离或人工确认,不自动编写替代内容。
|
||||
|
||||
### 7.3 Presidio
|
||||
|
||||
[Presidio](https://microsoft.github.io/presidio/) 支持文本、图片和结构化数据中的 PII 检测与匿名化,并允许使用
|
||||
正则、校验和、上下文、NER 和自定义 recognizer。官方也明确说明自动检测不能保证找到全部敏感信息。
|
||||
|
||||
适合:
|
||||
|
||||
- 作为可选 privacy adapter;
|
||||
- 为中国身份证、统一社会信用代码、手机号、银行账号等实现校验和与上下文 recognizer;
|
||||
- 用 custom operator 实现稳定、按实体区分的伪名;
|
||||
- 把文本、表格单元格和图片脱敏放进同一 profile。
|
||||
|
||||
不适合:
|
||||
|
||||
- 默认把所有候选直接覆盖;
|
||||
- 把不同值统一变成同一 `[PHONE]`/`[ID]`;
|
||||
- 认为通用 NER 已覆盖中文政务/合同实体;
|
||||
- 把 privacy profile 与 fidelity 修复写死在一起。
|
||||
|
||||
## 8. 推荐的领域无关架构
|
||||
|
||||
下面是候选架构,不是已批准契约:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Markdown / HTML / PDF / DOCX / Image] --> B[Immutable source artifact]
|
||||
B --> C[Preflight detectors]
|
||||
B --> D[Parser / source adapters]
|
||||
C --> E[Issue ledger]
|
||||
D --> F[Document IR]
|
||||
F --> G[Validation and routing]
|
||||
E --> G
|
||||
G --> H[Safe deterministic repair]
|
||||
G --> I[Source-verified repair]
|
||||
G --> J[Quarantine / human review]
|
||||
H --> K[Canonical fidelity document]
|
||||
I --> K
|
||||
J --> K
|
||||
K --> L[Fidelity profile]
|
||||
K --> M[Retrieval profile]
|
||||
K --> N[Compare profile]
|
||||
K --> O[Public/privacy profile]
|
||||
L --> P[Markdown + assets + audit]
|
||||
M --> P
|
||||
N --> P
|
||||
O --> P
|
||||
```
|
||||
|
||||
### 8.1 Immutable source artifact
|
||||
|
||||
任何输入先冻结:原始 bytes、SHA-256、媒体类型、来源 ID 和接收时间。后续全部是新产物,不原地覆盖。
|
||||
只有路径而没有内容哈希不足以复现。
|
||||
|
||||
### 8.2 Document IR
|
||||
|
||||
IR 至少需要表达:
|
||||
|
||||
- block/node 类型、层级和子节点;
|
||||
- 原始 byte/line/column span;
|
||||
- 有源文档时的 page、bbox、source artifact hash;
|
||||
- 文本、表格网格、图片 asset ref 和文档边界;
|
||||
- parser/extractor、版本和置信度;
|
||||
- issue、annotation、repair 和 unresolved 关联。
|
||||
|
||||
不要让 Markdown AST 直接承担全部职责:mdast 或 markdown-it token 不包含完整的 PDF provenance、表格网格、
|
||||
修复证据和多 profile 状态。也不要直接把 DoclingDocument 定为公共契约,否则核心会被某个提取器绑定。
|
||||
|
||||
### 8.3 Detector 与 transformer 分离
|
||||
|
||||
每条规则先检测,再决定是否变换。建议规则声明:
|
||||
|
||||
- `rule_id` 与版本;
|
||||
- 支持的 node/input 类型;
|
||||
- source span 与证据;
|
||||
- safety level;
|
||||
- 是否确定性、幂等、可逆;
|
||||
- 影响文本、数字、实体、结构、资产或下游权重;
|
||||
- 验收 predicate。
|
||||
|
||||
安全级别建议:
|
||||
|
||||
| 级别 | 含义 | 默认行为 |
|
||||
|---|---|---|
|
||||
| `detect_only` | 只能确认异常,不能确认正确内容 | 记录 issue,不修改 |
|
||||
| `deterministic` | 不改变语义、前置条件严格 | 可自动执行并记录 |
|
||||
| `source_verified` | 新内容可回链到可信源区域 | 自动或抽检执行 |
|
||||
| `heuristic` | 有合理推断但可能误伤 | profile 显式开启或人工确认 |
|
||||
| `forbidden_without_source` | 金额、编号、缺失正文等无法猜测 | 隔离/未解决 |
|
||||
|
||||
### 8.4 Canonical fidelity 与 profiles
|
||||
|
||||
核心不应硬编码只有 `clean_fidelity.md` 和 `clean_compare.md`。更通用的方式是先生成 canonical fidelity
|
||||
document,再由 profile 派生:
|
||||
|
||||
| Profile | 目标 | 典型变化 |
|
||||
|---|---|---|
|
||||
| `fidelity` | 法律/业务忠实与可回源 | 只含确定性和源验证修复 |
|
||||
| `retrieval` | 搜索、RAG 和可读分块 | 规范段落、结构化 chunk、保留来源 |
|
||||
| `compare` | 相似度与模板分析 | 页眉页脚降噪、稳定图片 token、模板标注/降权 |
|
||||
| `public` | 可共享样例或外部处理 | 确定性伪名、图片/二维码脱敏、严格日志脱敏 |
|
||||
|
||||
未来项目可以增加自己的 profile;GovDoc 的章节模式、投标模板、compare 权重和中国政务字段放在插件/配置包,
|
||||
不能污染领域无关 core。
|
||||
|
||||
## 9. 建议的第一版产品边界
|
||||
|
||||
第一版不要一开始就做“全自动修复所有 Markdown”。建议逐层交付。
|
||||
|
||||
### M0:只读 audit
|
||||
|
||||
- 接受 Markdown;
|
||||
- 冻结哈希并解析 CommonMark/GFM/raw HTML 边界;
|
||||
- 输出 issue、source span、统计和阻断等级;
|
||||
- 覆盖编码、超长行、重复退化、链接/图片、标题、HTML/GFM 表格和 PII 候选;
|
||||
- 不改输入,不需要 PDF 模型。
|
||||
|
||||
这一阶段可以最早验证规则召回、误报、性能和审计 schema,不把修复风险混进来。
|
||||
|
||||
### M1:安全规范化
|
||||
|
||||
- 只执行严格确定性的 LF、NFC、尾空白、空标题等修复;
|
||||
- 每项变更有 source span 和 before/after hash;
|
||||
- 输出 fidelity Markdown、audit 和 unresolved;
|
||||
- 强制幂等、确定性和原输入不覆盖。
|
||||
|
||||
### M2:结构与回源
|
||||
|
||||
- raw HTML fragment 恢复和 table grid;
|
||||
- Docling source adapter;
|
||||
- 图片 asset store 与 manifest;
|
||||
- 页/区域级 re-extract;
|
||||
- 标题、列表、段落只在来源或高置信结构证据下恢复。
|
||||
|
||||
### M3:多用途 profile
|
||||
|
||||
- `retrieval`、`compare`、`public`;
|
||||
- privacy adapter;
|
||||
- 模板标注/权重和稳定实体/图片 token;
|
||||
- 各 profile 的差异可回链到 fidelity。
|
||||
|
||||
### M4:插件与规模化
|
||||
|
||||
- 稳定 rule/adapter/profile API;
|
||||
- 项目专属配置包;
|
||||
- 并行批处理、缓存、可恢复任务和机器可读报告;
|
||||
- 再评估 CLI、Python SDK、服务接口和跨语言消费。
|
||||
|
||||
## 10. 选型 spike 与验收建议
|
||||
|
||||
进入实现前建议建立下一份 design,并批准两个小型 spike。
|
||||
|
||||
### Spike A:Markdown/HTML 核心
|
||||
|
||||
使用脱敏合成 fixture 和审计列出的结构模式,比较:
|
||||
|
||||
- `markdown-it-py` + 自有 IR/renderer;
|
||||
- remark/mdast 作为对照;
|
||||
- html5lib 与 lxml recover 对损坏 table fragment 的差异。
|
||||
|
||||
至少覆盖:未闭合 table、GFM 多/少列、raw HTML 与 Markdown 交错、代码围栏内伪标签、超长行、中文硬换行、
|
||||
图片 URL、Word `_Toc`、标题断裂和多余转义。
|
||||
|
||||
验收关注:source span 完整率、round-trip 语义一致、没有静默 cell 丢失、幂等性、峰值内存和每 MiB 耗时。
|
||||
|
||||
### Spike B:回源提取
|
||||
|
||||
只在受控环境抽取 001、003 的风险分层页面,对 Docling、MinerU、Marker 做 A/B:
|
||||
|
||||
- 原文字符和关键实体准确率;
|
||||
- 表格网格、合并单元格和阅读顺序;
|
||||
- 图片数量、bbox 和 asset 引用;
|
||||
- 已知幻觉与重复退化命中;
|
||||
- CPU/GPU、耗时、峰值内存、模型版本和许可证约束。
|
||||
|
||||
不能只比较“生成的 Markdown 肉眼是否整齐”,也不能把某个引擎自己的置信度当作金标。
|
||||
|
||||
### 回归体系
|
||||
|
||||
- 公开/合成 fixture 进入 Git,复现结构问题但不包含客户原文;
|
||||
- 真实样本只在外部受控目录运行,以 case/file/page ID 和聚合指标报告;
|
||||
- P0 页面 100% 人工核对,其他页面风险分层抽样;
|
||||
- 金额、日期、项目编号、公司名、身份证候选做前后对账;
|
||||
- 每个 transformer 测幂等、确定性、边界和反例;
|
||||
- fidelity、retrieval、compare、public 分别验收,不能用单一“清洗率”。
|
||||
|
||||
## 11. 明确不建议的路线
|
||||
|
||||
- 不恢复旧版逐行正则清洗器作为默认基线;
|
||||
- 不对原文件直接运行 Prettier/mdformat 并覆盖;
|
||||
- 不用正则解析或补齐 HTML 表格;
|
||||
- 不把 parser 无报错当成 Markdown 正确;
|
||||
- 不对全文执行 `clean_extra_whitespace`、`clean_dashes`、全局 NFKC 或非 ASCII 删除;
|
||||
- 不因重复就删除合同条款,不因语言突变就自动删除段落;
|
||||
- 不用生成模型补写缺失文字、表格单元格或图片说明;
|
||||
- 不让不同实体、图片和缺失区域坍缩成同一个通用 token;
|
||||
- 不把某个 PDF 提取器的 Markdown 直接当权威真值;
|
||||
- 不把 GovDoc 的投标/采购规则写进通用 core。
|
||||
|
||||
## 12. 下一份 design 需要决定的事项
|
||||
|
||||
1. 是否批准“Python core + adapter/profile”方向;
|
||||
2. 第一阶段是否只做 Markdown audit,暂不引入 PDF/OCR 重依赖;
|
||||
3. 内部 IR 的最小字段和版本策略;
|
||||
4. audit/unresolved 的事件粒度与敏感信息保存边界;
|
||||
5. `fidelity`、`retrieval`、`compare`、`public` 哪些进入第一版;
|
||||
6. Markdown dialect 是 CommonMark + GFM,还是还要支持 frontmatter、math、directives;
|
||||
7. Docling/MinerU/Marker 的 benchmark 范围和许可证审查责任;
|
||||
8. 真实数据输出目录、保留周期、人工审核和脱敏规则;
|
||||
9. Python SDK、CLI、配置文件和插件 API 哪些属于首个可交付范围。
|
||||
|
||||
在这些事项获得批准前,本报告只代表调研判断,不代表依赖、schema 或产品行为已经确定。
|
||||
|
||||
## 13. 主要资料来源
|
||||
|
||||
本次优先使用官方文档、规范和上游仓库,GitHub 活跃度与许可证检查日期为 2026-08-20:
|
||||
|
||||
- [CommonMark 规范](https://spec.commonmark.org/0.31.2/)
|
||||
- [GitHub Flavored Markdown 规范](https://github.github.io/gfm/)
|
||||
- [markdown-it-py 文档](https://markdown-it-py.readthedocs.io/en/latest/)
|
||||
- [mdformat 文档](https://mdformat.readthedocs.io/en/stable/)
|
||||
- [remark](https://github.com/remarkjs/remark) 与 [mdast](https://github.com/syntax-tree/mdast)
|
||||
- [Pandoc filters](https://pandoc.org/filters.html)
|
||||
- [Docling](https://docling.org/) 与 [DoclingDocument](https://github.com/docling-project/docling/blob/main/docs/concepts/docling_document.md)
|
||||
- [Unstructured partition/cleaning](https://docs.unstructured.io/open-source/core-functionality/partitioning)
|
||||
- [html5lib](https://html5lib.readthedocs.io/en/stable/)
|
||||
- [ftfy](https://ftfy.readthedocs.io/en/latest/)
|
||||
- [Presidio](https://microsoft.github.io/presidio/)
|
||||
- [DataTrove](https://github.com/huggingface/datatrove)
|
||||
- [MinerU](https://github.com/opendatalab/MinerU)
|
||||
- [Marker](https://github.com/datalab-to/marker)
|
||||
- [MarkItDown](https://github.com/microsoft/markitdown)
|
||||
Reference in New Issue
Block a user