#!/usr/bin/env python3
"""Stage 4 (alternate): render the structured manuscript as plain text and
Markdown, so the transcription survives independently of the .docx.

Footnotes become numbered notes: Markdown uses proper [^n] references; plain
text places them at the end of the chapter they belong to.
"""

import os as _os
# resolve paths relative to this archive rather than the machine it was built on
_ROOT = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
ARCHIVE = _ROOT
_DATA = _os.path.join(_ROOT, 'data')
import json, re, sys, textwrap

ARCHIVE = _ROOT
data = json.load(open('/tmp/doc.json'))
blocks, TOC = data['blocks'], data['toc']

TITLE = 'THE CHINA AFFAIR'
AUTHOR = 'Ernest Walton'
EPIGRAPH = ('We must respect the past, remembering that once it was all that '
            'was humanly possible.')
EPI_ATTR = 'George Santayana'

# footnote id per anchoring paragraph, in document order
notes, note_of = {}, {}
nid = 0
for b in blocks:
    if b['type'] == 'footnote':
        nid += 1
        notes[nid] = b['text']
        note_of.setdefault(b['anchor'], []).append(nid)


def title_case(s):
    """Title-case without breaking on apostrophes ('Zupitza's', not 'Zupitza'S')."""
    return re.sub(r"[A-Za-zÀ-ÿ][A-Za-zÀ-ÿ']*",
                  lambda m: m.group(0)[0].upper() + m.group(0)[1:].lower(), s)


def with_markers(b, style):
    """Replace the author's '*' with a numbered reference."""
    ids = list(note_of.get(b.get('pid'), []))
    text = b['text']
    if not ids:
        return text
    out, parts = [], text.split('*')
    for i, part in enumerate(parts):
        out.append(part)
        if i < len(parts) - 1:
            if ids:
                n = ids.pop(0)
                out.append(f'[^{n}]' if style == 'md' else f'[{n}]')
            else:
                out.append('*')
    tail = ''.join(f'[^{n}]' if style == 'md' else f'[{n}]' for n in ids)
    return ''.join(out) + tail


# ------------------------------------------------------------------ Markdown
md = [f'# {TITLE}', '', f'*by {AUTHOR}*', '',
      '> ' + EPIGRAPH, '>', f'> — {EPI_ATTR}', '', '---', '',
      '## Contents', '']
for label, title in TOC:
    md.append(f'- **{label}** — {title_case(title)}')
md += ['- **Appendix** — How A Zeppelin Flies (not included)', '', '---', '']

used_md = []
for b in blocks:
    t = b['type']
    if t == 'heading':
        md += ['', f'## {b["label"]}', '', f'### {b["title"]}', '']
    elif t == 'para':
        md += [with_markers(b, 'md'), '']
    elif t == 'quote':
        md += ['> ' + (b.get('text') or ' '.join(b['lines'])), '']
    elif t == 'verse':
        md += ['> ' + '  \n> '.join(b['lines']), '']
    elif t == 'footnote':
        used_md.append(b)

md += ['', '---', '', '## Notes', '']
for n in sorted(notes):
    md.append(f'[^{n}]: {notes[n]}')
    md.append('')

open(f'{ARCHIVE}/manuscript/The China Affair.md', 'w').write('\n'.join(md) + '\n')

# ---------------------------------------------------------------- plain text
W = 76
out = ['', TITLE.center(W).rstrip(), '', ('by ' + AUTHOR).center(W).rstrip(), '',
       '', *[l.center(W).rstrip() for l in textwrap.wrap(EPIGRAPH, 58)],
       ('— ' + EPI_ATTR).center(W).rstrip(), '', '', 'CONTENTS'.center(W).rstrip(), '']
for label, title in TOC:
    out.append(f'    {label} — {title_case(title)}')
out += ['    Appendix — How A Zeppelin Flies (not included)', '']

pending = []          # notes to flush at the next chapter break / end


def flush_notes():
    if not pending:
        return
    out.append('')
    out.append('    ' + '-' * 40)
    for n in pending:
        body = textwrap.fill(notes[n], W - 8,
                             initial_indent=f'    [{n}] ',
                             subsequent_indent='        ')
        out.append(body)
    out.append('')
    pending.clear()


for b in blocks:
    t = b['type']
    if t == 'heading':
        flush_notes()
        out += ['', '', '', b['label'].center(W).rstrip(), '',
                b['title'].center(W).rstrip(), '']
    elif t == 'para':
        out.append(textwrap.fill(with_markers(b, 'txt'), W,
                                 initial_indent='     ', subsequent_indent=''))
        out.append('')
    elif t == 'quote':
        body = b.get('text') or ' '.join(b['lines'])
        out.append(textwrap.fill(body, W - 12, initial_indent='        ',
                                 subsequent_indent='        '))
        out.append('')
    elif t == 'verse':
        out += ['        ' + l for l in b['lines']]
        out.append('')
    elif t == 'footnote':
        for n, txt in notes.items():
            if txt == b['text'] and n not in pending:
                pending.append(n)
                break

flush_notes()
open(f'{ARCHIVE}/manuscript/The China Affair.txt', 'w').write('\n'.join(out) + '\n')

print('wrote manuscript .md and .txt')
print('  markdown lines:', len(md), ' notes:', len(notes))
print('  text lines:', len(out))
