#20286: Matrix: render LaTeX for Element Desktop by emitting data-mx-maths in formatted_body
channel: matrix
size: S
Cluster:
Model Reasoning Fixes
## Summary
- Problem: Matrix messages containing LaTeX (`.........`, `.........`) were sent as plain Markdown HTML (`<p>.........</p>`), which Element does not render as math.
- Why it matters: Users see raw LaTeX text instead of rendered equations, making math-heavy chats difficult to read. Element is the most used and feature-riched client for Matrix.
- What changed: Updated `extensions/matrix/src/matrix/send/formatting.ts` to detect inline/block LaTeX and emit Element-compatible `data-mx-maths` markup in `formatted_body`.
- What did NOT change (scope boundary): No changes to non-math Markdown rendering behavior, no protocol-level Matrix API changes, no config schema changes.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [x] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #20276
## User-visible / Behavior Changes
- Matrix messages containing LaTeX now render in Element when sent by OpenClaw:
- Inline math: `$$x^2$$` → `<span data-mx-maths="x^2"><code>x^2</code></span>`
- Display math: `E=mc2E = mc^2E=mc2` → `<div data-mx-maths="E = mc^2"><code>E = mc^2</code></div>`
- Non-math messages are unchanged.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
## Repro + Verification
### Environment
- OS: Ubuntu 24.04.4 LTS
- Runtime/container: OpenClaw gateway local runtime
- Model/provider: ChatGPT Codex 5.3
- Integration/channel (if any): Matrix (Element Desktop)
- Relevant config (redacted): Matrix plugin enabled; standard `org.matrix.custom.html` message formatting path
### Steps
1. Send a Matrix message via OpenClaw containing `E=mc2E = mc^2E=mc2`.
2. Inspect sent event `content.formatted_body`.
3. Open message in Element Desktop and verify rendering.
4. Repeat for inline example `$$x^2$$` embedded in normal text.
### Expected
- `formatted_body` contains `data-mx-maths` markup for detected math.
- Element renders equations as math, not raw `$` delimiters.
### Actual
- Before fix: `formatted_body` contained `<p>E=mc2E = mc^2E=mc2</p>` (raw text shown in Element).
- After fix: `formatted_body` contains `data-mx-maths` HTML and renders correctly.
## Evidence
Attach at least one:
- [ ] Failing test/log before + passing after
- [x] Trace/log snippets
- [] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios:
- Display math-only message renders in Element.
- Inline math in mixed text renders.
- Normal non-math markdown remains unchanged.
- Edge cases checked:
- Multiple math expressions in one message.
- Multiline display-math capture with `.........`.
- What you did **not** verify:
- Full escaped-dollar edge cases (e.g. `\$`) across all clients.
- Behavior in non-Element Matrix clients.
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly:
- Revert commit affecting `extensions/matrix/src/matrix/send/formatting.ts`.
- Files/config to restore:
- `extensions/matrix/src/matrix/send/formatting.ts`
- Known bad symptoms reviewers should watch for:
- Raw placeholders like `OC_MATH_BLOCK_*` appearing in chat.
- Missing or malformed `formatted_body`.
- Regressions in non-math markdown formatting.
## Risks and Mitigations
List only real risks for this PR. Add/remove entries as needed. If none, write `None`.
None
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR adds LaTeX math rendering support for Matrix messages in Element by detecting `$...$` (inline) and `$$...$$` (block) delimiters and converting them to Element-compatible `data-mx-maths` HTML markup. The implementation uses a placeholder-based approach: math expressions are extracted before markdown rendering, then re-injected as proper HTML elements afterward.
- **Critical: Inline math regex false-positives on currency text.** The pattern `\$([^\n$]+?)\$` will match text like `$10 and $20` as a single math expression, corrupting non-math messages. This needs word-boundary guards (e.g. `(?<!\w)\$...\$(?!\w)`) to avoid treating dollar amounts as LaTeX delimiters.
- **No test coverage** for the new `extractMath`/`injectMath` logic — the existing test file only covers `markdownToMatrixHtml`. Given the regex edge cases, tests are important for confidence in this change.
- The overall architecture (extract → render markdown → inject) is reasonable and the `escapeHtml` usage correctly prevents injection in the `data-mx-maths` attribute.
<h3>Confidence Score: 2/5</h3>
- The inline math regex will corrupt messages containing dollar amounts, which is a common real-world scenario
- Score of 2 reflects that while the approach is architecturally sound, the inline math regex has a confirmed false-positive bug with currency text (e.g. "$10 and $20" gets treated as math). This would corrupt normal messages in production. Additionally, there are no tests for the new logic.
- `extensions/matrix/src/matrix/send/formatting.ts` — the inline math regex at line 51 needs word-boundary guards to prevent false positives on currency text
<sub>Last reviewed commit: 3e845bd</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#20405: feat(ui): KaTeX math rendering, collapsible tool cards, image attac...
by ayaanngandhi · 2026-02-18
79.7%
#7842: Fix Matrix mention detection for Element client (formatted_body links)
by emadomedher · 2026-02-03
77.8%
#7845: Fix Matrix mention detection with URL-encoded user IDs
by emadomedher · 2026-02-03
73.5%
#22389: Fix: Matrix plugin not sending images from content blocks
by fryccerGit · 2026-02-21
69.8%
#20278: Fix/matrix missing bot sdk dependency
by saurav470 · 2026-02-18
69.7%
#12028: fix: normalize // to / for Matrix client escaped commands
by githabideri · 2026-02-08
69.5%
#10721: fix for matrix media: destructure downloadContent return value in m...
by mklasen · 2026-02-06
69.0%
#13026: matrix: optionally include media metadata in message.read
by yamoroc · 2026-02-10
68.7%
#14996: feat(matrix): pass asVoice flag through message tool and add wavefo...
by mauldus · 2026-02-12
68.4%
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
67.1%