Files
Redflag/system/matrix_formatting_reference.md

4.1 KiB

description, limit
description limit
Matrix formatting reference implementation from lettabot-v017 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)

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.

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, "<strong>$1</strong>");

    // 3. Italic *text*
    html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");

    // 4. Code blocks (triple backticks FIRST)
    html = html.replace(/```(\w*)\n?([\s\S]*?)```/g, (_, lang, code) => {
        const langAttr = lang ? ` class="language-${lang}"` : "";
        return `<pre><code${langAttr}>${code}</code></pre>`;
    });

    // 5. Inline code (single backtick)
    html = html.replace(/`([^`]+)`/g, "<code>$1</code>");

    // 6. Spoilers ||text||
    html = html.replace(/\|\|(.+?)\|\|/g, '<span data-mx-spoiler>$1</span>');

    // 7. Colors {color|text}
    html = html.replace(/\{([^}|]+)\|([^}]+)\}/g, (match, color, content) => {
        const hexColor = getColorHex(color.trim());
        return `<font color="${hexColor}" data-mx-color="${hexColor}">${content}</font>`;
    });

    // 8. Links
    html = html.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>');

    // 9. Newlines to <br>
    html = html.replace(/\n/g, "<br>");

    return { plain, html };
}

Supported Formatting

Feature Syntax HTML Output
Bold **text** <strong>text</strong>
Italic *text* <em>text</em>
Code inline `code` <code>code</code>
Code block ```lang code ``` <pre><code class="language-lang">code</code></pre>
Spoilers `
Colors {hot_pink|text} <font color="#FF1493" data-mx-color="#FF1493">text</font>
Links https://... <a href="...">...</a>
Emoji :smile: Unicode emoji

Color Palette (types.ts:148-160)

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 <font>
Links

Note: Element mobile sanitizes HTML heavily. data-mx-color is the Matrix standard, but mobile may still strip colors.


Files to Reference

# 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