#!/usr/bin/env python3
"""生成"接受所有修订后"的干净 docx，用于 OnlyOffice 渲染做字体/排版的决定性视觉验证。

为什么需要：OnlyOffice 渲染修订态文字（w:ins，紫色+下划线）时视觉上常显示为类无衬线、
看起来字体/粗细与正文不同——这是 track-changes 的渲染特性，不是真实字体差异。vision 工具
会据此误报"字体不一致"，导致无谓返工。把所有修订接受、批注去掉后再渲染，才能在无修订
颜色干扰下看到插入文字与正文的真实字体一致性。

用法: python accept-revisions-preview.py <in.docx> <out.docx>
处理: 解包所有 w:ins（保留内容）+ 删除所有 w:del（连内容）+ 移除批注锚点标记。
注意: 产物仅供"渲染核对"，不是正式交付物（交付的是带修订痕迹的版本）。
"""
import sys, zipfile, io
from lxml import etree

W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
Wq = '{' + W + '}'


def accept_revisions(in_path, out_path):
    with open(in_path, 'rb') as f:
        data = f.read()
    bin_, bout = io.BytesIO(data), io.BytesIO()
    with zipfile.ZipFile(bin_) as zin, zipfile.ZipFile(bout, 'w', zipfile.ZIP_DEFLATED) as zout:
        for item in zin.infolist():
            raw = zin.read(item.filename)
            if item.filename == 'word/document.xml':
                root = etree.fromstring(raw)
                # 删除所有 w:del（含内容）
                for d in [e for e in root.iter(Wq + 'del')]:
                    d.getparent().remove(d)
                # 解包所有 w:ins：把子元素提到 ins 的位置后删除 ins 壳
                for ins in [e for e in root.iter(Wq + 'ins')]:
                    parent = ins.getparent()
                    idx = list(parent).index(ins)
                    for child in reversed(list(ins)):
                        parent.insert(idx, child)
                    parent.remove(ins)
                # 移除批注锚点标记
                for tag in ('commentRangeStart', 'commentRangeEnd'):
                    for e in [x for x in root.iter(Wq + tag)]:
                        e.getparent().remove(e)
                for r in [x for x in root.iter(Wq + 'r')]:
                    if r.find(Wq + 'commentReference') is not None:
                        r.getparent().remove(r)
                raw = etree.tostring(root, xml_declaration=True, encoding='UTF-8', standalone=True)
            zout.writestr(item, raw)
    with open(out_path, 'wb') as f:
        f.write(bout.getvalue())
    print(f'接受修订版已生成: {out_path}')


if __name__ == '__main__':
    if len(sys.argv) != 3:
        print('用法: python accept-revisions-preview.py <in.docx> <out.docx>')
        sys.exit(1)
    accept_revisions(sys.argv[1], sys.argv[2])
