The IR supersedes both intermediate designs (requirements D6, D7):
station/tools/docgen and the graph model that briefly lived in graphgen.
Shipping them beside atlas2/docgen would mean two graph models, which is the
thing the architecture argues against.
Carried across rather than lost:
- style/extract.py and tokens.py, the offline theme harvester (R31). Rewritten
to emit a *theme* — a slot-to-hex binding — rather than a whole style file,
since what harvesting recovers is which colour a slot should be, not what a
kind should look like.
- graphgen/README.md, rewritten for what graphgen actually is now: the
schema explorer. It fixes the blank station-index entry at run.py:304.
Two bugs found while doing it:
- Canvas and ink are the two lightness extremes, not the two most common
values. In a Graphviz SVG every label carries a fill, so the ink outnumbers
the canvas 87 to 43 and the old rule produced a theme whose text was
invisible against its own background.
- A name defined in both branches of an if/else produced a duplicate id, which
failed validation on docgen's own source. Disambiguated by line.
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
""" python3 -m docgen.emitters minimap <ir.json> [-o out.svg] [--scale 0.55]"""
|
|
|
|
import argparse
|
|
import json
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from ..ir import check
|
|
from ..style import Style, StyleError
|
|
from .minimap import emit
|
|
|
|
|
|
def main(argv=None):
|
|
p = argparse.ArgumentParser(prog="python3 -m docgen.emitters minimap")
|
|
p.add_argument("ir", type=Path)
|
|
p.add_argument("--output", "-o", type=Path)
|
|
p.add_argument("--style", default="lucid")
|
|
p.add_argument("--theme", default=None)
|
|
p.add_argument("--scale", type=float, default=0.55, help="Pixels per source line.")
|
|
p.add_argument("--width", type=int, default=1180, help="Wrap a shelf past this.")
|
|
args = p.parse_args(argv)
|
|
|
|
try:
|
|
data = json.loads(args.ir.read_text())
|
|
except (OSError, json.JSONDecodeError) as e:
|
|
print(f"Error: could not read {args.ir}: {e}", file=sys.stderr)
|
|
return 1
|
|
problems = check(data)
|
|
if problems:
|
|
print(f"Error: {args.ir} is not a valid IR ({len(problems)}):", file=sys.stderr)
|
|
for pr in problems[:5]:
|
|
print(f" {pr}", file=sys.stderr)
|
|
return 1
|
|
|
|
try:
|
|
style = Style.load(args.style, theme=args.theme)
|
|
svg = emit(data, style, scale=args.scale, target_width=args.width)
|
|
except (StyleError, ValueError) as e:
|
|
print(f"Error: {e}", file=sys.stderr)
|
|
return 1
|
|
|
|
if args.output:
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(svg)
|
|
m = re.search(r'width="(\d+)pt" height="(\d+)pt"', svg)
|
|
print(f" minimap {args.output} {m.group(1)}x{m.group(2)}" if m else "")
|
|
else:
|
|
sys.stdout.write(svg)
|
|
return 0
|