#!/usr/bin/env python3 """Restructure section SUMMARY.md to CANON v1 (lossless: legacy blocks โ†’ ### under Notes). Usage: python3 tools/restructure_summary.py
[--dry-run]""" import re, sys, os, subprocess, glob NAMES = {'01-fundamentals': 'Fundamentals', '02-dreams': 'Dreams', '03-myths-fairy-tales': 'Myths & Fairy Tales', '04-pictures': 'Pictures'} def main(): sec = sys.argv[1] dry = '--dry-run' in sys.argv p = f'sections/{sec}/SUMMARY.md' c = open(p).read() lines = c.split('\n') h1 = lines[0] # split into (heading, body) blocks; preface = lines before first ## blocks, preface, cur = [], [], None for l in lines[1:]: if l.startswith('## '): if cur: blocks.append(cur) cur = [l, []] elif cur: cur[1].append(l) else: preface.append(l) if cur: blocks.append(cur) preface = '\n'.join(preface).strip() glance = authors = None rest = [] for h, body in blocks: name = h[3:].strip() b = '\n'.join(body).strip() if 'at a glance' in name.lower(): glance = (name, b) elif re.match(r'^Table 1 โ€” Authors|^Authors', name): authors = (name, b) else: rest.append((name, b)) if not authors: gen = subprocess.run(['python3', 'tools/make_authors_table.py', sec], capture_output=True, text=True).stdout.strip() authors = ('Authors', gen) if not glance: print('ERROR: no at-a-glance table'); sys.exit(1) # Final counts: from card statuses + manifest totals marks = {'โœ…': 0, '๐Ÿ”ถ': 0, 'โŒ': 0} for cp in glob.glob(f'sections/{sec}/[0-9][0-9]-*.md'): m = re.search(r'\*\*Status:\*\* (.)', open(cp).read()) if m and m.group(1) in marks: marks[m.group(1)] += 1 nitems = sum(marks.values()) mtot = re.search(r'^## Totals\n\n(.+)', open(f'downloads/{sec}/MANIFEST.md').read(), re.M) mtot = mtot.group(1).strip() if mtot else 'โ€”' final = (f"**{sec[:2]} COMPLETE.** Final: {marks['โœ…']} โœ… / {marks['๐Ÿ”ถ']} ๐Ÿ”ถ / {marks['โŒ']} โŒ " f"({nitems} items) ยท Downloads: {mtot}") gname = '## Publication status at a glance' aname = '## Authors โ€” EN โ†’ RU (how verified)' out = f'# Section {sec[:2]} โ€” {NAMES[sec]}: summary\n\n' out += '## Final counts\n\n' + final + '\n\n' out += gname + '\n\n' + glance[1] + '\n\n' out += aname + '\n\n' + authors[1] + '\n\n' if rest: out += '## Notes\n' for name, b in rest: out += f'\n### {name}\n\n{b}\n' txt = out.rstrip() + '\n' if dry: print(txt) else: open(p, 'w').write(txt) print(f'restructured {p}: glance kept, authors {"" if re.search(r"Table 1 โ€” Authors", "\n".join(h for h,_ in blocks)) else "GENERATED"}, {len(rest)} legacy blocks โ†’ Notes') if __name__ == '__main__': main()