feat: add Typst as an alternative formula renderer#2655
Conversation
✅ Deploy Preview for slidev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
1117f24 to
7c316c9
Compare
f11de5d to
b770595
Compare
…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>
b770595 to
58bd5de
Compare
|
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. |
|
Maybe related (or not): |
|
Thanks @peekxc! The WASM approach is interesting. My rationale for using a native Typst binary from I'm not opposed to either direction, so I'm open to what the reviewers think. I might be wrong but I'm a little inclined to think that typst-wasm is less battle tested than Myriad-Dreamin's typst.ts, maybe that's part of the equation (pun not intended)? Anyways the presentation went really well with the Typst slides. The only troublesome part that I found:
Will try to fix those over the weekend, then this should be ready to review! |
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 vianpm i -D @myriaddreamin/typst-ts-node-compiler.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.