--- description: Matrix formatting reference implementation from lettabot-v017 limit: 2000 --- # Matrix Formatting Reference (LettaBot v017) ## Source Location `/home/ani/Projects/lettabot-v017/src/channels/matrix/` **Reference Implementation:** Use this as THE example for Matrix formatting. --- ## Message Formatting Flow ### 1. Entry Point (adapter.ts:226-251) ```typescript async sendMessage(msg: OutboundMessage): Promise<{ messageId: string }> { const { plain, html } = formatMatrixHTML(text); const content = { msgtype: "m.text", body: plain, format: "org.matrix.custom.html", formatted_body: html, }; await this.client.sendMessage(chatId, content); } ``` ### 2. HTML Formatter (html-formatter.ts:19-65) **Key insight:** Uses custom regex-based conversion, NOT external markdown libraries. ```typescript export function formatMatrixHTML(text: string): FormattedMessage { // 1. Convert emoji shortcodes first let plain = convertEmojiShortcodes(text); let html = escapeHtml(plain); // 2. Bold **text** html = html.replace(/\*\*(.+?)\*\*/g, "$1"); // 3. Italic *text* html = html.replace(/\*(.+?)\*/g, "$1"); // 4. Code blocks (triple backticks FIRST) html = html.replace(/```(\w*)\n?([\s\S]*?)```/g, (_, lang, code) => { const langAttr = lang ? ` class="language-${lang}"` : ""; return `
${code}`;
});
// 5. Inline code (single backtick)
html = html.replace(/`([^`]+)`/g, "$1");
// 6. Spoilers ||text||
html = html.replace(/\|\|(.+?)\|\|/g, '$1');
// 7. Colors {color|text}
html = html.replace(/\{([^}|]+)\|([^}]+)\}/g, (match, color, content) => {
const hexColor = getColorHex(color.trim());
return `${content}`;
});
// 8. Links
html = html.replace(/(https?:\/\/[^\s]+)/g, '$1');
// 9. Newlines to code` |
| **Code block** | ```` ```lang code ``` ```` | `code` |
| **Spoilers** | `||text||` | `text` |
| **Colors** | `{hot_pink\|text}` | `text` |
| **Links** | `https://...` | `...` |
| **Emoji** | `:smile:` | Unicode emoji |
---
## Color Palette (types.ts:148-160)
```typescript
MATRIX_COLORS = {
RED: "#FF0000",
GREEN: "#00FF00",
BLUE: "#0000FF",
HOT_PINK: "#FF1493", // Primary "sexy" color
PURPLE: "#800080", // For transcripts
ORANGE: "#FFA500",
YELLOW: "#FFFF00",
CYAN: "#00FFFF",
GREY: "#808080",
}
```
**Usage:** `{hot_pink|this text will be hot pink}`
---
## Key Design Decisions
1. **No external markdown libraries** - Uses regex-based conversion for control
2. **Custom HTML escaping** - Before applying formatting
3. **Matrix-specific attributes** - `data-mx-spoiler`, `data-mx-color`
4. **Plain text fallback** - Always generates `body` (plain) alongside `formatted_body` (HTML)
5. **Emoji first** - Convert shortcodes before HTML escaping
---
## Element Mobile Compatibility
| Feature | Desktop | Mobile |
|---------|---------|--------|
| Bold | ✅ | ✅ |
| Italic | ✅ | ✅ |
| Code | ✅ | ✅ |
| Spoilers | ✅ | ✅ |
| Colors | ✅ | ⚠️ May strip `` |
| Links | ✅ | ✅ |
**Note:** Element mobile sanitizes HTML heavily. `data-mx-color` is the Matrix standard, but mobile may still strip colors.
---
## Files to Reference
```bash
# Main files
cat /home/ani/Projects/lettabot-v017/src/channels/matrix/html-formatter.ts
cat /home/ani/Projects/lettabot-v017/src/channels/matrix/adapter.ts
cat /home/ani/Projects/lettabot-v017/src/channels/matrix/types.ts
```
---
Last updated: 2026-03-21
Based on: LettaBot v017 reference implementation