Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

mdbook-typst-math

Crates.io Version docs.rs

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-preprocessor crate 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 cache option 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 cache to:

  • $XDG_CACHE_HOME/typst/packages or ~/.cache/typst/packages on Linux
  • ~/Library/Caches/typst/packages on macOS
  • %LOCALAPPDATA%\typst\packages on 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.