# -*- coding: utf-8 -*-
"""Chuyen mot muc Markdown (subset: H1/H2/H3, doan van, bullet, blockquote, bang, anh) sang DOCX.
Dung: python _md2docx.py <file.md> <file.docx> [thu_muc_goc_de_tim_anh]
Ho tro **bold** va *italic* trong dong."""
import os, re, sys
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Pt, Inches, RGBColor


def runs(p, text, base_bold=False):
    """Them text vao doan p, xu ly **bold** va *italic*."""
    for tok in re.split(r'(\*\*.+?\*\*|\*[^*]+?\*)', text):
        if not tok:
            continue
        b, i = base_bold, False
        t = tok
        if tok.startswith('**') and tok.endswith('**') and len(tok) > 4:
            t, b = tok[2:-2], True
        elif tok.startswith('*') and tok.endswith('*') and len(tok) > 2:
            t, i = tok[1:-1], True
        r = p.add_run(t)
        r.bold = b
        r.italic = i
    return p


def main():
    src, dst = sys.argv[1], sys.argv[2]
    goc = sys.argv[3] if len(sys.argv) > 3 else os.path.dirname(src)
    md = open(src, encoding='utf-8').read().split('\n')
    d = Document()
    st = d.styles['Normal']
    st.font.name = 'Calibri'
    st.font.size = Pt(11)
    i = 0
    while i < len(md):
        ln = md[i].rstrip()
        s = ln.strip()
        if not s:
            i += 1
            continue
        # bang
        if s.startswith('|') and i + 1 < len(md) and re.match(r'^\|[\s:|-]+\|$', md[i + 1].strip()):
            rows = []
            while i < len(md) and md[i].strip().startswith('|'):
                cells = [c.strip() for c in md[i].strip().strip('|').split('|')]
                if not re.match(r'^[\s:|-]+$', ''.join(cells)):
                    rows.append(cells)
                i += 1
            n = max(len(r) for r in rows)
            tb = d.add_table(rows=0, cols=n)
            tb.style = 'Table Grid'
            for k, r in enumerate(rows):
                cells = tb.add_row().cells
                for j in range(n):
                    txt = r[j] if j < len(r) else ''
                    p = cells[j].paragraphs[0]
                    runs(p, txt, base_bold=(k == 0))
                    for run in p.runs:
                        run.font.size = Pt(9.5)
                        if k == 0:
                            run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
                    if k == 0:
                        sh = cells[j]._tc.get_or_add_tcPr()
                        from docx.oxml.ns import qn
                        from docx.oxml import OxmlElement
                        el = OxmlElement('w:shd')
                        el.set(qn('w:fill'), '2F5496')
                        sh.append(el)
            d.add_paragraph()
            continue
        # anh
        m = re.match(r'^!\[.*?\]\((.+?)\)$', s)
        if m:
            pth = m.group(1).replace('/', os.sep)
            if not os.path.isabs(pth):
                pth = os.path.join(goc, pth)
            if os.path.exists(pth):
                d.add_picture(pth, width=Inches(6.3))
                d.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER
            else:
                d.add_paragraph('[thiếu ảnh: %s]' % pth)
            i += 1
            continue
        # tieu de
        if s.startswith('### '):
            d.add_heading(s[4:], level=3)
        elif s.startswith('## '):
            d.add_heading(s[3:], level=2)
        elif s.startswith('# '):
            d.add_heading(s[2:], level=1)
        # tieu de in dam **...** dung rieng mot dong
        elif re.match(r'^\*\*[^*].*\*\*:?$', s):
            runs(d.add_paragraph(), s)
        # blockquote
        elif s.startswith('>'):
            buf = []
            while i < len(md) and md[i].strip().startswith('>'):
                buf.append(md[i].strip().lstrip('>').strip())
                i += 1
            for b in buf:
                if not b:
                    continue
                p = d.add_paragraph()
                p.paragraph_format.left_indent = Inches(0.35)
                runs(p, b)
                for r in p.runs:
                    r.italic = True
                    r.font.size = Pt(10)
            continue
        # bullet
        elif re.match(r'^[-*] ', s):
            p = d.add_paragraph(style='List Bullet')
            runs(p, s[2:])
        else:
            runs(d.add_paragraph(), s)
        i += 1
    d.save(dst)
    print('da luu:', dst, os.path.getsize(dst), 'byte | so doan:', len(d.paragraphs), '| so bang:', len(d.tables))


main()
