Draft Standard

Ribose Standard

•
1005(d) (draft 2026-10-31)
Plurimath specifications — The AsciiMath notation
Plurimath
Ribose Standard

Draft Standard

Warning for Drafts

This document is not a Ribose Standard. It is distributed for review and comment, and is subject to change without notice and may not be referred to as a Standard. Recipients of this draft are invited to submit, with their comments, notification of any relevant patent rights of which they are aware and to provide supporting documentation.





Foreword

General

This document is the fifth document of the Plurimath specifications series. It specifies the AsciiMath notation as Plurimath reads and writes it: the complete accepted surface — every token, construct, fence and channel — and the rules that turn linear text into the formula tree of PM 1001.

AsciiMath is a linear format for mathematics: plain text, readable and writable without markup, with mathematics’ own conventions for precedence and grouping. Plurimath’s implementation has grown specifics of its own — the uncertainty forms, the UnitsML channel, localized readings — and this document states the whole surface as it is, grounded in the reader’s tables and pinned by the corpus. Where Plurimath’s AsciiMath differs from the asciimath.org public definition, this document says so in the compatibility notes of each clause; the notation specified here is Plurimath’s.

Documents in the series

Table 1 — Documents in the series
NumberTitleSubject
1001Math modelThe formula tree, the node classes, the registry, the rendering surfaces
1002Uncertainty modelThe uncertainty node, its categories, its encodings
1003Format interfacesThe readers and writers per format
1004EvaluationNumeric evaluation of trees
1005The AsciiMath notationThis document: the complete AsciiMath surface

Maintainers

This document is maintained by the Plurimath project at https://github.com/plurimath/plurimath.


Introduction

AsciiMath writes mathematics the way mathematicians type it: ∑ i = 1 n i 3 = ( n ( n + 1 ) 2 ) 2 is the sum of cubes, written with no markup at all — tokens for symbols, ^ and _ for scripts, parentheses for grouping, / for fractions, and function names for the rest. The format’s genius is that its text is already unambiguous to a trained eye; the reader’s work is to make that reading mechanical.

This document makes it mechanical. Every token the reader accepts is listed; every construct’s shape, precedence and yielded tree is stated; the fences — including the multi-character and letter-pair fences the implementation adds — are tabulated; the quoted-string channels are defined; the uncertainty forms of PM 1002 are given their reading rules; and the whole surface is pinned by a corpus that replays byte-identically, generation after generation.

The document is written to serve three readers at once: the implementer who needs the exact tables, the author who wants to know what they can write, and the tool builder deciding whether to accept or emit the notation. Each clause states its rules once, in the form the corpus tests.

EXAMPLE

x^2 + y_1 — two scripts and an addition. Expected outcome. a power of x to the Number 2, an addition symbol, and a base of y with subscript 1: the shape PM 1001’s examples carry, read from nine characters of plain text.

0.1  What this document is not

It is not a tutorial — the examples teach the rules, not the mathematics. It is not the pma notation (that document is separate), and it is not the history of the format — the compatibility notes carry exactly as much of that as the rules need. It is the notation as Plurimath implements it, stated so that a careful reader can predict the reader’s answer for any input before asking it.

1  Scope

1.1  General

This document specifies the AsciiMath notation as implemented by Plurimath:

  • the token surface: symbols, numbers, function names, fonts, fences;

  • the construct shapes: unary, binary, ternary and sub/sup classes, with their arguments;

  • tables and their bracket forms;

  • scripts and fractions, with the precedence that joins them;

  • quoted strings and the UnitsML channel;

  • the uncertainty forms of PM 1002 as they read and write in AsciiMath;

  • precedence and grouping;

  • the reading algorithm and its errors;

  • the corpus and conformance.

This document does not specify: the other formats (PM 1003), the tree (PM 1001), the uncertainty model (PM 1002), evaluation (PM 1004), or the pma notation, which is its own document.

1.2  Relationship to the series

Table 2 — Relationship to the series
DocumentRelationship to this one
1001 Math modelthe tree this notation reads into and writes from
1002 Uncertainty modelthe uncertainty forms this notation reads and writes
1003 Format interfacesthe reader and writer contracts this notation satisfies
1006 The pma notationthe featureful notation that shares this one’s registry

1.3  Compatibility with asciimath.org

Plurimath’s AsciiMath descends from the asciimath.org public definition and extends it. This document specifies Plurimath’s surface; where it extends or sharpens the public definition, the clause says so in a Compatibility note. The compatibility notes are informational; the rules are normative.

1.4  Audience

Implementers of Plurimath and of other AsciiMath processors, authors writing AsciiMath, and tool builders.

1.5  Extensions over the baseline, in one table

Table 3 — The extensions this document adds to the asciimath.org baseline
ExtensionClauseShape
the uncertainty calls and the reporting form12ustd/uexp/ucov, v(digits)
the UnitsML channel11"unitsml(…​)"
the special bold alphabets8ZZ RR QQ NN CC
the added font tokens8rm, ii
the added fencesAnnex Cᑕ/ᑐ, ℒ/ℛ
the added symbols6per the registry’s superset
shared-exponent reporting12the concise shift form

Everything else in this document is the baseline as Plurimath reads it — sharpened, tabulated and pinned, but not changed.

2  Normative references

The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

PM 1001 (math model), of this series.

PM 1002 (uncertainty model), of this series.

PM 1003 (format interfaces), of this series.

CalConnect 36817 (asciiunits content language), of the UnitsML series — the content of the quoted channel of clause 11.

asciimath.org, — the public AsciiMath definition, cited in the compatibility notes as the baseline this surface descends from.

3  Terms and definitions

For the purposes of this document, the following terms and definitions apply.

For the purposes of this document, the following terms and definitions apply.

3.1 token

a maximal lexical unit of AsciiMath input: a symbol token, a number, a function or font name, a fence, or a structure character

3.2 symbol

a registry entry’s AsciiMath token: alpha, sum, infty, and the rest of the symbol space

3.3 unary class

a construct taking one operand, written name(x) or name x: the list of clause 8

3.4 binary class

a construct taking two operands: frac, root, underset, overset, stackrel

3.5 ternary class

a construct taking an operand and both scripts: sum, prod, int, oint

3.6 sub/sup class

a construct taking an operand and optional sub or superscript: lim, log

3.7 font style name

a token applying a font variant to its operand: the list of clause 8

3.8 fence

a token pair delimiting content: the parenthesis table of Annex C, including the multi-character and letter-pair fences

3.9 structure character

one of ^, _, /, @, and the grouping parentheses

3.10 quoted string

double-quoted content read verbatim, with the UnitsML channel as its one special case

3.11 channel

the quoted string form "unitsml(…​)" carrying a unit expression

3.12 reporting form

the concise uncertainty shape v(digits), read per PM 1002

3.13 corpus

the pinned AsciiMath corpus this document’s claims replay, with its generations

3.14 canonical token

the registry entry’s primary AsciiMath spelling; the token the writer emits

3.15 longest match

the tokeniser’s rule that the longest vocabulary entry at a position wins

3.16 open stack

the reader’s record of unclosed fence openers, matched by opener identity

3.17 generation

a published, immutable version set of the corpus; claims name the generation they were checked against

4  Symbols

4.1  The symbol surface

The symbol tokens are the registry’s AsciiMath tokens (PM 1001’s symbol space, 1 438 entries at edition 1). A symbol token reads to its registry entry’s Symbol node and nothing else: no arguments, no variants. The families:

Table 5 — Symbol families
FamilyRepresentative tokens
Greek loweralpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi pi rho sigma tau upsilon phi chi psi omega
Greek upperAlpha Beta Gamma Delta Theta Lambda Xi Pi Sigma Upsilon Phi Psi Omega
binary operators+ - * ** times div pm mp cdot ast star circ bullet oplus ominus otimes
relations= != < <= > >= approx equiv sim simeq cong propto asymp
logicand or not implies iff forall exists neg land lor
setsin notin ni subset supset subseteq supseteq cup cap emptyset
arrows-> --> => ==> <- <-- <=> iff mapsto hookrightarrow
calculusint oint sum prod partial nabla iint iiint
accents as symbolshbar ell Re Im wp aleph
miscellanyoo degree angle perp parallel triangle square prime therefore

