#!/usr/bin/env python3 """Render groups.json + records.json + options_by_entry.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()) obe = json.loads((here / 'options_by_entry.json').read_text()) new = obe.pop('_new_entries') 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 fable {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] moral = f'
Moral: {e(r["moral"])}' if r['moral'] else '' return (f'
{c} · {e(stories[r["story"]]["title"])} — {e(r["predicament"])}' f'

{e(r["summary"])}{moral}

') def section(g): tag = ' small group, below the 13-fable rule' if g['small'] else '' return f'''

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

{e(g["predicament"])}

{e(g["sentence"])} · {len(g["members"])} fables · stage {g["stage"]}

Options

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

Fables

{"".join(scene(m["chunk"]) for m in g["members"])}
''' big = ''.join(section(g) for g in d['groups'] if not g['small']) small = ''.join(section(g) for g in d['groups'] if g['small']) un = ''.join(scene(c) for c in d['unassigned']) def entry(k, v): name = new[k]['name'] + ' (new)' if k in new else e(k) rows = ''.join(f'
  • {e(o["text"])} {moves(o["moves"])} fable {o["source"].split(":")[1]} · ' f'{"stated" if o["stated"] else "inferred"}
    “{e(o["evidence"])}”
  • ' for o in v) return f'
    {name} — {len(v)} options, {sum(o["stated"] for o in v)} stated
    ' opts = [o for v in obe.values() for o in v] meas = ''.join(entry(k, v) for k, v in obe.items()) page = f''' Aesop Reference Groups

    Aesop's Fables: reference groups

    Three Hundred Aesop's Fables, tr. George Fyler Townsend, 1867 (Project Gutenberg). 313 fables, one scene per fable. Summaries, predicaments, groups, options and the options measurement written by Claude reading every fable: no inference of any kind. A comparison baseline, not a pack. Option moves give a direction only, never a number.

    {big}

    Small groups (5-12 fables)

    Situations that recur, but below the 13-fable rule this corpus's size sets.

    {small}

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

    Fables that fit no situation recurring in five or more fables.

    {un}

    Fables as an option source

    {len(opts)} options for {len(obe)} catalogue situations, {sum(o["stated"] for o in opts)} of them stated: the fable's own outcome or moral shows where every move goes. The rest are inferred.

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