Skip to content

math_spec.typesetting.markdown

GitHub-flavoured Markdown. The format that renders where the docs already live.

Markdown has no math of its own — GitHub delegates to MathJax, which reads LaTeX — so the math is :class:LatexFormat's and only the document layer differs. It exists so docs/examples/ does not write its math by hand with nothing checking it against the model — see test_the_gallery_math_is_current.

MarkdownFormat #

Bases: LatexFormat

See :class:math_spec.typesetting.format.Format. Math is LaTeX's; prose is not.

cases_row = ' \\cr ' class-attribute #

dash = '—' class-attribute #

operators = {**LatexFormat.operators, 'forall': '\\forall\\thinspace', 'such_that': '\\thinspace:\\thinspace'} class-attribute #

suffix = '.md' class-attribute #

document(blocks, *, standalone) #

No preamble: standalone adds the heading a fragment is pasted under.

Source code in src/math_spec/typesetting/markdown.py
@override
def document(self, blocks: list[str], *, standalone: bool) -> str:
    """No preamble: ``standalone`` adds the heading a fragment is pasted under."""
    body = '\n\n'.join(blocks) + '\n'
    return f'## The math\n\n{body}' if standalone else body

equations(lines, *, numbered) #

One display block per equation, with the name outside the math.

\text{total\_cost} renders its escape literally under MathJax, and aligned has nothing to line up across one-equation blocks. numbered is ignored: aligned cannot carry numbers.

Source code in src/math_spec/typesetting/markdown.py
@override
def equations(self, lines: list[Line], *, numbered: bool) -> str:
    r"""One display block per equation, with the name *outside* the math.

    ``\text{total\_cost}`` renders its escape literally under MathJax, and
    ``aligned`` has nothing to line up across one-equation blocks.
    ``numbered`` is ignored: ``aligned`` cannot carry numbers.
    """
    del numbered
    blocks = []
    for line in lines:
        body = f'{line.left} {line.right}'.strip()
        if line.condition:
            body = f'{body} \\qquad {line.condition}'
        block = f'$${body}$$'
        if line.label:
            block = f'**{self.mono(line.label)}**\n\n{block}'
        blocks.append(block)
    return '\n\n'.join(blocks)

escape(prose) #

Markdown's text mode is prose, so author prose is already in it.

Source code in src/math_spec/typesetting/markdown.py
@override
def escape(self, prose: str) -> str:
    """Markdown's text mode *is* prose, so author prose is already in it."""
    return prose

glossary(title, entries) #

Source code in src/math_spec/typesetting/markdown.py
@override
def glossary(self, title: str, entries: list[Entry]) -> str:
    rows = '\n'.join(f'| {_cell(self.math(e.symbol))} | {_cell(e.meaning)} |' for e in entries)
    return f'#### {title}\n\n| Symbol | Meaning |\n|---|---|\n{rows}'

joined(parts, operator) #

,\enspace as the bare separator: a letter-named macro, so visibly not a Markdown escape.

Source code in src/math_spec/typesetting/markdown.py
@override
def joined(self, parts: list[str], operator: str) -> str:
    r"""``,\enspace`` as the bare separator: a letter-named macro, so visibly not a Markdown escape."""
    return f' {operator} '.join(parts) if operator else r',\enspace '.join(parts)

mono(text) #

A backtick span — this one lands in prose, not in math.

Source code in src/math_spec/typesetting/markdown.py
@override
def mono(self, text: str) -> str:
    """A backtick span — this one lands in prose, not in math."""
    return f'`{text}`'

note(text) #

Source code in src/math_spec/typesetting/markdown.py
@override
def note(self, text: str) -> str:
    return text

section(title, body) #

Source code in src/math_spec/typesetting/markdown.py
@override
def section(self, title: str, body: str) -> str:
    return f'#### {title}\n\n{body}'