# Workflow INS Format Repair — ContractEditor Font Contamination Pattern ## 2026-07-13 洋励/安全生产/消防设施检测 连续验证 ### 问题根因 ContractEditor库在处理文档时会**污染原文runs**——给原本没有显式属性的runs添加`eastAsia`、`cs`、`sz`。 典型对比: ``` 原文(待审查): rFonts={ascii=宋体, hAnsi=宋体, hint=eastAsia}, szCs=21, NO sz, NO eastAsia v1中orig runs: rFonts={ascii=宋体, hAnsi=宋体, hint=eastAsia, cs=宋体, eastAsia=宋体}, szCs=21, sz=21 v1中WB INS: rPr=空 (什么属性都没有) ``` **后果**: 1. 原文字号从继承docDefaults(如sz=22=11pt)变为显式sz=21(10.5pt)——整体缩小0.5pt 2. INS runs无属性→走docDefaults继承→11pt,与被改小的orig runs(10.5pt)不一致 3. wb-ins-font-verify报"orig=宋体/21 wb=None"——但这个"orig"已被污染,不是真实原文 ### 诊断铁律 **永远对比待审查目录的原文,不信v1中的orig runs**: ```python # 对比同一段落的run属性 for label, path in [('待审查原文', orig_path), ('交付v1', v1_path)]: # 读P4 first run rPr的所有子元素 # 如果v1比原文多了eastAsia/cs/sz → 被污染 ``` ### 修复方法(三步) **Step 1:清除orig runs的污染属性** ```python for r in p.findall(f'{WNS}r'): # 只处理原文runs(不在ins/del内的) rpr = r.find(f'{WNS}rPr') rf = rpr.find(f'{WNS}rFonts') if rf is not None: # 如果原文没有eastAsia,strip之 if f'{WNS}eastAsia' in rf.attrib: del rf.attrib[f'{WNS}eastAsia'] if f'{WNS}cs' in rf.attrib: del rf.attrib[f'{WNS}cs'] # 如果原文没有sz(靠继承),strip之 sz = rpr.find(f'{WNS}sz') if sz is not None: rpr.remove(sz) ``` **Step 2:设INS runs匹配真实原文** ```python for ins in p.findall(f'.//{WNS}ins'): if ins.get(f'{WNS}author') != 'WB': continue for r in ins.findall(f'{WNS}r'): rf = rpr.find(f'{WNS}rFonts') # 设置为原文实际有的属性(如ascii=宋体, hAnsi=宋体) # 不设原文没有的(如eastAsia, cs) # hint按同段orig run的值设 ``` **Step 3:逐段匹配hint** 不同段落的orig runs hint状态不同(有的有hint=eastAsia,有的没有)。必须逐段检查并匹配。 ### 注意事项 - **不能一刀切**:同一文档不同段落的orig run属性可能不同(P4有hint, P19没hint; P20有完整rFonts, P36完全没rFonts) - **docDefaults是真正的参考基准**:检查`word/styles.xml`的`docDefaults/rPrDefault`了解继承值 - **"MISSING HINT (无同段原文可比)"是已知限制**:整段WB INS的新增段落没有orig run对比,脚本报MISSING不是真实错误 - **洋励案实证**:120处orig runs被污染,修复后INS只剩14个MISSING HINT(全是新增段落)