#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""深挖 pptx 文字：普通文本框 + 组合形状 + SmartArt/图表部件（diagram data）。

python-pptx 的 shape.text_frame 读不到 SmartArt（发展历程/企业荣誉/技术平台常是 SmartArt），
需从 slide.part.rels 里找 diagramData/diagram 部件，再抽 <a:t> 文本。
"""
import re, sys, json
from pptx import Presentation
from pptx.util import Emu

SRC = sys.argv[1]
prs = Presentation(SRC)
EMU = 914400

T_RE = re.compile(rb'<a:t>([^<]*)</a:t>')


def walk(shapes, out, depth=0):
    for sh in shapes:
        try:
            if sh.shape_type is not None and str(sh.shape_type).startswith('GROUP'):
                walk(sh.shapes, out, depth + 1)
                continue
        except Exception:
            pass
        if sh.has_text_frame:
            t = ' '.join(sh.text_frame.text.split())
            if t:
                fs = [r.font.size.pt for p in sh.text_frame.paragraphs for r in p.runs if r.font.size]
                out.append({'kind': 'text', 'fs': max(fs) if fs else None,
                            'top': round(sh.top / EMU, 2) if sh.top is not None else None,
                            'left': round(sh.left / EMU, 2) if sh.left is not None else None, 'txt': t})
        if getattr(sh, 'has_table', False) and sh.has_table:
            rows = [[' '.join(c.text.split()) for c in r.cells] for r in sh.table.rows]
            out.append({'kind': 'table', 'rows': rows})
        # 图形框（SmartArt / 图表）里往往有图，文字在部件中
        try:
            if str(sh.shape_type).startswith('GRAPHIC_FRAME') or 'CHART' in str(sh.shape_type):
                out.append({'kind': 'graphic', 'type': str(sh.shape_type)})
        except Exception:
            pass


for idx, slide in enumerate(prs.slides, 1):
    out = []
    walk(slide.shapes, out)
    diagrams = []
    for rel in slide.part.rels.values():
        try:
            if 'diagram' in rel.reltype or 'chart' in rel.reltype:
                part = rel.target_part
                txts = [x.decode('utf-8', 'ignore').strip()
                        for x in T_RE.findall(part.blob)]
                txts = [t for t in txts if t]
                if txts:
                    diagrams.append({'rel': rel.reltype.rsplit('/', 1)[-1], 'texts': txts})
        except Exception:
            pass
    print('=' * 70)
    print('P%d' % idx)
    for o in out:
        if o['kind'] == 'text':
            print('   [text fs=%s top=%s] %s' % (o['fs'], o['top'], o['txt'][:150]))
        elif o['kind'] == 'table':
            for r in o['rows']:
                print('   [table] ' + ' | '.join(r)[:150])
        else:
            print('   [%s]' % o['type'])
    for d in diagrams:
        print('   [部件:%s] %s' % (d['rel'], ' ⏐ '.join(d['texts'])[:600]))
