Convert olympiad-style plane geometry statements into constraint-solved TikZ diagrams, with a schematic fallback when exact solving fails.
statement → GeometryIR → SciPy solve → TikZ → compile + residual report
↘ schematic layout (fallback)
Discoverability: see AGENTS.md (for coding agents), llms.txt, and README_HF.md (Hugging Face card).
cd statement-to-tikz
pip install -e ".[dev]"Requires Python 3.11+. Optional: pdflatex or latexmk for PDF compilation.
# Offline pattern formalizer (no API key) for known phrasings
stt "In triangle ABC, AB = AC, and D is the midpoint of BC. Draw the median AD." -o out/median
# From a text file
stt examples/equilateral.txt -o out/equilateral
# Skip LaTeX compile
stt examples/equilateral.txt -o out/equilateral --no-compile
# Re-solve and emit from saved IR (no LLM)
stt --ir out/median.ir.json --emit-only -o out/median2Outputs (for -o out/fig):
| File | Contents |
|---|---|
out/fig.tex |
Standalone TikZ document |
out/fig.ir.json |
Formal GeometryIR |
out/fig.report.json |
Mode, residuals, compile status |
out/fig.pdf |
If compile succeeds |
- exact — max constraint residual ≤
1e-4(default--tol) - schematic — solver failed or underconstrained; incidence soft-repaired, still labeled
For statements outside the offline patterns, set:
export OPENAI_API_KEY=...
# optional
export OPENAI_BASE_URL=https://api.openai.com/v1
export STT_MODEL=gpt-4o-miniThen:
stt "..." --no-offline -o out/figfrom statement_to_tikz.pipeline import run_pipeline
result = run_pipeline(
"Equilateral triangle ABC.",
out_dir="out",
basename="eq",
compile_pdf=False,
)
print(result["mode"], result["coordinates"])Or build IR by hand / from JSON and skip formalization:
from statement_to_tikz.pipeline import load_ir, run_pipeline
ir = load_ir("tests/fixtures/equilateral.json") # strip expected_mode first if presentpytest -qequal_length, length, equal_angle, angle_measure, perpendicular, parallel, on_line, on_circle, midpoint, collinear, intersection, plus circles (center/through).
MIT — see LICENSE.