The complete listing is generated from the registry; Annex D shows the families with their full member counts. The reader resolves a token by longest match — `==> ` reads as one arrow, not == then > — and an unresolvable token is a reading error naming the token and its position.

4.2  Fractions of the surface: what the public definition adds

Compatibility note. Plurimath’s token set is a superset of the asciimath.org set: the uncertainty tokens of clause 12, the UnitsML channel of clause 11, and additional symbols the registry carries. The public set reads unchanged; nothing in the baseline was removed or re-spelled.

4.3  Case sensitivity

Tokens are case-sensitive: alpha and Alpha are different entries, EE (the special bold E) differs from ee. There are no aliases that differ only by case.

4.4  Numbers are not symbols

Digits and decimal points read as Number nodes (clause 7), never as symbol tokens; the reader’s token classes are disjoint by first character.

4.5  Symbol vs construct: the classification rule

A token first matches the construct and font names (clause 8), then the special alphabets, then the symbols. The classification is total and ordered; sum can never be a symbol, d can never be a construct. The constants carry the order, and the generated tables of the annexes are that order’s statement.

4.6  The Greek letters, complete

Table 6 — Greek lower
alphabetagammadeltaepsilon
zetaetathetaiotakappa
lambdamunuxipi
rhosigmatauupsilonphi
chipsiomega
Table 7 — Greek upper
GammaDeltaThetaLambdaXi
PiSigmaUpsilonPhiPsi
Omega

4.7  The operators and relations, complete

Table 8 — Binary operators
+-***times
divpmmpcdotast
starcircbulletoplusominus
otimes
Table 9 — Relations
=!=<<=>
>=approxequivsimsimeq
congproptoasymp

4.8  Logic, sets, arrows, calculus

Table 10 — Logic and sets
andornotimpliesiff
forallexistsneginnotin
nisubsetsupsetsubseteqsupseteq
cupcapemptyset
Table 11 — Arrows
->-->=>==><-
<--<=>mapstohookrightarrowiff
Table 12 — Calculus and miscellany
intointsumprodpartial
nablahbarellReIm
wpalephoodegreeangle
perpparalleltrianglesquareprime

These are the registry’s AsciiMath tokens for the families; the counts of Annex D are their totals. The generated listing remains authoritative — these tables are its statement at edition 1.

4.9  Unicode and entities

Input is Unicode text: symbol tokens are the spellings the registry declares, and a character outside every token’s set is an unresolvable run — named, positioned, refused. The reader does not decode HTML entities in AsciiMath input (the writer emits character references in some surfaces; that is output encoding, not input syntax). An author pasting rendered mathematics strips the entities first, or the reader will name every ampersand.

4.10  The registry is the whole truth

Every token this clause lists is a registry entry’s AsciiMath token, and every registry entry’s AsciiMath token is accepted. Neither side of that sentence bends: no unlisted token reads, and no listed token fails. When the registry grows (PM 1001’s entry lifecycle), the token surface grows with it at the next edition, and the generated tables of this document regenerate with it.

5  Conventions

5.1  General

Input text is shown verbatim between backticks; trees are shown in the math-zone notation of PM 1001. Tokens are the reader’s lexical units; this document writes them exactly as accepted.

5.2  Examples

Examples carry an Expected outcome paragraph. Where an example names a tree, the outcome names the node classes; where it names an error, the outcome names the error of PM 1003’s Annex A.

5.3  Compatibility notes

Paragraphs beginning Compatibility note compare this surface with the asciimath.org baseline. They are informational; the rules of the clause are normative regardless.

5.4  Tables

The tables of clauses 6 to 12 and the annexes are generated from the reader’s constants, and a mismatch between a table here and the constants fails the build of this document. The tables are the surface.

5.5  The generated tables

The tables of clauses 6 to 12 and Annexes A to D are generated from the reader’s constants and the registry at build time of this document. An edit to the constants that a table here does not reflect fails the build; the tables and the implementation cannot drift apart silently. Edition 1’s tables were generated from the 0.11 series implementation.

6  Notation overview

6.1  The shape of the language

AsciiMath input is a sequence of tokens. Tokens come from four sources: the symbol space (clause 6), the construct names (clause 8), the structure characters (^, _, /, @, parentheses), and quoted strings (clause 11). Whitespace separates tokens and never means anything by itself.

EXAMPLE

sum_(i=1)^n i^3 Expected outcome. five token groups: the ternary class sum with its _/^ scripts, and the operand i^3. Whitespace between the ^n and the i^3 ends the nary’s upper script and starts the summand.

6.2  A linear format

The notation is linear: no environments, no begin/end pairs, no markup beyond the construct parentheses. Everything is characters. The fences pair by the table of Annex C — including the pairs the public definition lacks and Plurimath adds: the letter-pair fences (: and :) for angle-bracket content and the single-letter Unicode fences.

6.3  What a reading yields

A reading yields one formula tree per PM 1001: node classes with operands in class order, symbols resolved through the registry, uncertainty nodes constructed through PM 1002’s validation. The tree carries nothing about the notation — the same tree can be written from pma, MathML or OMML (PM 1003).

6.4  The reader’s promises

The reader of this notation (PM 1003, clause 8) is total on this surface: every text built from the constructs of this document reads; everything else is a typed error. The corpus of clause 15 pins both directions.

6.5  A first reading, token by token

The sum of cubes, ∑ i = 1 n i 3 = ( n ( n + 1 ) 2 ) 2 , as the reader sees it:

  1. sum — the ternary token; its scripts follow;

  2. _(i=1) — the lower limit: an index definition i = 1 (evaluation reads it per PM 1004; the tree carries the limit as written);

  3. ^n — the upper limit: the name n;

  4. i^3 — the summand: a power;

  5. = — the relation symbol;

  6. ( n ( n + 1 ) 2 ) 2 — the right side: a power over a fenced fraction — the inner fence holds the product n(n+1), the fraction takes the fence and the 2, the outer fence groups the fraction, and ^2 scripts it all.

Expected outcome. one relation between a limited nary and a scripted fraction — the tree PM 1001’s introduction carries, read from characters a mathematician typed without thinking about markup.

6.6  The three extensions over the baseline

Everything in this document that the asciimath.org baseline lacks is one of three extensions, each with its clause: the uncertainty forms (clause 12), the UnitsML channel (clause 11), and the added tokens and fences (clauses 6 and 8, noted per case). The baseline itself — its symbols, constructs, precedence and fences — reads unchanged.

6.7  Whitespace

Whitespace between tokens is a separator and nothing else: it ends attachments (clause 13) and never creates content. Inside construct argument groups, the argument’s own grammar governs. Inside quoted strings, spaces are content verbatim. The reader normalises nothing about the input’s spacing — input_string keeps it — but the tree records structure only.

6.8  Two readings of one habit

Mathematicians write sin 2x meaning sin(2x). The notation reads sin(2) · x (clause 13’s ruling). The gap between habit and ruling is not a defect to patch with a smarter reader; it is the reason grouping exists, and every AsciiMath author learns it once. The ruling is old, public, and pinned by the corpus — this document states it rather than relitigates it.

6.9  The whitespace rules, in one table

Table 4 — Whitespace behaviour
PositionEffect
between tokensseparator; ends script and argument attachments
inside a construct’s argument groupcontent spacing; the argument grammar governs
inside quoted stringscontent, verbatim
leading and trailing on the inputinsignificant; trimmed before tokenising
inside a number or tokenimpossible — a token never contains space

6.10  Reading across the series

An AsciiMath tree is a PM 1001 tree: PM 1002’s uncertainty forms read to validated nodes, PM 1003’s reader contract wraps this reader, PM 1004’s evaluator consumes what the tree denotes, and the writer of clause 16 emits PM 1001’s AsciiMath surface. This document is the notation; the series is the system.

7  Numbers and text

7.1  Numbers

