# How TeXForm compares

TeXForm next to LaTeX parsers, normalization scripts, renderers, and CAS tools: a feature matrix for the tools that overlap with it, and when to use which.

https://texform.dev/docs/comparison

Any program that reads LaTeX math as more than a string needs to know what each command takes. `\frac12` has two arguments, `\binom{n}{k}` has two, and `\dv{f}{x}` has two only when the `physics` package is in play. Several kinds of tool carry some of that knowledge, and TeXForm overlaps with each of them in a different way.

## The landscape [#the-landscape]

| Tool                                    | Kind                 | What you get                                   | Overlap with TeXForm                      |
| --------------------------------------- | -------------------- | ---------------------------------------------- | ----------------------------------------- |
| pylatexenc, unified-latex, TexSoup      | LaTeX parser         | A tree of a LaTeX document, and LaTeX back out | Parsing, editing, serialization           |
| Compute Engine                          | Math engine          | MathJSON expressions, and LaTeX back out       | Parsing and serialization, as mathematics |
| SymPy, Math-Verify                      | Math engine          | SymPy expressions for checking answers         | Comparing formulas, as mathematics        |
| im2markup normalizer                    | Normalization script | A token string for recognition labels          | Normalization                             |
| MATH `strip_string`, Minerva normalizer | Normalization script | A comparison key for grading answers           | Normalization                             |
| KaTeX, MathJax, Temml                   | Renderer             | HTML and MathML                                | Knowing what commands mean                |
| texvcjs                                 | Validator            | LaTeX checked against a fixed command list     | Knowing what commands mean                |

