Parserclass#
A knowledge-driven LaTeX parser.
Parser turns LaTeX source into a ParseResult by consulting the
knowledge base for command and environment signatures. It does not normalize
— use TransformEngine for that. Parsing never throws on malformed
input; failures surface in the result. For the conceptual model, see the
Parsing guide.
Since 0.4.0 the default is ParseConfig LENIENT
(rejectUnknown: false, abortOnError: false). Per-call config is a
camelCase overlay object: 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. Omit knowledgeBase
to share the default instance, or construct a KnowledgeBase to customize packages and entries.
import { Parser, KnowledgeBase } from 'texform';
const parser = new Parser();
parser.parse(String.raw`\frac{x}{y}`).document?.toLatex(); // '\\frac { x } { y }'
const restricted = new Parser({ knowledgeBase: new KnowledgeBase({ packages: ['base', 'ams'] }) });Parser#
Parser(options: ParserOptions | null | undefined)Construct a parser with an optional shared knowledge base.
| Parameter | Type | Description |
|---|---|---|
options | Parser |
|
parse#
parse(src: string, config: ParseConfig | null | undefined): ParseResultParse a LaTeX string into a ParseResult.
Never throws on malformed input: the result has one of three honest states
(no tree, complete tree, or partial tree with Error nodes). Empty input
('') yields a clean, complete document, not null.
| Parameter | Type | Description |
|---|---|---|
src | string |
|
config | Parse |
|
ParseResult — The parse result (document and diagnostics).
const result = new Parser().parse(String.raw`\frac{x}{y}`);
const document = result.document;
const diagnostics = result.diagnostics;defaultParseConfig#
defaultParseConfig(): Complete<ParseConfig>Return this parser's complete default ParseConfig.
Every field is present. Use it as a starting point when you want to change one key and pass the rest through.
Complete<ParseConfig>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.
Lifecycle#
free#
free(): voidRelease the WASM handle for this parser 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 parsers
would otherwise accumulate WASM memory.
[Symbol.dispose]#
[Symbol.dispose](): voidRelease the WASM handle. Same as Parser.free; used by using.
ParserOptionsinterface#
| Field | Type | Description |
|---|---|---|
knowledgeBase | Knowledge | — |
defaultParseConfig | Parse | Overlay applied to ParseConfig |
ParseConfiginterface#
Parser strictness configuration overlay, as a plain object with camelCase
keys. All fields are optional; null / undefined means not set. Unknown
keys, snake_case keys, arrays in object positions, and wrong scalar types
throw TexformConfigError with a path.
The two boolean axes are orthogonal: ParseConfig.rejectUnknown controls how unknown names are handled, while ParseConfig.abortOnError controls whether the parser stops at the first error or keeps recovering. Neither implies the other, and neither is equivalent to the resulting tree's Document.hasErrors signal.
| Field | Type | Description |
|---|---|---|
rejectUnknown | boolean | | Reject unknown command and environment names. Default When |
abortOnError | boolean | | Stop at the first error per item instead of recovering. Default When |
maxGroupDepth | number | | Maximum group nesting depth before the parser aborts a group. Default
|
new Parser().parse(String.raw`\foobar{x}`, {
rejectUnknown: true,
abortOnError: true,
});ParseResultinterface#
The outcome of Parser.parse (and TransformEngine.parse): an optional Document plus the diagnostics emitted while parsing.
There are exactly three honest states, and parse never throws on malformed
input nor fabricates a placeholder tree:
- Hard failure —
documentisnull; the failure is described entirely bydiagnostics. - Clean parse —
documentis a complete, editable tree withhasErrors() === false. Empty input ('') lands here, not innull. - Partial parse —
documentis present withhasErrors() === true; recovery preserved the unparseable parts as read-onlyErrornodes.
| Field | Type | Description |
|---|---|---|
document | Document | | The parsed document, or |
diagnostics | Parse | Diagnostics emitted while parsing; may be empty on a clean parse. |
ParseDiagnosticinterface#
One diagnostic emitted while parsing, describing a recovered or rejected condition.
Diagnostics are a separate channel from Error placeholder nodes: a
diagnostic does not by itself make an otherwise editable tree read-only.
Within a parser-produced result, however, a tree that
Document.hasErrors always comes with at least one diagnostic.
| Field | Type | Description |
|---|---|---|
kind | Parse | The diagnostic category, or |
message | string | Human-readable description of the problem. |
span | Span | Source span the diagnostic points at. |
expected | string[ | Tokens the parser expected at this position; may be empty. |
found | string | | The token actually found, or |
contexts | Parse | Enclosing-construct frames, outermost-relevant first; may be empty. |
ParseDiagnosticContextinterface#
One nested context frame attached to a ParseDiagnostic, locating the enclosing construct (such as the command or environment) the error occurred within.
| Field | Type | Description |
|---|---|---|
label | string | Human-readable label for the enclosing construct. |
span | Span | Source span of the enclosing construct. |
ParseDiagnosticKindtype#
"ambiguous-infix" | "argument-validation" | "command-mode-error" | "comment-truncated-argument" | "environment-mode-error" | "environment-name-mismatch" | "invalid-character" | "left-right-delimiter" | "max-group-depth-exceeded" | "raw-expected-found" | "text-script-error" | "unclosed-environment" | "unclosed-inline-math" | "unexpected-math-shift" | "unknown-command" | "unknown-environment"The category of a ParseDiagnostic, or null when the parser emits a
diagnostic without a specific category.
Each variant names a distinct recoverable or rejected parse condition, such as an unknown command, an argument-validation failure, or an unclosed inline math span.
Spaninterface#
A source byte range, half-open as [start, end), indexing into the original
LaTeX input.
| Field | Type | Description |
|---|---|---|
start | number | Inclusive start byte offset. |
end | number | Exclusive end byte offset. |
SyntaxNodetype#
{ Root: { mode: SyntaxContentMode; children: SyntaxNode[] } } | { Group: { mode: SyntaxContentMode; kind: GroupKind; children: SyntaxNode[]; }; } | { Command: { name: string; args: ArgumentSlot[]; known: boolean } } | { Infix: { name: string; args: ArgumentSlot[]; left: SyntaxNode; right: SyntaxNode; }; } | { Declarative: { name: string; args: ArgumentSlot[] } } | { Environment: { name: string; args: ArgumentSlot[]; known: boolean; body: SyntaxNode; }; } | { Scripted: { base: SyntaxNode; subscript?: SyntaxNode; superscript?: SyntaxNode; }; } | { Prime: { count: number } } | { Error: { message: string; snippet: string } } | { Text: string } | { Char: string } | "ActiveSpace" | "AlignmentTab"The lossless, immutable parse snapshot — the single serde wire format.
SyntaxNode is a plain object (not a class instance) that backs JSON
snapshots, transport across the binding, and test fixtures. It can represent
a partial parse: unparseable fragments survive as Error nodes. It carries
no editing behavior; bridge it into an editable tree with
Document.fromSyntax, and recover one with Document.toSyntax.
The two conversions are symmetric over every node kind, including Error and
Prime. A Prime node represents symbols in the current math list;
Scripted supplies any superscript binding. A leading quote has an empty
group as its scripted base. External snapshots cannot infer the old intent
of a bare Prime node; reparse the source or update the tree explicitly.
ContextItemtype#
{ target: "command"; name: string; kind: CommandKind; allowedMode: string; argspec: string; tags?: string[]; } | { target: "environment"; name: string; allowedMode: string; bodyMode: RuntimeContentMode; argspec: string; tags?: string[]; } | { target: "delimiter"; name: string; }One custom knowledge entry supplied to KnowledgeBase
through the items option, discriminated by
target.
A command entry carries its kind, allowed mode, and argspec; an
environment entry additionally carries its bodyMode; a delimiter entry
registers a delimiter-control name. Unknown keys and disallowed fields throw
TexformConfigError.
CommandInfointerface#
The knowledge-base entry for a command, returned by KnowledgeBase.lookupCommand and related lookups.
| Field | Type | Description |
|---|---|---|
name | string | The command name, without the leading backslash. |
kind | Command | The command's syntactic role (prefix, infix, declarative). |
allowedMode | string | The modes the command is allowed in. |
specString | string | The raw xparse-style argument-specification string. |
fromPackages | string[ | The knowledge packages that define this command. |
tags | string[ | Free-form classification tags. |
args | Parsed | The parsed argument slots, mirroring validateArgspec output. |
EnvInfointerface#
The knowledge-base entry for an environment, returned by KnowledgeBase.lookupEnv.
| Field | Type | Description |
|---|---|---|
name | string | The environment name. |
allowedMode | string | The modes the environment is allowed in. |
bodyMode | Runtime | The content mode the environment body is parsed in. |
specString | string | The raw xparse-style argument-specification string. |
fromPackages | string[ | The knowledge packages that define this environment. |
tags | string[ | Free-form classification tags. |
args | Parsed | The parsed argument slots for the environment's arguments. |
CharacterInfointerface#
The knowledge-base entry for a special character, returned by KnowledgeBase.lookupCharacter.
| Field | Type | Description |
|---|---|---|
name | string | The character name, without the leading backslash. |
allowedMode | string | The modes the character is allowed in. |
unicodeValue | string | The Unicode code point the character maps to, as a string. |
attributes | Character | Rendering attributes such as |
package | string | The knowledge package that defines this character. |
CharacterAttributesInfointerface#
Rendering attributes for a special character in the knowledge base.
| Field | Type | Description |
|---|---|---|
mathvariant | string | | The MathML |
AllowedModetype#
"math" | "text" | "both"The content modes a command, environment, or character is allowed in:
"math", "text", or "both".
CommandKindtype#
"prefix" | "infix" | "declarative"The syntactic role of a command in the knowledge base: "prefix" (takes its
arguments after the control sequence), "infix" (binds operands on both
sides, like \over), or "declarative" (a scope-affecting declaration).
ArgSpecKindInfotype#
{ type: "content"; mode: RuntimeContentMode } | { type: "operatorname" } | { type: "delimiter" } | { type: "csname" } | { type: "dimension" } | { type: "integer" } | { type: "keyval" } | { type: "column" } | { type: "star" }The value kind one parsed argument slot accepts, with a type discriminator.
content carries the RuntimeContentMode its body parses in; the
other variants are leaf kinds (operatorname, delimiter, csname, dimension,
integer, keyval, column, star).
DelimiterTokenInfotype#
{ type: "char"; value: string } | { type: "control-seq"; value: string }A single delimiter token in an argspec form: a literal char (such as ()
or a control-seq (such as langle).
ArgSpecFormInfotype#
{ type: "standard" } | { type: "star" } | { type: "group" } | { type: "until"; close: DelimiterTokenInfo } | { type: "delimited"; open: DelimiterTokenInfo; close: DelimiterTokenInfo } | { type: "paired"; pairs: Array<{ open: DelimiterTokenInfo; close: DelimiterTokenInfo }>; }The syntactic form one parsed argument slot takes, with a type
discriminator: a standard argument, a star flag, a brace group, a
delimited argument bounded by an open/close pair, or a paired argument
accepting any of several interchangeable delimiter pairs.