equamorph is a mathematical expression transformation pipeline for converting notation among LaTeX, GitHub MathJax, ASCII, and Unicode, extracting text-encoded mathematics from PDFs, and compiling normalized expressions into executable Python or Rust functions.
- Complete directed conversion matrix among
latex,mathjax,ascii, andunicode. - Per-file automatic source-syntax detection when
--fromis omitted. - Single-file and non-recursive directory processing.
- In-place conversion or output-directory copies.
- Text-PDF extraction for LaTeX-style spans:
\(...\),\[...\],$...$, and$$...$$. - Non-overlapping PDF extraction so display-dollar expressions are not re-extracted as inline expressions.
- Shared SymPy parsing with ANTLR-first, Lark fallback, and deterministic common-LaTeX fallback parsing.
- Python scalar function generation with safe source/docstrings and
mathqualification. - Rust scalar
f64generation using SymPy's Rust printer plus support for constants, abs, floor/ceil, min/max, powers, roots, and common transcendental functions. - Stable symbol registry and exported symbol/provenance metadata.
- Hash, sequential, and semantic function naming.
- Explicit partial-generation failure reporting.
pip install -e .For PDF extraction:
pip install -e ".[pdf]"The package installs the equamorph command.
equamorph --from latex --to mathjax --input notes.md
equamorph --from ascii --to unicode --input equations.txt
equamorph --from unicode --to latex --input unicode_notes.mdAutomatic source detection is enabled when --from is omitted:
equamorph --to mathjax --input notes.md -Y-N is strict non-interactive mode and therefore requires both --from and --to.
equamorph --input paper.pdf --output equations.mdThe current extractor operates on text recovered from the PDF and recognizes explicit LaTeX-style delimiters in that text. It does not yet reconstruct arbitrary visually typeset equations from glyph geometry or raster images. That broader PDF-equation capability is part of the full-vision roadmap in ROADMAP.md.
Python:
equamorph --input paper.pdf --codegen python --codegen-output generated/Rust:
equamorph --input paper.pdf --codegen rust --codegen-output generated/Generated artifacts:
<name>_lib.pyor<name>_lib.rs<name>_lib.symbols.json<name>_lib.metadata.jsonfailed_expressions.txtwhen any expression cannot be parsed/generated
Code generation currently has an explicit scalar-function contract. Equality/inequality relations are not silently coerced into scalar functions; they are reported as failures so equation semantics can be added deliberately rather than guessed.
hash: stable hash-derived function names.sequential:expr_0,expr_1, ...semantic: deterministic names derived from expression structure and free variables.
equamorph/
domain/
syntax_types.py
codegen_types.py
application/
converter.py
expression_parser.py
expression_pipeline.py
file_processor.py
pdf_extractor.py
symbol_registry.py
function_generator.py
codegen_orchestrator.py
backends/
base.py
python_backend.py
rust_backend.py
registry.py
presentation/
cli/main.py
infrastructure/
The domain contains data/contracts only. Mathematical parsing has one shared owner. Target-language rendering is owned by backends. The former duplicate Python-only LibraryAssembler path was removed.
python -m pytest -qThe stabilization suite currently contains 89 passing tests covering:
- the full syntax conversion matrix and auto-detection
- LaTeX/MathJax wrapper round trips
- ASCII/Unicode conversion
- parser fallbacks and Unicode symbol handling
- PDF overlap/de-duplication behavior
- symbol normalization and provenance
- all naming strategies and docstring modes
- Python expression generation and executable E2E imports
- Rust expression generation regressions
- partial failure behavior
- architecture/file-size checks
See HARDENING_REPORT.md for the completed repair inventory and ROADMAP.md for the remaining full-vision work.
