Skip to content

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.math to 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 #

One legend row: a symbol, and everything opposite it as one string.

meaning instance-attribute #

symbol instance-attribute #

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) #

A coordinate map applied to an index: bus(g).

Source code in src/math_spec/typesetting/format.py
def apply(self, function: str, argument: str) -> str:
    """A coordinate map applied to an index: ``bus(g)``."""
    ...

cardinality(inner) #

How many members a set has: |T|. A fence, so not an infix entry in :data:OPERATOR_NAMES.

Source code in src/math_spec/typesetting/format.py
def cardinality(self, inner: str) -> str:
    """How many members a set has: ``|T|``. A fence, so not an infix entry in :data:`OPERATOR_NAMES`."""
    ...

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
def cases(self, arms: list[tuple[str, str]]) -> str:
    """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.
    """
    ...

document(blocks, *, standalone) #

Source code in src/math_spec/typesetting/format.py
def document(self, blocks: list[str], *, standalone: bool) -> str: ...

equations(lines, *, numbered) #

Source code in src/math_spec/typesetting/format.py
def equations(self, lines: list[Line], *, numbered: bool) -> str: ...

escape(prose) #

Author prose — a description: — made safe for this format's text mode.

Source code in src/math_spec/typesetting/format.py
def escape(self, prose: str) -> str:
    """Author prose — a ``description:`` — made safe for this format's text mode."""
    ...

fraction(numerator, denominator) #

Source code in src/math_spec/typesetting/format.py
def fraction(self, numerator: str, denominator: str) -> str: ...

glossary(title, entries) #

Source code in src/math_spec/typesetting/format.py
def glossary(self, title: str, entries: list[Entry]) -> str: ...

greek(name) #

A lower-case name that is a Greek letter, set as the letter.

Source code in src/math_spec/typesetting/format.py
def greek(self, name: str) -> str:
    """A lower-case name that *is* a Greek letter, set as the letter."""
    ...

italic(name) #

A multi-letter name, set as one italic symbol rather than a product.

Source code in src/math_spec/typesetting/format.py
def italic(self, name: str) -> str:
    """A multi-letter name, set as one italic symbol rather than a product."""
    ...

joined(parts, operator) #

a op b op c — the one place inter-term spacing is decided.

Source code in src/math_spec/typesetting/format.py
def joined(self, parts: list[str], operator: str) -> str:
    """``a op b op c`` — the one place inter-term spacing is decided."""
    ...

math(expression) #

Wrap bare math for embedding in prose.

Source code in src/math_spec/typesetting/format.py
def math(self, expression: str) -> str:
    """Wrap bare math for embedding in prose."""
    ...

mono(text) #

A name exactly as the YAML spells it.

Source code in src/math_spec/typesetting/format.py
def mono(self, text: str) -> str:
    """A name exactly as the YAML spells it."""
    ...

note(text) #

A paragraph of plain prose between blocks.

Source code in src/math_spec/typesetting/format.py
def note(self, text: str) -> str:
    """A paragraph of plain prose between blocks."""
    ...

parenthesise(inner) #

Source code in src/math_spec/typesetting/format.py
def parenthesise(self, inner: str) -> str: ...

prose(text) #

Words inside math.

Source code in src/math_spec/typesetting/format.py
def prose(self, text: str) -> str:
    """Words inside math."""
    ...

quoted(label) #

A string value as the file spells it — quoted, so a label reads as data rather than a name.

Source code in src/math_spec/typesetting/format.py
def quoted(self, label: str) -> str:
    """A string value as the file spells it — quoted, so a label reads as data rather than a name."""
    ...

script(letter) #

A set symbol.

Source code in src/math_spec/typesetting/format.py
def script(self, letter: str) -> str:
    """A set symbol."""
    ...

section(title, body) #

Source code in src/math_spec/typesetting/format.py
def section(self, title: str, body: str) -> str: ...

subscript(base, indices) #

Source code in src/math_spec/typesetting/format.py
def subscript(self, base: str, indices: list[str]) -> str: ...

summation(domain, body) #

Source code in src/math_spec/typesetting/format.py
def summation(self, domain: str, body: str) -> str: ...

superscript(base, tail) #

Source code in src/math_spec/typesetting/format.py
def superscript(self, base: str, tail: str) -> str: ...

upright(name) #

A qualifier or a function name — upright, because it is not a variable.

Source code in src/math_spec/typesetting/format.py
def upright(self, name: str) -> str:
    """A qualifier or a function name — upright, because it is not a variable."""
    ...

Glossary(title, entries) dataclass #

One legend section: its title, and the entries under it.

entries instance-attribute #

title instance-attribute #

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.

condition = '' class-attribute instance-attribute #

label instance-attribute #

left instance-attribute #

right instance-attribute #