A run of digits with an optional decimal point reads as one Number node: 3, 0.5, 42, 2.10. The digits are verbatim — 2.10 keeps its trailing zero (PM 1002’s exact-decimal discipline applies to the tree’s numbers). There is no exponent form, no thousands separator, no sign: a minus is a symbol sibling, and 1e5 reads as the Number 1 followed by the name e5 is refused — e5 is not a token, so the input errors, which is the correct answer for a notation without exponent forms.

7.2  Upright text: the two forms

Text enters the notation in two forms:

  • text(content) — the text function: the content reads as upright text, and AsciiMath commands inside it are honoured (text(the "sum" is) reads its quotes as text);

  • quoted strings — "content" — read verbatim with the channel exception of clause 11.

Both yield Text nodes; they differ in processing, not in the node. The choice is the author’s: text(...) for text that may contain structure, quotes for literal text.

EXAMPLE

text(hello world) and "hello world". Expected outcome. two Text nodes with equal content. The first form’s content passes through the reader’s text processing; the second is verbatim.

7.3  Spacing

Whitespace separates tokens and is never content. The spaces the surfaces render come from the constructs, not from the input’s spacing: x+y and x + y read to equal trees, and input_string preserves whichever the author wrote.

7.4  Text in constructs

text(...) inside constructs composes: color(red)(text(urgent)) colours its text; [[a,text(total)]] sits text in a cell. The text content participates in the tree as an operand like any other, and the writer surfaces render it upright per PM 1001.

7.5  The number boundary

A token boundary ends a number: 2x is the number 2 then the name x (an implicit product per clause 13), 2.5.1 is the number 2.5 then a fault, and 1..5 is a number, a fault, a number — the reader does not guess ranges into existence.

7.6  Verbatim, one more time

The exact-decimal discipline (CalConnect 36813, PM 1002) is visible here at the notation’s front door: 2.10 reads to a Number whose text is 2.10, and every writer emits those digits. An author who writes the trailing zero made a precision statement; the notation’s job is to carry it to every surface, and it does.

8  Constructs

8.1  The four shapes

The construct classes come in four argument shapes, and every name below belongs to exactly one:

Table 13 — .The four construct shapes
ShapeWrittenYields
unaryname(x) or name xone-operand function node
binaryname(x)(y)two-operand function node
ternaryname(x)(y)(z) — or with scriptsthe nary classes
sub/supname with _/^lim, log with optional limits

Parenthesised arguments group: sqrt(x+1) takes the whole sum; sqrt x+1 takes only x. The parenthesis form is always available, and adjacency is always available for the last argument of a unary class.

8.2  Unary classes

The complete unary list, from the reader’s constants:

Table 14 — The unary classes
underbraceoverbraceunderlinearccosarcsin
arctanubraceobracecanceltilde
floorceilddotcothcsch
sechsinhtanhcoshsqrt
normtextsecsintan
cosexpgcdglblcm
lubcotcscdetdim
maxminabsbardot
hatvecullnlog

Each reads to its function class of PM 1001’s Annex A: the trigonometric and hyperbolic names to their classes, the accents (bar, dot, hat, vec, tilde, ddot) to the accent classes, the fences (abs, norm, floor, ceil, obrace, ubrace) to their fence classes, cancel to the strike-through class, underline and ul to the underbar forms, and the operator names to upright operator classes.

8.3  Binary classes

Table 15 — The binary classes
NameArgumentsYields
frac(a)(b)numerator, denominatorFrac
root(a)(b)radicand, degreeRoot
underset(a)(b)base, underUnderset
overset(a)(b)base, overOverset
stackrel(a)(b)bottom, topStackrel

8.4  Ternary classes: the nary constructs

sum, prod, int and oint take an operand with optional _/^ scripts as the lower and upper limits: sum_(i=1)^n. Without scripts they read as the plain nary operator; with both they read to the nary class carrying its limits (PM 1001’s nary family).

8.5  Sub/sup classes

lim and log take an operand with optional scripts: lim_(x->0), log_2 x. They read to their classes with the limits attached; a bare lim x is the operator over its operand.

8.6  Font style names

Table 16 — The font style tokens
mathfrakmathcalmathbbmathsfmathtt
mathbfbbbbbrmfr
ccsfttii

Each applies its variant to the operand (PM 1001’s font styles). rm reads to the upright variant, ii to the italic — the shorthand spellings the implementation carries alongside the math-prefixed ones.

Compatibility note. The public definition carries mathfrak, mathcal, mathbb, mathsf, mathtt, mathbf and the shorthands fr, cc, bb, sf, tt. Plurimath adds rm and ii for the upright and italic readings the set lacked.

8.7  The special bold alphabets

ZZ, RR, QQ, NN, CC read to the double-struck number-set letters — the natural, integer, rational, real and complex number symbols — as single tokens. They are the one place a bare uppercase pair is a token, and the reader’s longest-match resolves them before any two-symbol reading.

Compatibility note. These are a Plurimath addition to the public definition, which writes them as bbZ and kin.

8.8  Adjacency vs parentheses

Every unary class accepts both name(x) and name x; the parenthesised form is unambiguous and the adjacency form takes one operand — sqrt x+1 roots x only. Binary and ternary classes require their parenthesised arguments: frac(a)(b) has no adjacency form, because two adjacency arguments would not be distinguishable. The rule is uniform: one-argument constructs may go bare; multi-argument constructs group.

8.9  Overloading, deliberately absent

No token serves two construct roles: root is always the binary root, never a radical sign; text is always the text function. The reader’s classification is single-valued per token (clause 6), and the notation pays for that simplicity with a few explicit spellings (obrace/ubrace for the braces rather than overloading the accents).

8.10  Worked readings per shape

EXAMPLE 1

sqrt(x+1) and sqrt x+1. Expected outcome. the root of the sum in the first; the root of x plus one in the second — the parenthesised form groups, the adjacency form takes one operand.

EXAMPLE 2

frac(a)(b), root(x)(3), underset(a)(b), overset(a)(b), stackrel(a)(b). Expected outcome. Frac, Root, Underset, Overset, Stackrel — operand order per Annex A’s binary table.

EXAMPLE 3

sum_(i=1)^n f(i) and bare int f(x) dx. Expected outcome. the nary with both limits in the first; the plain nary over its operand in the second — the dx is adjacency, not a second argument.

EXAMPLE 4

lim_(x->0) x/ sin x and log_2 8. Expected outcome. the limit class carrying its lower script; the logarithm with base 2 over 8 — the sub/sup readings with their scripts.

EXAMPLE 5

mathbf(F) = m mathbf(a) and bbR. Expected outcome. font style nodes over the names; the double-struck R from the special alphabet token.

8.11  What the shapes do not do

No class accepts keyword arguments, optional named forms or arity overloads: a name’s shape is fixed by its class list membership. sqrt cannot take a degree (that is root), frac cannot take three arguments (nesting composes), and no unary class reads a second adjacency operand as part of itself — adjacency after a unary is the notation’s product, always.

8.12  The construct shapes at a glance

One shape per class, from the constants, is the notation’s whole economy: the reader classifies once and the argument grammar follows. The table of the four shapes, the complete class lists of this clause and Annex A, and the corpus’s per-class vectors are three views of one fact. Nothing in this document introduces a construct that is not in the lists, and nothing in the lists is absent from this document.

9  Tables and matrices

9.1  The bracket forms

A double-bracketed, comma-separated grid reads as a table: [[a,b,[c,d]]] is a two-by-two matrix — each inner bracket pair is a row, commas separate the cells within it. The delimited variants wrap the grid in a fence, and the fence selects the class:

Table 17 — The table forms
GridWrapped inYields
double-bracket gridnothingMatrix
double-bracket gridround fencesPmatrix
double-bracket gridbrace fencesBmatrix
double-bracket gridbar fencesVmatrix
the cases formleft brace, null rightCases

9.2  Alignment

align and eqarray content carries the ampersand alignment points their input wrote; split and multline preserve line structure. The table node keeps the alignment as data (PM 1001’s table classes), and the writer surfaces emit it per their mappings.

9.3  Cells

A cell’s content is a full expression: [[x^2, text(notes)],[frac(a)(b), sum_(i=1)^n i]] reads all four cells as complete subtrees. An empty cell — nothing between separators — reads to the None node.

