100 lines
5.8 KiB
Markdown
100 lines
5.8 KiB
Markdown
# 函数式修改核心如何工作
|
|
|
|
## 1. 它解决什么问题
|
|
|
|
项目规则如果直接返回一整篇新 Markdown,库无法确认它改了哪里,也无法在文本已经变化时阻止旧位置继续执行。
|
|
`mdpolish` 把三个职责分开:项目规则提出修改,库验证并在内存中执行,调用项目决定是否写回文件。
|
|
|
|
当前机制来自已批准的
|
|
[`0008-generic-functional-library-boundary.md`](../design/0008-generic-functional-library-boundary.md)。公共类名、字段和
|
|
函数签名以 [`src/mdpolish/`](../../src/mdpolish/) 和测试为准,本文只解释不变量与边界。
|
|
|
|
## 2. 当前数据流
|
|
|
|
```text
|
|
项目选择 Modifier、参数和顺序
|
|
│
|
|
▼
|
|
当前 Markdown 快照
|
|
│
|
|
▼
|
|
Modifier 提出精确修改 ──► 整批验证 ──► 内存中整批应用 ──► 新快照
|
|
│ │
|
|
└────────── 按项目给定顺序重复 ◄──────────┘
|
|
│
|
|
▼
|
|
最终只复查,不再应用
|
|
│
|
|
┌────────────────┼────────────────┐
|
|
▼ ▼ ▼
|
|
success unstable failed
|
|
```
|
|
|
|
| 层次 | 负责 | 不负责 |
|
|
| --- | --- | --- |
|
|
| 不可变数据模型 | 保存快照、范围、候选修改、实际改动、错误和结果 | 项目业务判断 |
|
|
| `Modifier` | 冻结身份、版本、参数、适用边界和提议函数 | 直接改变字符串或文件 |
|
|
| 修改执行器 | 校验并原子应用一个修改器批次 | 判断规则是否符合某个项目 |
|
|
| `Pipeline` | 按显式顺序运行修改器并做最终稳定性复查 | 自动选规则、文件读写和默认组合 |
|
|
|
|
`mdpolish` 不导入使用项目。项目可以使用正则工厂、通用内置修改器,也可以用普通函数建立自己的 `Modifier`。
|
|
|
|
## 3. 修改器拥有什么权限
|
|
|
|
修改函数接收不可变 `DocumentSnapshot`,返回一个 `ProposedChange` 元组。每项候选修改说明原因,并包含一条或多条
|
|
精确 `TextEdit`。修改器拥有规则判断权,可以提议插入、删除或替换,但不能通过公共契约原地改变快照,也不能用
|
|
整篇新文本绕过执行器。
|
|
|
|
`Modifier` 还保存稳定 ID、语义版本、冻结后的参数和适用边界。普通函数无需继承基类。相同输入、身份、版本和参数
|
|
应产生相同顺序的候选修改;修改函数不得读取文件、网络、环境变量、当前时间或随机数。
|
|
|
|
Python 不能沙箱隔离任意调用方函数。外部函数若私下写文件,属于绕过库契约的副作用,不在 `mdpolish` 的验证、
|
|
审计和回滚保证内。
|
|
|
|
## 4. 为什么修改必须绑定快照
|
|
|
|
每个快照都带有完整 Markdown 的 SHA-256。候选修改及其中每条编辑必须绑定这个哈希,并提供半开字符串范围、该范围
|
|
应有的原文和替换文本。执行器再次确认:
|
|
|
|
1. 哈希对应当前快照;
|
|
2. 范围没有越界;
|
|
3. 当前位置与预期原文完全一致;
|
|
4. 编辑不是无变化操作;
|
|
5. 当前修改器批次没有重复或冲突范围。
|
|
|
|
任意检查失败,当前修改器的整批候选都不执行。范围使用 Python 字符串索引,不是 UTF-8 字节位置;核心不会隐式
|
|
改变换行、Unicode 形式或末尾换行。
|
|
|
|
执行器从文本后方向前应用编辑,避免前面的修改使后面的下标失效;审计记录仍按原文位置排列。
|
|
|
|
## 5. `Pipeline` 的状态
|
|
|
|
`Pipeline` 先预检全部修改器及重复 ID,再按调用方顺序各运行一次。后一个修改器读取前一个修改器生成的新快照。
|
|
全部执行完成后,每个修改器对最终快照再提议一次,但复查阶段只验证,不应用,也不会自动开始第二轮。
|
|
|
|
| 状态 | 含义 | 文本字段 |
|
|
| --- | --- | --- |
|
|
| `success` | 运行和复查均完成,所选修改器不再提出修改 | `output_markdown` |
|
|
| `unstable` | 运行无错误,但最终快照仍有有效候选修改 | `partial_markdown` |
|
|
| `failed` | 提议、契约或执行验证发生错误 | `partial_markdown` |
|
|
|
|
`success` 只说明调用方选择的这组修改器在这次输入上已经稳定,不说明文档不存在其他质量问题。库只返回内存结果;
|
|
调用项目检查状态后,自己决定是否保存。
|
|
|
|
## 6. 当前通用能力与边界
|
|
|
|
除了核心,当前包只提供:
|
|
|
|
- `build_review_document()` / `render_markdown_report()`:验证已有结果并生成内存评审视图或 Markdown 报告字符串;
|
|
- `regex_replace()`:把非空正则匹配转换为精确编辑;
|
|
- `mapped_line_join()`:按调用方映射合并跨行片段,库不附带词表;
|
|
- `html_table_entity_unescape()`:在严格表格单元格文本中解除一层受支持的实体转义;
|
|
- `html_table_layout()`:把严格单行 HTML 表格展开为每行一个表格行。
|
|
|
|
HTML 能力使用失败关闭的词法子集,不是完整 HTML parser,也不识别 Markdown 围栏。正则工厂只保证定位和执行契约,
|
|
不保证调用方正则的业务语义正确。
|
|
|
|
当前没有默认流水线、文件适配器、CLI、profile、配置加载、批处理、artifact、报告文件、Web/桌面评审器或项目规则集。
|
|
安装或导入库不会自动修改任何文本。评审投影的重放机制与边界见 [`review-projection.md`](review-projection.md);实际安装、
|
|
示例和当前检查命令只以根目录 [`README.md`](../../README.md) 为准。
|