mathtex-editor
Structural math editing for Rust and the web, typeset by real TeX.
Type x^2, a/b or alpha and watch it lay out the way TeX would. The document is a tree, so the caret moves through fractions, scripts and matrices the way you think about them, and every edit exports clean LaTeX.
- Real TeX layout. Every keystroke is typeset by mathtex, the XeTeX engine in Rust, in the browser or natively.
- Keyboard first. Autocorrect for
<=and->, about 190 backslash words, a command palette with live previews, and a Backspace that selects a structure first and offers to swap brackets. - Pick your layer. An explicit headless core, a pluggable keymap, a batteries included session, a wasm runtime and a Leptos component. Take as much or as little as your app needs.
- Your widgets inside the math. Host boxes reserve space in a formula for anything you draw, from a text field to a chart.
- Documents you can trust. Versioned JSON, validated on load, with seeded fuzz tests over random edits.
Crates
| Crate | Role |
|---|---|
mathtex-editor-core |
the editable tree, caret, selection, LaTeX export and geometry, with no hidden behaviour |
mathtex-editor-keymap |
key events and typed text to editor commands |
mathtex-editor-session |
core, keymap and typesetter wired together with undo, clipboard and host box tokens |
mathtex-editor-js |
the session for the web, rendering SVG |
mathtex-editor-leptos |
a MathEditor component for Leptos 0.8 |
Quick start
let mut session = new;
session.key;
let view = session.view?;
// Draw view.fragment, then view.render.caret, selection and placeholders on top.
Build the typesetter from a baked mathtex format as the mathtex README shows. The session typesets only when the document changed, keeps undo in one step per edit, copies as JSON and LaTeX, and gives pasted host boxes fresh tokens. UndoStack, TokenRegistry and RenderCache also work on their own.
Full control with the core
The core never typesets, keeps no history, reads no keys and calls nothing back. You send a command and get a value back that says exactly what happened.
let before = editor.snapshot;
if editor.exec.changed
let source = editor.source;
let output = editor.render?;
execreturns anOutcomewithchanged,moved,exit,close,entered_host_boxand therevision. Retypeset only when the revision moves.- A
CaretPathnames the route to the caret through each slot, survives serialization and can be set directly withset_cursororset_selection. snapshotandrestorecapture the document with its caret for undo.at_start,in_text_slot,menu,matrix_shapeandinput_contextanswer questions without moving anything.- Geometry is in points with y down from the fragment's top left, the units of the mathtex SVG
viewBox, andsourcespans are byte ranges of the LaTeX.
Typing
The keymap turns a/b into a fraction, x^2 into a superscript and alpha plus space into α. The longest known word at the end wins, so xsin gives x then sin. <=, -> and friends become one symbol, while ordinary input like x<-1 is left alone. Inside \text{} everything types literally.
Read Editor::input_context() before each map_key or map_text call, run the returned commands once in order, and call reset() when the caret moves outside the keymap. Conversions ask the core to replace exactly the letters typed, so a stale word can never delete the wrong thing.
Documents
Document is versioned JSON, the unit of storage and of the clipboard.
Every document is validated on load, Document::repair fixes one built in code and lists each fix, and to_tex_with exports LaTeX with your own content in place of host boxes. The LaTeX uses amsmath, and \mathbb or \mathfrak need amssymb or a Unicode math font.
On the web
const editor = ;
editor.;
stage. = editor.;
The resolver hands back font files as Uint8Array or null. key, text, click, the clipboard calls and the toolbar calls return an Update saying what changed. render returns SVG with the caret and selection drawn in and throws the TeX error when a formula does not typeset. The demo in web/ shows the whole feature set, and web/hostbox.html puts live HTML inputs inside a formula.
In Leptos, MathEditor takes a shared WebEditor and handles keys, IME, pointer, clipboard, undo and the swap menu for you.
Development
The e2e reads format.pkg and fonts from MATHTEX_ASSETS, the sibling mathtex checkout's web/assets by default. For the web demo, build with --target web, copy the output with cp -r crates/mathtex-editor-js/pkg/. web/pkg/ and the assets into web/assets, then serve web/.
Known gaps
- Up and Down between unrelated lines only moves structurally, through fractions, scripts and matrices.
- The Leptos component compiles for wasm32 but no browser test drives it yet.
Licensed under either Apache-2.0 or MIT.