EXAMPLE

[[1,2],[3,4]] and ([1,2],[3,4]) with round fences. Expected outcome. the first is a plain Matrix; the second is the same grid read to Pmatrix. Both round-trip per PM 1003.

9.4  Row and cell rules, precisely

A table grid is a bracketed sequence of bracketed rows: [[row],[row]]. Inside a row, commas separate cells; inside a cell, a full expression goes. The reader allows trailing separators to read as an empty trailing cell — the corpus pins whether it warns — and a row mismatch (two cells in one row, three in the next) reads as written: tables are not square by force.

9.5  The delimited forms, precisely

A grid wrapped in (...) reads to Pmatrix; in {...) — the brace pair of Annex C — to Bmatrix; between bar pairs to Vmatrix; and the cases reading comes from the input form the public definition writes. The delimiters live on the tree as the table class; the writer surfaces re-emit the class’s delimiters, which is why the class matters.

9.6  Alignment, precisely

align and eqarray content uses & for alignment points and \ for line breaks, the grid conventions the public definition carries. The alignment points are data: the table node keeps them, the writer surfaces emit them where their format has alignment (`aligned` in LaTeX, `maligngroup` in MathML per its mapping), and the round trip preserves the count and order of points. A surface without alignment drops them as presentation (PM 1001’s fallback rule).

9.7  Tables inside tables

A cell may carry a grid: ],[c,d]] nests. Nesting depth is unbounded; the corpus carries the two-deep case, and nothing in the reader’s recursion limits applies to it that does not apply to any grouping.

9.8  Tables in the corpus, and what they freeze

The table vectors freeze: each bracket form with a known grid; the alignment forms with their points; the empty-cell reading; the nested grid; and the row-mismatch reading as written. Tables are the notation’s most structure-heavy construct, and the corpus treats them accordingly — a table reading that drops a cell cannot hide.

10  Scripts and fractions

10.1  Scripts

^ attaches a superscript and _ a subscript to the preceding operand: x^2, x_1, x_1^2. The operand is the preceding group — a token, a parenthesised expression, or a construct’s result — and the script content is the following group. Both orders of sub and superscript on one operand read to PowerBase; a lone script reads to Power or Base.

EXAMPLE

x^2, x_1, x_1^2, x^2_1. Expected outcome. the four readings: Power, Base, and two PowerBase nodes that are equal — the script order on one operand is not significant.

10.2  Scripts on constructs

Scripts attach to the construct that just closed: sum_(i=1)^n, lim_(x->0), log_2 x. The sub/sup classes read the scripts as their limits; the ternary classes read them as the nary limits.

10.3  Fractions

a/b reads to Frac: the operand before the slash is the numerator, the operand after is the denominator, each being a token or a group. ( n ( n + 1 ) 2 ) shows the idiom — groups on both sides of the slash. The slash binds tighter than addition and looser than scripts: a/b^2 is a over b², and a^2/b is a² over b.

10.4  Precedence interplay

The full precedence is clause 13; this clause states the local rules: scripts bind tightest, then fences and constructs, then fractions, then adjacency, then the operators. The reader’s behaviour is the definition; the corpus pins the contested shapes vector by vector.

10.5  Scripts on fences and constructs, worked

( n ( n + 1 ) 2 ) 2 — the worked case of clause 5 — and its kin:

Table 18 — .Script attachments
InputReading
sqrt(x)^3the root, cubed — the script attaches to the construct’s result
frac(a)(b)^2the fraction, squared
x_1^2 + y^2_1two PowerBases, script order insignificant
sum_(i=1)^nthe nary with both limits
lim_(x->0) f(x)the limit with its lower script, then adjacency

10.6  The fraction edge cases

a//b — the double slash — is not a token; the reader sees two slashes and errors. a/b/c is (a/b)/c — fractions chain left-associatively. a/b^2 puts the script inside the denominator: scripts bind tighter than the slash.

10.7  Scripts on scripts

A script’s content may carry scripts: x^(y_1) nests the base inside the exponent. Nesting is unlimited and the tree carries it as written — the parser’s levels describe sibling precedence, not a depth limit. The corpus carries the two-deep and three-deep cases.

10.8  The empty script

x^() — a script with an empty group — reads to a script node with an empty operand: the None node fills the slot, the same construct MathML uses for the empty half of a pair. The author who means “nothing here yet” has a notation; the corpus pins it.

11  Quoted strings and the channel

11.1  The quoted string

A double-quoted string reads verbatim as a Text node: no command processing, no entity decoding, no interpretation. Quotes inside a quoted string are escaped by doubling — the corpus pins the exact escape rule the reader applies.

11.2  The channel

One string form is reserved: "unitsml(<expression>)", with no leading or trailing whitespace inside the outer quotes, reads as a Unitsml node carrying the expression (clause 10 of PM 1002’s unit rules apply). The channel is the only way units enter AsciiMath machine-readably.

Table 19 — Channel rules
InputReading
"unitsml(g)"the unit embedding of g
"unitsml(m/s2)"the unit embedding of m/s2
" unitsml(g)"a Text node — the leading space disqualifies the channel
"unitsml(…​)" with an unreadable expressiona reading error naming the expression
"hello"a Text node

11.3  Why quotes are literal

The channel’s safety is the literalness: a quoted string never executes a command, so content the writer intends as data cannot become structure. This is what lets uncertainty encodings (PM 1002) place units in the channel — the unit expression is data by construction.

11.4  Escapes, precisely

Inside a quoted string, the only escape is the doubled quote for a quote. Backslashes are literal — a quoted string carries \frac as four characters plus text, never as a command. This is the channel’s contract: verbatim means verbatim, and the corpus carries a string with a backslash, a doubled quote, and Unicode to pin all three.

11.5  The channel’s content grammar

The channel’s expression is the asciiunits content language (CalConnect 36817), read by the unit reader at reading time. The reader’s refusal propagates as a reading error — the channel never stores an expression it could not read, because the unit embedding is constructed, not deferred. A unit the language accepts but the registry lacks symbols for is a unit-reader matter, and its refusal names the missing piece.

11.6  Placement in expressions

A channel string is an operand: it sits in a product (3 "unitsml(m)"), attaches after uncertainty calls (PM 1002), and stands alone as a unit statement. It never opens or closes a construct — quotes inside construct arguments are text unless the argument’s grammar says otherwise (the uncertainty calls accept the channel after the call, not inside its parentheses).

11.7  The channel and PM 1002, in one place

The uncertainty forms place units in the channel (ustd(10.3, 0.2) "unitsml(g)"); the visible placement is the fallback. The channel’s grammar is the unit reader’s, and the channel’s authority is the same as every marker’s in PM 1002: the machine-readable form wins, the visible form is regenerated. Nothing in this clause adds rules — it is where the two documents meet, stated once so no reader has to reconstruct the seam.

12  Uncertainty forms

12.1  The calls

The uncertainty forms read per PM 1002’s AsciiMath encodings: ustd(v, m), uexp(v, m, k, p), ucov(v, l, u, p, kind) — the three categories with their argument orders, optional arguments omitted without empty positions.

Table 20 — Uncertainty reading
InputYields
ustd(10.3, 0.2)standard, absolute
uexp(10.3, 0.5, 2, 0.95)expanded with factor and probability
uexp(10.3, 0.5, 2)expanded without probability
ucov(10.3, 9.9, 10.7, 0.95, shortest)interval, shortest kind
ucov(10.3, 9.9, 10.7, symmetric)interval, probabilistically symmetric
10.3(2)standard, concise (the reporting form)

The symmetric spelling reads to the model’s probabilistically-symmetric; the reporting form reads per PM 1002’s reconstruction rule — the digit string at the value’s decimal places, AmbiguousDecimalError where the places cannot match.

12.2  Units on uncertainty

The unit follows in the channel: ustd(10.3, 0.2) "unitsml(g)" carries the unit in the embedding. A unit the reader refuses, written visibly after the call, is accepted as the visible placement (PM 1002’s clause 10); the channel form is preferred and the corpus carries both.

12.3  Shared exponents

