7.9 KiB
诉讼文书的修订态技法(contract-editor 库在合同以外文书上的复用)
ContractEditor 库不止用于合同——审/改诉讼文书(监督申请书、起诉状、答辩状等)同样适用。本文记录 2026-06-23 邹家民事诉讼监督申请书审改中验证过的几招,都用 OnlyOffice x2t(Doro/Maggie 实际引擎)渲染核对过。
1. 大段改写用「整块 del+ins」,不用字符级 diff(markup 可读性铁律)
tracked_replace 是字符级 diff(CJK 每字一 token + difflib)——补字/小改(错别字、补一个"在"字、称谓换词)用它,markup 干净。
但大段改写(整句重写、换论证)若用字符级 diff,新旧文本大量字符重合,markup 会交错成一团("未经及法庭审理""一百二十八条切国家机关"),Doro 在 OnlyOffice 看修订态根本读不下去。接受修订后的最终文本虽正确,但修订态不可读 = 不合格交付(Doro 有格式洁癖,看的就是 markup)。
- 正解:对整句/整段改写,做「整块删 + 整块插」——
[<w:del>旧整句</w:del>][<w:ins>新整句</w:ins>],markup 显示为一条删除线旧句紧跟一条下划线新句,清清楚楚。 - 实现:复制
tracked_replace的定位逻辑,但不跑 difflib,直接_mk_del(old_text)+_mk_ins(new_text)整块插。判据:新旧文本相似度高、改动跨度大 → 整块;纯增删几个字 → 字符级。
2. 称谓/词替换也要整词块替换,别让共享字符碎裂
把"法庭"改"莲都法院"时,"法"字共享,字符级 diff 会渲染成"莲都法庭院"(接受后对,markup 脏)。
- 正解:整词
tracked_block_replace("本案法庭向申请人送达", "莲都法院向申请人送达")→ markup 是干净的[删旧短语][插新短语]。 - 同理坑:替换前先分类全文每处目标词——actor 指代(要改)vs 法条/术语原文(如"法庭审理""在法庭上出示"=不能动)。grep 出所有命中,逐个判,别一刀切 replace_all。
3. 整段删除(让自动编号重排)——库没有,需自加 tracked_delete_paragraph
合并两个自动编号请求项(删一项、后项自动续号)时,要的是段落级修订删除:段内每个 run 包进 <w:del>,且段落标记也要标删——在 pPr/rPr 里插一个 <w:del>。这样接受修订后整段连段落标记一起消失,自动编号从 一二三四 重排成 一二三。
def tracked_delete_paragraph(self, search_text):
p = self.find_para(search_text)
for r in list(p.findall(qn('r'))):
# 每个run的w:t搬进新建<w:del><w:r><w:delText>
...
ppr = p.find(qn('pPr')) or 新建
rpr = ppr.find(qn('rPr')) or 新建
rpr.insert(0, <w:del author=... date=...>) # 段落标记删除标记
缺了"段落标记删除"那一步,接受后会残留一个空的编号项。
4. 半角括号→全角:改 numbering.xml 的 lvlText,一次性根治
子标题 (一)(二)… 是自动编号时,半角括号来自 word/numbering.xml 里 <w:lvlText w:val="(%1)">。逐段改文档没用(那是渲染出来的)。
- 正解:遍历 numbering.xml 所有
<w:lvlText>,val里的(→(、)→),一次改全文所有同源编号。本例 37 处 lvlText 一次改完。 - 注意只动含
()的 lvlText,、分隔的(如请求"一、二、三"用%1、)不受影响。
5. 引号"统一为仿宋全角"——根因是引号 run 的字体不是中文字体
现象:正文中文是仿宋(继承样式),但弯引号 “”(U+201C/U+201D) 的 run ascii=Times New Roman, eastAsia=None。因为弯引号是中西文模糊字符,OnlyOffice 对没有 eastAsia 设定的字符按 ascii 字体渲染 → 引号显示成西文 Times 的粗重样式,和仿宋正文不协调。
- 正解(彻底版):对纯引号/中文 run,把 rFonts 的
ascii/eastAsia/hAnsi/cs全设为「仿宋」+hint="eastAsia",消除歧义。对引号+数字混排 run(如“2026…),按字符拆 run:引号段走仿宋、数字段保留 Times New Roman。 - 只设 eastAsia 不够稳——某些渲染下仍可能按 ascii 走 Times。纯引号 run 连 ascii 一起设仿宋最保险(数字 run 才需要保留 Times)。
- 核对:OnlyOffice x2t 渲染后裁剪含引号区域,确认引号纤细、与仿宋协调(不是又粗又重的衬线引号)。
6. 验证三件套(同合同终审,文书一样适用)
ed.validate()返回空。注意:诉讼文书的「请求项」原文常是加粗的(与合同正文不加粗体例不同),validate 的"不应加粗"规则会误报——先读原文该段普通 run 的<w:b>状态,若原文请求项本就加粗、INS 继承同样加粗=格式一致=误报,可放行。- 逐个
w:ins核 author 正确(诉讼文书署当前文书归属人,如本例 Doro 文书上署"小Maggie"修订;合同历史署"WB"——按文书归属定)、eastAsia 字体不缺。 - OnlyOffice x2t 渲两版:修订态(看 markup 干净)+ 接受态(删 w:del、解包 w:ins、删段落标记被删的空段后重渲,看编号连续、全角括号生效、无乱码)。接受态自己生成:解包所有 ins、删所有 del、删 numPr 空段。
一句话
合同库的修订能力对所有 docx 文书通用;诉讼文书审改的差异点是:①大改写要整块 del+ins 保 markup 可读 ②引号/括号这类「字体/编号源」问题改 styles/numbering 层不改文档层 ③validate 加粗规则对加粗请求项会误报。
7. 接受所有修订 → 干净版 docx(反向操作,2026-06-24 徐函任务验证)
用户给一份带修订痕迹+批注的 docx,要「先接受现有修订、让我看干净版本」时——不是用 Word 手点"接受全部",用 zipfile+lxml 一次处理:
W='http://schemas.openxmlformats.org/wordprocessingml/2006/main'
def w(t): return f'{{{W}}}'+t
# 1) w:del → 整个元素删掉(连 delText 一起没)
for d in root.findall('.//'+w('del')): d.getparent().remove(d)
# 2) w:ins → 解包:用其子元素替换它本身(保留插入内容,去掉ins包裹)
for ins in root.findall('.//'+w('ins')):
parent=ins.getparent(); idx=list(parent).index(ins)
for child in reversed(list(ins)): parent.insert(idx, child)
parent.remove(ins)
# 3) 属性变更追踪一并清:pPrChange/rPrChange/sectPrChange/tblPrChange/tcPrChange/trPrChange
for tag in ('pPrChange','rPrChange','sectPrChange','tblPrChange','tcPrChange','trPrChange'):
for el in root.findall('.//'+w(tag)): el.getparent().remove(el)
# 4) 批注三处一起拆(用户要"干净版"= 连批注也清):
# document.xml: 删 commentRangeStart/End,删含 commentReference 的整个 run
# settings.xml: 删 <w:trackRevisions/>(让文件退出跟踪模式)
# 打包时跳过 word/comments*.xml,并从 [Content_Types].xml 和 document.xml.rels 删 comments 的 Override/Relationship
要点:
- w:del 删整块、w:ins 解包——方向别搞反(del 是要丢弃的,ins 是要保留的)。
- 务必清 settings.xml 的 trackRevisions,否则文件仍处于"跟踪修订"模式,用户继续编辑会又开始记修订。
- 批注要三处协同删(comments.xml 本体 + document.xml 的 range/reference 锚点 + Content_Types/rels 注册),漏一处 OnlyOffice/Word 打开可能报损坏。
- 验证:解包后
root.findall('.//w:ins')/w:del/w:commentReference全为 0;'word/comments.xml' in zip.namelist()为 False;python-docx 能打开;OnlyOffice x2t 渲染核对无修订痕迹无批注无错位。 - vision 核干净版时顺带抓残留内部标记:黄色高亮(内部校对标记)、留白占位(编号"第 号"、日期" 日")、标题英文双连字符
--应为中文破折号————这些不是修订痕迹但属"未清的内部审核稿"特征,正式交付前要清。