# Node

Navigate the document tree and read node content through read-only Node handles.

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

## `Node`

Kind: class

A read-only handle into a [Document](/api/js/document#Document).

`Node` carries navigation and accessor members but no editing methods — all
edits go through the owning document. It is a cheap reference, not a copy of
the subtree; reads delegate back into the document. Obtain handles from
[Document.root](/api/js/document#Document.root), [Document.errors](/api/js/document#Document.errors), [Document.findCommands](/api/js/document#Document.findCommands),
the `create*` staging constructors, and the navigation members below.

```ts
const doc = new Parser().parse(String.raw`\frac{x}{y}`).document!;
const cmd = doc.root().children()[0];
cmd.kind; // 'command'
cmd.isCommand('frac'); // true
```

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

### Kind

#### `kind`

The node's kind, read as a property (not a method).

Its value is one of the lowercase [NodeKind](/api/js/node#NodeKind) strings (`'root'`,
`'group'`, `'command'`, `'scripted'`, ...).

### Predicates

#### `isCommand`

```ts
isCommand(name: string | null | undefined): boolean
```

Whether the node is a command; with `name`, whether it is that specific
command.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | null | undefined | — | - Optional command name to match; omit/`null` matches any
command. |

**Returns** `boolean` `true` if the node is a (matching) command.

```ts
node.isCommand();       // any command
node.isCommand('frac'); // specifically \frac
```

#### `isChar`

```ts
isChar(value: string | null | undefined): boolean
```

Whether the node is a char; with `value`, whether it holds that specific
character.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | string | null | undefined | — | - Optional character to match; omit/`null` matches any char. |

**Returns** `boolean` `true` if the node is a (matching) char.

#### `isError`

```ts
isError(): boolean
```

Whether the node is an `Error` placeholder.

**Returns** `boolean` `true` for an `Error` node.

#### `isKnown`

```ts
isKnown(): boolean | null
```

Whether the knowledge base knows this command or environment; `null` for other kinds.

**Returns** `boolean | null`

### Navigation

#### `parent`

```ts
parent(): Node | null
```

The parent [Node](/api/js/node#Node), or `null` for the root.

**Returns** `Node | null` The parent handle, or `null`.

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

#### `children`

The child [Node](/api/js/node#Node)s, as a read-only property.

#### `nextSibling`

```ts
nextSibling(): Node | null
```

The following sibling [Node](/api/js/node#Node), or `null`.

**Returns** `Node | null` The next sibling handle, or `null`.

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

#### `prevSibling`

```ts
prevSibling(): Node | null
```

The preceding sibling [Node](/api/js/node#Node), or `null`.

**Returns** `Node | null` The previous sibling handle, or `null`.

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

#### `ancestors`

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

The ancestor [Node](/api/js/node#Node)s from parent upward.

**Returns** `Node[]` The ancestor handles, nearest first.

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

#### `descendants`

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

The descendant [Node](/api/js/node#Node)s in document order.

**Returns** `Node[]` The descendant handles.

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

#### `path`

```ts
path(): string | null
```

The node's current path from the root, or `null` if detached. Edits change it; [Document.nodeAt](/api/js/document#Document.nodeAt) resolves it.

**Returns** `string | null`

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

#### `slot`

```ts
slot(): NodeSlot | null
```

The slot this node fills in its parent, or `null` for the root and detached nodes.

**Returns** `NodeSlot | null`

### Content accessors

#### `commandName`

The command name for a `command` / `declarative` node, else `null`
(read-only property).

#### `envName`

The environment name for an `environment` node, else `null` (read-only property).

#### `text`

The string value for a `text` node, else `null` (read-only property).

#### `char`

The character for a `char` node, else `null` (read-only property).

#### `primeCount`

```ts
primeCount(): number | null
```

The prime count (greater than zero) for a `prime` node, else `null`.

**Returns** `number | null` The number of consecutive prime symbols, or `null`. `Scripted` determines their binding.

```ts
const doc = new Parser().parse(String.raw`f''`).document;
const prime = doc.root().descendants().find((n) => n.kind === 'prime');
prime.primeCount(); // 2
```

#### `errorParts`

```ts
errorParts(): { message: string; snippet: string } | null
```

For an `error` node, its captured `{ message, snippet }`, else `null`.

**Returns** `{ message: string; snippet: string } | null` The error message and the original source snippet, or `null`.

```ts
const doc = new Parser().parse(String.raw`\sqrt[`).document;
const err = doc.root().descendants().find((n) => n.isError());
err.errorParts(); // { message: 'unclosed bracket argument', snippet: '\\sqrt[' }
```

#### `contentMode`

```ts
contentMode(): RuntimeContentMode | null
```

The runtime content mode (`"math"` or `"text"`) where applicable, else
`null`.

**Returns** `RuntimeContentMode | null` The node's content mode, or `null`.

### Groups

#### `groupKind`

```ts
groupKind(): GroupKindRef | null
```

The [GroupKindRef](/api/js/node#GroupKindRef) for a `group` node, else `null`.

The result carries a capitalized `kind` discriminator (`'Explicit'`,
`'Implicit'`, `'InlineMath'`, `'Delimited'`). A `Delimited` group also
carries `left` and `right` delimiter strings such as `'('` or `'\\langle'`.

**Returns** `GroupKindRef | null` The group kind view, or `null`.

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

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

### Command arguments

#### `argCount`

```ts
argCount(): number
```

The number of argument slots for a command-like node.

**Returns** `number` The slot count.

#### `arg`

```ts
arg(index: number): ArgRef | null
```

The argument at `index`, or `null` if the slot is empty.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `index` | number | — | - The zero-based slot index. |

**Returns** `ArgRef | null` The [ArgRef](/api/js/node#ArgRef) for the slot, or `null`.

```ts
const doc = new Parser().parse(String.raw`\frac{x}{y}`).document;
const frac = doc.root().descendants().find((n) => n.isCommand('frac'));
frac.argCount(); // 2
frac.arg(0);     // { kind: 'Math', node: <Node> }
```

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

#### `argKind`

```ts
argKind(index: number): ArgForm | null
```

The delimiter form of the argument slot at `index`, or `null` if there is no such slot.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `index` | number | — |  |

**Returns** `ArgForm | null`

#### `argSlots`

```ts
argSlots(): Array<ArgRef | null>
```

The full array of argument slots, with `null` for any empty slot.

**Returns** `Array<ArgRef | null>` The [ArgRef](/api/js/node#ArgRef) per slot, `null` where empty.

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

### Scripts and infix

#### `scriptBase`

```ts
scriptBase(): Node | null
```

The base of a `scripted` node, else `null`.

**Returns** `Node | null` The base node handle, or `null`.

#### `subscript`

```ts
subscript(): Node | null
```

The subscript slot of a `scripted` node, else `null`.

**Returns** `Node | null` The subscript node handle, or `null`.

```ts
const doc = new Parser().parse(String.raw`x_i^2`).document;
const sc = doc.root().descendants().find((n) => n.kind === 'scripted');
[sc.subscript().kind, sc.superscript().kind]; // ['char', 'char']
```

#### `superscript`

```ts
superscript(): Node | null
```

The superscript slot of a `scripted` node, else `null`.

**Returns** `Node | null` The superscript node handle, or `null`.

#### `infixLeft`

```ts
infixLeft(): Node | null
```

The left operand of an `infix` node, else `null`.

**Returns** `Node | null` The left operand handle, or `null`.

#### `infixRight`

```ts
infixRight(): Node | null
```

The right operand of an `infix` node, else `null`.

**Returns** `Node | null` The right operand handle, or `null`.

#### `envBody`

```ts
envBody(): Node | null
```

The body group of an `environment` node, else `null`.

**Returns** `Node | null` The body group handle, or `null`.

### Spans

#### `span`

```ts
span(): Span | null
```

The source byte [Span](/api/js/parser#Span) for the node, or `null` if it has no recorded
span.

**Returns** `Span | null` The span, or `null`.

```ts
const doc = new Parser().parse(String.raw`a + b`).document;
doc.root().children[0].span(); // { start: 0, end: 1 }
```

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

### Identity

#### `document`

```ts
document(): Document
```

**Returns** `Document`

#### `isSameNode`

```ts
isSameNode(other: Node): boolean
```

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

**Returns** `boolean`

### Lifecycle

#### `free`

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

Release this node handle's WASM wrapper immediately.

This does not free the owning [Document](/api/js/document#Document). Prefer a `using`
declaration so `[Symbol.dispose]()` runs at scope exit. After `free()`,
further use of this handle is invalid. Skipping `free()` is safe:
garbage collection still reclaims the wrapper.

**Returns** `void`

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

#### `[Symbol.dispose]`

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

Release this handle. Same as [Node.free](/api/js/node#Node.free); used by `using`.

**Returns** `void`

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

## `NodeKind`

Kind: typeAlias

```ts
"root" | "group" | "command" | "infix" | "declarative" | "environment" | "scripted" | "prime" | "text" | "char" | "activeSpace" | "alignmentTab" | "error"
```

The runtime kind of a [Node](/api/js/node#Node), read from the lowercase
[Node.kind](/api/js/node#Node.kind) property.

Note the casing convention: node kinds are lowercase strings (`'command'`,
`'scripted'`), unlike the capitalized discriminators inside argument and
group views (`arg.kind === 'Math'`, `groupKind().kind === 'Explicit'`).

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

## `SyntaxContentMode`

Kind: typeAlias

```ts
"Math" | "Text"
```

Content mode as it appears in a [SyntaxNode](/api/js/parser#SyntaxNode) snapshot: `"Math"` or
`"Text"` (capitalized snapshot form).

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

## `RuntimeContentMode`

Kind: typeAlias

```ts
"math" | "text"
```

Content mode as reported by the runtime tree API: `"math"` or `"text"`
(lowercase form used by [Node.contentMode](/api/js/node#Node.contentMode) and the `mode` arguments of
lookup methods).

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

## `GroupKind`

Kind: typeAlias

```ts
"Explicit" | "Implicit" | { Delimited: { left: Delimiter; right: Delimiter } } | "InlineMath"
```

The kind of a group in [SyntaxNode](/api/js/parser#SyntaxNode) snapshot form: an `Explicit` brace
group, an `Implicit` group, a `Delimited` group carrying its `left`/`right`
delimiters, or an `InlineMath` group.

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

## `GroupKindRef`

Kind: typeAlias

```ts
{ kind: "Explicit" } | { kind: "Implicit" } | { kind: "Delimited"; left: string; right: string } | { kind: "InlineMath" }
```

The kind of a group in runtime view form, with a `kind` discriminator.
Returned by [Node.groupKind](/api/js/node#Node.groupKind); the discriminator keeps its capitalized
form (`'Explicit'`, `'Delimited'`, ...). A `Delimited` group carries
`left` and `right` delimiter strings.

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

## `Delimiter`

Kind: typeAlias

```ts
"None" | { Char: string } | { Control: string }
```

A delimiter token in [SyntaxNode](/api/js/parser#SyntaxNode) snapshot form: the literal `"None"`,
a single character (`{ Char }`), or a control sequence (`{ Control }`).
Runtime views use delimiter strings instead: `.`, one character, or a
backslash-prefixed control sequence such as `\langle`.

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

## `Argument`

Kind: interface

A present command/environment argument in [SyntaxNode](/api/js/parser#SyntaxNode) snapshot form,
pairing its syntactic [ArgumentKind](/api/js/node#ArgumentKind) with its parsed
[ArgumentValue](/api/js/node#ArgumentValue).

| Name | Type | Description |
| --- | --- | --- |
| `kind` | ArgumentKind | The argument's syntactic kind (mandatory, optional, delimited, ...). |
| `no_leading_space` | boolean | undefined | Whether the argspec slot was prefixed with `!`. |
| `value` | ArgumentValue | The argument's parsed value. |

- [SyntaxNode](https://texform.dev/api/js/parser.md#SyntaxNode)
- [ArgumentKind](https://texform.dev/api/js/node.md#ArgumentKind)
- [ArgumentValue](https://texform.dev/api/js/node.md#ArgumentValue)

## `ArgumentKind`

Kind: typeAlias

```ts
"Mandatory" | "Optional" | "Star" | "Group" | { Until: { close: Delimiter } } | { Delimited: { open: Delimiter; close: Delimiter } } | { Paired: { open: Delimiter; close: Delimiter } }
```

The syntactic kind of a command argument in [SyntaxNode](/api/js/parser#SyntaxNode) snapshot form
(mandatory, optional, starred, group, until, or delimited/paired).
Until forms carry `close`; delimited/paired forms carry `open` and `close`.

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

## `ArgumentValue`

Kind: typeAlias

```ts
{ MathContent: SyntaxNode } | { TextContent: SyntaxNode } | { OperatorNameContent: SyntaxNode } | { Delimiter: Delimiter } | { CSName: string } | { Dimension: string } | { Integer: string } | { KeyVal: string } | { Column: string } | { Boolean: boolean }
```

The parsed value carried by an [Argument](/api/js/node#Argument) in snapshot form: math or
text content, a delimiter, a control-sequence name, a dimension, an integer,
a key=value list, a column spec, or a boolean flag.

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

## `ArgumentSlot`

Kind: typeAlias

```ts
Argument | null | undefined
```

An argument slot of a [Node](/api/js/node#Node)'s argument list: either a present
[Argument](/api/js/node#Argument) or an empty slot (`null`/`undefined`).

Optional argument slots that were not supplied in the source surface as the
empty value rather than being dropped, so a slot's index stays stable.

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

## `ArgRef`

Kind: typeAlias

```ts
{ form: ArgForm } & ( | { kind: "Math"; node: Node } | { kind: "Text"; node: Node } | { kind: "OperatorName"; node: Node } | { kind: "Delimiter"; value: string } | { kind: "CSName"; value: string } | { kind: "Dimension"; value: string } | { kind: "Integer"; value: string } | { kind: "KeyVal"; value: string } | { kind: "Column"; value: string } | { kind: "Boolean"; value: boolean })
```

A command/environment argument in runtime view form, returned by
[Node.arg](/api/js/node#Node.arg) and [Node.argSlots](/api/js/node#Node.argSlots).

Content kinds (`Math`, `Text`, `OperatorName`) carry a live `node` [Node](/api/js/node#Node) handle; leaf
kinds (`Delimiter`, `CSName`, `Dimension`, `Integer`, `KeyVal`, `Column`,
`Boolean`) carry a `value`. `Delimiter` values use source strings. The `kind` discriminator keeps its capitalized
form.

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

## `ArgForm`

Kind: typeAlias

```ts
{ kind: "mandatory" | "optional" | "star" | "group" | "until" | "delimited" | "paired"; open?: string; close?: string }
```

The delimiter form of an argument slot; `close` is present for `until`, and both `open` and `close` for `delimited` and `paired` forms.

## `NodeSlot`

Kind: typeAlias

```ts
{ kind: "child" | "arg" | "script_base" | "subscript" | "superscript" | "infix_left" | "infix_right" | "env_body"; index: number | null }
```

The parent slot a [Node](/api/js/node#Node) fills; `index` is set for indexed slots such as children and arguments.

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

## `Arg`

Kind: typeAlias

```ts
Node | string | boolean | null | { value: Arg; open: string; close: string }
```

A slot value accepted by construction and editing methods: a `string` is the source written inside the slot's boundaries, a detached [Node](/api/js/node#Node) is content, `boolean` sets a star slot, `null` omits an optional slot, and `{ value, open, close }` selects an explicit delimiter pair.

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

