#!/usr/bin/env python3 """Render groups.json + records.json as one self-contained page: REFERENCE.html.""" import html, json, pathlib here = pathlib.Path(__file__).parent d = json.loads((here / 'groups.json').read_text()) recs = {r['chunk']: r for r in json.loads((here / 'records.json').read_text())} stories = json.loads((here.parent / 'stories.json').read_text()) e = html.escape SRC = {'archetype': 'archetype', 'filled': 'filled gap'} def src(o): if o['source'].startswith('scene:'): n = o['source'].split(':')[1] return f'from scene {n}' + ('' if o['in_group'] else ' (outside this group)') return SRC[o['source']] def moves(m): return ' '.join(f'{e(k)} {e(v)}' for k, v in m.items()) def scene(c): r = recs[c] return (f'
{c} · {e(stories[r["story"]]["title"])} — {e(r["predicament"])}' f'

{e(r["summary"])}

') out = [] for g in d['groups']: out.append(f'''

{g["id"]} · {e(g["name"])}

{e(g["predicament"])}

{e(g["sentence"])} · {len(g["members"])} scenes from {len(g["stories"])} stories ({e(", ".join(g["story_titles"]))}) · stage {g["stage"]}

Options

    {"".join(f"
  1. {e(o['text'])} {src(o)}
    {moves(o['moves'])}
  2. " for o in g["options"])}

Scenes

{"".join(scene(m["chunk"]) for m in g["members"])}
''') un = ''.join(scene(c) for c in d['unassigned']) page = f''' Jacobs Reference Groups

The Lady of the Barge: reference groups

W. W. Jacobs, 1902 (Standard Ebooks text). 12 stories, 157 scenes cut by the same rule as chunk.py. Summaries, predicaments, groups and options written by Claude by reading every scene: no local inference. A comparison baseline, not a pack. Option moves give a direction only, never a number.

{"".join(out)}

Unassigned ({len(d["unassigned"])})

Scenes that fit no situation recurring in two or more stories.

{un}
''' (here / 'REFERENCE.html').write_text(page, encoding='utf-8') print('wrote', here / 'REFERENCE.html', len(page), 'bytes')