From b4ac39d1fe9f05c9dffa3841e26f5eff40e544c0 Mon Sep 17 00:00:00 2001 From: Ani -- Annie Tunturi Date: Fri, 20 Mar 2026 22:24:37 -0400 Subject: [PATCH] Document Matrix formatting reference from lettabot-v017 as the example to follow --- system/matrix_formatting_reference.md | 149 ++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 system/matrix_formatting_reference.md diff --git a/system/matrix_formatting_reference.md b/system/matrix_formatting_reference.md new file mode 100644 index 0000000..cabaccc --- /dev/null +++ b/system/matrix_formatting_reference.md @@ -0,0 +1,149 @@ +--- +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
+ html = html.replace(/\n/g, "
"); + + return { plain, html }; +} +``` + +--- + +## Supported Formatting + +| Feature | Syntax | HTML Output | +|---------|--------|-------------| +| **Bold** | `**text**` | `text` | +| **Italic** | `*text*` | `text` | +| **Code inline** | `` `code` `` | `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