The shared-exponent reporting form — the concise form where the exponent digits apply to the value’s magnitude — reads to the concise node with the exact decimal shifts the shared-exponent reading defines. The corpus carries the shared-exponent vectors; the rule they pin is that the shift happens at reading, producing the full magnitude, never at evaluation.

12.4  Contexts and locale

The uncertainty forms are locale-independent in their names (ustd/uexp/ucov are fixed tokens) and locale-sensitive in nothing else. Contexts — the surrounding construct an uncertainty appears in — do not change the reading: the node is the node wherever it sits.

12.5  Errors

The uncertainty reading errors are PM 1003’s: arity faults and unknown kinds are ParseError; the concise place-count mismatch is AmbiguousDecimalError; a node that would violate PM 1002’s field rules refuses at construction with InvalidUncertainty.

EXAMPLE 1

uexp(10.3, 0.5) — an expanded call without its factor. Expected outcome. ParseError naming the call: the expanded form requires the factor.

EXAMPLE 2

10.3(25). Expected outcome. AmbiguousDecimalError: two digits cannot reconstruct at the value’s one decimal place.

12.6  The reporting form in expressions

10.3(2) parses as one uncertainty node, not as 10.3 times (2): the reader recognises the reporting form by its shape — a number directly followed by a parenthesised digit string — and claims it before the adjacency rule could. A genuine product of a number and a parenthesised number, 2(3), is therefore also read as the reporting form’s shape — and refused, because 2(3) cannot reconstruct (the digit string 3 at zero decimal places against a value with none — the corpus carries the vector). The author who means the product writes 2*(3).

Compatibility note. The reporting form is a Plurimath extension; the baseline reads 10.3(2) as an adjacency product. The extension is what PM 1002’s concise notation needs, and the corpus carries both the acceptance and the refusal vectors.

12.7  Reading the forms in context

Uncertainty nodes compose: (uexp(10.3, 0.5, 2) + uexp(4.1, 0.2, 2)) "unitsml(g)" is an addition of two expanded nodes — evaluation refuses it per PM 1004’s clause 12 until propagation exists, but reading and rendering carry it faithfully. The uncertainty forms are content, and everything this document says about composition applies to them.

12.8  The complete reading table

Table 21 — Every uncertainty form
InputNode
ustd(10.3, 0.2)standard, absolute, magnitude 0.2
ustd(10.3, 0.2) "unitsml(g)"standard with unit g
10.3(2)standard, concise
10.3(0)standard, concise, magnitude 0 (the zero magnitude is well formed)
uexp(10.3, 0.5, 2)expanded, factor 2, no probability
uexp(10.3, 0.5, 2, 0.95)expanded with probability
ucov(10.3, 9.9, 10.7, 0.95, shortest)interval, shortest, with probability
ucov(10.3, 9.9, 10.7, symmetric)interval, probabilistically symmetric, no probability

12.9  The refusals, complete

Table 22 — Reading refusals
InputRefusal
ustd(10.3)ParseError — the standard call requires the magnitude
uexp(10.3, 0.5)ParseError — the expanded call requires the factor
ucov(10.3, 9.9)ParseError — the interval call requires both endpoints and the kind
uexp(10.3, 0.5, 0)InvalidUncertainty — the factor must be positive
ucov(..., fastest)ParseError — unknown kind
10.3(25)AmbiguousDecimalError — the place mismatch
2(3)AmbiguousDecimalError — the reporting shape claimed, reconstruction impossible

2(3) deserves its note: the reporting-form recognition precedes adjacency (clause 12), so a number directly followed by a parenthesised number is claimed as the reporting form and refused on reconstruction. The author who means a product writes 2*(3); the corpus carries the pair.

12.10  Why the uncertainty forms read here

The uncertainty forms are AsciiMath extensions because uncertainty must be writable in a linear format: a laboratory reporting results in AsciiMath needs to state 10.3(2) and have it survive. PM 1002 defines what the node means; this clause defines what the text does; PM 1003 wraps the pair in the reader contract. Three documents, one form, each stating its layer — the seam is deliberate and tested by the shared corpus.

13  Precedence and grouping

13.1  The chain

Precedence, tightest first:

Table 23 — Precedence, tightest first
LevelConstructsNotes
1construct parentheses, fencesthe argument grouping of clause 8
2scripts ^, _attach to the closed operand
3fractions /token-or-group operands
4adjacency and unary applicationsin x, 2x
5multiplication, division*, / (outside fractions)
6addition, subtraction+, -
7relations=, <, <=, and kin

Each level binds tighter than the ones below it; the construct parentheses of level 1 override everything. The reader’s behaviour is the definition, and the corpus pins the contested shapes explicitly — every row of the table has vectors where the levels interact.

13.2  Groups override

Parentheses group an expression into one operand: x^(2+1) scripts the whole sum; sqrt(x+1) roots the whole sum; ( n ( n + 1 ) 2 ) 2 scripts the whole fenced fraction. Grouping is the author’s precedence tool and always wins.

13.3  Ambiguity is resolved, never negotiated

Where two readings are conceivable, the rules above decide — the reader does not pick the “intended” reading. The classic cases, with their rulings:

Table 24 — Rulings on the classic ambiguities
InputReading
a/bca/b times c — the fraction takes the token, not the run
sin 2xsin(2) times x — adjacency after the unary application
x^2yx² times y — the script takes one token
e^-xrefused — the script content starts with a bare operator
x^(-x)x to the −x — grouped, it reads

An author who means something else groups. This is the notation’s contract with its users, and every row here is a corpus vector.

13.4  Spaces end attachments

Whitespace after a script or argument ends the attachment: x^2 y scripts only the 2; sum_(i=1)^n i^3 ends the nary’s limits before the summand. Spaces are otherwise insignificant (clause 7).

13.5  Unary application, precisely

name x applies the unary to the adjacency operand — one token, or a group. sin x y is sin(x) times y; sin xy is sin(x) times y as well — the adjacency operand is one token, never a run. sin (x y) is the sine of the product. The corpus carries the three; the ruling is always “one operand, then adjacency”.

13.6  Relations and their low binding

Relations bind loosest: a = b + c relates the whole sum. Chains — a = b = c — fold left as the relation evaluation of PM 1004 defines. A relation inside scripts or arguments is fine where grouping puts it: x->0 inside lim_(...) is the limit’s lower script content, read as the arrow token, not the relation level’s property.

13.7  The whitespace rule’s edge

A space inside construct parentheses is content spacing: sqrt( x + 1 ) reads identically to sqrt(x + 1) — the construct’s argument grammar, not the token grammar, governs inside. The whitespace-ends-attachment rule of clause 13 applies between tokens, not inside argument groups.

13.8  The whole precedence, worked twice more

−x^2 — unary before power? The power binds tighter: the tree is −(x²), the negation applied to the power. An author who means (−x)² groups: (−x)^2. The corpus carries both.

2^-3 — refused: the script content starts with a bare operator (clause 13’s ruling table). 2^(-3) reads. 2^−3 with the Unicode minus reads too — the tokeniser classifies the Unicode minus as the minus symbol, and the grouped script takes it.

a/b c d — the fraction takes b (one token), then adjacency multiplies by c and d in sequence: (a/b) · c · d. Nothing about the slash reaches past its operand.

13.9  The rule behind the rulings

One rule generates the table: each construct and operator takes the smallest operand the grammar allows, and grouping is the only way to offer it more. Every ruling above is that rule applied; an author who internalises it needs no table. The table exists for implementers and for the corpus.

13.10  The one-rule summary, once more

Smallest operand, unless grouped. Every precedence question in this notation resolves to it: the fraction takes a token unless you group; the script takes a token unless you group; the unary takes a token unless you group; the nary’s scripts take tokens unless you group. The reader has no other source of ambiguity, and grouping is always available. This is the clause most authors need, and it fits in one line.

14  The reading algorithm

14.1  The stages

The reader proceeds in four stages:

  1. Tokenise. The input splits into tokens by longest match against the constants: construct names and fonts first (longest name wins), then symbol tokens, then numbers, then structure characters, then fences. A character sequence matching nothing is a reading error with its position.

  2. Resolve. Tokens resolve through the constants’ classification: unary, binary, ternary, sub/sup, font, special alphabet, symbol, number, fence, structure.

  3. Build. The construct tree builds by the precedence of clause 13: classes take their arguments (parenthesised or adjacent), scripts attach, fractions bind, operators fold.

  4. Validate. Uncertainty nodes construct through PM 1002’s validation; the tree yields.

The stages are separable only in description; the implementation interleaves them. What this document pins is the outcome: the tree a given input yields, and the error a malformed input raises.

14.2  Longest match

Longest match is the tokeniser’s rule and the disambiguator: `==> ` is one arrow; <= is one relation; (: opens an angle fence; ZZ is the number-set token before Z could be a symbol. Construct names match before symbols share their letters — sum is the nary construct even though a symbol could begin with s.

14.3  The fences

Fences pair per Annex C’s table. The pairing is by token: an opener matches its own closer, and nesting tracks the open stack. The unpaired cases — an opener without its closer, a closer without an opener — are reading errors naming the fence and its position.

14.4  Errors

The reading errors are PM 1003’s, and this notation produces them thus:

Table 25 — AsciiMath reading errors
FaultErrorCarries
unresolvable character sequenceParseErrorthe sequence and its position
unpaired fenceParseErrorthe fence token and position
construct arity faultParseErrorthe construct and its argument count
unknown interval kindParseErrorthe kind as written
concise place mismatchAmbiguousDecimalErrorthe value and the digit string
unreadable channel expressionParseErrorthe expression, from the unit reader

14.5  What the reader never does

It never guesses an intent for a malformed input, never skips a faulting token to continue, never normalises digits, never resolves a symbol outside the registry, and never returns a partially built tree. A reading is total or absent.

14.6  A worked reading

uexp(10.3, 0.5, 2, 0.95) "unitsml(g)" + x:

  1. tokenise: the construct name, its fence, the number tokens, the channel string, the plus, the name;

  2. resolve: uexp is a construct with its fixed arity; the channel matches;

  3. build: the call takes four arguments; the channel is the unit operand following per PM 1002’s placement; the addition joins the uncertainty node and x as operands;

  4. validate: the uncertainty node constructs through PM 1002 — category expanded, fields complete, factor positive, probability in range.

Expected outcome. an addition of an expanded uncertainty (with unit) and a name — reading total, tree valid, ready for any writer.

14.7  Positional accuracy of errors

Every error of clause 14 carries its input position: the tokeniser’s offsets survive into the typed errors, so a caller can point at the offending character. The corpus pins the positions for its error vectors — a refusal without a position is not a conforming refusal.

14.8  Tokenisation’s edge cases, pinned

  • (: opens an angle fence only where a fence can open — inside a construct argument it is still a fence; the construct’s argument grammar wraps it.

  • (( is two opens, not one special token; the table recognition of clause 9 happens at the construct-argument level.

  • 2.10 is one number; 2.1.0 is a number then a fault; .. is two faults in a row and the reader reports the first.

  • The reader is Unicode-native: symbol tokens are Unicode where the registry says so, and the letter-pair fences are ASCII. A lookalike character (a fullwidth parenthesis for () is an unresolvable run, named and positioned.

14.9  Recovery is not a feature

The reader stops at the first fault. A specification of recovery — skip, resync, best-effort — is a specification of a second reader with different guarantees; this document specifies one reader with complete guarantees instead. Applications that want fault tolerance get it by splitting input and reading the pieces; the typed errors with positions make that practical.

14.10  The reader against the writer

The reader of this document and the writer of PM 1001’s AsciiMath surface are one interface’s two halves (PM 1003). The reader is the generous half — the surface is what it accepts, tokens, synonyms and all. The writer is the conservative half — canonical tokens, canonical forms, one encoding per construct. An author may write generously; a writer never does. Round trips pass through both halves and yield equal trees with re-spelled tokens where synonyms were written — the tree is the same even when the text is not.

14.11  The reading algorithm, recited

Tokenise by longest match; resolve through the constants’ classification; build by the smallest-operand precedence with grouping as the override; validate the uncertainty nodes through PM 1002; yield the tree or the typed error with its position. Four stages, one pass, no second chances — the reader’s entire behaviour is this recitation plus the tables, and the corpus is the proof that the recitation is complete.

15  The corpus

15.1  The corpus and its generations

The AsciiMath corpus is the pinned corpus of the plurimath testsuite: a frozen set of inputs with their frozen trees and renderings, replayed by digest. A corpus generation is immutable once published; generations extend, never rewrite — the first generation’s 143 cases are present in every later one.

15.2  What the corpus covers

Table 26 — Coverage
AreaVectors
every symbol familyrepresentative tokens per family, all formats’ renderings
every construct classplain and grouped arguments, scripts, nesting
fencesevery pair of Annex C, nesting, the unpaired errors
tablesevery bracket form, alignment, empty cells
uncertaintyall categories, notations, kinds; shared exponents; both unit placements
channelexpressible, inexpressible and refused units
precedenceevery ruling of clause 13’s tables
localizationthe localized readings per supported locale
errorsone vector per error row of clause 14

15.3  Provenance

Each entry states its origin: a clause of this series, a defect fix, or a community report. Provenance is the corpus’s memory — a vector’s existence documents that the behaviour was deliberate, and the generation that froze it is named.

15.4  Replay

Replay is byte-identical: the corpus runner computes digests over the trees’ canonical forms and the renderings, and a mismatch is a failure, not a warning. The runner itself is versioned with the corpus generation.

15.5  The corpus and this document

Every rule in this document has at least one corpus vector: the symbol tables (family representatives), the construct tables (each class plain and grouped), the fence table (each pair, nesting, unpaired), the channel (accepted, degraded, refused), the uncertainty forms (every category, notation, kind, unit placement), the precedence rulings (every row of clause 13’s tables), the localization pairs, and every error row. A rule without a vector is a defect in one of the two — and the build of this document checks the correspondence for the generated tables.

15.6  Size and shape

The corpus generation carries its counts: cases per area of the coverage table, per format column, and per error row. The counts are facts about the generation, published with it; a generation that loses coverage in an area is not a successor, it is a different corpus — and this document’s claims follow the generations, so the loss would be visible in the claim, not buried in the set.

15.7  The replay contract

Replay is part of CI, not a ceremony: the runner runs on every change to the implementation, and the digests are checked on every run. The corpus is the fastest way to know that a change moved behaviour, which is precisely its job.

15.8  A generation’s anatomy

One generation, described concretely so the next is judged against something: the case files (input text, expected tree, expected bytes per surface), the manifest (per-area counts, model version, provenance), the runner version, and the digest set. All four travel together; a generation missing any of them is not publishable. The current generation’s counts publish with the repository release that freezes it, and this document’s claims reference that release by name.

15.9  What the corpus is not

It is not a test suite for the implementation’s internals — it never imports code. It is not a sample of convenient inputs — the refusal vectors and the contested-precedence rows are deliberately uncomfortable. And it is not finished — generations append as the surface grows and as the world reports inputs the set lacked; the append-only rule is what makes every generation a permanent, checkable statement about the notation at its time.

16  Conformance

16.1  General

Conformance to this document is claimed as the AsciiMath reading and writing classes of PM 1003, discharged per this document’s surface.

16.2  Conformance classes

Table 27 — Conformance classes
ClassLicenses the implementation to claimReplay requirements
read-asciimathreads the full surface of clauses 5 to 13the reading corpus, tree-identical
write-asciimathwrites the surface per PM 1001/1002’s encodingsthe AsciiMath column, byte-identical
roundtrip-asciimaththe lossless claim of PM 1003, clause 14write-then-read per corpus entry

The reading claim is the demanding one: the surface is total on well-formed input, so a reader’s refusals are as much a part of the claim as its successes — the error vectors are inside the corpus, not beside it.

16.3  Claiming

A claim names the corpus generation. A claim without a generation is not checkable and is not a claim; a claim against an older generation is void for the current one until rechecked.

16.4  The writer’s side of the claim

The writing claim covers the whole surface too: every node family writes, the uncertainty encodings write per PM 1002, the channel writes for expressible units, and the token chosen per entry is the canonical token of the registry. A writer emitting a non-canonical synonym (an arrow alias where the entry’s canonical token differs) still round-trips — but the byte corpus freezes the canonical form, and that is what the write claim replays.

16.5  Editions

This document’s surface changes only at an edition: tokens join the registry per PM 1001’s process, constructs join with their classes and clauses, and the corpus generation pins each edition’s surface. Between editions, nothing moves.

16.6  What conformance means for authors

For an author, the conforming implementations are interchangeable: text written for one reads the same in another, and the corpus is the guarantee. For a tool builder, the claim to look for is read-asciimath against a named generation — and the refusal behaviour is part of what they are buying, because a reader that accepts everything cannot promise anything about what it read.

16.7  The claim, in one sentence

An implementation conforming to this document reads every input built from this surface into the tree of PM 1001, refuses everything else with a typed error and its position, writes the canonical surface back byte-identically to the corpus, and round-trips losslessly — and names the corpus generation that says so.

17  Annex A: the construct tables in full

17.1  General

The construct lists of clause 8, restated with each name’s reading. These are generated from the reader’s constants; a mismatch fails the build.

17.2  Unary classes and their readings

Table 28 — Unary readings
TokenReads toTokenReads to
underbraceover/under brace formoverbraceover brace form
underlineunderlinearccosinverse cosine
arcsininverse sinearctaninverse tangent
ubraceunder braceobraceover brace
cancelstrike-throughtildetilde accent
floorfloor fenceceilceiling fence
ddotdouble-dot accentcothhyperbolic cotangent
cschhyperbolic cosecantsechhyperbolic secant
sinhhyperbolic sinetanhhyperbolic tangent
coshhyperbolic cosinesqrtsquare root
normnorm fencetextupright text
secsecantsinsine
tantangentcoscosine
expexponentialgcdgreatest common divisor
glbgreatest lower boundlcmleast common multiple
lubleast upper boundcotcotangent
csccosecantdetdeterminant
dimdimensionmaxmaximum
minminimumabsabsolute-value fence
barbar accentdotdot accent
hathat accentvecvector accent
ulunderlinelnnatural logarithm
loglogarithm (sub/sup class)limlimit (sub/sup class)

17.3  Binary readings

Table 29 — Binary readings
TokenArgumentsReads to
fracnumerator, denominatorFrac
rootradicand, degreeRoot
undersetbase, underUnderset
oversetbase, overOverset
stackrelbottom, topStackrel

17.4  Ternary readings

Table 30 — Ternary readings
TokenCharacterReads to
sum∑Sum with limits
prod∏Prod with limits
int∫Int with limits
oint∮Oint with limits

17.5  Sub/sup readings

lim reads to the limit class with optional scripts; log reads to the logarithm with optional base scripts. Both take the operand adjacency gives and the scripts the input writes.

17.6  The unary readings, worked

Table 31 — Worked unary cases
InputReading
sqrt xSqrt over x — the adjacency operand
sqrt(x^2 + 1)Sqrt over the sum — the grouped operand
bar x, hat x, vec xthe accent classes — one operand each
abs x, norm xthe fence classes — the delimiters ride the node
floor x, ceil xthe floor and ceiling fences
obrace x, ubrace x, underbrace x, overbrace xthe brace forms
cancel x, underline x, ul xthe strike and underbar forms
sin x, cosh x, arctan xthe trigonometric, hyperbolic and inverse classes
ln x, log x, exp xthe logarithmic and exponential classes
gcd x, lcm x, glb x, lub xthe binary-named-but-unary classes — one operand in the notation
det x, dim x, max x, min xthe operator-name classes
ddot x, tilde x, dot xthe remaining accents
text xupright text — adjacency form of the text function

The last-but-one row is the table’s trap: gcd, lcm, glb, lub, max and min are unary classes in this notation, whatever their arity in mathematics — an author who means gcd(a, b) writes it as a product-adjacency the reader splits, and the corpus pins the split. The comma form is not a two-argument call; grouping composes.

18  Annex B: fonts and the special alphabets

18.1  Font tokens and their variants

Table 32 — Font tokens
TokenVariantMathML mathvariant
mathbfboldbold
iiitalicitalic
rmuprightnormal
mathsfsans-serifsans-serif
sfsans-serifsans-serif
mathttmonospacemonospace
ttmonospacemonospace
mathfrakfrakturfraktur
frfrakturfraktur
mathcalscriptscript
ccscriptscript
mathbbdouble-struckdouble-struck
bbdouble-struckdouble-struck
bbbdouble-struckdouble-struck

18.2  The special bold alphabets

Table 33 — Special alphabets
TokenGlyphMeans
ZZℤthe integers
RRℝthe reals
QQℚthe rationals
NNℕthe naturals
CCℂthe complexes

Both spellings exist for the double-struck set: the prefixed form (bbZ) from the public definition and the special token (ZZ). The tokens read to the same registry entries; the corpus pins both spellings in every rendering.

18.3  Fonts in use

Table 34 — Worked font cases
InputReading
mathbf(F) and bf F-shaped shorthands where carriedthe bold variant over the name
mathfrak(g) and fr gthe fraktur variant — prefixed and shorthand forms of one variant
mathbb(R) and bb Rthe double-struck variant — distinct from the RR special alphabet token, which is a symbol
rm xthe upright variant — the added token
ii xthe italic variant — the added token

bb R and RR read to different nodes — a font style over the letter versus the number-set symbol — and the corpus carries both, because the two readings are the classic confusion the special alphabets exist to end.

19  Annex C: the fences

19.1  The fence table

The reader’s parenthesis table, normative:

Table 35 — Fences
OpenerCloserContent reading
()ordinary grouping and construct arguments
[]bracket grouping; row delimiters inside table grids
{}brace grouping; brace-delimited matrices
ᑕᑐthe single-glyph bracket pair, content as ordinary
ℒℛthe script-letter bracket pair, content as ordinary
(::)the angle-bracket pair of the public definition
bar pairitselfthe bar pair — Vmatrix delimiters and absolute-value-like grouping per context

The multi-glyph pairs (ᑕ/ᑐ, ℒ/ℛ) and the letter pair (:/:) are Plurimath’s additions to the public set; the plain three are the baseline’s.

Compatibility note. The public definition also carries the bare : closer; Plurimath’s pairing is strictly two-sided per this table, and a bare closer is a reading error.

19.2  Nesting

Fences nest: ( a b ) is a parenthesised group containing a comma-adjacent pair — the table-reader sees the grid only in the bracketed forms of clause 9. The open stack tracks pairs by opener identity; the table forms are recognised at their own positions, not by the fence stack.

19.3  Fences as constructs

abs(x), norm(x), floor(x), ceil(x), obrace(x), ubrace(x) are unary constructs, not bare fences: their delimiters come from the construct, and the bare fence characters group without a node of their own. The distinction matters for round trips: a construct’s fence survives (the construct carries it), a bare group’s fence survives as grouping.

19.4  The pairs in use

Table 36 — Worked fence cases
InputReading
(:a, b:)the angle fence around the pair — the public definition’s inner product form
ᑕaᑐthe single-glyph bracket pair, content ordinary
ℒxℛthe script-letter pair, content ordinary
bar-x-barthe bar pair grouping — or abs x, which carries its fence on the node
( a b ) two opens — adjacency, not a table; the grid reading needs the bracketed form

The bar pair’s dual role (grouping here, Vmatrix delimiter there) is resolved by position: around a bracketed grid it delimits the matrix, elsewhere it groups. The corpus carries both positions.

19.5  Fences and round trips

A bare group’s fence is grouping, and grouping is not a node — so a round trip may re-spell the grouping (parentheses for brackets where the tree allows). The construct fences (abs, norm, and kin) ride their nodes and survive exactly. An author who needs a specific fence in the output uses the construct that owns it; an author who needs only grouping takes the round trip’s re-spelling. The corpus freezes which cases re-spell and which do not.

20  Annex D: symbol families in full

20.1  The families and their counts

The symbol surface at edition 1, by family, with representative members. The complete token listing is generated from the registry alongside the other tables.

Table 37 — Symbol families
FamilyMembersRepresentatives
Greek lower23alpha beta gamma pi omega
Greek upper13Gamma Delta Omega
binary operators16times pm cdot oplus
relations10approx equiv propto
logic9forall exists neg iff
sets9in subset cup cap emptyset
arrows10-> => mapsto iff
calculus7int oint sum prod partial nabla
accents and miscellany9hbar ell Re Im wp aleph oo degree prime
geometry4angle perp parallel triangle

20.2  Tokens with several spellings

Some entries accept more than one token: the arrows carry their ASCII spellings (->, -->) alongside their named ones; the logic tokens carry words (and, or) alongside signs. Every spelling reads to the same entry and writes to the entry’s canonical AsciiMath token — the round trip may re-spell, and the tree does not change.

20.3  What is not a symbol

Digits, the structure characters, the construct names, the font names and the quoted strings are not symbol tokens; the reader’s classification is total and a token belongs to exactly one class. The boundary cases are decided by the constants and pinned by the corpus: e alone is a symbol; e5 is nothing (a reading error); 2e5 is a number followed by an error.

20.4  The smaller families, complete

Table 38 — Geometry
angleperpparalleltrianglesquare
Table 39 — Accents and miscellany
hbarellReImwp
alephoodegreeprime

The largest families (Greek, operators, relations) carry their complete listings in clause 6; the counts in the family table above are the totals the generated listing holds, and this annex repeats only the families small enough to print in full.

21  Annex E: corpus provenance

21.1  Generations

Table 40 — Corpus generations
GenerationContentsProvenance
1the initial 143 casesthe first frozen surface: constructs, symbols, precedence rulings
2uncertainty formsthe PM 1002 encodings: calls, reporting form, kinds, unit placements
3shared exponents, locale pairsthe shared-exponent reading and the localized reading pairs

Generations extend by appending; a generation’s entries are immutable once published, and the digest replay covers all generations on every run.

21.2  Entry provenance

Each entry names its origin: the clause of this document that first required it, the defect it froze, or the report that brought it. The provenance is the specification’s institutional memory: a behaviour with a provenance entry is deliberate, and a proposal to change it must name the entry.

21.3  Where the corpus lives

The corpus is versioned outside this document, pinned by the replay script the implementation carries. This document’s claims name the generation they were checked against; the register’s build checks the naming.

22  Annex F: test-suite examples

Vectors illustrative of the conformance classes of clause 16. The corpus freezes them; these are their statements.

22.1  Symbol vectors (class read-asciimath)

EXAMPLE 1

One representative per family of Annex D, read. Expected outcome. the family’s registry entry per token; the tree is a formula of symbols, and the writer emits each entry’s canonical token.

EXAMPLE 2

The longest-match cases: ==> against == then >; <= against < then =; ZZ against Z times Z. Expected outcome. the long reading in each pair — one arrow, one relation, one number-set token; the corpora freeze all three against their short readings.

EXAMPLE 3

An unresolvable character run — a Greek letter with a modifier the registry lacks. Expected outcome. ParseError naming the run and its position.

22.2  Construct vectors (class read-asciimath)

EXAMPLE 1

Every unary class of Annex A with a plain argument and a grouped argument. Expected outcome. the class’s node with the argument as its operand; the two forms read to equal trees.

EXAMPLE 2

Every binary class with grouped arguments, and frac with token arguments. Expected outcome. operand order per the class; frac(a)(b) and a/b read to equal Frac nodes.

EXAMPLE 3

The ternary classes bare, with one script, and with both. Expected outcome. the nary node with no limits, the lower limit, and both limits respectively.

EXAMPLE 4

lim_(x->0), log_2 x, bare lim x. Expected outcome. the sub/sup class readings with limits attached where written.

22.3  Table vectors (class read-asciimath)

EXAMPLE 1

Each bracket form of clause 9 with a two-by-two grid. Expected outcome. the class per form — Matrix, Pmatrix, Bmatrix, Vmatrix — with equal cell trees.

EXAMPLE 2

A grid with an empty middle cell and a labelled row in the aligned form. Expected outcome. the None node in place; the label carried per the aligned class.

22.4  Script and fraction vectors

EXAMPLE 1

The four script shapes of clause 10 and both orders of sub and superscript. Expected outcome. Power, Base, and two equal PowerBase nodes.

EXAMPLE 2

a/b^2, a^2/b, a/b/c. Expected outcome. the script inside the denominator; the script on the numerator; the left-associative fraction chain.

22.5  Channel and uncertainty vectors (classes read-asciimath)

EXAMPLE 1

The channel with g, with m/s2, with a leading space, with an unreadable expression, and a plain quoted string. Expected outcome. two unit embeddings; a Text node; a reading error naming the expression; a Text node — the five rows of clause 11.

EXAMPLE 2

The six uncertainty readings of clause 12’s table. Expected outcome. the categories, notations and kinds per PM 1002; the reporting form reconstructs the magnitude.

EXAMPLE 3

uexp(10.3, 0.5) and 10.3(25). Expected outcome. ParseError for the arity; AmbiguousDecimalError for the place mismatch.

EXAMPLE 4

A shared-exponent reporting form. Expected outcome. the concise node with the shifted exact magnitude, per the shared-exponent rule.

22.6  Precedence vectors (class read-asciimath)

EXAMPLE 1

Every ruling row of clause 13’s two tables. Expected outcome. the stated reading for each — a/bc, sin 2x, x^2y, the refused bare-operator script, the grouped x^(-x) — each also frozen in its refused or accepted form.

EXAMPLE 2

The whitespace-ends-attachment rule on a nary and on a script. Expected outcome. the limits end before the summand; the script takes one token.

22.7  Round-trip vectors (classes write-asciimath, roundtrip-asciimath)

EXAMPLE

A tree containing every construct family, one uncertainty node per category, and a unit-bearing node — written, read back. Expected outcome. an equal tree, notation and kind intact, the unit in the channel; the writer’s bytes byte-frozen.

23  Annex G: annotated readings

Twenty inputs, their trees in brief, and the rule each exercises. These are the shapes to internalise; the corpus freezes all of them.

Table 41 — The readings
InputTree and the rule it shows
x^2Power over x and 2 — scripts bind to the closed operand.
x_1^2PowerBase — both scripts on one operand, either written order.
a/bFrac — the fraction takes one token per side.
(a+b)/(c-d)Frac over two groups — grouping offers the bigger operand.
sqrt(x+1)Sqrt over the sum — construct parentheses group.
sqrt xSqrt over x — adjacency takes one token.
sin 2xsine of 2, times x — the unary adjacency rule.
sum_(i=1)^n i^3limited Sum, then the summand — whitespace ends the attachment.
lim_(x->0)the limit with its lower script — the arrow is script content.
log_2 8the logarithm with base 2 — the sub/sup reading.
[[1,2],[3,4]]plain Matrix — each inner bracket pair is a row.
([1,2],[3,4])Pmatrix — the fence selects the class.
text(hello) and "hello"two Text routes to equal content.
"unitsml(g)"the channel — the unit embedding, not text.
uexp(10.3, 0.5, 2, 0.95)the expanded uncertainty — category in the call name.
10.3(2)the reporting form — the shape claimed before adjacency.
ZZthe double-struck integers — the special alphabet before letters.
x^(-x)x to the −x — the grouped script content.
a/bca/b times c — the smallest-operand rule.
( n ( n + 1 ) 2 ) 2 the fenced fraction, scripted — grouping offers the fraction, the script takes it.

Each row is one corpus vector with its renderings frozen; this annex is the reading guide, the corpus is the contract.


Bibliography

[1]  Plurimath repository, — https://github.com/plurimath/plurimath

[2]  asciimath.org, — the public AsciiMath definition (the compatibility baseline)

[3]  PM 1001, of this series

[4]  PM 1002, of this series

[5]  PM 1003, of this series

[6]  PM 1004, of this series

[7]  CalConnect 36817, — the asciiunits content language (the channel’s content)

[8]  plurimath-testsuite, — the pinned corpus repository and its generations