If you display user-supplied or scraped LaTeX in a browser, you have probably seen formulas that fail to render because the author used a macro their package provides and your renderer does not. \dv{f}{x} is valid LaTeX in a document that loads physics, and it is nothing at all to a stock MathJax or KaTeX deployment. TeXForm fixes that before display: normalize under a profile that expands convenience macros, and hand the resulting string to the renderer you already use.
TeXForm is not a MathJax or KaTeX plugin, and it does not render anything. It is a preprocessing step. Input is a LaTeX string, output is a LaTeX string, and the renderer stays exactly where it is in your stack.
Expand macros the renderer does not know#
The faithful and corpus profiles both expand convenience macros into the universal forms a vanilla renderer understands. faithful is the conservative choice for display: it keeps the rendered formula the same and only replaces markup that needs a package. physics is not in the default package set, so an engine that should expand its macros names it.
import texform
kb = texform.KnowledgeBase(packages=["base", "ams", "physics"])
engine = texform.TransformEngine(profile="faithful", knowledge_base=kb)
for src in [r"\dv{f}{x}", r"\pdv{f}{x}", r"\abs{x}", r"\norm{v}", r"a \over b", r"{\bf x}"]:
print(f"{src!r:14} -> {engine.normalize(src)!r}")'\\dv{f}{x}' -> '\\frac { \\mathrm { d } f } { \\mathrm { d } x }'
'\\pdv{f}{x}' -> '\\frac { \\partial f } { \\partial x }'
'\\abs{x}' -> '\\left | x \\right |'
'\\norm{v}' -> '\\left \\| v \\right \\|'
'a \\over b' -> '\\frac { a } { b }'
'{\\bf x}' -> '\\mathbf { x }'import { KnowledgeBase, TransformEngine } from 'texform';
const knowledgeBase = new KnowledgeBase({ packages: ['base', 'ams', 'physics'] });
const engine = new TransformEngine({ profile: 'faithful', knowledgeBase });
for (const src of ['\\dv{f}{x}', '\\pdv{f}{x}', '\\abs{x}', '\\norm{v}', 'a \\over b', '{\\bf x}']) {
console.log(src, '->', engine.normalize(src));
}Every output on the right is plain base/ams LaTeX. \frac, \partial, \left, \right, and \mathbf are all things a default MathJax or KaTeX build renders without extra configuration, while none of the inputs on the left would have rendered at all. Legacy syntax like \over is modernized by every profile, so that one comes along for free.
Wire it into the render path#
The normalization is one call in front of whatever you already do. Reuse a single engine — construction compiles the rule plan, so building one per formula is wasted work — and fall back to the original string when normalization declines, so a malformed formula degrades to the renderer's own error handling rather than disappearing.
import { KnowledgeBase, TexformParseError, TransformEngine } from 'texform';
import katex from 'katex';
const knowledgeBase = new KnowledgeBase({ packages: ['base', 'ams', 'physics'] });
const engine = new TransformEngine({ profile: 'faithful', knowledgeBase });
function render(element, src) {
let source = src;
try {
source = engine.normalize(src);
} catch (err) {
if (!(err instanceof TexformParseError)) throw err;
// Incomplete formula: let the renderer report it against the original text.
}
katex.render(source, element, { throwOnError: false });
}Choosing a profile for display#
faithful is the default recommendation for rendering because it is defined to preserve the rendered result. corpus expands further and may collapse layout variants that a reader would notice, which is the right trade for training data and the wrong one for a page someone is reading. equiv goes further still and discards visually salient notation — it rewrites \cfrac to \frac, for instance — so it belongs in comparison and deduplication pipelines, not in a render path. The profile table in Transforms lays out the targets side by side.
How the knowledge base relates to renderers#
MathJax, KaTeX, and XeTeX appear in TeXForm's development as validators, not dependencies. Every argument specification in the knowledge base is checked by rendering it against all three engines, which is how the project knows a signature is right rather than merely plausible. That is also why the coverage data on this site reports support per engine: the same formula can be renderable in one and not another.
Two pages cover that ground. Renderer validation explains the methodology and how to read the full, partial, and none verdicts. The renderer coverage reference lets you look up a specific command and see which engines accept it — useful when a formula still fails after normalization and you need to know whether the command is supported by your renderer at all.
Next steps#
Look up which of MathJax, KaTeX, and XeTeX support a given command.
Renderer validationHow specifications are validated by rendering against three engines.
TransformsWhat each profile targets and how the phase pipeline produces it.
Normalize a corpusApply the same engine across a dataset with error handling and statistics.