JavaScriptTransformEngine

TransformEngine

Python

Normalize formulas with a profile, tune the pipeline, and read the transform report.

TransformEngineclass#

A profile-based normalization engine: a parser paired with a transform pipeline.

TransformEngine normalizes a formula into the canonical form selected by a Profile. It exposes a string-to-string TransformEngine.normalize path and an in-place TransformEngine.transform path over a live Document. It also exposes its own TransformEngine.parse and the shared knowledge base through TransformEngine.knowledgeBase. For the conceptual model — profiles, the multi-phase pipeline, and the eliminated-form contract — see the Transforms guide.

Since 0.4.0 the bundled parser defaults to lenient ParseConfig, and transform options are a nested camelCase overlay (TransformConfig / NormalizeConfig), not flat rewriteEnabled / maxIterations keys. null / undefined / omitted means not set. Unknown keys, snake_case keys, arrays in object positions, and wrong scalar types throw TexformConfigError with a camelCase path. There is no complete config class on the JavaScript surface; read the effective defaults with TransformEngine.defaultTransformConfig.

TypeScript
import { TransformEngine } from 'texform';

const engine = new TransformEngine({ profile: 'corpus' });
engine.normalize(String.raw`a \over b`); // '\\frac { a } { b }'
engine.normalize(String.raw`a \over b`, { rewrite: { enabled: false } });
engine.normalizeWithReport(String.raw`a \over b`).report.rewrite.iterations;

TransformEngine#

TransformEngine(options: TransformEngineOptions)

Construct an engine for a profile, optionally sharing a knowledge base, or disabling rules.

ParameterTypeDescription
optionsTransformEngineOptions

parse#

parse(src: string, config: ParseConfig | null | undefined): ParseResult

Parse a LaTeX string into a ParseResult, using this engine's parser.

Non-null documents from this result share the engine's KnowledgeBase, so they can be edited and then passed to TransformEngine.transform. The The engine parser defaults to lenient parsing; pass config to override it per call.

ParameterTypeDescription
srcstring
  • The LaTeX source string.
configParseConfig | null | undefined
  • A ParseConfig overlay, or omit/null for the defaults.
Returns
ParseResult —

The parse result (document and diagnostics).

normalize#

normalize(    src: string,    config: NormalizeConfig | null | undefined,): string

Parse, normalize, and serialize a formula in one call.

Normalization is gated on a complete tree: if the input cannot produce one, this throws TexformParseError carrying its diagnostics and the partial document. Empty input is complete and normalizes normally.

ParameterTypeDescription
srcstring
  • The LaTeX source string.
configNormalizeConfig | null | undefined
Returns
string —

The serialized LaTeX string. This path does not build a report.

TypeScript
const engine = new TransformEngine({ profile: 'corpus' });
engine.normalize(String.raw`\dv{f}{x}`);
// '\\frac { \\mathrm { d } f } { \\mathrm { d } x }'

normalizeWithReport#

normalizeWithReport(    src: string,    config: NormalizeConfig | null | undefined,): NormalizeReportResult

Parse, normalize, and serialize a formula, returning text and a diagnostic report.

Accepts the same source and NormalizeConfig overlay as TransformEngine.normalize. Output text and errors follow that contract. Report fields, phase divisions, and counters are diagnostic and are not part of the stable compatibility promise. A failure does not return a partial report.

ParameterTypeDescription
srcstring
  • The LaTeX source string.
configNormalizeConfig | null | undefined
Returns
NormalizeReportResult —

The normalized string and its TransformReport.

transform#

transform(    document: Document,    config: TransformConfig | null | undefined,): void

Transform a live Document in place.

The document must share this engine's KnowledgeBase instance. A document that Document.hasErrors is read-only and cannot be transformed; this precondition error is surfaced as TexformTransformError. This path returns no value and does not build a report.

ParameterTypeDescription
documentDocument
  • The live document to update in place.
configTransformConfig | null | undefined
  • A TransformConfig overlay, or omit/null to use the profile defaults. Nested per-phase shape; does not accept parse options.
TypeScript
const engine = new TransformEngine({ profile: 'corpus' });
const result = engine.parse(String.raw`a \over b`);
if (result.document) {
  engine.transform(result.document);
  result.document.toLatex(); // '\\frac { a } { b }'
}

transformWithReport#

transformWithReport(    document: Document,    config: TransformConfig | null | undefined,): TransformReport

Transform a live Document in place and return its diagnostic report.

Accepts the same document and TransformConfig overlay as TransformEngine.transform. Ownership, completeness, and errors follow that contract. The report is diagnostic and is not part of the stable compatibility promise. A failure does not return a partial report.

ParameterTypeDescription
documentDocument
  • The live document to update in place.
configTransformConfig | null | undefined
Returns
TransformReport —

The diagnostic transform report.

TypeScript
const engine = new TransformEngine({ profile: 'corpus' });
const result = engine.parse(String.raw`a \over b`);
if (result.document) {
  const report = engine.transformWithReport(result.document);
  report.rewrite.rules.some((rule) => rule.key === 'base/over-to-frac');
}

