Skip to content

texform-dev/texform

Repository files navigation

TeXForm

The missing foundation for LaTeX formula processing.

TeXForm parses, edits, and transforms LaTeX math, built on a structured knowledge base of 530+ command and environment specifications across 7 LaTeX packages, validated against MathJax, KaTeX, and XeTeX. One Rust core, available in Rust, Python, and JavaScript.

crates.io PyPI npm License

Playground · Architecture · Changelog

Why TeXForm

Programs that process LaTeX formulas — cleaning OCR training data, comparing formulas for equivalence, preparing pretraining corpora, building math editors — keep reinventing the same fragile layer: regular expressions and one-off heuristics that guess what \frac, \over, or \quantity mean. The hard part was never the string manipulation. It is knowing the argument structure of every command well enough to work on formulas as syntax trees instead of text.

TeXForm is that missing layer. It parses formulas against a real command knowledge base, gives you an editable document tree, and normalizes formulas into canonical forms tuned for specific downstream uses.

What TeXForm gives you

Knowledge-driven parser Editable document tree Profile-based transform engine

Formulas parse into real syntax trees, driven by xparse-style argument specifications for every command in base, ams, physics, braket, bboldx, boldsymbol, and textmacros. Unknown commands and unparseable fragments survive as explicit nodes — under your control, never a crash.

Parsing produces a Document — a DOM-style tree you can query, mutate, and serialize back to LaTeX. Edits are validated and return structured errors; no panic ever reaches the caller. The canonical serializer guarantees text idempotency.

Normalization has no single correct answer, so TeXForm never imposes one true form. You pick a Profile, and a curated rule pipeline produces the canonical form for that use case — from polished authoring output to aggressive corpus normalization.

Normalization at a glance

Each Profile targets one downstream scenario:

Profile Target scenario
Authoring Polished author-facing output; stylistic choices kept.
Faithful Same rendered formula; convenience macros expanded into universal forms.
Corpus Training-data normalization; layout hints dropped.
Equiv Aggressive canonicalization for formula equivalence comparison.

The same input, normalized under different profiles (real engine output):

Input Authoring Corpus Corpus, rendered
a \over b \frac { a } { b } \frac { a } { b } $\frac { a } { b }$
\substack{a \\ b} \substack { a \\ b } \begin {subarray} {c} a \\ b \end {subarray} $\begin {subarray} {c} a \ b \end {subarray}$
\dv{f}{x} \dv { f } { x } \frac { \mathrm { d } f } { \mathrm { d } x } $\frac { \mathrm { d } f } { \mathrm { d } x }$
\ket{\psi} \ket { \psi } \left \vert \psi \right \rangle $\left \vert \psi \right \rangle$

Every profile modernizes legacy syntax like \over. Authoring keeps the author's shorthand; Corpus expands it into universal forms that render on any vanilla MathJax or KaTeX deployment with no extra packages — including right here on GitHub, where inputs like \dv and \ket would not render at all.

What's underneath

Behind a profile, normalization runs as a multi-phase pipeline, not a find-and-replace pass:

  • Rewrite applies a curated rule set in a fixed-point loop — modernizing legacy syntax, canonicalizing aliases, and expanding semantic macros, depending on the levels the profile selects.
  • LowerAttributes canonicalizes font and style markup, so {\bf x} and \mathbf{x} converge to a single form with declarative scope tracked correctly.
  • FlattenGroups strips redundant braces behind semantic and spacing guards, so flattening never changes script binding, environment cell boundaries, or atom spacing unless you opt in.

Two assets carry most of the weight, and neither existed as a reusable artifact before:

  • The argspec knowledge base. Machine-readable, xparse-style argument signatures for every supported command and environment — validated by rendering against MathJax, KaTeX, and XeTeX rather than transcribed from documentation.
  • The curated rewrite rule set. Every rule declares its normalization level, its worst-case render fidelity, and the forms it eliminates. The engine enforces that eliminated-form contract after every run, and corpus regression re-checks it against real-world datasets.

Quick start

Python

pip install texform
import texform

engine = texform.TransformEngine(profile="corpus")
assert engine.normalize(r"a \over b")["normalized"] == r"\frac { a } { b }"

parsed = engine.parse(r"a \over b")
if parsed["document"] is not None:
    document = parsed["document"]
    engine.transform(document)
    assert document.to_latex() == r"\frac { a } { b }"

JavaScript / TypeScript

npm install texform
import { TransformEngine } from "texform";

const engine = new TransformEngine({ profile: "corpus" });
console.assert(engine.normalize("a \\over b").normalized === "\\frac { a } { b }");

const parsed = engine.parse("a \\over b");
if (parsed.document) {
  engine.transform(parsed.document);
  console.assert(parsed.document.toLatex() === "\\frac { a } { b }");
}

Rust

cargo add texform
use texform::{Profile, TransformEngine};

let engine = TransformEngine::builder().profile(Profile::Corpus).build()?;
let result = engine.normalize(r"a \over b")?;
assert_eq!(result.normalized, r"\frac { a } { b }");

let (mut document, _) = engine.parser().parse(r"a \over b").try_into_document()?;
engine.transform(&mut document)?;
assert_eq!(document.to_latex()?, r"\frac { a } { b }");

Note: the texform crate is the only public, stability-guaranteed Rust entry point; the texform-* crates it depends on are internal and may change in any release. See ARCHITECTURE.md for the crate layout and the public API guarantees.

The Python and JavaScript bindings expose the same parser, document, and engine from the single Rust core. See the PyPI package notes and the npm package notes for language-specific details.

Links

  • Playground — try TeXForm in the browser
  • ARCHITECTURE.md — crate layout, pipeline, tree representations, API guarantees
  • TESTING.md — how TeXForm is tested, from contract tests to corpus regression
  • CHANGELOG.md — release history

License

Apache-2.0. See LICENSE.

About

The missing foundation for LaTeX formula processing.

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors