math_spec.typeset.format
The seam between what a model says and how a format spells it.
One walk, many formats — the split relational/sinks/ makes at the other end
of the pipeline. :mod:math_spec.typeset.walk decides where a bracket is needed,
which dimension a reduction binds and where a mask belongs; a :class:Format
decides only that a sum is \sum_{…} or sum_(…).
Two rules make the split hold:
- Everything a walk emits is bare math. No
$, no environment; a format wraps it with :meth:Format.mathto embed it in prose, so the walk never knows which mode it is in. - A format spells; it never decides. No method takes an AST node or a schema. If a format had to look at the model, the question belongs in the walk.
OPERATOR_NAMES = frozenset({'cdot', 'plus', 'minus', 'equal', 'le', 'ge', 'lt', 'gt', 'ne', 'in', 'and', 'or', 'not', 'true', 'false', 'forall', 'such_that', 'infinity', 'minus_infinity', 'cyclic_minus', 'cyclic_plus', 'edge_minus', 'edge_plus', 'times', 'maps_to', 'reals', 'integers', 'binary_set', 'sos_set', 'position', 'minimize', 'maximize'})
module-attribute
#
Entry(symbol, name, detail='', description='')
dataclass
#
One legend row: a symbol, the name it stands for, and what it is.
description = ''
class-attribute
instance-attribute
#
detail = ''
class-attribute
instance-attribute
#
name
instance-attribute
#
symbol
instance-attribute
#
meaning(dash)
#
Everything opposite the symbol, as one string.
What the row says is the walk's answer, not a spelling, so the three formats differ only in the table cell they put it in — and in how they spell the dash between a name and its description, which is the one piece of punctuation here that is not the same in all three.
Source code in src/math_spec/typeset/format.py
Format
#
Bases: Protocol
How one output format spells what a walk emits.
dash
class-attribute
#
notation
class-attribute
#
operators
class-attribute
#
suffix
class-attribute
#
apply(function, argument)
#
cardinality(inner)
#
How many members a set has: |T|.
A fence rather than an entry in :data:OPERATOR_NAMES, which is a
vocabulary of infix spellings — tests/typeset/test_typeset.py
compiles every one of them between two operands.
Source code in src/math_spec/typeset/format.py
cases(arms)
#
A value defined by region: (value, condition) per arm.
The arms partition the frame, so every one carries a condition and there is no otherwise-arm to print last. They arrive in the order the file declares them and print in it — nothing depends on the order, but a reader comparing the page to the file does.
Source code in src/math_spec/typeset/format.py
document(blocks, *, standalone)
#
Source code in src/math_spec/typeset/format.py
equations(lines, *, numbered)
#
Source code in src/math_spec/typeset/format.py
escape(prose)
#
Author prose, made safe for this format's text mode.
Every other atom escapes as it wraps, so what passes through here is
what arrives already being prose — a description:. Not
:meth:prose, which is words inside math, and not :meth:note,
which is handed generated markup too.
Source code in src/math_spec/typeset/format.py
fraction(numerator, denominator)
#
Source code in src/math_spec/typeset/format.py
glossary(title, entries)
#
Source code in src/math_spec/typeset/format.py
greek(name)
#
A name that is a Greek letter, set as the letter.
The walk decides which names those are; a format only spells one. Lower-case names only — every one of them has a letter in both notations, which the capitals do not.
Source code in src/math_spec/typeset/format.py
italic(name)
#
joined(parts, operator)
#
math(expression)
#
mono(text)
#
note(text)
#
parenthesise(inner)
#
Source code in src/math_spec/typeset/format.py
prose(text)
#
script(letter)
#
section(title, body)
#
Source code in src/math_spec/typeset/format.py
subscript(base, indices)
#
Source code in src/math_spec/typeset/format.py
summation(domain, body)
#
Source code in src/math_spec/typeset/format.py
superscript(base, tail)
#
Source code in src/math_spec/typeset/format.py
Glossary(title, entries)
dataclass
#
Line(label, left, right, condition='')
dataclass
#
One typeset line of the model, split where a format may align it.
left and right are the two sides of a relation — right carries
the relation symbol, so a format aligns on the boundary between them
without having to parse anything back out.