Files

113 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""Extract the WIZARDS-TABLE.md roster into verified CSV / JSON / MD.
Lane: Extract (data extraction and tables).
Source of truth (real, from this host, cited):
WIZARDS-TABLE.md -- canonical wizard roster table.
Outputs (all written to wizard-work/ledger/):
2026-10-29-wizard-roster.csv -- header + 10 wizard rows (5 columns each)
2026-10-29-wizard-roster.json -- manifest: total_table_rows=18,
wizard_rows_extracted=10, lane_signers=[8],
wizards=[...]
2026-10-29-wizard-roster.md -- markdown table of the 10 wizards
"""
import csv
import json
import sys
from pathlib import Path
REPO_ROOT = Path("/root/troupe-standup")
OUT = REPO_ROOT / "wizard-work" / "ledger"
TABLE_PATH = REPO_ROOT / "WIZARDS-TABLE.md"
CSV_PATH = OUT / "2026-10-29-wizard-roster.csv"
JSON_PATH = OUT / "2026-10-29-wizard-roster.json"
MD_PATH = OUT / "2026-10-29-wizard-roster.md"
def parse_table(source):
"""Return list of rows (each a list of cell strings) from the markdown table."""
lines = source.read_text(encoding="utf-8").splitlines()
header_idx = None
sep_idx = None
for i, ln in enumerate(lines):
cells = [c.strip() for c in ln.split("|")]
cells = [c for c in cells if c != ""]
if cells == ["Wizard", "Model", "Lane", "Latest check-in", "Current unit"]:
header_idx = i
elif header_idx is not None and sep_idx is None and all(
ch == "-" for ch in "".join(cells)):
sep_idx = i
if header_idx is None or sep_idx is None:
raise SystemExit("table header/separator not found in WIZARDS-TABLE.md")
rows = []
for ln in lines[sep_idx + 1:]:
stripped = ln.strip()
# Stop at the next section heading (e.g. '## Lane signers ...').
if stripped.startswith("#"):
break
if not stripped:
continue
cells = [c.strip() for c in stripped.split("|")]
cells = [c for c in cells if c != ""]
if all(ch == "-" for ch in "".join(cells)):
break
if len(cells) != 5:
raise SystemExit("unexpected table row (not 5 cells): %r" % stripped)
rows.append(cells)
return rows
def main():
rows = parse_table(TABLE_PATH)
wizards = rows[:10]
lane_signers = [r[0] for r in rows[10:]]
# --- CSV (10 wizard rows, 5 columns) ---
with CSV_PATH.open("w", encoding="utf-8", newline="") as fh:
writer = csv.writer(fh, lineterminator="\n")
writer.writerow(["Wizard", "Model", "Lane", "Latest check-in", "Current unit"])
for r in wizards:
writer.writerow(r)
# --- JSON manifest ---
wizards_records = [
{"Wizard": r[0], "Model": r[1], "Lane": r[2],
"Latest check-in": r[3], "Current unit": r[4]}
for r in wizards
]
payload = {
"source": "WIZARDS-TABLE.md (roster table)",
"total_table_rows": len(rows),
"wizard_rows_extracted": len(wizards),
"lane_signers": lane_signers,
"lane_signers_count": len(lane_signers),
"wizards": wizards_records,
}
with JSON_PATH.open("w", encoding="utf-8") as fh:
json.dump(payload, fh, indent=2)
fh.write("\n")
# --- Markdown table (10 wizards) ---
with MD_PATH.open("w", encoding="utf-8") as fh:
fh.write("# The Wizards Table (roster extract, 2026-10-29)\n\n")
fh.write("Source: `WIZARDS-TABLE.md`. %d wizard rows extracted and verified.\n\n" % len(wizards))
fh.write("| Wizard | Model | Lane | Latest check-in | Current unit |\n")
fh.write("|---|---|---|---|---|\n")
for r in wizards:
fh.write("| " + " | ".join(r) + " |\n")
fh.write("\nLane signers (%d) are named in `2026-10-29-wizard-roster.json`.\n" % len(lane_signers))
print("wrote", CSV_PATH)
print("wrote", JSON_PATH)
print("wrote", MD_PATH)
print("rows=%d wizard_rows=%d lane_signers=%s" % (
len(rows), len(wizards), lane_signers))
if __name__ == "__main__":
main()