$…$ / $$…$$ do not render in the rich editor. Cause: Milkdown Crepe’s LaTeX feature is explicitly switched off in our wrapper (packages/js/milkdown/src/index.ts: [Crepe.Feature.Latex]: false — “keep the surface small”), and the bundle build strips fonts (--loader:.woff2=empty), so KaTeX’s fonts would be missing even if it were on.

Wanted

  • Inline $E = mc^2$ and block $$ … $$ render with KaTeX in the rich editor; clicking a formula edits its source (Crepe’s Latex feature does this: inline → a popup editor, block → a code-like block with live preview); the markdown on disk stays $…$/$$…$$ (remark-math syntax, what Quartz and Obsidian read).
  • The source editor highlights math spans once 010 (highlighting) exists; no rendering there.
  • Errors (bad LaTeX) show KaTeX’s red message inline, never break the document.
  • Typst preview is unaffected (it has its own math).

Change

  1. Enable Crepe.Feature.Latex (KaTeX is a dependency of @milkdown/crepe’s feature; add katex explicitly to pin the version). Bundle cost to measure: KaTeX ≈ 280 KB JS + CSS; fonts ≈ 60 files / 1.2 MB — ship them as assets under editors/markdown/assets/katex/ (copied by the build script like xterm.css) and point KaTeX’s CSS at them, instead of --loader:.woff2=empty; on Android that is more APK bytes (Android Extensions and Bundling), so the fonts could be a separate dx asset group loaded on first formula.
  2. Macros: a \newcommand block per vault (.moonkale/katex.toml → KaTeX macros), because papers define their own notation; the same file Unicode Input scopes could extend.
  3. E2E rich.mjs: a note with $\alpha$ shows a .katex element; editing the formula updates the markdown.

Acceptance: this vault’s theory-style notes (see Julia and Lenticulum — the Lenticulum vault is full of formulas) render in the rich editor as they do in Quartz.

Done 2026-09-20. Crepe.Feature.Latex is on with throwOnError: false; KaTeX 0.18.7’s stylesheet and its 20 woff2 fonts are copied by packages/js/milkdown/katex-assets.mjs into editors/markdown/assets/katex/ (a dx folder asset, asset!("/assets/katex", AssetOptions::folder()), so the relative fonts/… urls keep working; woff/ttf sources stripped) and linked by the rich view through the new moonkale_ext_api::StylesheetUrl. Per-folder macros: .moonkale/katex.json → { "macros": { "\\R": "\\mathbb{R}" } }, read by Workspace::read_text_at and passed in the init message. Bundle +65 KB. Covered by rich.mjs (inline + block render, .katex elements, CSS linked, fonts loaded, \R macro, markdown unchanged on disk). Source-mode highlighting of math spans comes with 010’s markdown grammar.