feat: 增加项目无关的本地清洗评审器
This commit is contained in:
@@ -3,10 +3,9 @@
|
||||
`mdpolish` 是实验室共用的、项目无关的 Python Markdown 修改库。它提供函数式 `Modifier`、精确文本编辑执行器、
|
||||
有序 `Pipeline`、正则修改器工厂,以及少量可以用合成样例完整说明的通用修改器。
|
||||
|
||||
当前发布版本是 [`v0.6.0`](https://github.com/Bepr4/mdpolish/releases/tag/v0.6.0),当前工作树候选版本是尚未发布的
|
||||
`0.6.1`。库只处理内存中的 Markdown 字符串,
|
||||
不读取或写入文件,不提供默认流水线,也不包含任何项目的规则集合、
|
||||
数据清单、实验脚本或评审界面。
|
||||
当前发布版本是 [`v0.7.0`](https://github.com/Bepr4/mdpolish/releases/tag/v0.7.0)。清洗核心只处理内存中的 Markdown
|
||||
字符串,不读取或写入文件,不提供默认流水线,也不包含任何项目的规则集合、数据清单或实验脚本。安装包另外提供一个
|
||||
必须显式启动的本地只读评审器,用来展示项目已经保存的正式 `full` review JSON;它不替项目运行清洗或管理产物。
|
||||
|
||||
## 当前能力
|
||||
|
||||
@@ -19,6 +18,8 @@
|
||||
| `render_markdown_report()` | 把评审视图编排成完整 Markdown 源码报告字符串 | 只返回内存字符串,不创建文件或业务页面 |
|
||||
| `review_document_to_dict()` | 按 schema `1.0` 把评审视图投影成普通 JSON 基本值 | 单向投影,不反序列化或重新应用修改 |
|
||||
| `render_json_report()` | 复用正式 dict 投影生成确定的内存 JSON 字符串 | 不创建文件;默认摘要不等于公开安全日志 |
|
||||
| `parse_json_report()` | 解析并校验正式 review JSON;`full` 会验证哈希、阶段链和 Change 重放 | 不恢复 `ReviewDocument`,不接收路径 |
|
||||
| `mdpolish-reviewer` | 在回环地址展示一个明确目录中的 `full` JSON | 只读,不运行 Pipeline,不提供业务审核流程 |
|
||||
| `mdpolish.text_ranges` | 返回 CR/LF/CRLF 物理行的精确不可变原文范围 | 不解析 Markdown 块,不自动执行或修改文本 |
|
||||
| `regex_replace()` | 把非空正则匹配转换为精确编辑 | 不提供规则注册表、配置加载或默认模式 |
|
||||
| `mapped_line_join()` | 用精确、正则或可选本地词典规则合并跨行片段 | 无默认规则;代码、表格、未知结构和歧义失败关闭 |
|
||||
@@ -38,15 +39,15 @@
|
||||
不可移动的 tag:
|
||||
|
||||
```bash
|
||||
python -m pip install 'mdpolish @ git+https://github.com/Bepr4/mdpolish.git@v0.6.0'
|
||||
python -m pip install 'mdpolish[lexical] @ git+https://github.com/Bepr4/mdpolish.git@v0.6.0'
|
||||
python -m pip install 'mdpolish[frequency] @ git+https://github.com/Bepr4/mdpolish.git@v0.6.0'
|
||||
python -m pip install 'mdpolish @ git+https://github.com/Bepr4/mdpolish.git@v0.7.0'
|
||||
python -m pip install 'mdpolish[lexical] @ git+https://github.com/Bepr4/mdpolish.git@v0.7.0'
|
||||
python -m pip install 'mdpolish[frequency] @ git+https://github.com/Bepr4/mdpolish.git@v0.7.0'
|
||||
```
|
||||
|
||||
也可以安装同一 GitHub Release 附带的 wheel:
|
||||
|
||||
```bash
|
||||
python -m pip install 'mdpolish[lexical] @ https://github.com/Bepr4/mdpolish/releases/download/v0.6.0/mdpolish-0.6.0-py3-none-any.whl'
|
||||
python -m pip install 'mdpolish[lexical] @ https://github.com/Bepr4/mdpolish/releases/download/v0.7.0/mdpolish-0.7.0-py3-none-any.whl'
|
||||
```
|
||||
|
||||
Release 页面同时提供 wheel 的 SHA-256 校验值。仓库或 Release 如果是私有的,调用方需要自行配置 GitHub 访问权限;
|
||||
@@ -57,7 +58,8 @@ python -m venv .venv
|
||||
.venv/bin/python -m pip install -e '.[dev]'
|
||||
```
|
||||
|
||||
核心运行时只依赖 Python 标准库,支持 Python 3.11 及以上版本。自动词典规则需要调用方明确安装并选择对应 extra:
|
||||
核心和本地评审服务的 Python 运行时只依赖标准库,支持 Python 3.11 及以上版本。React 和 CodeMirror 已编译为 wheel
|
||||
内的静态资源,使用评审器不需要 Node.js。自动词典规则需要调用方明确安装并选择对应 extra:
|
||||
|
||||
```bash
|
||||
python -m pip install '/path/to/mdpolish[lexical]' # pyspellchecker + Pyphen
|
||||
@@ -163,8 +165,9 @@ if result.status is RunStatus.SUCCESS and result.output_markdown is not None:
|
||||
output_path.write_text(result.output_markdown, encoding="utf-8")
|
||||
```
|
||||
|
||||
文件读取、输出命名、覆盖策略、批处理和 CLI 都属于调用项目。`mdpolish` 可以生成通用的内存评审视图、机器投影、JSON
|
||||
字符串与 Markdown 报告字符串,但不会自动保存它们,也不知道报告来自哪个文件。
|
||||
清洗输入发现、输出命名、覆盖策略和批处理仍属于调用项目。`mdpolish` 可以生成通用的内存评审视图、机器投影、JSON
|
||||
字符串与 Markdown 报告字符串,但不会自动保存它们,也不知道报告来自哪个文件。唯一通用 CLI 是下面的只读评审器;它只
|
||||
消费调用方已经保存的正式 JSON,不承担项目文件适配。
|
||||
|
||||
## 构建内存评审视图和报告
|
||||
|
||||
@@ -173,6 +176,7 @@ if result.status is RunStatus.SUCCESS and result.output_markdown is not None:
|
||||
```python
|
||||
from mdpolish.review import (
|
||||
build_review_document,
|
||||
parse_json_report,
|
||||
render_json_report,
|
||||
render_markdown_report,
|
||||
review_document_to_dict,
|
||||
@@ -185,11 +189,13 @@ review = build_review_document(input_markdown, result)
|
||||
review_summary = review_document_to_dict(review)
|
||||
report_json = render_json_report(review, detail="changes")
|
||||
report_markdown = render_markdown_report(review)
|
||||
parsed_report = parse_json_report(report_json, expected_detail="changes")
|
||||
|
||||
assert review.current_markdown == "an example text"
|
||||
assert review_summary["schema_version"] == "1.0"
|
||||
assert review_summary["detail"] == "summary"
|
||||
assert report_json.startswith('{\n "schema_name": "mdpolish.review"')
|
||||
assert parsed_report["status"] == "success"
|
||||
assert report_markdown.startswith("# mdpolish review report\n")
|
||||
```
|
||||
|
||||
@@ -210,9 +216,51 @@ Markdown reporter 会包含完整输入、当前全文、统一 diff 以及实
|
||||
- `full`:再加入完整输入、当前全文和每个阶段的完整前后全文。
|
||||
|
||||
高 detail 可能还原敏感内容。即使 `summary` 不含正文,它仍然携带项目元数据和哈希,不能自动视为匿名或适合公开传播。
|
||||
dict 和 JSON 都是单向派生视图,不用于恢复 `ReviewDocument` 或重新应用修改。完整 schema、坐标、哈希和兼容口径见
|
||||
dict 和 JSON 都是单向派生视图,不用于恢复 `ReviewDocument` 或重新应用修改。`parse_json_report()` 返回新的普通 dict/list
|
||||
容器;对 `full` 会验证全文哈希、阶段首尾,并用核心共用的精确编辑原语证明每个 stage after 确实由所列 Change 产生。
|
||||
完整 schema、坐标、哈希和兼容口径见
|
||||
[`review-projection-schema-v1.md`](research-wiki/reference/review-projection-schema-v1.md)。
|
||||
|
||||
## 使用本地评审页面
|
||||
|
||||
项目先把每份评审结果显式保存为直属的 `*.review.json`。页面需要完整输入、当前文本和所有 Modifier 阶段,因此必须使用
|
||||
`detail="full"`:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
from mdpolish.review import build_review_document, render_json_report
|
||||
|
||||
review = build_review_document(input_markdown, result)
|
||||
review_path = Path("artifacts/reviews/example.review.json")
|
||||
review_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
review_path.write_text(
|
||||
render_json_report(review, detail="full") + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
```
|
||||
|
||||
文件路径、目录创建、权限、Git 忽略、覆盖和保留周期都属于项目。`full` JSON 重复包含完整文档和阶段全文,不能当作安全日志
|
||||
或公开产物。
|
||||
|
||||
然后显式启动只读页面:
|
||||
|
||||
```bash
|
||||
mdpolish-reviewer --review-dir artifacts/reviews
|
||||
```
|
||||
|
||||
也可以使用等价模块入口:
|
||||
|
||||
```bash
|
||||
python -m mdpolish.reviewer --review-dir artifacts/reviews
|
||||
```
|
||||
|
||||
命令默认绑定 `127.0.0.1` 的系统空闲端口,并打印本机 URL。页面可以选择文档和 Modifier,比较完整 before/after,保留
|
||||
零修改阶段,并通过 Change 列表跳转。服务只读取所给目录直属的 `*.review.json`,不递归、不跟随符号链接、不运行
|
||||
Pipeline,也不渲染原文中的 Markdown、HTML、图片或脚本。文件名去掉 `.review.json` 后只是页面标签,不会被解释成输入
|
||||
路径或业务文档 ID。完整操作与排障见
|
||||
[`use-local-reviewer.md`](research-wiki/guides/use-local-reviewer.md)。
|
||||
|
||||
## 扫描精确物理行
|
||||
|
||||
项目 Modifier 如果需要识别独占行、检查相邻行或连同行尾删除一行,可以按原文 code point 范围扫描:
|
||||
@@ -307,10 +355,14 @@ src/mdpolish/
|
||||
├── modifier.py # 函数式 Modifier 契约
|
||||
├── edits.py # 批次验证与原子应用
|
||||
├── pipeline.py # 有序执行与最终稳定性复查
|
||||
├── review.py # 可信评审视图、机器投影及内存 JSON/Markdown reporter
|
||||
├── review.py # 可信评审视图、机器投影、JSON reader 及内存 reporter
|
||||
├── _review_json.py # 正式 JSON 的私有解析和 full 语义校验
|
||||
├── reviewer.py # 本地只读服务和公共 CLI
|
||||
├── _reviewer_static/ # wheel 内的页面 bundle 与第三方许可证
|
||||
├── regex.py # 正则修改器工厂
|
||||
├── text_ranges.py # 公共精确物理行范围
|
||||
└── modifiers/ # 少量项目无关的通用修改器
|
||||
reviewer/ # React/TypeScript 源码、锁文件与合成界面测试
|
||||
tests/ # 只使用虚构文本的核心与通用修改器测试
|
||||
research-wiki/
|
||||
├── design/ # 已批准决策及被冻结的历史记录
|
||||
@@ -322,10 +374,10 @@ research-wiki/
|
||||
|
||||
## 当前不提供
|
||||
|
||||
- 文件适配器、公共 CLI、配置文件、profile 或批处理协议;
|
||||
- 清洗文件适配器、清洗 CLI、配置文件、profile 或批处理协议;
|
||||
- 自动规则发现、注册表或默认流水线;
|
||||
- Markdown AST、完整 HTML parser 或必装的第三方运行依赖;
|
||||
- artifact、自动保存的报告文件、正式 JSON Schema 文件、HTML reporter、Web/桌面评审器或项目审核流程;
|
||||
- artifact、自动保存的报告文件、正式 JSON Schema 文件、远程/桌面评审器或项目审核流程;
|
||||
- 任何业务项目的规则、固定参数、文档 ID、数据或验收统计。
|
||||
|
||||
公共边界与原因见
|
||||
@@ -337,6 +389,8 @@ research-wiki/
|
||||
查询口径见 [`review-projection-schema-v1.md`](research-wiki/reference/review-projection-schema-v1.md)。精确物理行公共接口的边界见
|
||||
[`0013-public-physical-line-ranges.md`](research-wiki/design/0013-public-physical-line-ranges.md),稳定查询口径见
|
||||
[`physical-line-ranges.md`](research-wiki/reference/physical-line-ranges.md)。旧 design 只保存历史决策,不代表当前交付能力。
|
||||
项目无关本地评审器的批准边界见
|
||||
[`0014-generic-local-reviewer.md`](research-wiki/design/0014-generic-local-reviewer.md)。
|
||||
|
||||
## 当前可用检查
|
||||
|
||||
@@ -349,6 +403,16 @@ research-wiki/
|
||||
.venv/bin/python -m pip wheel . --no-deps --wheel-dir /tmp/mdpolish-wheel-check
|
||||
```
|
||||
|
||||
修改前端源码或依赖时,再在 Node.js 24 环境中运行:
|
||||
|
||||
```bash
|
||||
cd reviewer
|
||||
nvm use 24
|
||||
npm ci
|
||||
npm run check
|
||||
cd ..
|
||||
```
|
||||
|
||||
检查本地变更:
|
||||
|
||||
```bash
|
||||
@@ -356,27 +420,21 @@ git diff --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
上述检查已于 2026-08-27 实际运行。Python 3.13.11 核心开发环境中 Ruff 和 mypy 通过,pytest 为
|
||||
`211 passed, 3 skipped`;三个 skip 是该环境没有安装的真实 optional backend 路径,不计入发布验收。
|
||||
上述检查已于 2026-08-28 对 `v0.7.0` 实际运行。Python 3.13.11 开发环境中 Ruff 和 mypy 通过;未安装可选 backend 时
|
||||
pytest 为 `330 passed, 3 skipped`,三个 skip 分别对应真实 lexical 和 frequency backend 路径。
|
||||
|
||||
`mdpolish-0.4.0-py3-none-any.whl` 共 17 个文件,包含 `review.py` 和 `py.typed`,不包含 tests、Wiki、artifact、页面或
|
||||
真实数据。安装全部 extras 后,Python 3.11.16 和 Python 3.13.11 环境分别得到 `214 passed`,没有 skip;仓库外消费者
|
||||
smoke test 已覆盖核心正则、`pyspellchecker + Pyphen`、`wordfreq`、评审视图和 Markdown reporter。核心运行依赖仍只有
|
||||
Python 标准库。Release wheel 的 SHA-256 是
|
||||
`12e24863314958130ed082f78e89ab8bc0dad39a3848f2ae42e273d19a409693`。
|
||||
Node.js 24.19.0、npm 11.17.0 环境中,`npm ci` 未发现漏洞,ESLint、TypeScript、8 项 Vitest 和 Vite 生产构建通过。
|
||||
生产 bundle 随 wheel 提供;普通使用者不需要 Node.js,页面运行时不从 CDN 下载资源。24 份生产依赖许可证文本和版本清单
|
||||
已随 bundle 收录。
|
||||
|
||||
上述结果证明当前版本可安装并按合成契约运行,不代表任意词典阈值已经在真实业务语料上达到生产准确率。
|
||||
同一个 Release wheel 在全新 Python 3.11.16 和 Python 3.13.11 环境中安装全部 extras 后,分别得到 `333 passed`,没有
|
||||
skip;导入路径均确认来自环境的 `site-packages`。另一全新环境只安装 wheel、未安装第三方运行依赖,已实际完成 full JSON
|
||||
生成、console script 与模块入口启动、集合/文档/Modifier API、UTF-16 定位和静态页面资源 smoke test。
|
||||
|
||||
`v0.6.0` 于 2026-08-28 在 Python 3.13.11 开发环境中实际得到:Ruff 和 mypy 通过,pytest 为
|
||||
`290 passed, 3 skipped`;三个 skip 仍是没有安装的 optional backend。
|
||||
`mdpolish-0.7.0-py3-none-any.whl` 压缩后为 315,279 bytes,共 49 个文件;解压后为 961,976 bytes,其中 29 个页面与许可证
|
||||
文件为 742,678 bytes。相对未发布的 `0.6.1` 候选增加 32 个文件和 274,510 bytes 压缩体积。wheel 不包含 tests、Wiki、
|
||||
`node_modules`、source map、真实报告、项目规则或数据。Release wheel 的 SHA-256 是
|
||||
`b81a9a07fa0479854cd21d5a65f0f485cadf2031b5d731c3658ca10a1d72dc09`。
|
||||
|
||||
Release wheel `mdpolish-0.6.0-py3-none-any.whl` 共 17 个文件,包含 `text_ranges.py`、`review.py` 和 `py.typed`,不包含
|
||||
`_text_ranges.py`、tests、Wiki、报告或真实数据;在仓库外全新虚拟环境中无依赖安装后,版本、公共导入、精确混合行尾范围、
|
||||
行尾集合、空行判断和 wheel 清单 smoke test 通过。Release wheel 的 SHA-256 是
|
||||
`695502b1a443d4e98dbf63e8bdcee59452baea2185cb7e1e13160127f70c920f`。
|
||||
|
||||
尚未发布的 `0.6.1` 候选修复了严格 HTML 表格扫描在未闭合或无法解析的外层 `<table>` 中继续处理完整内层表格的问题;
|
||||
两个 HTML Modifier 的版本均为 `1.0.1`。2026-08-28 在 Python 3.13.11 开发环境中 Ruff 和 mypy 通过,pytest 为
|
||||
`294 passed, 3 skipped`。安装候选 wheel 的全部 extras 后,Python 3.11.15 和 Python 3.13.11 环境分别得到
|
||||
`297 passed`,没有 skip。候选 wheel 共 17 个文件并通过内容检查,SHA-256 是
|
||||
`f628658a6d0b2860720e9425d190a477b78723dcda9b2d4b5a5e9f6e252faf07`。
|
||||
自动检查不能替代真实浏览器中的最终视觉、长文滚动和跨 Modifier 跳转人工确认。上述结果只证明当前版本可安装并按合成契约
|
||||
运行,不代表任意清洗规则已经在真实业务语料上达到生产准确率。
|
||||
|
||||
Reference in New Issue
Block a user