This commit is contained in:
53
website/build-chapters.py
Normal file
53
website/build-chapters.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build website/chapters.json from chapters/*.md
|
||||
|
||||
Run from project root:
|
||||
python3 website/build-chapters.py
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
chapters_dir = Path(__file__).parent.parent / "chapters"
|
||||
website_dir = Path(__file__).parent
|
||||
|
||||
chapters = []
|
||||
for i in range(1, 19):
|
||||
fname = chapters_dir / f"chapter-{i:02d}.md"
|
||||
if not fname.exists():
|
||||
print(f"Warning: {fname} not found, skipping")
|
||||
continue
|
||||
|
||||
text = fname.read_text()
|
||||
title_match = re.match(r'^# (.+)', text, re.MULTILINE)
|
||||
title = title_match.group(1) if title_match else f"Chapter {i}"
|
||||
body = text[title_match.end():].strip() if title_match else text.strip()
|
||||
|
||||
paragraphs = body.split('\n\n')
|
||||
html_parts = []
|
||||
for p in paragraphs:
|
||||
p = p.strip()
|
||||
if not p:
|
||||
continue
|
||||
if p.startswith('>'):
|
||||
lines = [l.lstrip('> ').strip() for l in p.split('\n')]
|
||||
html_parts.append(f'<blockquote>{"<br>".join(lines)}</blockquote>')
|
||||
elif p.startswith('####'):
|
||||
html_parts.append(f'<h4>{p.lstrip("# ").strip()}</h4>')
|
||||
elif p.startswith('###'):
|
||||
html_parts.append(f'<h3>{p.lstrip("# ").strip()}</h3>')
|
||||
else:
|
||||
p = re.sub(r'\*(.+?)\*', r'<em>\1</em>', p)
|
||||
p = p.replace('\n', '<br>')
|
||||
html_parts.append(f'<p>{p}</p>')
|
||||
|
||||
chapters.append({
|
||||
"number": i,
|
||||
"title": title,
|
||||
"html": "\n".join(html_parts)
|
||||
})
|
||||
|
||||
out = website_dir / "chapters.json"
|
||||
out.write_text(json.dumps(chapters, indent=2))
|
||||
print(f"Wrote {len(chapters)} chapters ({out.stat().st_size / 1024:.1f} KB) to {out}")
|
||||
Reference in New Issue
Block a user