defaultParseConfig#

defaultParseConfig(): Complete<ParseConfig>

Return this engine's complete default ParseConfig.

Returns
Complete<ParseConfig>
See also

defaultTransformConfig#

defaultTransformConfig(): Complete<TransformConfig>

Return this engine's complete default TransformConfig for its profile.

Returns
Complete<TransformConfig>

Knowledge-base lookups#

Query the knowledge the parser loaded. Predicate methods take a single name; lookup methods take name and a mode of "math" or "text" and return a knowledge-entry object or null.

knowledgeBase#

knowledgeBase(): KnowledgeBase

Lifecycle#

free#

free(): void

Release the WASM handle for this engine immediately.

Prefer a using declaration so [Symbol.dispose]() runs at scope exit. After free(), further use is invalid. Skipping free() is safe: garbage collection still reclaims the handle, just not at a determined time. Call free() (or use using) when many short-lived engines would otherwise accumulate WASM memory.

[Symbol.dispose]#

[Symbol.dispose](): void

Release the WASM handle. Same as TransformEngine.free; used by using.

TransformEngineOptionsinterface#

Construction options for TransformEngine: a shared knowledge base, the required normalization Profile, and optional rule disabling.

FieldTypeDescription
profileProfile

The normalization profile (required). Unknown values throw TexformConfigError.

disableRulesstring[] | undefined

Rewrite rule keys to disable, such as "physics/dv-to-frac-d".

NormalizeConfiginterface#

Per-run overlay for TransformEngine.normalize: parse keys from ParseConfig plus transform keys from TransformConfig, flattened together. null / undefined / omitted means not set.

TypeScript
const engine = new TransformEngine({ profile: 'corpus' });
engine.normalize(String.raw`a \over b`, {
  rewrite: { maxIterations: 50 },
  flattenGroups: { enabled: false },
});

TransformConfiginterface#

The nested, per-phase transform configuration, overriding a profile's transform defaults.

Each field controls one pipeline phase. This is the transform-only shape; it does not accept parser-strictness keys (those belong to NormalizeConfig).

Every field is an optional overlay key: null / undefined / omitted keeps the profile's value. Unknown keys, snake_case keys, arrays in object positions, and wrong scalar types throw TexformConfigError with a camelCase field path. Read the effective defaults with TransformEngine.defaultTransformConfig.

FieldTypeDescription
lowerAttributesLowerAttributesConfig | undefined

LowerAttributes phase switches.

rewriteRewriteConfig | undefined

Rewrite phase switches.

finalizeAstFinalizeAstConfig | undefined

FinalizeAst phase switches.

flattenGroupsFlattenGroupsConfig | null | undefined

FlattenGroups phase switches. null keeps the profile's FlattenGroups values.

RewriteConfiginterface#

Per-run switches for the fixed-point Rewrite phase.

FieldTypeDescription
enabledboolean | undefined

Whether the phase runs. When false, legacy syntax is left untouched.

maxIterationsnumber | undefined

Cap on Rewrite fixed-point passes.

LowerAttributesConfiginterface#

Per-run switches for the LowerAttributes phase.

FieldTypeDescription
enabledboolean | undefined

Whether the phase runs. Defaults to the profile's setting.

FinalizeAstConfiginterface#

Per-run switches for the FinalizeAst phase.

FieldTypeDescription
enabledboolean | undefined

Whether the phase runs. Defaults to enabled in every public profile.

FlattenGroupsConfiginterface#

Per-run switches for the FlattenGroups phase (redundant-brace removal).

enabled governs whether the phase runs. preserveRenderedSpacing keeps groups whose only public-facing effect is rendered math spacing; it does not control serializer source whitespace (SerializeOptions *Spacing fields). Structural guards stay on even when preserveRenderedSpacing is false. Omitted keys fall back to the profile's defaults — for example, corpus leaves preserveRenderedSpacing off.

FieldTypeDescription
enabledboolean | null | undefined

Whether the phase runs. null / omitted keeps the profile value.

preserveRenderedSpacingboolean | null | undefined

Keep groups whose only public-facing effect is rendered math spacing.

This is not serializer source spacing. Structural guards stay on even when this is false. null / omitted keeps the profile value.

NormalizeReportResultinterface#

Text plus the diagnostic report from TransformEngine.normalizeWithReport.

Plain TransformEngine.normalize returns the string directly and does not build this object.

FieldTypeDescription
normalizedstring

The serialized LaTeX after parsing and normalization.

reportTransformReport

The diagnostic report for this call.

TransformReportinterface#

Diagnostic report for one explicit report call.

Output text and errors follow the ordinary transform contract. Report fields, phase divisions, and these counters are diagnostic: they are not part of the stable compatibility promise. A disabled phase stays present as zeros or an empty array. Field names are camelCase, the JavaScript view of the snake_case data exposed by the Python binding.

