Introduce first-class support for rendering text and markup via Typst (optional dependency)#4681
Conversation
…port Implement the initial TypstMobject proposal (see agents/typst.md): - TypstMobject: renders arbitrary Typst markup to SVG via the 'typst' Python package (self-contained Rust binary, no system install needed), then imports through SVGMobject. - TypstMathMobject: convenience subclass that wraps input in Typst math delimiters ($ ... $). Pipeline: user string → wrap in minimal Typst document (auto-sized page, transparent background) → write .typ file → compile to SVG via typst.compile() → import via SVGMobject → scale/center/recolor. Key details: - Compilation helper in manim/utils/typst_file_writing.py with SHA-256 content-hash caching (same scheme as the LaTeX pipeline). - font_size property mirrors SingleStringMathTex: compile at fixed 11pt, scale after import using initial_height / SCALE_FACTOR_PER_FONT_POINT. - init_colors() recolors black submobjects to self.color (Typst default fill is black), preserving any explicit Typst colors. - path_string_config enables curve subdivision for smooth animation. - 'typst' added as optional dependency group in pyproject.toml. - 10 tests covering creation, font_size, caching, preamble, and repr.
- Override modify_xml_tree in Typst to convert data-typst-label
attributes to id attributes before svgelements parsing (avoids
attribute inheritance issue with data-* attributes)
- Add Typst.select(key) method accepting str labels or int indices
to retrieve VGroup sub-expressions from id_to_vgroup_dict
- Implement {{ }} double-brace preprocessor on TypstMath:
- {{ content }} → manimgrp("_grp-N", content) (auto-numbered)
- {{ content : label }} → manimgrp("label", content) (named)
- Skips {{ }} inside string literals and [...] content blocks
- Uses math-mode call convention (no # prefix) to keep args in
math mode
- Auto-inject manimgrp preamble when groups are detected
- Add 12 new tests covering label mapping, nesting, select(),
error handling, and preprocessor edge cases
Remove some LaTeX assumptions to allow for Typst objects
for more information, see https://pre-commit.ci
|
Tests pass and the general state of things is quite good I think, but specifically looking at the rendered examples at https://manimce--4681.org.readthedocs.build/en/4681/reference/manim.mobject.text.typst_mobject.html did reveal that some things still need a bit of polish. Changed this PR to a draft for now. |
|
implementation and docs are more or less clean, ready to be looked at! |
|
Thank you! Looking forward to the merge of this feature |
There was a problem hiding this comment.
LGTM! Thanks for this huge addition!
Small details can be added in follow-up PRs if necessary. One detail I would like to add is that, given that our recommended installation method for Manim is via uv, we should suggest installing Typst with uv add typst in using_text.rst and typst_to_svg_file() if the user installed Manim with uv.
|
Amazing! Thanks @behackl! |


This PR adds first-class Typst support to Manim via new
TypstandTypstMathmobjects. Typst source is compiled directly to SVG through the Pythontypstpackage, so users can render both general Typst markup and math without relying on a TeX installation. The branch also integrates Typst with existing label-oriented APIs and adds user-facing documentation and examples.In addition to the core Typst mobjects, this PR includes a few polish and compatibility improvements: subexpression selection via Typst labels and
{{ ... }}groups (incl. a named version), optional baseline-frame tracking for debugging/alignment, and updates to the docs build so Typst examples render in the documentation.Documentation:
In short:
TypstandTypstMathselect(...){{ ... }}grouping inTypstMathManimTextLabel)TypstandTypstMath, they'd have to eitherpip install typstseparately, or install manim viapip install 'manim[typst]'Closes #3339.