paseo.cafe
All plugins

ratex-formula

by ZedRover

LaTeX rendering and selectable formula source for Paseo

v0.1.2 Requires Paseo >=0.8.0 <0.10.0

Install

npmjs · Paseo 0.9+

paseo plugin add npm:ratex-math-render@0.1.2

GitHub · Paseo 0.8 fallback

paseo plugin add ZedRover/ratex-paseo --ref 68af1d3a5260116485b640038ae80e0ad69b29cc

Git security status and fallback installation are pinned to commit 68af1d3a5260.

README

RaTeX for Paseo

English | 简体中文

Render LaTeX formulas directly in Paseo conversations, select and copy their original source, and double-click a formula to inspect its TeX in place.

Features

  • Automatically renders formulas in assistant and user messages.
  • Supports inline delimiters $...$ and \(...\), and display delimiters $$...$$ and \[...\].
  • Preserves the original formula delimiters, whitespace, and line breaks when copying across a formula.
  • Double-click a formula to replace it with a Markdown-style code box. Copy is in the upper right; Show formula restores the rendered view.
  • Keyboard access: focus a formula and press Enter or Space to show its source.
  • Embeds the math fonts and WASM binary; rendering does not fetch assets from a CDN.
  • Provides a RaTeX sidebar scratch pad and a RaTeX formula workspace panel.
  • Shows selectable TeX while loading, on render failure, and on native iOS/Android clients.

Plugin controls, tooltips, and accessibility labels use English. The installed Paseo plugin SDK does not expose the app's language setting.

Requirements

Component Requirement
Paseo Manifest targets >=0.8.0 <0.10.0; developed against SDK 0.9.0-beta.2
Client Web for rendered formulas and double-click interaction; native clients show source
Development runtime Node.js 22.14+ recommended; tested with Node.js 22.21.1 and npm 11.10.1
Installation runtime Node.js and npm available on the daemon host; use a Paseo version that supports npm plugin sources

Paseo plugins must already be enabled on the target daemon. Plugins run as trusted code on that daemon and in its connected clients.

Install from npm (recommended)

Install the published ratex-math-render package on your Paseo daemon host:

paseo plugin install npm:ratex-math-render
paseo plugin ls

You can also paste npm:ratex-math-render into Settings → Plugins → Plugin source in Paseo. Paseo downloads the package and installs its dependencies; no separate npm install command is needed.

To install a specific version:

paseo plugin install npm:ratex-math-render@0.1.0

The npm package name is ratex-math-render; the installed plugin ID is ratex-formula. Use that ID to update the plugin:

paseo plugin update ratex-formula

Refresh the web client after installation to load the formula UI.

Install from GitHub

paseo plugin add ZedRover/ratex-paseo --ref main
paseo plugin ls

A private repository requires Git access from the daemon machine. The plugin manifest runs npm ci --omit=dev during Git installation, which also generates the embedded assets. The runtime plugin ID is ratex-formula.

To update a Git installation:

paseo plugin update ratex-formula

Local development

git clone https://github.com/ZedRover/ratex-paseo.git
cd ratex-paseo
npm ci
npm run typecheck
npm test
npm run render:launch

Install the checkout into your local daemon:

paseo plugin install "$PWD"
paseo plugin ls

After editing the source:

npm run typecheck
paseo plugin reload ratex-formula

Refresh the web client if it still shows the previous UI. Source edits do not require restarting the daemon.

Using formulas

For example, send a message containing:

Energy is $E=mc^2$.

\[
a^2 + b^2 = c^2
\]

Select across the message to copy the formulas as TeX. Double-click either formula to show a code box at its original location. The copy button copies the complete formula source, including its delimiters.

The scratch pad is available from the RaTeX sidebar entry, the RaTeX formula workspace panel, and the Open RaTeX formula Command Center action.

How rendering works

  1. A client timeline transformer detects complete formulas in messages.
  2. The client sends TeX, display mode, and color through a plugin RPC.
  3. ratex-wasm parses and lays out the formula in the daemon, returning a DisplayList.
  4. The web client draws that DisplayList using Canvas 2D and embedded KaTeX font files.
  5. Selectable source text preserves copy behavior; opening the code box replaces the canvas with visible source.

The server caches render results with both an entry limit and a serialized-size budget. Large results bypass the cache. Formula input is limited to 4096 characters.

Markdown behavior and limits

Messages without a complete formula retain Paseo's built-in Markdown renderer. For messages containing formulas, this plugin renders the whole message. It supports headings, emphasis, strikethrough, code spans, fenced and indented code, links, quotes, lists, task lists, pipe tables, and horizontal rules.

  • This is a limited Markdown renderer, not a complete CommonMark/GFM implementation.
  • Images are shown as their label and URL, rather than fetched and displayed.
  • Copying preserves formula source, but does not reconstruct all original Markdown markers or table separators.
  • Native clients display TeX source; Canvas rendering and double-click source inspection are web features.
  • Unsupported formulas fall back to their source.

