math_spec.typesetting.format
The seam between what a model says and how a format spells it.
One walk, many formats. :mod:math_spec.typesetting.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(OPERATOR_SPELLINGS)
module-attribute
#
OPERATOR_SPELLINGS = {'cdot': ('\\cdot', 'dot'), 'plus': ('+', '+'), 'minus': ('-', '-'), 'equal': ('=', '='), 'le': ('\\le', '<='), 'ge': ('\\ge', '>='), 'lt': ('<', '<'), 'gt': ('>', '>'), 'ne': ('\\neq', '!='), 'in': ('\\in', 'in'), 'and': ('\\wedge', 'and'), 'or': ('\\vee', 'or'), 'not': ('\\neg', 'not'), 'false': ('\\bot', 'bot'), 'forall': ('\\forall\\,', 'forall'), 'such_that': ('\\,:\\,', 'colon'), 'infinity': ('\\infty', 'infinity'), 'cyclic_minus': ('\\ominus', 'minus.o'), 'cyclic_plus': ('\\oplus', 'plus.o'), 'edge_minus': ('\\boxminus', 'minus.square'), 'edge_plus': ('\\boxplus', 'plus.square'), 'times': ('\\times', 'times'), 'maps_to': ('\\to', 'arrow.r'), 'reals': ('\\mathbb{R}', 'RR'), 'integers': ('\\mathbb{Z}', 'ZZ'), 'binary_set': ('\\{0, 1\\}', '{0, 1}'), 'sos_set': ('\\mathrm{SOS}', 'upright("SOS")'), 'position': ('\\mathrm{pos}', 'upright("pos")'), 'minimize': ('\\min', 'min'), 'maximize': ('\\max', 'max')}
module-attribute
#
Entry(symbol, meaning)
dataclass
#
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)
#
cases(arms)
#
A value defined by region: (value, condition) per arm, in order.
Both halves arrive rendered — which arm is the fallback is the walk's to decide, and this only stacks the rows.
Source code in src/math_spec/typesetting/format.py
document(blocks, *, standalone)
#
Source code in src/math_spec/typesetting/format.py
equations(lines, *, numbered)
#
Source code in src/math_spec/typesetting/format.py
escape(prose)
#
fraction(numerator, denominator)
#
Source code in src/math_spec/typesetting/format.py
glossary(title, entries)
#
Source code in src/math_spec/typesetting/format.py
greek(name)
#
italic(name)
#
joined(parts, operator)
#
math(expression)
#
mono(text)
#
note(text)
#
parenthesise(inner)
#
Source code in src/math_spec/typesetting/format.py
prose(text)
#
quoted(label)
#
script(letter)
#
section(title, body)
#
Source code in src/math_spec/typesetting/format.py
subscript(base, indices)
#
Source code in src/math_spec/typesetting/format.py
summation(domain, body)
#
Source code in src/math_spec/typesetting/format.py
superscript(base, tail)
#
Source code in src/math_spec/typesetting/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.