"""Reproducible syntax experiments, distinct from PDF extraction benchmarks. HTML is stored as .txt so it can pass the existing public evidence allowlist. """ import argparse import importlib.metadata import json import platform import subprocess from datetime import datetime, timezone from html.parser import HTMLParser from pathlib import Path import markdown from markdown_it import MarkdownIt SAMPLES = { 'diagnostic': 'alpha\nbeta\n\nalpha\\\nbeta\n\nalpha \nbeta\n', 'soft-break': 'alpha\nbeta\n', 'two-spaces': 'alpha \nbeta\n', 'backslash-break': 'alpha\\\nbeta\n', 'blank-line': 'alpha\n\nbeta\n', 'ordered-list': '3. alpha\n4. beta\n\n8. restart\n', 'bullet-list': '- alpha\n- beta\n', 'table': '| a | b |\n| --- | --- |\n| 1 | 2 |\n', 'code-block': '```python\nprint("alpha")\n```\n', 'link': '[alpha](https://example.com)\n', 'checkbox': '- [x] alpha\n- [ ] beta\n', 'frontmatter': '---\ntitle: Alpha\n---\n\n# Alpha\n', } class Structure(HTMLParser): def __init__(self): super().__init__() self.counts = {} def handle_starttag(self, tag, attrs): self.counts[tag] = self.counts.get(tag, 0) + 1 def run(lab): lab = Path(lab) out = lab / 'renderers' out.mkdir(parents=True, exist_ok=True) version = subprocess.check_output(['pandoc', '--version'], text=True).splitlines()[0] versions = {'markdown-it-commonmark': importlib.metadata.version('markdown-it-py'), 'markdown-it-breaks': importlib.metadata.version('markdown-it-py'), 'python-markdown': importlib.metadata.version('Markdown'), 'pandoc-gfm': version} results = [] for name, source in SAMPLES.items(): (out / f'{name}.md').write_text(source) rendered = { 'markdown-it-commonmark': MarkdownIt('commonmark').render(source), 'markdown-it-breaks': MarkdownIt('commonmark', {'breaks': True}).render(source), 'python-markdown': markdown.markdown(source, extensions=['tables', 'fenced_code']), 'pandoc-gfm': subprocess.run(['pandoc', '-f', 'gfm', '-t', 'html'], input=source, text=True, capture_output=True, check=True).stdout, } for renderer, html in rendered.items(): path = out / f'{name}--{renderer}.txt' path.write_text(html) parser = Structure() parser.feed(html) results.append({'sample': name, 'renderer': renderer, 'tags': parser.counts, 'source': f'lab/renderers/{name}.md', 'output': f'lab/renderers/{path.name}'}) report = {'kind': 'markdown-rendering', 'date': datetime.now(timezone.utc).isoformat(), 'python': platform.python_version(), 'versions': versions, 'scope': 'Local implementations; not GitHub.com or VS Code UI. Tag counts describe structure, not visual fidelity.', 'command': '.venv/bin/python runs/2026-10-18-markovo-markdown-line-break/lab/reproduce.py --lab runs/2026-10-18-markovo-markdown-line-break/lab', 'results': results} (out / 'results.json').write_text(json.dumps(report, indent=2) + '\n') lines = ['# Markdown renderer experiment', '', report['scope'], '', '| Sample | Renderer | br | p | table | li |', '|---|---|---:|---:|---:|---:|'] for row in results: c = row['tags'] lines.append(f"| {row['sample']} | {row['renderer']} | {c.get('br', 0)} | {c.get('p', 0)} | {c.get('table', 0)} | {c.get('li', 0)} |") (out / 'results.md').write_text('\n'.join(lines) + '\n') return report if __name__ == '__main__': ap = argparse.ArgumentParser() ap.add_argument('--lab', type=Path, required=True) report = run(ap.parse_args().lab) print(json.dumps({'kind': report['kind'], 'cases': len(report['results']), 'versions': report['versions']}))