"""Migrate inline `
` patterns to stat_card() primitive. Per motto_v3 §11, this mechanical migration consolidates stat-card patterns under the canonical primitive. Four common cases: 1. Simple stat-card with just a heading: `stat_card(value, label)` 2. Stat-card with a section heading: `stat_card("", "", body_html="

...

...")` 3. Stat-card with complex content (e.g. barcode info, swiggy section header) 4. Stat-card with additional attributes (role, id) - skipped for manual review """ from __future__ import annotations import re import sys from pathlib import Path SCREENS_DIR = Path("shopstack/ui/screens") # Stat-card with a heading AND body content (e.g. swiggy section header). # The body contains `

...

` plus other content. # `

TITLE

BODY
` P_HEADING_BODY = re.compile( r"

([^<]+)

(.*?)
\s*\n?", re.DOTALL, ) # Plain stat-card wrapper (just opens a stat-card section). # `
` or `
CONTENT
` P_PLAIN = re.compile( r"
(.*?)
\s*\n?", re.DOTALL, ) def migrate(content: str) -> tuple[str, int]: """Apply stat-card migrations. Conservative — skips ambiguous patterns.""" count = 0 def _replace_heading_body(m: re.Match) -> str: nonlocal count count += 1 style, title, body = m.group(1), m.group(2), m.group(3) body_html = f"

{title}

{body}" if style: return f"stat_card(value='', label='', body_html={body_html!r}, style={style!r})\n" return f"stat_card(value='', label='', body_html={body_html!r})\n" # First pass: heading+body pattern (most specific) content = P_HEADING_BODY.sub(_replace_heading_body, content) return content, count def process_file(path: Path) -> int: src = path.read_text(encoding="utf-8") if "stat-card" not in src: return 0 new_src, count = migrate(src) if count == 0: return 0 path.write_text(new_src, encoding="utf-8") return count def main() -> int: total = 0 for path in sorted(SCREENS_DIR.glob("*.py")): if path.name in ("__init__.py", "_utils.py", "_legacy") or path.name.startswith("_"): continue count = process_file(path) if count > 0: print(f"{path.name}: {count} migrations") total += count print(f"\nTOTAL: {total} stat-card heading+body patterns migrated to stat_card(body_html=)") return total if __name__ == "__main__": sys.exit(0 if main() >= 0 else 1)