Skip to content

feat: add Typst as an alternative formula renderer#2655

Draft
GZGavinZhao wants to merge 6 commits into
slidevjs:mainfrom
GZGavinZhao:gzgz/native-typst-renderer
Draft

feat: add Typst as an alternative formula renderer#2655
GZGavinZhao wants to merge 6 commits into
slidevjs:mainfrom
GZGavinZhao:gzgz/native-typst-renderer

Conversation

@GZGavinZhao

@GZGavinZhao GZGavinZhao commented Jul 1, 2026

Copy link
Copy Markdown

Fixes #2157.

Allows writing Typst in both inline math expressions $ $ and multi-line math blocks $$ $$.

Previously implemented in #2183, but that was done when Typst doesn't have native HTML support. The recently release Typst v0.15 supports emitting MathML for HTML-native math expressions. The MathML are emitted at build-time, so this adds no runtime dependencies.

The build-time dependency is kind of huge though (a ~50M native Typst compiler executable is needed). Therefore, like the playwright feature, it's added to peerDependencies. Slidev users who want to use Typst need to manually add it as a dependency via npm i -D @myriaddreamin/typst-ts-node-compiler.

  "peerDependencies": {
    "@myriaddreamin/typst-ts-node-compiler": "0.8.0-rc2",
    "playwright-chromium": "^1.10.0"
  },
  "peerDependenciesMeta": {
    "@myriaddreamin/typst-ts-node-compiler": {
      "optional": true
    },
    "playwright-chromium": {
      "optional": true
    }
  },

Demo slides with source.

Commit history contains a revert of a buggy commit (due to #2629, waiting on #2630) purely for personal testing; will revert before requesting a review. Fix has been merged; the commit history is now clean.

@netlify

netlify Bot commented Jul 1, 2026

Copy link
Copy Markdown

Deploy Preview for slidev ready!

Name Link
🔨 Latest commit 58bd5de
🔍 Latest deploy log https://app.netlify.com/projects/slidev/deploys/6a49a4a52cbd2e0008f8593c
😎 Deploy Preview https://deploy-preview-2655--slidev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

GZGavinZhao and others added 6 commits July 4, 2026 17:26
…mpiler

Add `mathRenderer: typst` headmatter option to render $...$ and
$$...$$ expressions with Typst math syntax instead of LaTeX/KaTeX.

Rendering goes through the official Typst 0.15.0 Rust implementation via
`@myriaddreamin/typst-ts-node-compiler` (a NAPI binding around an
unmodified Typst 0.15.0; the MathML `mathml.rs` code is untouched by the
fork). Math is compiled to native MathML at build time during the Vite
markdown transform, so no client-side JS or KaTeX CSS/fonts are shipped.

- types: add `mathRenderer` to `HeadmatterConfig` and `typstMath` to
  `SlidevDetectedFeatures`
- parser: set `typstMath` (and suppress `katex`) when `mathRenderer` is
  `typst`
- syntax: new `typst-math.ts` markdown-it plugin reusing the existing
  $/$$ delimiter rules, backed by a singleton `NodeCompiler`
- wire the plugin into the markdown pipeline, notes loader, and inject
  Typst's MathML CSS via the conditional-styles virtual module
- cli: restart the dev server when the `typstMath` feature toggles

Co-authored-by: opencode <noreply@opencode.ai>
Harden the Typst math renderer for upstream:

- make `@myriaddreamin/typst-ts-node-compiler` an optional peer
  dependency (kept as a devDependency for the monorepo). It is loaded
  on demand via `loadTypstCompiler()` with the same multi-root dynamic
  import + fallback strategy as `playwright-chromium`, throwing a
  helpful install hint when missing.
- own a single shared compiler instance on `utils.typstCompiler`,
  loaded only when `mathRenderer: typst`; thread it through the
  markdown pipeline, notes loader, and conditional-styles CSS injection.
- replace the brittle string-reconstruction fragment extractor with a
  single robust `<math>…</math>` regex.
- surface Typst compile errors: log the diagnostic (with Typst's hints)
  via `console.warn` and render a visible inline error placeholder
  instead of silently swallowing failures.
- regenerate the VS Code headmatter schema for `mathRenderer`.

Co-authored-by: opencode <noreply@opencode.ai>
Implement `$$ {1|3|all}` click-based line highlighting for Typst math,
matching the existing KaTeX behaviour but operating on MathML.

Typst renders multi-line equations as `<mtable class="multiline-equation">`
with one `<mtr>` per line, so highlighting is far simpler and more robust
than KaTeX's span-tree walking:

- add `collectMathmlEquationLines()` that maps each top-level
  `multiline-equation` `<mtr>` to a logical line (ignoring nested tables
  such as `cases` and matrices)
- add `TypstBlockWrapper.vue` (auto-registered from client/builtin) that
  toggles `highlighted`/`dishonored` classes on the `<mtr>` rows across
  click steps
- add `styles/typst.css` dimming non-highlighted rows
- the markdown plugin already emits `<TypstBlockWrapper>` when ranges are
  present, and raw MathML otherwise

Co-authored-by: opencode <noreply@opencode.ai>
Cover the Typst markdown-it plugin:
- inline math renders as bare `<math>` (no display attr)
- block math renders as `<math display="block">`
- block math with ranges is wrapped in `<TypstBlockWrapper>` and yields
  one `<mtr>` per aligned line
- math inside code blocks is left untransformed
- invalid math emits a visible error placeholder instead of throwing
- output is free of Vue interpolation (`{{`)
- the MathML stylesheet is extractable

Assertions use targeted `toContain` checks rather than full snapshots so
they stay stable across Typst compiler versions.

Co-authored-by: opencode <noreply@opencode.ai>
Add a 'Typst Math' section to the LaTeX feature page covering:
- enabling it via `mathRenderer: typst` and installing the optional
  `@myriaddreamin/typst-ts-node-compiler` package
- inline, block, and line-highlighting usage with Typst syntax
- a LaTeX-vs-Typst syntax cheatsheet
- a link to the official Typst math reference

Co-authored-by: opencode <noreply@opencode.ai>
Add `fonts.math` to Slidev's font config and use it when Typst math renders browser-native MathML. The resolved font stack is injected into the Typst MathML stylesheet, and configured math fonts participate in generated webfont requests like the existing sans/serif/mono families.

Document the option and regenerate the VS Code headmatter schema.

Co-authored-by: opencode <noreply@opencode.ai>
@GZGavinZhao GZGavinZhao force-pushed the gzgz/native-typst-renderer branch from b770595 to 58bd5de Compare July 5, 2026 00:26
@GZGavinZhao

Copy link
Copy Markdown
Author

Just to note: this is not stale and is actually ready for use! I'm just doing more stress testing as I'm dogfooding this PR by using Typst in a pretty important presentation, noting any weird bugs or inconveniences along the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Typst support as another option for formula rendering

1 participant