Math content may say its source is in scienting-math/1's canonical TeX (form, in no hash); derived/math.jsonl holds papermath's tree, symbols and issues, and the validator now checks derived files. A symbol annotation names its symbol by key; lode claim references use lode's tag and pin syntax. The zip reader refuses entries zipfile cannot read, and checkpoint lines end in LF only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017R7sgDNvUGWY2zFPCq2JH6
154 lines
10 KiB
Markdown
154 lines
10 KiB
Markdown
# 3. Nodes
|
|
|
|
A document is a tree of nodes.
|
|
`nodes.jsonl` holds one node per line, in document order: the root first, then each node before its children, and siblings in order.
|
|
|
|
## 3.1 The node record
|
|
|
|
| Property | Required | Holds |
|
|
| --- | --- | --- |
|
|
| `id` | Yes | The node ID ([4](04-identity.md)). |
|
|
| `kind` | Yes | One of the kinds in [3.2](#32-kinds-and-children). |
|
|
| `parent` | Yes | The parent's ID, or null for the root. |
|
|
| `ord` | Yes | The position among its siblings, from 0. |
|
|
| `label` | No | The printed label (`2.3`, `Figure 2`, `(1)`, `a`), for kinds that take one. |
|
|
| `attrs` | No | Structural attributes, by kind ([3.4](#34-attributes)). |
|
|
| `content` | No | The node's own content, by kind ([3.3](#33-content)). |
|
|
| `withheld` | No | `true` when the policy withholds the content ([12.5](12-package.md#125-text-policies)). |
|
|
| `fidelity` | No | For leaves, the level the pipeline established: `F0`, `F1` or `F2` ([8.1](08-fidelity.md#81-levels-of-fidelity)). |
|
|
| `prov` | No | `{witnesses, backend?, reading?, corroborated_by?}`: the witness IDs the text came from, the backend, and the witnesses that agree. |
|
|
| `text_hash`, `match_hash`, `align_key`, `own_hash`, `node_hash` | Yes | The five content values ([5](05-hashes.md)). |
|
|
|
|
Optional properties are omitted, never written as null.
|
|
The schema is `node.schema.json`.
|
|
|
|
## 3.2 Kinds and children
|
|
|
|
| Kind | May contain | Content | Label |
|
|
| --- | --- | --- | --- |
|
|
| `document` | `front`, `section`, `back` | | |
|
|
| `front` | `title`, `authors`, `abstract`, `keywords`, `notes` | | |
|
|
| `title` | `sentence` | | |
|
|
| `authors` | | runs | |
|
|
| `abstract` | blocks, `section` | | |
|
|
| `keywords` | | runs | |
|
|
| `notes` | `footnote`, `paragraph` | | |
|
|
| `section` | `heading` first, then blocks and `section` | | Yes |
|
|
| `heading` | `sentence` | | |
|
|
| `paragraph` | `sentence` | | |
|
|
| `sentence` | `equation` | runs | |
|
|
| `equation` | `equation-line` | math | Yes |
|
|
| `equation-line` | | math | Yes |
|
|
| `figure` | `panel`, `caption`, `figure-note` | | Yes |
|
|
| `panel` | | | Yes |
|
|
| `caption` | `sentence` | | |
|
|
| `figure-note` | `sentence` | | |
|
|
| `table` | `caption`, `table-head`, `table-body`, `table-note` | | Yes |
|
|
| `table-head`, `table-body` | `row` | | |
|
|
| `table-note` | `sentence` | | |
|
|
| `row` | `cell` | | |
|
|
| `cell` | | runs | |
|
|
| `list` | `item` | | |
|
|
| `item`, `quote` | blocks | | |
|
|
| `code`, `algorithm` | | verbatim | Yes |
|
|
| `theorem` | blocks | | Yes |
|
|
| `footnote` | `sentence` | | Yes |
|
|
| `back` | `acknowledgments`, `references`, `appendix`, `notes` | | |
|
|
| `acknowledgments` | blocks | | |
|
|
| `references` | `reference` | | |
|
|
| `reference` | | runs | Yes |
|
|
| `appendix` | `section` | | |
|
|
|
|
Blocks are `paragraph`, `equation`, `figure`, `table`, `list`, `quote`, `code`, `algorithm`, `theorem` and `footnote`.
|
|
|
|
These rules also hold:
|
|
|
|
1. Exactly one node is a root, and it is a `document`.
|
|
2. A `heading` is a section's first child, and a section has at most one.
|
|
3. `front`, `back`, `title`, `authors`, `abstract`, `keywords`, `caption`, `table-head`, `table-body`, `acknowledgments` and `references` occur at most once among their siblings.
|
|
4. A `table` has exactly one `table-body`.
|
|
5. `title`, `heading`, `paragraph`, `caption`, `figure-note`, `table-note`, `table-head`, `table-body`, `row`, `list`, `item`, `quote`, `theorem`, `footnote` and `appendix` have at least one child.
|
|
6. Only the kinds marked in the table take a `label`.
|
|
7. A body without headings, as in a letter, is a section with no heading.
|
|
|
|
Kinds outside this list are refused; a new kind is a minor version.
|
|
Page breaks, running heads and columns are not nodes: they are geometry ([7](07-geometry.md)).
|
|
|
|
## 3.3 Content
|
|
|
|
| Content | Kinds | Shape |
|
|
| --- | --- | --- |
|
|
| Runs | `sentence`, `cell`, `reference`, `authors`, `keywords` | A non-empty list of inline runs ([3.5](#35-inline-runs)). |
|
|
| Math | `equation`, `equation-line` | `{notation, source, form?}`: `tex` or `typst`, the source as written or as a form spells it, and that form ([3.7](#37-math-forms)). |
|
|
| Verbatim | `code`, `algorithm` | `{language?, text}`. |
|
|
|
|
Other kinds have no `content`.
|
|
Derived renderings and readings, such as MathML and a formula's tree, are not content; they live in `derived/` ([12.7](12-package.md#127-derived-files)).
|
|
|
|
## 3.4 Attributes
|
|
|
|
| Kind | Attribute | Holds |
|
|
| --- | --- | --- |
|
|
| `section` | `level` (required) | 1 for a section, 2 for a subsection, and so on. |
|
|
| `table` | `columns` | The column definitions: `[{id, header_path}]`, where `header_path` lists header cell IDs, outermost first ([9.2](09-figures-tables-equations.md#92-tables)). |
|
|
| `cell` | `column`, `rowspan`, `colspan`, `role` | The column's ID, spans (default 1), and `data` (default), `column-header`, `row-header` or `row-group-header`. |
|
|
| `row` | `header_path` | The cell IDs that label the row, outermost first. |
|
|
| `list` | `ordered` | Whether the list is numbered. |
|
|
| `item` | `marker` | The printed marker. |
|
|
| `theorem` | `variant` | The printed kind: Theorem, Lemma, Definition, Proof, Remark. |
|
|
| `panel` | `image`, `crop`, `figure_text` | The image asset, a crop, and the text found inside the panel ([9.1](09-figures-tables-equations.md#91-figures-and-panels)). |
|
|
|
|
No other kind carries `attrs`, and each kind carries only its own attributes.
|
|
|
|
## 3.5 Inline runs
|
|
|
|
| Run | Properties | Plain projection |
|
|
| --- | --- | --- |
|
|
| `text` | `text`, and optional `style`: a sorted list of distinct values from `em`, `strong`, `sup`, `sub`, `sc`, `mono`, never both `sup` and `sub`. | The text. |
|
|
| `math` | `notation` (`tex` or `typst`), `source`, and optional `form` ([3.7](#37-math-forms)). | `$` + source + `$` |
|
|
| `cite` | `refs`: reference node IDs; `text`: the printed form, such as `23`, `[1,2]` or `(Smith, 2019)`. | The printed form. |
|
|
| `xref` | `target`: a node ID in this document, an address in another, or null when not yet resolved; `text`. | The printed form. |
|
|
| `fnmark` | `footnote`: a footnote's ID, or null; `text`: the mark. | The mark. |
|
|
| `link` | `url`, `text`. | The text. |
|
|
| `equation` | `node`: the ID of an equation child of the sentence. | `$$` + that equation's source + `$$` |
|
|
|
|
A `text`, `link`, `cite`, `xref` or `fnmark` run MAY carry `printed`: its text as the paper prints it, where an `emend` corrected the authors ([11.6](11-corrections.md#116-emendations)).
|
|
The run's `text` is then the emended text, and only an emend writes `printed`.
|
|
|
|
Runs are canonical: no `text` run is empty, no two adjacent `text` runs have the same style list unless one of them carries `printed`, and no run's `printed` equals its `text`.
|
|
A sentence's `equation` runs name its `equation` children, each once, in the children's order, and a sentence has no other children.
|
|
A display equation the sentence runs through is thus part of the sentence, while keeping its own ID and hashes.
|
|
|
|
## 3.6 The plain projection
|
|
|
|
The plain projection of a node with runs is the concatenation of its runs' projections.
|
|
That of an equation or an equation line is `$$` + source + `$$`, and that of a verbatim node is its text.
|
|
That of any other node is the plain projections of its text leaves joined with one U+0020.
|
|
|
|
A node's text leaves are found by walking its subtree in document order and stopping at `sentence`, `cell`, `reference`, `authors`, `keywords`, `code` and `algorithm` nodes, and at `equation` nodes whose parent is not a sentence; an `equation-line` is never a text leaf.
|
|
|
|
Offsets, quotations and the text hash are all defined on the plain projection as stored, before normalization.
|
|
|
|
A node's runs as printed are its runs with each run's `printed` in place of its `text`, and each `text` run that carried one joined with the adjacent `text` runs of the same style list, as the run was before an emend split it.
|
|
Its projection as printed is the plain projection of its runs as printed; an equation's or a verbatim node's is its plain projection, and any other node's joins its text leaves' projections as printed with one U+0020.
|
|
It is the text a witness of the paper holds, recovered from `nodes.jsonl` alone; for a node no emend touched it is the plain projection.
|
|
The strict and lossy projections are taken over the runs as printed ([5.3](05-hashes.md#53-the-strict-projection)), and `projections.jsonl` gives an emended sentence's projections with its projection as printed.
|
|
|
|
## 3.7 Math forms
|
|
|
|
A math form is a standard spelling of formulas, so that one formula is written alike whichever paper, converter or claim it comes from.
|
|
An equation's or equation line's content and a `math` run MAY carry `form`, which names the form its `source` is written in; a source without `form` is as the witness wrote it.
|
|
The one form is `scienting-math/1`, canonical TeX, which [9.4](09-figures-tables-equations.md#94-the-math-form) describes; a node or run with `form` has the notation `tex`.
|
|
|
|
A consumer MAY rely on these properties of a source that carries `form`:
|
|
|
|
1. It is canonical: it is the form's own spelling of the formula the witness wrote, which renders as that formula did, apart from presentation such as spacing, `\displaystyle` and delimiter sizes.
|
|
2. It is idempotent: spelling it in the form again gives it back unchanged, so a tool that rewrites it to check it, or a converter run twice, changes nothing.
|
|
3. It carries no label: the form lifts a `\tag` out of the source, and an equation keeps it as its `label`; `\label`, `\nonumber` and `\notag` are gone.
|
|
4. Everything else is derived from it: the tree, the symbol keys and the issues of [9.4](09-figures-tables-equations.md#94-the-math-form) are read from the source by a pinned tool into `derived/math.jsonl` ([12.7](12-package.md#127-derived-files)), are never content, and are the same for the same source under the same form.
|
|
|
|
A producer writes `form` only on a source it has spelled in that form.
|
|
A correction that changes such a source writes the new source in the form too, since the gate does not implement the form and cannot check it.
|
|
A validator that implements the form reports a source with `form` that is not its own canonical spelling as `doc.math.form`.
|
|
`form` enters no content value, so adding it to a source already in the form changes no hash, ID or anchor, while respelling a source in the form changes them as any edit of the source does ([5.2](05-hashes.md#52-own-content)).
|