79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Restructure section SUMMARY.md to CANON v1 (lossless: legacy blocks → ### under Notes).
|
|
Usage: python3 tools/restructure_summary.py <section> [--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()
|