FieldTypeDescription
warningsTransformWarning[]

Unknown input names, deduplicated and sorted by kind and name.

lowerAttributesLowerAttributesReport

LowerAttributes activity, summed across its two passes.

rewriteRewriteReport

Rewrite iterations and per-rule outcomes.

finalizeAstFinalizeAstReport

Prime merges and text normalizations.

flattenGroupsFlattenGroupsReport

Flatten actions and guard hits.

TransformWarninginterface#

An unknown input name whose arguments or scope cannot be guaranteed.

FieldTypeDescription
kind"unknown-command" | "unknown-environment"

The unknown input name's category.

namestring

Name without command or environment delimiters.

messagestring

Explanation of the semantic uncertainty.

LowerAttributesReportinterface#

The LowerAttributes phase report.

FieldTypeDescription
attributesAttributeStat[]

Per-attribute activity, sorted by attr then value.

eliminatedEmptySegmentsnumber

Empty attribute segments removed by the phase.

AttributeStatinterface#

Activity for one (attr, value) pair in LowerAttributes.

FieldTypeDescription
attrstring

Stable attribute name, such as "math_font" or "text_size".

valuestring

Stable value token for that attribute.

consumedAttributeFormCounts

Input forms consumed by LowerAttributes.

redundantAttributeFormCounts

Consumed forms that did not change the emitted attribute state.

emittedAttributeFormCounts

Canonical forms emitted by LowerAttributes.

AttributeFormCountsinterface#

Counts of an attribute form split by carrier: declaratives (scope-affecting declarations such as {\bf ...}) and prefixes (prefix commands such as \mathbf{...}).

FieldTypeDescription
declarativesnumber

Count carried by declarative-form markup.

prefixesnumber

Count carried by prefix-command markup.

RewriteRuleStatinterface#

One rewrite rule's outcome for a single call.

FieldTypeDescription
keystring

Stable rule key.

appliedCountnumber

Times the rule applied.

skippedCountnumber

Times the scheduler matched the rule and apply returned skipped.

RewriteReportinterface#

The Rewrite phase report.

FieldTypeDescription
iterationsnumber

Fixed-point passes, including the final unchanged convergence check. Zero when the phase is disabled or no rules are scheduled.

rulesRewriteRuleStat[]

Rules that recorded activity, sorted by key.

FinalizeAstReportinterface#

The FinalizeAst phase report.

FieldTypeDescription
primeRunMergesnumber

Contiguous Prime runs merged. Each run counts once.

textNormalizationsnumber

Text segments or text argument slots whose content changed.

FlattenGroupsActionCountsinterface#

Flatten actions that changed the tree.

FieldTypeDescription
removedEmptynumber

Empty groups removed.

replacedSingleChildnumber

Groups replaced by their only child.

inlinedMultiChildnumber

Multi-child groups inlined into the parent.

unwrappedSlotnumber

Slot wrappers removed.

FlattenGroupsGuardCountsinterface#

Preserve-guard hits for one FlattenGroups run.

A hit is the first guard branch reached for a group, plus the scripted-base sub-count. commandContactViaScriptedBase is also included in commandContact. These counters are not a partition of preserved groups.

FieldTypeDescription
unknownCommandArgumentsnumber

Possible arguments following an unknown command.

argumentCapturenumber

Groups whose removal would let a command before or inside them read the next token as an omitted optional or delimited argument.

declarativeScopenumber

Declarative-scope protection.

scriptBasenumber

Script-base protection.

envBodynumber

Environment-body protection.

infixScopenumber

Infix-scope protection.

commandContactnumber

Command-contact protection.

commandContactViaScriptedBasenumber

Command contact established through a scripted base.

emptyGroupnumber

Empty-group protection.

loneAtomSpacingCharnumber

Single spacing-character protection.

leadingAtomSpacingCharnumber

Leading spacing-character protection.

delimitedPairnumber

Delimited-pair protection.

FlattenGroupsReportinterface#

The FlattenGroups phase report.

FieldTypeDescription
actionsFlattenGroupsActionCounts

Flatten actions that changed the tree.

guardHitsFlattenGroupsGuardCounts

Preserve-guard hits for this call.

TransformProfiletype#

"authoring" | "faithful" | "corpus" | "equiv"

Normalization profile selecting the canonical form for one downstream scenario: authoring (polished author-facing output), faithful (same rendered formula, convenience macros expanded), corpus (training-data normalization, layout hints dropped), or equiv (aggressive canonicalization for equivalence comparison).

Profiletype#

"authoring" | "faithful" | "corpus" | "equiv"

Normalization profile passed to TransformEngineOptions: "authoring", "faithful", "corpus", or "equiv".

RuleLeveltype#

"authoring" | "faithful" | "corpus" | "equiv"

How aggressively a transform rule may rewrite, layered from least to most destructive of stylistic detail.

A rule level is the first profile that accepts a rule's output as a suitable product; it is orthogonal to a rule's equivalence guarantee.