Document model
Every paper is parsed into one canonical document tree. Every node has a stable anchor, and every format is a rendering of the tree.
Each paper version is parsed from arXiv’s LaTeXML HTML into one tree. Markdown, JSON, plain text, sections, references, figures and token counts are all renderings of it.
The tree
type Document = {
title: Inline[];
authors: Author[];
abstract: Block[];
body: Block[]; // top-level sections and any front-matter blocks
appendices: Block[];
bibliography: Reference[];
footnotes: Footnote[];
};
Block nodes
type |
Key fields | Notes |
|---|---|---|
section |
id, level (1–4), number?, title, children |
Section, subsection, subsubsection, paragraph-level heading (4) |
paragraph |
id?, content |
|
equation |
id, number?, latex |
Display math. Equation groups flatten to one node per equation |
figure |
id, number?, caption, images, children? |
children holds subfigures |
table |
id, number?, caption, rows |
Cells carry header, colspan?, rowspan? |
list |
ordered, items |
|
theorem |
id, kind, number?, title?, children |
kind: theorem, lemma, proof, definition, … |
code |
language?, text |
Listings and verbatim |
quote |
children |
|
raw |
markdown |
Unrecognised element, converted best-effort |
Other shapes
| Type | Fields | Notes |
|---|---|---|
Image |
src, alt? |
src is relative to the version’s asset root, e.g. Figures/ModalNet-21.png |
Cell |
content, header, colspan?, rowspan? |
|
Author |
name, affiliations?, email? |
As rendered in the paper |
Reference |
id, number?, text, content, arxivId?, doi?, url? |
text is plain text; ids are extracted when present |
Footnote |
id, number?, content |
content is Block[] |
Inline nodes
type |
Key fields | Notes |
|---|---|---|
text |
text |
|
span |
style[], content |
emph, strong, code, sub, sup, smallcaps, underline |
math |
id?, latex |
Inline math |
cite |
targets, content |
targets are bibliography ids; content is the printed text, e.g. [12] |
ref |
target, content |
Cross-reference to any node id |
link |
href, content |
|
footnoteRef |
target |
Body lives in Document.footnotes |
break |
Clients must ignore node types they do not recognise. New types can appear within schema 1. See compatibility.
Anchors
Every addressable node keeps its LaTeXML id verbatim. Short aliases are resolved on request, never stored.
| Node | Stored id | Aliases |
|---|---|---|
| Section 3 | S3 |
Slug of its title, e.g. model-architecture |
| Subsection 3.2 | S3.SS2 |
S3.2, or a slug such as attention |
| Subsubsection 3.2.1 | S3.SS2.SSS1 |
S3.2.1 |
| Appendix A | A1 |
Subsections alias the same way: A1.SS2 → A1.2 |
| Paragraph | S3.SS2.p3 |
|
| Equation 1 | S3.E1 |
E1 (by printed number) |
| Figure 1 | S3.F1 |
F1 (by printed number) |
| Table 1 | S6.T1 |
T1 (by printed number) |
| Theorem | LaTeXML id | |
| Reference 12 | bib.bib12 |
|
| Footnote 3 | footnote3 |
Resolution order, first match wins:
- Exact stored id.
- Section alias (
S3.2→S3.SS2,S3.2.1→S3.SS2.SSS1). F<n>,T<n>,E<n>: the figure, table or equation whose printednumberis<n>.- Slug: the input is slugified (lowercase, runs of non-alphanumerics →
-) and matched against the first section with the same title slug.Introductionandintroductionboth work.
Addressing parts
| Part | URL | Accepts |
|---|---|---|
| Section | /1706.03762/sections/S3.2.md |
Section id, alias or slug |
| Section by slug | /1706.03762/sections/introduction.md |
|
| Figure | /1706.03762/figures/F1.json |
Figure id or F<n> |
| All figures and tables | /1706.03762/figures.json |
|
| References | /1706.03762/references.json |
|
| Figure image | /1706.03762v7/assets/Figures/ModalNet-21.png |
Image.src path |
| Equation | MCP equation tool, or the equation node in .json |
Equation id or E<n> |
An anchor that resolves to the wrong kind of node (e.g. a paragraph id on /sections/) returns 404 not-found.
In Markdown, section headings carry their id: ### 3.2 Attention {#S3.SS2}. Quote a node and link its anchor for grounded citations.
Quality score
Each tree gets a score from 0 to 1, in build.quality (JSON) and the X-Arxivv-Quality header. The counts behind it are in build.quality.stats.
score = 1
- min(1, 0.02 × errors)
- (sections = 0 ? 0.6 : 0)
- 0.3 × mathWithoutLatex / max(1, mathNodes)
- 0.1 × unresolvedCites / max(1, cites)
- 0.1 × figuresWithoutImages / max(1, figures)
| Signal | Stat | Penalty |
|---|---|---|
LaTeXML errors (ltx_ERROR) |
errors |
0.02 each, up to 1 |
| No sections | sections |
0.6 |
| Math without LaTeX | mathWithoutLatex / mathNodes |
up to 0.3, by share of math nodes |
| Unresolved citations | unresolvedCites / cites |
up to 0.1, by share of citations |
| Figures without images | figuresWithoutImages / figures |
up to 0.1, by share of figures |
- The score is clamped to
[0, 1]and rounded to 4 decimal places. - A page with no paragraphs (e.g. one that only wraps a PDF) scores 0.
- Below 0.8, the tree would be rebuilt from TeX source by the fallback. The fallback is not yet available, so v1 serves the arXiv HTML tree whatever its score.
Sources
v1 builds trees from arXiv’s HTML only.
X-Arxivv-Source |
Meaning | Status |
|---|---|---|
arxiv-html |
arXiv’s own LaTeXML HTML | v1 |
latexml-oxide |
Our own latexml-oxide run on TeX source |
Reserved, not yet served |
A version with no arXiv HTML returns 422 no-html.