# Document

Construct, query, edit, and serialize the editable TeXForm document tree.

https://texform.dev/api/js/document

## `Document`

Kind: class

```ts
Document(options: { knowledgeBase?: KnowledgeBase; mode?: RuntimeContentMode; } | undefined)
```

The editable LaTeX document tree — the working format you read, mutate,
serialize, and transform.

Reads go through read-only [Node](/api/js/node#Node) handles; edits are validated eagerly
and throw [TexformEditError](/api/js/utilities#TexformEditError) on misuse, so no internal failure ever
corrupts the tree. A tree that [Document.hasErrors](/api/js/document#Document.hasErrors) is read-only and
fixed that way at construction: every editing method then throws.

`Document` is a live WASM-backed class instance, not plain data. Documents
share an immutable KnowledgeBase with their parser or engine. Transform accepts any complete document with the same knowledge-base identity.

```ts
import { Document } from 'texform';

const doc = new Document();
doc.toLatex(); // ''
```

- [Node](https://texform.dev/api/js/node.md#Node)
- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)
- [Document.hasErrors](https://texform.dev/api/js/document.md#Document.hasErrors)
- [TransformEngine](https://texform.dev/api/js/transform-engine.md#TransformEngine)
- [Parsing](https://texform.dev/docs/parsing.md)

### Construction and copying

#### `Document`

```ts
Document(options: { knowledgeBase?: KnowledgeBase; mode?: RuntimeContentMode; } | undefined)
```

Construct an empty math-mode document holding a single empty root.

This is a complete tree (`hasErrors()` is `false`) — the same legal state
an empty parse produces. The document is editable and serializable, and it
shares the default KnowledgeBase unless one is supplied.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | { knowledgeBase?: KnowledgeBase; mode?: RuntimeContentMode; } | undefined | — |  |

#### `fromSyntax`

```ts
fromSyntax(node: SyntaxNode, options: { knowledgeBase?: KnowledgeBase } | undefined): Document
```

Build a document from a [SyntaxNode](/api/js/parser#SyntaxNode) snapshot.

Invalid external syntax is rejected rather than corrupting the tree.
`fromSyntax` and [Document.toSyntax](/api/js/document#Document.toSyntax) are symmetric over every node
kind, including `Error` and `Prime`. A bare `Prime` is a symbol, not a
shorthand superscript. The imported document is
bound to the supplied KnowledgeBase or the shared default.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the snapshot does not conform to the knowledge base.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | SyntaxNode | — | - A `SyntaxNode` object, typically produced by `toSyntax()`. |
| `options` | { knowledgeBase?: KnowledgeBase } | undefined | — |  |

**Returns** `Document` The reconstructed editable document.

```ts
import { Document, Parser } from 'texform';

const result = new Parser().parse(String.raw`\frac{x}{y}`);
if (!result.document) throw new Error('parse failed');
const syntax = result.document.toSyntax();
const doc = Document.fromSyntax(syntax);
```

- [SyntaxNode](https://texform.dev/api/js/parser.md#SyntaxNode)
- [Document.toSyntax](https://texform.dev/api/js/document.md#Document.toSyntax)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `clone`

```ts
clone(): Document
```

Deep-copy the tree into a new document with new node identities, sharing this document's knowledge base.

**Returns** `Document`

### Queries

#### `root`

```ts
root(): Node
```

Return the root [Node](/api/js/node#Node) of the tree.

The root is unique and parentless; it is the document's top-level container
node — a `Root` node, not a `Group` — and its children are the top-level
content.

**Returns** `Node` The root node handle.

```ts
const doc = new Parser().parse(String.raw`\frac{x}{y}`).document;
doc.root().kind; // 'root'
```

- [Node](https://texform.dev/api/js/node.md#Node)

#### `hasErrors`

```ts
hasErrors(): boolean
```

Whether the tree contains any `Error` placeholder node.

This is a cheap O(1) signal, independent of the
[ParseConfig.abortOnError](/api/js/parser#ParseConfig.abortOnError) parse-strictness knob and separate
from structural validity. A tree that has errors is read-only.

**Returns** `boolean` `true` if any `Error` node is present.

```ts
new Parser().parse(String.raw`\sqrt[`).document.hasErrors(); // true
```

- [ParseConfig.abortOnError](https://texform.dev/api/js/parser.md#ParseConfig.abortOnError)

#### `isReadOnly`

```ts
isReadOnly(): boolean
```

Whether the document rejects edits.

Read-only-ness is fixed at construction and is equivalent to
[Document.hasErrors](/api/js/document#Document.hasErrors): a tree containing error nodes cannot be edited,
so its error count cannot change.

**Returns** `boolean` `true` if every editing method will throw.

- [Document.hasErrors](https://texform.dev/api/js/document.md#Document.hasErrors)

#### `errors`

```ts
errors(): Node[]
```

Return the `Error` placeholder [Node](/api/js/node#Node) handles in the tree.

**Returns** `Node[]` An array of the `Error` nodes; empty when `hasErrors()` is false.

- [Node](https://texform.dev/api/js/node.md#Node)

#### `findCommands`

```ts
findCommands(name: string): Node[]
```

Return every command [Node](/api/js/node#Node) in the tree whose name equals `name`.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — | - The command name to match, without the leading backslash. |

**Returns** `Node[]` The matching command node handles.

```ts
const doc = new Parser().parse(String.raw`\frac{x}{y} + \frac{a}{b}`).document;
doc.findCommands('frac').length; // 2
```

- [Node](https://texform.dev/api/js/node.md#Node)

#### `findEnvironments`

```ts
findEnvironments(name: string): Node[]
```

Return every environment [Node](/api/js/node#Node) in the tree whose name equals `name`.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — | - The environment name to match. |

**Returns** `Node[]` The matching environment node handles.

- [Node](https://texform.dev/api/js/node.md#Node)

#### `nodeSpans`

```ts
nodeSpans(): NodeSpanEntry[]
```

Export the parse-time span side table as a list of `{id, span}` entries.

Ids follow the parser's tree-path scheme rooted at `root`: `.child.N` for
container children, `.arg.N.content` for content-carrying argument slots,
`.left` / `.right` for infix operands, `.body` for environment bodies, and
`.base` / `.sub` / `.sup` for script slots. Nodes without a recorded span
are omitted. Spans reflect the original parse and are not updated by edits.

**Returns** `NodeSpanEntry[]` The span entries in tree order.

#### `nodeAt`

```ts
nodeAt(path: string): Node
```

Resolve a path to a node handle. Paths are rooted and use the scheme of [Node.path](/api/js/node#Node.path); edits shift them, so use paths read from the current tree.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the path does not exist.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `path` | string | — |  |

**Returns** `Node`

- [Node.path](https://texform.dev/api/js/node.md#Node.path)
- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `knowledgeBase`

```ts
knowledgeBase(): KnowledgeBase
```

The immutable knowledge base bound to this document. Construction and edits are checked against it; `toLatex` is not.

**Returns** `KnowledgeBase`

### Output

#### `toLatex`

```ts
toLatex(options: SerializeOptions | null | undefined): string
```

Serialize the tree back to LaTeX text.

The serializer guarantees text idempotency: re-parsing and re-serializing
the output yields the same string. `Error` nodes round-trip their captured
source snippet verbatim, and pure prime superscripts serialize compactly as
`f'` or `f''`. There is intentionally no method named `serialize` on
`Document`. For the output styles, see the Serialization guide and
[SerializeOptions](/api/js/serialize#SerializeOptions).

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | SerializeOptions | null | undefined | — | - A [SerializeOptions](/api/js/serialize#SerializeOptions) object, or omit/`null` for the
default (spaced) style. |

**Returns** `string` The serialized LaTeX string.

```ts
const doc = new Parser().parse(String.raw`x^2`).document;
doc.toLatex();                    // 'x ^ { 2 }'
doc.toLatex({ style: 'compact' }); // 'x^2'
```

- [SerializeOptions](https://texform.dev/api/js/serialize.md#SerializeOptions)
- [Serialization](https://texform.dev/docs/serialization.md)

#### `toTokenizedLatex`

```ts
toTokenizedLatex(options: SerializeOptions | null | undefined): TokenizedLatex
```

Serialize the tree to LaTeX together with typed output tokens.

Token spans use UTF-8 byte offsets, not JavaScript UTF-16 indices. Empty
error snippets produce no zero-width token; use [Document.hasErrors](/api/js/document#Document.hasErrors)
to detect whether the document contains error nodes.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | SerializeOptions | null | undefined | — | - A [SerializeOptions](/api/js/serialize#SerializeOptions) object, as for [Document.toLatex](/api/js/document#Document.toLatex).
`null` / `undefined` / omitted keeps the default (spaced) style. |

**Returns** `TokenizedLatex` Serialized LaTeX plus typed fragments from the same traversal.

```ts
const tok = new Parser().parse('x^2').document!.toTokenizedLatex();
tok.latex; // 'x ^ { 2 }'
tok.tokens[0].kind; // 'character'
```

- [Document.hasErrors](https://texform.dev/api/js/document.md#Document.hasErrors)
- [SerializeOptions](https://texform.dev/api/js/serialize.md#SerializeOptions)
- [Document.toLatex](https://texform.dev/api/js/document.md#Document.toLatex)

#### `toSyntax`

```ts
toSyntax(): SyntaxNode
```

Convert the tree to a [SyntaxNode](/api/js/parser#SyntaxNode) object for serde and transport.

This is the structured-data channel, distinct from the LaTeX text channel
[Document.toLatex](/api/js/document#Document.toLatex).

**Returns** `SyntaxNode` The lossless snapshot of the tree.

```ts
doc.toSyntax(); // { Root: { ... } }
```

- [SyntaxNode](https://texform.dev/api/js/parser.md#SyntaxNode)
- [Document.toLatex](https://texform.dev/api/js/document.md#Document.toLatex)

#### `toColumnar`

```ts
toColumnar(): ColumnarTree
```

Flatten the tree into columns for bulk structural analysis with Arrow or DataFrame tools.
Modes describe node contexts. Missing indices are -1; other missing values
are null. Detached subtrees are excluded. Error documents are supported.

**Returns** `ColumnarTree`

### Staging constructors

The `create*` methods, `parseFragment`, `cloneNode`, and `importNode` build detached subtrees owned by this document. A staged node is not in the tree until you attach it with an edit method.

#### `createChar`

```ts
createChar(value: string, options: ConstructionOptions | undefined): Node
```

Create a detached single-character node owned by this document.

The node is not in the tree until attached with an edit method such as
[Document.appendChild](/api/js/document#Document.appendChild). Every `create*` method takes `options.mode` to construct in another context; see [ConstructionOptions](/api/js/knowledge-base#ConstructionOptions) for the defaults.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the character cannot be
written in that mode, such as `\`, `^`, `~`, or a math-mode space, and
[TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | string | — | - The single character. `"&"` is a literal ampersand written `\&`. |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node` The detached node handle.

- [Document.appendChild](https://texform.dev/api/js/document.md#Document.appendChild)
- [ConstructionOptions](https://texform.dev/api/js/knowledge-base.md#ConstructionOptions)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `createText`

```ts
createText(value: string, options: ConstructionOptions | undefined): Node
```

Create a detached text node. Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the text cannot be written in the mode.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | string | — |  |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `createActiveSpace`

```ts
createActiveSpace(options: ConstructionOptions | undefined): Node
```

Create a detached active-space node.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

#### `createGroup`

```ts
createGroup(mode: RuntimeContentMode, children: (Node | string)[] | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached brace group built in its own `mode`.

Throws [TexformParseError](/api/js/utilities#TexformParseError) for source that does not parse cleanly, [TexformConformanceError](/api/js/utilities#TexformConformanceError) for a child built in another mode or an infix with siblings, and [TexformEditError](/api/js/utilities#TexformEditError) for an attached, foreign, or repeated child.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | RuntimeContentMode | — | - The group's content mode and context. |
| `children` | (Node | string)[] | undefined | — | - Detached nodes or source strings. A string is parsed in `mode` and its nodes are spliced into the list, so one string may yield several children. |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

```ts
const group = doc.createGroup('math', ['x^2', doc.createChar('y')]);
```

- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `createCommand`

```ts
createCommand(name: string, args: Arg[] | null | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached prefix command.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the name is not a prefix command (the message names the right constructor, such as `createDeclarative` for `bf`), the argument count is wrong, or an argument does not fit its slot; [TexformParseError](/api/js/utilities#TexformParseError) for invalid source arguments.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — | - The command name without the leading backslash. A name missing from the knowledge base creates an unknown command without arguments. |
| `args` | Arg[] | null | undefined | — | - Values for every signature slot, or only the required slots to omit optional and star slots. See [Arg](/api/js/node#Arg). |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

```ts
doc.appendChild(doc.root(), doc.createCommand('sqrt', ['x']));
doc.toLatex(); // '\\sqrt { x }'
```

- [Arg](https://texform.dev/api/js/node.md#Arg)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `createDeclarative`

```ts
createDeclarative(name: string, args: Arg[] | null | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached declarative command such as `\bf`. Same conditions as [Document.createCommand](/api/js/document#Document.createCommand), except the record must be declarative.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — |  |
| `args` | Arg[] | null | undefined | — |  |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [Document.createCommand](https://texform.dev/api/js/document.md#Document.createCommand)

#### `createEnvironment`

```ts
createEnvironment(name: string, args: Arg[] | null | undefined, body: Node | string | (Node | string)[] | null | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached environment.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if an argument does not fit the signature or the body is not a group in the body mode, and [TexformParseError](/api/js/utilities#TexformParseError) for invalid source.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — | - The environment name. An unknown environment takes no arguments and uses the surrounding mode. |
| `args` | Arg[] | null | undefined | — | - Slot values, as for [Document.createCommand](/api/js/document#Document.createCommand). |
| `body` | Node | string | (Node | string)[] | null | undefined | — | - A detached group in the body mode, a source string parsed in the recorded body mode, a list whose source strings are spliced as in [Document.createGroup](/api/js/document#Document.createGroup), or `null` for an empty body. |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [Document.createCommand](https://texform.dev/api/js/document.md#Document.createCommand)
- [Document.createGroup](https://texform.dev/api/js/document.md#Document.createGroup)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `createAlignmentTab`

```ts
createAlignmentTab(options: ConstructionOptions | undefined): Node
```

Create a detached unescaped `&` cell separator. Use `createChar("&")` for a literal ampersand.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

#### `createDelimitedGroup`

```ts
createDelimitedGroup(left: string, right: string, children: (Node | string)[] | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached `\left...\right` group, built in math mode by default.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) for a delimiter that is neither `.` nor registered in the knowledge base, plus the conditions of `createGroup`.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `left` | string | — | - The left delimiter source, such as `"("` or `"\\langle"`. |
| `right` | string | — | - The right delimiter source. |
| `children` | (Node | string)[] | undefined | — | - Nodes or source strings, spliced as in [Document.createGroup](/api/js/document#Document.createGroup). |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [Document.createGroup](https://texform.dev/api/js/document.md#Document.createGroup)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `createInlineMath`

```ts
createInlineMath(children: (Node | string)[] | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached `$...$` group of math children, in a text context by default.

Same failure conditions as `createGroup`.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | (Node | string)[] | undefined | — | - Nodes or source strings, spliced as in [Document.createGroup](/api/js/document#Document.createGroup). |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [Document.createGroup](https://texform.dev/api/js/document.md#Document.createGroup)

#### `createScripted`

```ts
createScripted(base: Node | string, sub: Node | string | null | undefined, sup: Node | string | null | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached scripted node, built in math mode by default.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if both scripts are absent or the base is a scripted node, an infix, or an alignment tab, and [TexformParseError](/api/js/utilities#TexformParseError) for invalid source.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `base` | Node | string | — | - The base node or source. |
| `sub` | Node | string | null | undefined | — | - The subscript node or source, or `null` for none. |
| `sup` | Node | string | null | undefined | — | - The superscript node or source, or `null` for none. |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

```ts
doc.appendChild(doc.root(), doc.createScripted('x', null, '2'));
```

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `createPrime`

```ts
createPrime(count: number, options: ConstructionOptions | undefined): Node
```

Create a detached run of `count` primes, built in math mode by default.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if `count` is not positive.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `count` | number | — |  |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `createInfix`

```ts
createInfix(name: string, left: Node | string, right: Node | string, args: Arg[] | null | undefined, options: ConstructionOptions | undefined): Node
```

Create a detached infix command such as `\over`, built in math mode by default.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) under the conditions of `createCommand`, except the record must be infix.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | — |  |
| `left` | Node | string | — | - The left operand node or source. |
| `right` | Node | string | — | - The right operand node or source. |
| `args` | Arg[] | null | undefined | — | - Values for extra slots, such as the dimension of `\above`. |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `parseFragment`

```ts
parseFragment(source: string, options: ConstructionOptions | undefined): Node
```

Parse source into a detached implicit group, in `options.mode` or the root mode.

Throws [TexformParseError](/api/js/utilities#TexformParseError) with the diagnostics if the source does not parse cleanly.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `source` | string | — |  |
| `options` | ConstructionOptions | undefined | — |  |

**Returns** `Node`

- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `cloneNode`

```ts
cloneNode(node: Node): Node
```

Deep-copy a subtree of this document as a detached node.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |

**Returns** `Node`

#### `importNode`

```ts
importNode(node: Node): Node
```

Copy a subtree from another document into this one as a detached node, validating it against this document's knowledge base.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the subtree does not conform to this knowledge base.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |

**Returns** `Node`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

### Edit methods

All edits are validated eagerly and throw `TexformEditError` on misuse. Nodes must belong to this document, the root cannot be detached, and a tree that `hasErrors()` is read-only.

#### `appendChild`

```ts
appendChild(parent: Node, child: Node): void
```

Append `child` as the last child of `parent`.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
either node is foreign or missing, `parent` is not a container, or the move
would create a cycle.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `parent` | Node | — | - The container node to append into. |
| `child` | Node | — | - The node to append. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `insertChild`

```ts
insertChild(parent: Node, index: number, child: Node): void
```

Insert `child` at position `index` among `parent`'s children.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
either node is foreign or missing, `parent` is not a container, `index` is
out of range, or the move would create a cycle.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `parent` | Node | — | - The container node. |
| `index` | number | — | - The zero-based insertion index. |
| `child` | Node | — | - The node to insert. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `insertBefore`

```ts
insertBefore(anchor: Node, node: Node): void
```

Insert `node` immediately before the sibling `anchor`.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
either node is foreign or missing, `anchor` has no parent (such as the
root), or the move would create a cycle.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `anchor` | Node | — | - The sibling to insert before. |
| `node` | Node | — | - The node to insert. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `insertAfter`

```ts
insertAfter(anchor: Node, node: Node): void
```

Insert `node` immediately after the sibling `anchor`.

Same failure conditions as [Document.insertBefore](/api/js/document#Document.insertBefore).

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `anchor` | Node | — | - The sibling to insert after. |
| `node` | Node | — | - The node to insert. |

**Returns** `void`

- [Document.insertBefore](https://texform.dev/api/js/document.md#Document.insertBefore)

#### `replaceWith`

```ts
replaceWith(target: Node, replacement: Node): void
```

Replace `target` in place with `replacement`.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
either node is foreign or missing, `target` is the root, or the move would
create a cycle.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `target` | Node | — | - The node to replace. |
| `replacement` | Node | — | - The node to put in its place. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `wrap`

```ts
wrap(target: Node, wrapper: Node): Node
```

Wrap `target` inside the container `wrapper`.

`wrapper` takes `target`'s place in the tree and `target` becomes its
child.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
either node is foreign or missing, `wrapper` is not a container, or
`target` is the root.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `target` | Node | — | - The node to wrap. |
| `wrapper` | Node | — | - The container node to wrap it in. |

**Returns** `Node` The `wrapper` node, now positioned in the tree.

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `unwrap`

```ts
unwrap(group: Node): Node[]
```

Unwrap a group, splicing its children into its parent in place.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`group` is foreign, missing, not a group, or the root.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `group` | Node | — | - The group node to dissolve. |

**Returns** `Node[]` The freed child node handles, now in the parent.

```ts
const doc = new Parser().parse(String.raw`{x y}`).document;
const group = doc.root().descendants().find((n) => n.kind === 'group');
doc.unwrap(group);
doc.toLatex(); // 'x y'
```

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `extract`

```ts
extract(node: Node): Node
```

Detach the subtree rooted at `node` and return it as a detached node.

The subtree is removed from its parent but kept alive, so it can be
re-attached elsewhere.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or the root.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The subtree root to detach. |

**Returns** `Node` The detached node.

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `remove`

```ts
remove(node: Node): void
```

Remove the subtree rooted at `node` and discard it.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or the root.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The subtree root to remove. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `clear`

```ts
clear(node: Node): void
```

Remove every child of the container `node`.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or not a container.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The container to empty. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `setText`

```ts
setText(node: Node, value: string): void
```

Set the content of a text node.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or not a text node.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The text node to update. |
| `value` | string | — | - The new text content. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `setChar`

```ts
setChar(node: Node, value: string): void
```

Set the character of a char node.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or not a char node.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The char node to update. |
| `value` | string | — | - The new single character. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `setCommandName`

```ts
setCommandName(node: Node, name: string): void
```

Rename a command node.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only, or
`node` is foreign, missing, or not a command node.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The command node to rename. |
| `name` | string | — | - The new command name. |

**Returns** `void`

- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)

#### `setEnvName`

```ts
setEnvName(node: Node, name: string): void
```

Rename an environment, keeping its arguments and body.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the new name's signature or body mode does not fit the existing arguments and body.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `name` | string | — |  |

**Returns** `void`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `setArg`

```ts
setArg(node: Node, index: number, value: Arg): void
```

Set the argument at `index` of a command or environment node.

Throws [TexformEditError](/api/js/utilities#TexformEditError) if the document is read-only,
`node` is foreign or missing, there is no argument slot at `index`, or
`value` does not match the slot shape; [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the value does not fit the slot; [TexformParseError](/api/js/utilities#TexformParseError) for invalid source.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — | - The command or environment node. |
| `index` | number | — | - The zero-based argument slot index. |
| `value` | Arg | — | - The new argument value; see [Arg](/api/js/node#Arg). `null` clears an optional slot. |

**Returns** `void`

- [Arg](https://texform.dev/api/js/node.md#Arg)
- [TexformEditError](https://texform.dev/api/js/utilities.md#TexformEditError)
- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `setArgDelimiters`

```ts
setArgDelimiters(node: Node, index: number, open: string, close: string): void
```

Change only the boundaries of a filled paired argument. Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the slot is not a filled paired slot or the delimiters are not allowed.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `index` | number | — |  |
| `open` | string | — |  |
| `close` | string | — |  |

**Returns** `void`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `setDelimiters`

```ts
setDelimiters(node: Node, left: string, right: string): void
```

Change the delimiters of a `\left...\right` group. Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) for a delimiter that is neither `.` nor registered.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `left` | string | — |  |
| `right` | string | — |  |

**Returns** `void`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

#### `setSubscript`

```ts
setSubscript(node: Node, value: Arg | undefined): Node
```

Set or clear the subscript of `node`. A non-scripted node becomes the base of a new scripted node; an existing scripted base is resolved automatically.

Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if the base cannot carry scripts and [TexformParseError](/api/js/utilities#TexformParseError) for invalid source.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `value` | Arg | undefined | — | - The subscript node or source, or omit/`null` to clear it. |

**Returns** `Node` The resulting scripted node, or the base when clearing the last script collapses the wrapper.

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)
- [TexformParseError](https://texform.dev/api/js/utilities.md#TexformParseError)

#### `setSuperscript`

```ts
setSuperscript(node: Node, value: Arg | undefined): Node
```

Set or clear the superscript of `node`; behaves like [Document.setSubscript](/api/js/document#Document.setSubscript).

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `value` | Arg | undefined | — |  |

**Returns** `Node`

- [Document.setSubscript](https://texform.dev/api/js/document.md#Document.setSubscript)

#### `setPrimeCount`

```ts
setPrimeCount(node: Node, count: number): void
```

Set the number of primes in a prime node. Throws [TexformConformanceError](/api/js/utilities#TexformConformanceError) if `count` is not positive.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `node` | Node | — |  |
| `count` | number | — |  |

**Returns** `void`

- [TexformConformanceError](https://texform.dev/api/js/utilities.md#TexformConformanceError)

### Lifecycle

#### `free`

```ts
free(): void
```

Release the WASM handle for this document 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 documents
would otherwise accumulate WASM memory.

**Returns** `void`

#### `[Symbol.dispose]`

```ts
[Symbol.dispose](): void
```

Release the WASM handle. Same as [Document.free](/api/js/document#Document.free); used by `using`.

**Returns** `void`

- [Document.free](https://texform.dev/api/js/document.md#Document.free)

## `NodeSpanEntry`

Kind: interface

One entry of [Document.nodeSpans](/api/js/document#Document.nodeSpans): a node identifier paired with its
recorded source [Span](/api/js/parser#Span).

| Name | Type | Description |
| --- | --- | --- |
| `id` | string | Tree path such as `root.child.0.arg.1.content`. |
| `span` | Span | The node's source byte span recorded by the parser. |

- [Document.nodeSpans](https://texform.dev/api/js/document.md#Document.nodeSpans)
- [Span](https://texform.dev/api/js/parser.md#Span)

## `TokenizedLatex`

Kind: interface

Serialized LaTeX and tokens produced by the same serializer traversal.

| Name | Type | Description |
| --- | --- | --- |
| `latex` | string | Serialized LaTeX string, identical to [Document.toLatex](/api/js/document#Document.toLatex). |
| `tokens` | SerializationToken[] | Ordered, non-overlapping, non-empty fragments. Gaps contain serializer-inserted spacing. Empty error snippets emit no token. |

## `SerializationToken`

Kind: interface

One non-empty serialization fragment.

| Name | Type | Description |
| --- | --- | --- |
| `text` | string | Fragment text, decoded from bytes `[startByte, endByte)` of the UTF-8 encoding of `latex`. |
| `startByte` | number | Inclusive UTF-8 byte offset into [TokenizedLatex.latex](/api/js/document#TokenizedLatex.latex), not a JavaScript UTF-16 index. |
| `endByte` | number | Exclusive UTF-8 byte offset into [TokenizedLatex.latex](/api/js/document#TokenizedLatex.latex), not a JavaScript UTF-16 index. |
| `kind` | SerializationTokenKind | Semantic category of the fragment. |
| `mode` | "math" | "text" | Semantic math/text mode of the fragment, independent of spacing policy. |

## `SerializationTokenKind`

Kind: typeAlias

```ts
"control_sequence" | "character" | "delimiter" | "text" | "raw" | "error"
```

Closed semantic categories emitted by tokenized serialization.

## `NodeTable`

Kind: interface

Preorder node columns; field names stay snake_case in both bindings.

| Name | Type | Description |
| --- | --- | --- |
| `kind` | Array<"Root" | "Group" | "Command" | "Infix" | "Declarative" | "Environment" | "Scripted" | "Prime" | "Text" | "Char" | "ActiveSpace" | "AlignmentTab" | "Error"> |  |
| `parent` | number[] |  |
| `slot` | Array<NodeSlot["kind"] | null> |  |
| `slot_index` | number[] |  |
| `depth` | number[] |  |
| `mode` | RuntimeContentMode[] |  |
| `name` | Array<string | null> |  |
| `value` | Array<string | null> |  |
| `known` | Array<boolean | null> |  |
| `group_kind` | Array<"explicit" | "implicit" | "delimited" | "inline_math" | null> |  |
| `left` | Array<string | null> |  |
| `right` | Array<string | null> |  |

## `ArgumentTable`

Kind: interface

All argument slots, ordered by owner row and slot index.

| Name | Type | Description |
| --- | --- | --- |
| `owner` | number[] |  |
| `index` | number[] |  |
| `form` | Array<ArgForm["kind"] | null> |  |
| `present` | boolean[] |  |
| `value_kind` | Array<"math" | "text" | "operator_name" | "delimiter" | "cs_name" | "dimension" | "integer" | "key_val" | "column" | "boolean" | null> |  |
| `value` | Array<string | null> |  |
| `content` | number[] |  |
| `open` | Array<string | null> |  |
| `close` | Array<string | null> |  |

## `ColumnarTree`

Kind: interface

Tree columns for bulk structural analysis with Arrow or DataFrame tools.

| Name | Type | Description |
| --- | --- | --- |
| `nodes` | NodeTable |  |
| `args` | ArgumentTable |  |

