feat: export core Hermes skills

This commit is contained in:
2026-07-15 02:45:56 +00:00
parent a028b63eda
commit 54711fee2a
308 changed files with 41310 additions and 1 deletions
@@ -0,0 +1,62 @@
# 法律文书:脚注、同源模板成稿、Doro 编辑后字体修复
contract-editor 库(zipfile+lxml)在**新成稿文书**(非修订态)上的复用。2026-06-23-24 邹家《情况反映》制作中验证。配套 `litigation-doc-tracked-changes.md`(那篇讲修订态;本篇讲脚注+新建文书+字体规范化,都不是 tracked-changes)。
## 1. 法条原文脚注——从同案"姊妹文书"克隆脚注样式(铁律:脚注样式不要凭空造)
需求场景:Doro 把正文里的法条引用("《民事诉讼法》第七十一条之规定")要求改成**脚注呈现法条全文**,且"脚注格式和申请书一样"。
正确做法是从**同案已有带脚注的文书**(如同目录的《民事诉讼监督申请书》v9)克隆脚注体例,而不是自己拼 footnotes.xml:
**脚注的两个组成**(先从姊妹文书读出样式模板):
- 正文里的**引用标**:一个 `<w:r>`,rPr 带 `<w:rStyle w:val="affb"/>` + Times New Roman + 与正文同字号(sz24),内含 `<w:footnoteReference w:id="N"/>``affb` 是 Word 默认的 FootnoteReference 字符样式 id(不同文档可能不同,**从姊妹文书正文的 footnoteReference 承载 run 实测,别硬编码**)。
- footnotes.xml 里的**脚注正文**:separator/continuationSeparator 两个特殊脚注(id=-1/0,原样复制)+ 内容脚注(id≥1)。内容脚注段落 spacing line=240,run 字号是**脚注体例 sz18(9pt,小于正文)**,法名加粗(`<w:b/>`)、条号与原文不加粗。
```python
# 从姊妹文书 sqs_v9.docx 取模板
fn_sqs = etree.fromstring(z_sqs.read('word/footnotes.xml'))
special = {ft: deepcopy(f) for f in fn_sqs.iter(qn('footnote'))
for ft in [f.get(qn('type'))] if ft in ('separator','continuationSeparator')}
content_tmpl_p = deepcopy([f.find(qn('p')) for f in fn_sqs.iter(qn('footnote'))
if f.get(qn('id'))=='1'][0])
# 从模板段落抽三种 rPr:mark(带rStyle affb)、bold(法名)、plain(原文)
# 正文引用标 rPr 则从姊妹文书 document.xml 里 footnoteReference 承载 run 抓
```
**目标 docx 必须已支持脚注**`word/_rels/document.xml.rels` 有 footnotes 关系、`[Content_Types].xml``footnotes+xml`、styles.xml 有 `affb` 样式。若目标是从同源文书演化来的(本例情况反映以申请书为母版),这三样天然齐全;若从零新建则要补。
## 2. 脚注标定位的坑:锚点跨 run 时 footnoteReference 会插错位置(本会话实犯)
把脚注标插在"第五十一条第二款"之后时,第一版用"找锚点子串→定位锚点所在 run→run 后插标",结果 ³ 插到了下游的"承办部门"后面——因为锚点文字**跨多个 run**,按 run 粒度定位会落到错误的 run。
**正解:字符流定位 + 必要时拆 run**。把全段所有 `w:t` 拼成字符流,建立 `每个字符→(t元素, 字符在t内的索引)` 映射,找到锚点**结束字符**的精确位置;若结束字符在某 run 中间,**split 该 run**(head 留原 run,tail 进新 run),脚注引用 run 插在 head 和 tail 之间。这样标精确落在"…第二款【标】所定…"。
验证只能靠 OnlyOffice x2t 渲染后看页脚——vision 一眼就抓出"³ 标在承办部门后",肉眼读 XML 容易漏。体例统一:四个脚注一律"法条号正后方"挂注(不要有的挂句末有的挂条号后)。
## 3. 用同案文书做"母版"新建文书——保证两份同源同体例
新建《情况反映》时,以同案《民事诉讼监督申请书》v9 为母版克隆,确保字体/字号/页边距/样式完全一致(Doro/Maggie 两份并排看不会有体例差):
- 从母版抽各类段落模板:title(居中bold sz30)、body(首行缩进480 sz24)、recip(顶格bold 机关名)、sign(右对齐)、date、attachment-title、attachment-item。`mk(tmpl_key, text, bold=, no_indent=)` 克隆模板段→清空 run/numPr/ins/del→重设仿宋+Times→填文字。
- 用母版的整个 docx 做容器(保留 sectPr 页面设置、styles、numbering),只重写 body 的段落序列 + 清掉 `<w:trackRevisions/>`
- **清掉母版页眉**:母版页眉可能是另一种文书的抬头(本例申请书页眉"申请监督案号/受理法院"套在情况反映上不对)。清页眉要两步:①删页眉段所有 run 文字;②**删页眉段 pPr 的 `<w:pBdr>`**(页眉那条横线来自段落下边框,只删文字会留一条孤线)。OnlyOffice 渲染确认顶部纯白到标题。
## 4. ⚠️Doro 用编辑器改过的 docx 会丢显式 eastAsia 字体属性——每轮都要补(本会话两轮各犯一次)
**现象**:Doro 在他本机编辑器改过 docx 后回传,正文中文 run 的 `rFonts` **没有显式 eastAsia 字体名**(本会话两轮分别 1283、1243 个中文字符 `eastAsia=None`,docDefaults 也空)。OnlyOffice 靠底层回退仍渲染成仿宋、肉眼看正常,但**显式字体属性缺失不符合交付标准**(我们要求中文显式仿宋)。
**判别**:交付前扫一遍——
```python
for r in root.iter(qn('r')):
rf = r.find(qn('rPr/rFonts'))
ea = rf.get(qn('eastAsia')) if rf is not None else None
# 统计含中文 run 里 ea is None 的数量;>0 就要补
```
**修复(格式规范化,不改字形/文字/Doro 内容)**:每个含文字的 run,rFonts 显式设 `eastAsia=仿宋`,缺 ascii/hAnsi 的补 `Times New Roman`;再给 `docDefaults/rPrDefault/rPr/rFonts``eastAsia=仿宋` 兜底。改完目标:CJK 全仿宋、英数全 Times。**这是和合同字体规范化同类的操作,但要点在"每次 Doro 回传都要重做一遍"**——他的编辑器每改一次就再剥一次,不是一次性问题。改完必须 OnlyOffice 重渲染确认无字形回退(字体属性动过就要重验)。
## 5. 附件/正文 Doro 自己加的内容:修错别字但不擅改实质
Doro 自己在附件加了"检查监督申请书"——①错别字"检**查**"→"检**察**"院的监督,规范名应是与正式文件名一致的《民事诉讼监督申请书》(改);②但若附件项之间有实质区分缺失(如两份《质证通知书》一份标了"3日期限版"另一份没标"15日期限版"),那是 Doro 定的内容,**只提示不擅改**。附件清单常是自动编号(numId),Doro 删手敲序号是对的,自动会续 1-6。
## 一句话
脚注从同案姊妹文书克隆样式(rStyle affb + sz18 脚注体、法名加粗)、标位置用字符流+拆run精确落在条号后;新建文书拿同案文书做母版保同源(清页眉含删 pBdr);**Doro 编辑器回传的 docx 每轮都丢显式 eastAsia,每次交付前都要全局补仿宋再渲染**。