#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
把两个 PPT 的 Markdown 转写合并成一份，并把 OCR 识别出的图片文字补充到对应位置。
- OCR 结果文件：ocr_ppt1.txt / ocr_ppt2.txt（格式：===== IMAGE: 文件名 ===== 后逐行文字）
- 图片归属：解析每张 slide 的 rels，得到「该页引用了哪些 media 文件」
- 只补充「确实有文字」的图片（过滤纯装饰：字符数 < 4、或全是数字/符号）
"""
import os, re, json, zipfile

BASE = os.path.expanduser('~/Desktop/Hermes输出-工作类/资料/PPT转写')
SRC = {
    'PPT1': ("/Users/liuxinyuan/.hermes/profiles/zone-b/cache/documents/doc_8055998b2b03_宝锐生物PPT（明德 0516）_竞品对标版.pptx",
             'PPT1_明德0516_竞品对标版.md', '宝锐生物PPT（明德 0516）· 竞品对标版'),
    'PPT2': ("/Users/liuxinyuan/.hermes/profiles/zone-b/cache/documents/doc_87fc8144ffe1_珠海宝锐生物简介PPT【[产品（分子）技术版】20260826~27.pptx",
             'PPT2_产品分子技术版_20260826-27.md', '珠海宝锐生物简介PPT【产品（分子）技术版】20260826～27'),
}

def load_ocr(tag):
    """解析 OCR 输出 → {图片文件名: [文本行]}"""
    p = os.path.join(BASE, 'ocr_%s.txt' % tag.lower())
    if not os.path.exists(p):
        return {}
    out, cur = {}, None
    for line in open(p, encoding='utf-8', errors='ignore'):
        m = re.match(r'^===== IMAGE:\s*(.+?)\s*=====\s*$', line)
        if m:
            cur = m.group(1); out[cur] = []
            continue
        if cur is not None:
            s = line.strip()
            if s and not s.startswith('ERROR'):
                out[cur].append(s)
    return out

def meaningful(lines):
    """判断 OCR 文字是否为「确实的文字内容」：去掉纯装饰/噪声"""
    txt = ' '.join(lines)
    # 去掉纯数字、纯符号、长度过短的
    han = re.findall(r'[\u4e00-\u9fff]', txt)
    alpha = re.findall(r'[A-Za-z]', txt)
    if len(han) >= 4 or len(alpha) >= 6:
        return True
    if len(han) + len(alpha) >= 4 and len(txt) >= 8:
        return True
    return False

def slide_images(pptx, tag):
    """返回 {slide 序号: [media 文件名]}（按演示顺序）"""
    z = zipfile.ZipFile(pptx)
    pres = z.read('ppt/presentation.xml').decode('utf-8', 'ignore')
    rid = re.findall(r'<p:sldId[^>]*r:id="(rId\d+)"', pres)
    prels = z.read('ppt/_rels/presentation.xml.rels').decode('utf-8', 'ignore')
    r2t = dict(re.findall(r'Id="(rId\d+)"[^>]*Target="([^"]+)"', prels))
    order = ['ppt/' + r2t[r].replace('../', '') for r in rid if r in r2t]
    res = {}
    for i, sn in enumerate(order, 1):
        rels = 'ppt/slides/_rels/' + os.path.basename(sn) + '.rels'
        imgs = []
        if rels in z.namelist():
            rx = z.read(rels).decode('utf-8', 'ignore')
            for _, t in re.findall(r'Id="(rId\d+)"[^>]*Target="([^"]+)"', rx):
                tt = t.replace('../', '')
                if tt.startswith('media/'):
                    imgs.append(os.path.basename(tt))
        res[i] = imgs
    return res

def main():
    all_ocr = {t: load_ocr(t) for t in SRC}
    for t in SRC:
        n = len(all_ocr[t])
        m = sum(1 for v in all_ocr[t].values() if meaningful(v))
        print('[%s] OCR 图片 %d 张，其中「确有文字」%d 张' % (t, n, m))

    parts = []
    parts.append('# 宝锐生物 PPT 双份完整转写（合并版）\n')
    parts.append('> **合并内容**：① 宝锐生物PPT（明德 0516）· 竞品对标版（35 张）'
                 '；② 珠海宝锐生物简介PPT【产品（分子）技术版】20260826～27（60 张）\n>\n'
                 '> **提取范围**：全部可见文字 + 原生表格 + 图表数据与图例 + 图片文字（OCR 补充）\n>\n'
                 '> **说明**：图片中的文字由 macOS Vision OCR 提取（中文/英文），已过滤纯装饰图；'
                 'OCR 对实验曲线图上的细小刻度标注可能识别不全，关键数据请对照原 PPT。\n')
    parts.append('\n---\n')

    stats = {}
    for tag, (pptx, mdfile, title) in SRC.items():
        md = open(os.path.join(BASE, mdfile), encoding='utf-8').read()
        imgmap = slide_images(pptx, tag)
        ocr = all_ocr[tag]
        added = 0
        # 按页切分：把每页里的 "🖼 [图标/图片 N：name]" 或 "<sub>本页含图片文件：…</sub>" 后追加 OCR
        blocks = re.split(r'(?m)^(## 第 \d+ 张)$', md)
        out = []
        cur_slide = None
        for seg in blocks:
            m = re.match(r'^## 第 (\d+) 张$', seg)
            if m:
                cur_slide = int(m.group(1))
                out.append(seg)
                continue
            if cur_slide:
                imgs = imgmap.get(cur_slide, [])
                texts = []
                for im in imgs:
                    if im in ocr and meaningful(ocr[im]):
                        texts.append((im, ocr[im]))
                if texts:
                    seg += '\n\n> 🔍 **图片文字（OCR 提取）**\n>\n'
                    for im, ls in texts:
                        seg += '> **%s**：%s\n>\n' % (im, ' ⏎ '.join(ls))
                        added += 1
            out.append(seg)
        body = ''.join(out)
        stats[tag] = added
        parts.append('\n\n# ═══════ %s ═══════\n' % title)
        parts.append(body)

    outfile = os.path.join(BASE, '宝锐生物PPT_双份合并转写.md')
    open(outfile, 'w', encoding='utf-8').write('\n'.join(parts))
    print('\n✓ 合并完成：%s' % outfile)
    print('   补充 OCR 图片文字：PPT1 %d 处 ｜ PPT2 %d 处' % (stats['PPT1'], stats['PPT2']))
    print('   总大小 %.1f KB ｜ 行数 %d' % (os.path.getsize(outfile)/1024,
          len(open(outfile, encoding='utf-8').read().split('\n'))))

if __name__ == '__main__':
    main()
