wapdown/tests/regenerate_golden.py

45 lines
1.4 KiB
Python
Raw Normal View History

Extract the WML exporter from md2txt into wapdown md2txt is a suite of minimal text-based markup exporters, and every other renderer in it (text, micron, ama, gemini, nex) is a straight transform of a document into a flat text format. The WML renderer is neither: it emits an XML tree, and it restructures the document rather than transforming it -- splitting one file into many <card>s, inventing navigation between them, building a menu card that exists in no source document, and paginating on a byte budget. That is why it needed levers no sibling renderer needed, and why it alone forced a CARD_BREAK block kind and a {.card} directive into the shared parser that every other renderer ignores. wapdown is that renderer given a repository of its own, where restructuring a document into a navigable deck is the point. Ported: the Markdown parser, block event models, and pipeline core, each trimmed to what a deck compiler actually uses (no FIGlet, no hyphenation, no ASCII-art includes, no text-layout frontmatter), plus the eight inline regexes the renderer had been borrowing from a 1039-line text renderer. The plugin registry comes along so other WAP-era targets can register alongside wml later. Zero runtime dependencies. Config is now first-class: every lever is an argparse flag with validation and a frontmatter equivalent, layered CLI > frontmatter > default, replacing the generic --renderer-option KEY=VALUE passthrough. Five defects found while reading the code, each with a regression test: - Link and image URLs were shredded by the emphasis patterns, which ran before LINK_RE: a path like /v1_2_3/ became /v1<i>2</i>3/ inside the href. Links and images are now resolved and stashed first. - <table> was emitted as a direct child of <card>. The WML 1.3 content model is (onevent*, timer?, (do | p | pre)*), so it must sit in a <p>. - Link labels carried emphasis, but <a> is declared (#PCDATA | br | img)* -- there is nowhere valid for a <b> inside one. Markers are now stripped. - The menu card was built directly and never byte-packed, so the one card most likely to be large was the one card exempt from the budget. - Output was written with CRLF line endings. WML is XML served over HTTP. New, WAP-idiomatic rather than Markdown-idiomatic: - deck-level <template> hoisting nav that would otherwise repeat per card - <select> menus, picked with a keypad digit instead of scrolled to - --deck-per-card, one file per section cross-linked by filename, which is the real answer to per-deck cache limits - <head> metadata: Cache-Control max-age and <access> - a Home options softkey, which <prev/> alone cannot provide - an image policy (keep/alt/drop) for the WBMP-only reality of WAP 1.x browsers -- no conversion is performed 186 tests, where neither repo had any. Golden files pin whole-document output; every deck is validated against the real WML 1.3 DTD, vendored at tests/dtd/wml13.dtd. Rendering examples/trail.md still matches md2txt's committed output byte for byte, modulo the CRLF fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 09:27:49 +03:00
#!/usr/bin/env python3
"""Rewrite every golden file under tests/golden/.
Run after an intentional change to the renderer, then read the diff --
that diff is the change, stated in output rather than in code:
uv run python tests/regenerate_golden.py
jj diff tests/golden
"""
from __future__ import annotations
import shutil
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
from conftest import EXAMPLES, GOLDEN, render_file # noqa: E402
from golden_cases import CASES, MULTI_CASES # noqa: E402
def main() -> int:
GOLDEN.mkdir(parents=True, exist_ok=True)
for name, (source, options) in CASES.items():
output = render_file(EXAMPLES / source, **options)
(GOLDEN / f"{name}.wml").write_text(output.text, encoding="utf-8")
print(f"wrote {name}.wml")
for name, (source, options) in MULTI_CASES.items():
directory = GOLDEN / name
if directory.exists():
shutil.rmtree(directory)
directory.mkdir(parents=True)
for document in render_file(EXAMPLES / source, **options).documents:
(directory / (document.name or "index.wml")).write_text(
document.text, encoding="utf-8"
)
print(f"wrote {name}/ ({len(list(directory.iterdir()))} files)")
return 0
if __name__ == "__main__":
raise SystemExit(main())