Generated assets

npm ci and npm install run the prepare script, which generates:

Generated file Command
server/vendor/ratex-wasm-bytes.ts npm run embed-wasm
client/vendor/fonts.ts npm run embed-fonts

These files are ignored by Git and regenerated from the pinned ratex-wasm dependency. The WASM binary is gzip-compressed before Base64 embedding and decompressed once during server initialization. Tests verify that decompression reproduces the upstream binary byte for byte. Do not use --ignore-scripts unless you then run npm run prepare. Asset consistency is checked by npm test.

Browser regression checks

The browser harness uses the production components, React Query, and server renderer. It substitutes only Paseo host hooks. Install the browser tools in a separate directory:

mkdir -p /tmp/ratex-browser-tools
npm install --prefix /tmp/ratex-browser-tools \
  esbuild puppeteer-core@25.11.0 react@19.1.0 react-dom@19.1.0 react-native-web@0.21.2

Run the real Chrome checks with an installed Chrome or Chromium executable:

RATEX_BROWSER_DEPS=/tmp/ratex-browser-tools \
CHROME_BIN=/absolute/path/to/chrome \
npm run test:browser

With obscura installed on PATH, also run:

RATEX_BROWSER_DEPS=/tmp/ratex-browser-tools npm run test:browser -- --obscura

Chrome checks actual mouse dragging, clipboard reads and writes, inline/display source boxes, the upper-right copy button, keyboard access, fonts, loading states, theme changes, failures, native fallback, and compact layout. Obscura checks programmatic Range selection through Puppeteer/CDP; it does not verify native mouse selection or clipboard behavior. Both commands shut down their own test servers and browsers.

Project layout

index.client.tsx       Client contributions and timeline transformers
index.server.ts       Server RPC registration
client/               Message, formula, code-box, and canvas UI
server/               WASM initialization, rendering, and cache
shared/               Parsing, layout, and RPC contracts
scripts/              Embedded asset generation and render smoke test
tests/                Unit tests and browser regression harness

Publishing

The npm package is ratex-math-render. Before publishing a new version:

npm ci
npm run typecheck
npm test
npm run check:package
npm publish --access public

files explicitly includes generated WASM and fonts, both READMEs, and license notices. The pinned ratex-wasm dependency is bundled to preserve the internal paths used by its renderer and WASM bindings. Tests and development tools are excluded from the tarball.

Paseo skips lifecycle scripts for npm installations, so the published package includes ready-to-use assets. The manifest's preparation command runs npm ci --omit=dev for Git checkouts with a lockfile, and checks the shipped assets for npm installations.

GitHub Actions releases

.github/workflows/publish.yml checks pushes to main, pull requests, and manual runs. Publishing a stable GitHub Release runs the same checks, then publishes to npm using OIDC with provenance. Drafts and prereleases do not publish. The release tag must exactly match v plus the version in package.json and package-lock.json.

Configure an npm trusted publisher once in the package settings:

Field Value
Provider GitHub Actions
Organization or user ZedRover
Repository ratex-paseo
Workflow filename publish.yml
Environment Leave empty
Allowed actions Enable direct npm publish

No NPM_TOKEN or NODE_AUTH_TOKEN secret is required. The workflow grants id-token: write only to the publish job and uses GitHub-hosted runners. See npm trusted publishing.

For the next patch release after 0.1.0, start from a clean, up-to-date main:

npm version patch -m "chore(release): %s"
git push origin main --follow-tags
gh release create v0.1.1 --verify-tag --generate-notes

Use the new version's tag for subsequent releases. Pushing a tag alone does not publish; the Release must be published. Inspect the Check and publish run in GitHub Actions. If publication fails, correct the npm trust configuration as needed and rerun the failed job; never reuse an already published npm version.

Acknowledgments

This plugin builds on the work of these projects and their contributors:

  • RaTeX: the Rust/WASM math parser and layout engine, plus the web DisplayList renderer used through ratex-wasm.
  • Paseo: the host application, plugin SDK, timeline integration, and client/server runtime.
  • KaTeX: the math font files bundled by ratex-wasm and embedded in this plugin.

Thank you to their maintainers and contributors for making this integration possible.

License and third-party notices

This project's original code is licensed under the MIT License, copyright © 2026 ZedRover.

Third-party code and assets retain their own licenses. RaTeX (ratex-wasm) uses the MIT license; the bundled KaTeX fonts use the SIL Open Font License 1.1. Their copyright and license notices are preserved in client/vendor/FONT-LICENSE.txt. The project's MIT license does not replace the fonts' OFL license or other dependency licenses.

When redistributing the plugin with these third-party components, include their applicable copyright and license notices as well as this project's license.

Scanned 22 Sep 2026, 12:46 UTC from ZedRover/ratex-paseo.