Text
The Text node is the catch-all: any input fragment that doesn’t
match a typed production lands here. The grammar is total — it
never fails on stray input, it just emits a Text node.
Fields
Section titled “Fields”| Field | Type | Description |
|---|---|---|
content | String | The captured text content |
Why a catch-all?
Section titled “Why a catch-all?”Two reasons:
- Forward compatibility. Inputs that use constructs not yet
implemented (e.g. aromatic rings before v0.3) parse successfully,
with the unknown fragment as a
Textnode. The renderer echoes the source verbatim — no data loss. - Punctuation and whitespace. Reaction separators (
+), padding spaces, and other syntactic glue between typed nodes are captured asTextso round-trip is exact.
Grammar production
Section titled “Grammar production”text_run := (not structural-char)*
where structural-char excludes: ` (math escape) + (reaction separator) arrow tokens (<=>, <->, ->, <-) group brackets ( ) [ ] { }The exclusion keeps structural boundaries crisp.
Formatter behaviour
Section titled “Formatter behaviour”Every formatter’s visit_text emits the content verbatim (with
appropriate escaping for the output format).
| Formatter | Output |
|---|---|
| MathML | <mtext>content</mtext> |
| Text | content |
| HTML | escaped content |
| LaTeX | content |
| SVG | content |
Round-trip
Section titled “Round-trip”Text nodes preserve their content exactly. The Text formatter is
the canonicaliser; any input that survives parsing as Text will
round-trip character-for-character.
When Text appears
Section titled “When Text appears”A typical input contains Text nodes for:
- The
+separators in reactions (2H_2 + O_2hasText(" ")between molecules — though the grammar usually trims this). - Multi-digit stoichiometric coefficients that don’t form a valid
element (e.g.
H_2O3parses as Molecule[H_2, O], Text(“3”)). - Punctuation the user includes (
H_2O., with a literal period).
Children contract
Section titled “Children contract”Text is a leaf node — children returns [].