mdbook-typst-math
mdbook-typst-math is an mdBook preprocessor that uses Typst to render mathematical expressions.
Requirements
- mdBook 0.5.x or later - This preprocessor uses the
mdbook-preprocessorcrate which requires mdBook 0.5.x - Rust (for building from source)
Installation
Cargo
You can install the latest released version from crates.io:
cargo install mdbook-typst-math
Or install the latest version from GitHub:
cargo install --git https://github.com/duskmoon314/mdbook-typst-math
Or build from source:
git clone https://github.com/duskmoon314/mdbook-typst-math.git
cd mdbook-typst-math
cargo build --release
Pre-built binaries
You can download pre-built binaries from the releases.
Usage
Setup preprocessor
Add the following to your book.toml:
[preprocessor.typst-math]
If mdbook-typst-math is not in your PATH, you need to specify its location:
[preprocessor.typst-math]
command = "path/to/mdbook-typst-math"
The path is usually ~/.cargo/bin/mdbook-typst-math if you installed it using cargo.
Control the style
Add css to control the style of the typst block:
/* css/typst.css as an example */
.typst-inline {
display: inline flex;
vertical-align: bottom;
}
.typst-display {
display: block flex;
justify-content: center;
}
.typst-display > .typst-doc {
transform: scale(1.5);
}
Add the following to your book.toml:
[output.html]
additional-css = ["css/typst.css"]
Theme support (Dark mode)
By default, this preprocessor generates SVGs with transparent backgrounds and
replaces black text color with currentColor. This allows the math to adapt
to different color themes.
To make the math text color adapt to the current theme automatically, add the following CSS:
/* Use the theme's foreground color for math */
.typst-doc {
color: var(--fg);
}
If you prefer to set specific colors for dark themes (coal, navy, ayu), you can use:
/* Set specific text color for dark themes */
html.coal .typst-doc,
html.navy .typst-doc,
html.ayu .typst-doc {
color: #b3b3b3;
}
What this preprocessor does
By default, this preprocessor converts all math blocks to a <div> with the
class typst-inline/typst-display (depending on the type of math block) and
an inline <svg> with the class typst-doc inside.
For an experimental, browser-native alternative, set html_math = true. Math
blocks are then emitted as MathML <math> elements generated by Typst’s HTML
target; fenced typst,render code blocks continue to use SVG. This target is
still under active development in Typst, and some layout features, custom
styling, or diagrams may be incomplete. MathML support and font rendering also
vary between browsers.
Say you have the following code block in your markdown:
hello
$$
y = f(x)
$$
world
This preprocessor will first change it to:
hello
- $$
- y = f(x)
- $$
+ #set page(width:auto, height:auto, margin:0.5em, fill:none)
+ $ y = f(x) $
world
The math content is wrapped in typst’s $ ... $ to indicate it is a math block, and a preamble is added before it to set the page size and margin.
Then preprocessor will leverage typst to render the math block and change it to:
hello
<div class="typst-display">
<svg class="typst-doc" ...></svg>
</div>
world
Rendering Typst with fenced code blocks
In addition to math blocks, you can render arbitrary Typst content using fenced code blocks:
```typst,render
#set text(fill: blue)
*Hello from Typst!*
```
This allows you to use Typst’s full capabilities beyond math mode, including:
- Diagrams with packages like cetz
- Tables and layouts
- Formatted text with custom styling
- Any other Typst features
Code blocks are also rendered using the display_preamble (or preamble if not set) and wrapped in <div class="typst-display">.
Using Typst Packages
This preprocessor supports Typst packages from Typst Universe. Packages are automatically downloaded and cached when first used.
To use a package like physica, add the import to your preamble:
[preprocessor.typst-math]
cache = ".typst-cache"
preamble = """
#set page(width:auto, height:auto, margin:0.5em)
#import "@preview/physica:0.9.7": *
"""
Then you can use the package features in your math blocks:
The derivative is $dv(f,x)$ and the partial derivative is $pdv(f,x,y)$.
$$
grad f = vu(x) pdv(f,x) + vu(y) pdv(f,y)
$$
Note: Make sure to set the
cacheoption to specify where downloaded packages should be stored. You may want to add this directory to your.gitignore.You may also want to re-use the same cache directory as your Typst installation by setting
cacheto:
$XDG_CACHE_HOME/typst/packagesor~/.cache/typst/packageson Linux~/Library/Caches/typst/packageson macOS%LOCALAPPDATA%\typst\packageson Windows
Configuration
Currently, only following configurations are supported. Here we use an example to show how to set them:
Font files configured directly are parsed when the preprocessor starts. Font directories and platform system-font directories are scanned for metadata at startup, while the font data itself is loaded only when Typst selects that font. Fonts are considered in this order: configured paths, system fonts (if enabled), and embedded fallback fonts (when the binary includes them).
[preprocessor.typst-math]
# Additional font files or directories to load.
# A string or an array of strings is accepted.
fonts = ["/path/to/FiraMath-Regular.otf", "/path/to/fonts"]
# Search platform system-font directories. Defaults to true.
# Embedded fallback fonts remain available when the binary is built with the
# default `embed-fonts` Cargo feature.
include_system_fonts = true
# Preamble to be added before the typst code
#
# The default preamble is:
# ```
# #set page(width:auto, height:auto, margin:0.5em, fill:none)
# ```
#
# The `fill: none` makes the background transparent, which allows the
# rendered math to adapt to different color themes (light/dark mode).
# If you want a specific background color, you can set it like:
# `fill: white` or `fill: rgb("#ffffff")` for white background.
#
# NOTE: When you customize `preamble`, the default value is completely
# overwritten. If you don't specify `fill`, Typst's default (white
# background) will be used. To keep transparent background, explicitly
# set `fill: none` in your custom preamble.
preamble = """
#set page(width:auto, height:auto, margin:0.5em, fill:white)
#set text(size: 12pt)
#show math.equation: set text(font: "Fira Math")
"""
# Preamble to be added before the typst code for inline math
#
# If not set, then `preamble` will be used.
#
# Usually, this is not needed. But if you want to use different settings for
# inline math and display math, you can set this.
inline_preamble = """
#set page(width:auto, height:auto, margin:0.5em, fill:white)
#set text(size: 12pt)
#show math.equation: set text(font: "Fira Math")
"""
# Preamble to be added before the typst code for display math
#
# If not set, then `preamble` will be used.
#
# Usually, this is not needed. But if you want to use different settings for
# inline math and display math, you can set this.
display_preamble = """
#set page(width:auto, height:auto, margin:0.5em, fill:white)
#set text(size: 14pt)
#show math.equation: set text(font: "Fira Math")
"""
# Cache directory for downloaded packages
#
# If you want to use Typst packages (e.g., physica), you should set this.
# The packages will be downloaded from packages.typst.org and cached here.
cache = ".typst-cache"
# Color mode for SVG output
#
# - "auto" (default): Replace black (#000000) with `currentColor` in SVG,
# allowing CSS to control text color for theme support (light/dark mode).
# - "static": Keep colors as-is from Typst output. Use this if you want to
# preserve exact colors or use a fixed background color.
color_mode = "auto"
# Code block language tag for rendering Typst code blocks
#
# By default, code blocks with the language tag `typst,render` are rendered.
# You can customize this to use a different tag.
code_tag = "typst,render"
# Enable rendering of math blocks (inline and display math)
#
# Set to false to disable math block rendering. Defaults to true.
enable_math = true
# Enable rendering of Typst code blocks
#
# Set to false to disable code block rendering. Defaults to true.
enable_code = true
# Experimental: emit math as browser-rendered MathML instead of SVG.
# Typst's HTML exporter is incomplete; this does not affect typst,render
# fenced code blocks, which continue to use SVG. Defaults to false.
html_math = false
Contributing
Contributions are welcome! Please open issues or pull requests with:
- Bug reports
- Feature requests
- Documentation improvements
- Any other contributions
If you use this preprocessor in your mdBook projects, please consider sharing your experience or examples.