Add mode: "text" to render quantities in the document font - #76
heisenbergpxh wants to merge 1 commit into
Conversation
Numbers and units were always typeset via a math.equation, so they inherited the math font even in documents set in a different body font, creating a visible mismatch with surrounding prose (siunitx has supported this via `mode = text` in LaTeX for a long time). Add a `mode: "math" | "text"` parameter to num, unit, qty, numrange, and qtyrange (default "math", fully backward compatible). In "text" mode, a `show math.text: set text(font: text.font, weight: text.weight)` rule restyles only the literal glyphs to the current document font and weight, while the math font still handles layout (superscripts, fractions, stretchy parentheses), so positioning stays correct and bold/emph contexts are inherited automatically. Unit symbols deliberately stay upright even in italic text, matching SI convention. Adds a _display-math helper in format.typ shared by all five public functions, and documents the feature in the README and example file.
There was a problem hiding this comment.
Pull request overview
Adds a mode parameter to quantity/number/unit formatting so callers can render digits and unit glyphs in the surrounding document font (text mode) while keeping math layout for scripts, fractions, and delimiters—similar to LaTeX siunitx’s mode=text.
Changes:
- Introduces
_display-math(formatted, mode)to centralize math evaluation and support"math"vs"text"rendering. - Adds
mode: "math"keyword parameter tonum,unit,qty,numrange, andqtyrange, routing rendering through_display-math. - Documents and demonstrates text mode usage in
README.mdandexamples/example.typ.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| README.md | Documents the new mode: "text" option and a pattern for enabling it globally. |
| lib.typ | Adds mode parameter to public formatting functions and uses _display-math for rendering. |
| format.typ | Adds _display-math helper implementing the "math"/"text" rendering behavior. |
| examples/example.typ | Demonstrates text-mode rendering and inheritance in bold context. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Evaluate a formatted math string and display it. | ||
| /// - `formatted`: Math string to evaluate (without the surrounding `$`). | ||
| /// - `mode`: Whether to render in the math font (`"math"`) or in the surrounding document font (`"text"`). | ||
| assert(("math", "text").contains(mode), message: "invalid mode: " + mode) | ||
|
|
| Right now, physical, monetary, and binary units are supported. New issues or pull requests for new units are welcome! | ||
|
|
||
| ## Math and text mode | ||
| By default, all output is rendered as math and therefore uses the math font. If you prefer numbers and units to match the surrounding document font (like `mode = text` in `siunitx`), set `mode: "text"`: |
|
Thank you for your contribution! This is a very good workaround for #27! I merged it with small changes into the rust branch (#80) in ff3f302, which will soon replace the current native typst version. I added it to the new global config format, and documented that change. I also updated the example. |
Summary
Adds an optional mode parameter to num, unit, qty, numrange, and qtyrange that lets numbers and units be typeset in the surrounding document font instead of the math font equivalent to siunitx's mode = text in LaTeX.
Motivation
unify always renders through a math.equation, so numbers and unit symbols are locked to the math font even in documents set in a different body font. This creates a visible mismatch between inline quantities and surrounding prose, which siunitx users don't have to deal with since it can switch to text mode. This PR closes that gap.
Changes
format.typ: added _display-math(formatted, mode), a helper that evaluates the formatted math string. In mode: "math" (default) it behaves exactly as before (eval("$" + formatted + "$")). In mode: "text" it wraps the evaluation with show math.text: set text(font: text.font, weight: text.weight), so only the literal glyphs (digits, unit letters, operators) are redrawn in the current document font and weight, while the math font is still used for structural layout superscripts, fraction bars, and stretchy lr(()) parentheses stay correctly positioned. This also means bold/emph contexts are inherited automatically.
Note: only font/weight are forwarded, not style unit symbols conventionally stay upright even in italic passages.
lib.typ: added mode: "math" as a keyword parameter to num, unit, qty, numrange, and qtyrange, and routed their final eval(...) calls through _display-math instead of doing it inline. Invalid mode values fail with an assertion.
README.md: added a "Math and text mode" section documenting the parameter and showing the #let qty = qty.with(mode: "text") pattern for enabling it document-wide.
examples/example.typ: added a mode: "text" usage line, including a bold-context example, alongside the existing math-mode output for comparison.
Compatibility
Fully backward compatible. mode defaults to "math" on all five functions, so existing documents and their rendered output are unaffected verified by compiling the example file and comparing math-mode output pixel-for-pixel before and after this change.