The parsers and Compute Engine are libraries that read LaTeX into a structure and write LaTeX back, which is what TeXForm does too, so the [feature comparison](#feature-comparison) below puts them side by side. Normalization scripts, renderers, and math engines solve narrower jobs; the sections after the matrix cover how TeXForm fits next to them.

## Feature comparison [#feature-comparison]

|                                                 | TeXForm                                                                 | pylatexenc                                                           | unified-latex                                                         | TexSoup                                                        | Compute Engine                                                         |
| ----------------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **Parsing**            |                                                                         |                                                                      |                                                                       |                                                                |                                                                        |
| Math command signatures                         | Yes: Knowledge base, by package       | Partly: LaTeX core                | Partly: Core and selected packages | No: Takes following groups   | Partly: Math dictionary             |
| `amsmath` commands, such as `\binom`            | Yes                                             | No: Groups left as siblings        | No: Groups left as siblings         | Partly: By position         | Partly: As mathematics              |
| Package macros, such as `\dv`                   | Yes: Opt-in `physics`                 | No: Groups left as siblings        | No: Groups left as siblings         | Partly: By position         | No: Error node                       |
| Unbraced arguments, `\frac12`                   | Yes                                             | Yes                                          | Yes                                           | No: Text `12`                | Yes                                            |
| Infix commands, `a \over b`                     | Yes: Infix node                       | No: Plain command                  | No: Plain command                   | No: Plain command            | Yes: As division                     |
| Your own command signatures                     | Yes                                             | Yes: Macro specs                   | Yes: Macro specs                    | No: No public API            | Yes: Dictionary entries              |
| **Errors**             |                                                                         |                                                                      |                                                                       |                                                                |                                                                        |
| Reports unknown commands                        | Yes: Rejected or marked               | No                                           | No                                            | No                                     | Yes: Error node                      |
| Reports malformed input, `\frac{a}{b`           | Yes: Diagnostics                      | Partly: With tolerant parsing off | No                                            | Yes: Exception               | Yes: Error node                      |
| **Output and editing** |                                                                         |                                                                      |                                                                       |                                                                |                                                                        |
| Writes LaTeX back                               | Yes: Canonical spacing                | Yes: Source text                   | Yes: Light reformatting             | Yes: Source text             | Partly: Notation may change         |
| Editable tree                                   | Yes: Edits checked against signatures | Partly: Write-back in 3.0 beta    | Yes: unist tree                     | Yes: Insert, replace, delete | Partly: Immutable expressions       |
| **Normalization**      |                                                                         |                                                                      |                                                                       |                                                                |                                                                        |
| Folds equivalent spellings                      | Yes: Four profiles                    | No                                           | No                                            | No                                     | Partly: Mathematical canonical form |
| Expands package macros to core LaTeX            | Yes                                             | No                                           | Partly: Definitions you supply     | No                                     | No                                             |
| **Scope**              |                                                                         |                                                                      |                                                                       |                                                                |                                                                        |
| Whole LaTeX documents                           | No: Formulas only                     | Yes                                          | Yes                                           | Yes                                    | No: Formulas only                    |
| Languages                                       | Rust, Python, JavaScript, CLI                                           | Python                                                               | JavaScript                                                            | Python                                                         | JavaScript                                                             |

Some cells need a qualifier:

* **TeXForm** loads a default package set; `physics` is opt-in because it gives `\ket` and related commands different meanings than `braket` does. Strict parsing rejects unknown commands, and the default lenient mode keeps them as nodes marked unknown. Package macros are expanded by the `Faithful` profile and stronger ones; `Authoring` keeps them. See [Transforms](https://texform.dev/docs/transforms) for the profiles.
* **pylatexenc** 2.x writes back each node's source text, so changing a node does not change the output; the 3.0 beta adds a recomposer that rebuilds LaTeX from the nodes.
* **unified-latex** ships signatures for the LaTeX core and selected packages, including `mathtools` but not `amsmath` or `physics`. Its `unified-latex-util-macros` package expands macros once you give it their definitions.
* **TexSoup** attaches every bracket and brace group that follows a command, apart from a small hard-coded table, so `\binom{n}{k}` and `\dv{f}{x}` get two arguments while `\frac12` gets none.
* **Compute Engine** reads formulas as mathematics: `a \over b` comes back as `\frac{a}{b}`, and an `aligned` environment as a list. Its canonical forms may change between versions.

The number of arguments each parser attached on the inputs above, with groups left as siblings in parentheses:

| Input          | pylatexenc   | unified-latex | TexSoup       | TeXForm |
| -------------- | ------------ | ------------- | ------------- | ------- |
| `\dv{f}{x}`    | 0 (2 groups) | 0 (2 groups)  | 2             | 2       |
| `\frac12`      | 2            | 2             | 0 (text `12`) | 2       |
| `\binom{n}{k}` | 0 (2 groups) | 0 (2 groups)  | 2             | 2       |

**When a parser is the right choice.** For whole LaTeX documents, with sections, environments, and preambles, use pylatexenc, unified-latex, or TexSoup; TeXForm parses formulas only. unified-latex also fits naturally if your pipeline already lives in the unified.js ecosystem. For formulas, TeXForm gives you the argument structure without writing signatures, and an editable [`Document`](https://texform.dev/docs/edit-a-document) whose edits are validated against the same signatures.

## Normalization scripts [#normalization-scripts]

Many recognition datasets and metrics normalize labels with a copy of the im2markup preprocessing script, which parses with a vendored KaTeX 0.6.0 and re-serializes the tree as space-separated tokens. Answer-grading code strips and rewrites strings until two answers can be compared: `strip_string` from the MATH benchmark, the normalization in lm-evaluation-harness adapted from the Minerva paper, and evaluation scripts derived from them.

TeXForm does the same jobs from the parse tree instead of string edits. The `Corpus` profile produces complete canonical forms intended as training labels, and `Equiv` folds equivalent spellings into one string for comparison and deduplication. Every rule declares the forms it eliminates, and the engine checks that they are gone. Malformed formulas fail with diagnostics instead of producing a different string, so you can sort a batch into normalized, repairable, and discarded formulas; [Clean OCR/MER output](https://texform.dev/docs/clean-ocr-mer-output) shows the workflow. Serialization in either style is text-idempotent: parsing a normalized formula and serializing it again returns the same string.

| Input                  | im2markup normalizer        | TeXForm `Corpus`                |
| ---------------------- | --------------------------- | ------------------------------- |
| `a \over b`            | `\frac { a } { b }`         | `\frac { a } { b }`             |
| `{\bf x} + \mathbf{y}` | `{ \bf x } + \mathbf { y }` | `\mathbf { x } + \mathbf { y }` |
| `a \le b \leq c`       | `a \le b \leq c`            | `a \leq b \leq c`               |

For `\dv{f}{x}`, the im2markup normalizer keeps `\dv { f } { x }`, while `Corpus` expands it into a fraction of differentials. TeXForm's spaced token output matches what tokenized training labels usually expect; if you want compact LaTeX instead, see [Configure output style](https://texform.dev/docs/configure-output-style).

**When the script is the right choice.** If you must reproduce numbers reported on an existing benchmark, use that benchmark's own normalizer, because changing it changes the scores. TeXForm is the choice for new labels and new pipelines.

## Renderers and math engines [#renderers-and-math-engines]

**Renderers** such as KaTeX, MathJax, and Temml know commands well enough to display them, and emit HTML or MathML, not LaTeX. Support for package macros varies: MathJax renders `physics` macros once its `physics` extension is loaded, which it is not by default; Temml bundles physics support; with KaTeX you define the macros yourself in its `macros` option. TeXForm's `Faithful` profile expands convenience macros into core LaTeX while keeping the rendered formula the same, so `\dv{f}{x}` becomes `\frac { \mathrm { d } f } { \mathrm { d } x }` and works on a stock renderer; see [Use TeXForm with MathJax or KaTeX](https://texform.dev/docs/use-with-a-renderer). If you control the renderer and only need display, loading the extension is the simpler path.

**texvcjs**, the checker behind math on Wikipedia, accepts LaTeX from a fixed table of functions and rejects anything else. It suits a site that needs one safe input language; TeXForm's knowledge base is curated per package and you choose which packages to load.

**Math engines** such as SymPy and Math-Verify read formulas as mathematics: `\frac12` becomes the number one half. That is the right tool for checking an answer, and the wrong one for keeping notation. TeXForm does not decide that `x + x` equals `2x`; for mathematical equivalence, normalize with TeXForm first and hand the result to SymPy or Math-Verify. [Compare formulas](https://texform.dev/docs/compare-formulas) shows the two layers together.

## When to use something else [#when-to-use-something-else]

* **Displaying math:** KaTeX, MathJax, or Temml. TeXForm emits LaTeX and never renders.
* **Symbolic math and answer checking:** SymPy, Math-Verify, or Compute Engine.
* **Whole documents:** LaTeXML, pandoc, or plasTeX convert full LaTeX documents to HTML, XML, or other formats.
* **Formatting `.tex` source:** tex-fmt or latexindent.
* **Converting to Typst or MathML:** MiTeX or tex2typst for Typst, Temml or texmath for MathML.

## What TeXForm does not cover [#what-texform-does-not-cover]

* **Commands outside the knowledge base.** The knowledge base is curated per package; browse what it covers in the [LaTeX reference](https://texform.dev/latex). Strict parsing rejects anything else, and lenient parsing keeps it as an opaque node. You can register your own commands; see [Inject custom commands](https://texform.dev/docs/inject-custom-commands) and [Handle parse errors](https://texform.dev/docs/handle-parse-errors).
* **Rewrites nobody has written yet.** Normalization covers the rules in the [rule reference](https://texform.dev/rules); a command the knowledge base parses is not necessarily rewritten by any profile.
* **Mathematical equivalence, rendering, and documents.** These are out of scope by design; [What TeXForm is](https://texform.dev/docs/what-is-texform) explains why.

## Tools compared [#tools-compared]

Project pages: [pylatexenc](https://github.com/phfaist/pylatexenc), [unified-latex](https://github.com/siefkenj/unified-latex), [TexSoup](https://github.com/alvinwan/TexSoup), [im2markup](https://github.com/harvardnlp/im2markup), [MATH](https://github.com/hendrycks/math), [lm-evaluation-harness](https://github.com/EleutherAI/lm-evaluation-harness), [SymPy](https://docs.sympy.org/latest/modules/parsing.html), [Math-Verify](https://github.com/huggingface/Math-Verify), [Compute Engine](https://mathlive.io/compute-engine/), [texvcjs](https://github.com/wikimedia/texvcjs), [KaTeX](https://katex.org/), [MathJax](https://docs.mathjax.org/), [Temml](https://temml.org/), [LaTeXML](https://math.nist.gov/~BMiller/LaTeXML/), [pandoc](https://pandoc.org/), [plasTeX](https://github.com/plastex/plastex), [tex-fmt](https://github.com/WGUNDERWOOD/tex-fmt), [latexindent](https://github.com/cmhughes/latexindent.pl), [MiTeX](https://github.com/mitex-rs/mitex), [tex2typst](https://github.com/qwinsi/tex2typst), [texmath](https://github.com/jgm/texmath). If a tool has changed since, corrections are welcome: [open an issue](https://github.com/texform-dev/texform/issues/new).

- [What TeXForm is](https://texform.dev/docs/what-is-texform) — The three pillars, and what TeXForm leaves to renderers and CAS tools.

- [Transforms](https://texform.dev/docs/transforms) — The four profiles and the rule ladder behind them.

- [Clean OCR/MER output](https://texform.dev/docs/clean-ocr-mer-output) — Sort recognition output into normalized, repairable, and discarded formulas.

