Something went wrong. Try again.
math snipping extension
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586r"""Render the golden corpus to PNGs for OCR benchmarking.
The acceptance table in tests/test_golden.py is already the list of expressionswe care about, so it doubles as the benchmark corpus: every rendered imagearrives with ground-truth LaTeX *and* the infix it must ultimately produce.That lets a benchmark score OCR in the unit that matters (did the pipeline emitthe right infix?) rather than edit distance on LaTeX strings.
Rendering with real LaTeX rather than a Python mathtext approximation mattershere: pix2tex was trained on LaTeX output, so anything else measures therenderer as much as the model.
uv run python scripts/render_corpus.py [outdir]"""
from __future__ import annotations
import jsonimport reimport subprocessimport sysimport tempfilefrom pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tests"))from test_golden import GOLDEN # noqa: E402
#: Roughly: a 1x screenshot, a Retina screenshot, and a zoomed-in crop.DPIS = (110, 220, 330)
TEMPLATE = r"""\documentclass[12pt]{article}\usepackage{amsmath,amssymb}\pagestyle{empty}\begin{document}\[ %s \]\end{document}"""
def slug(latex: str) -> str: cleaned = re.sub(r"[^a-z0-9]+", "-", latex.lower().replace("\\", "")) return cleaned.strip("-")[:40] or "expr"
def render(latex: str, dpi: int, target: Path, workdir: Path) -> bool: (workdir / "doc.tex").write_text(TEMPLATE % latex) for command in ( ["latex", "-interaction=nonstopmode", "-halt-on-error", "doc.tex"], ["dvipng", "-D", str(dpi), "-T", "tight", "-bg", "White", "-fg", "Black", "-q", "-o", str(target), "doc.dvi"], ): done = subprocess.run(command, cwd=workdir, capture_output=True) if done.returncode != 0: return False return target.exists()
def main(outdir: str = "corpus") -> int: out = Path(outdir) out.mkdir(parents=True, exist_ok=True) labels, skipped = [], []
with tempfile.TemporaryDirectory() as tmp: workdir = Path(tmp) for index, (latex, infix) in enumerate(GOLDEN): name = f"{index:02d}-{slug(latex)}" rendered = [] for dpi in DPIS: target = out / f"{name}@{dpi}.png" if render(latex, dpi, target, workdir): rendered.append(target.name) if not rendered: skipped.append(latex) continue labels.append({"latex": latex, "infix": infix, "images": rendered})
(out / "labels.json").write_text(json.dumps(labels, indent=2) + "\n") print(f"{len(labels)} expressions, {sum(len(l['images']) for l in labels)} images -> {out}/") for latex in skipped: print(f" skipped (LaTeX would not compile): {latex}") return 0
if __name__ == "__main__": sys.exit(main(*sys.argv[1:]))