Markdown-formatering
OpenClaw-format utgående Markdown genom att konvertera det till en delad mellanliggande representation (IR) före rendering av kanalspecifik utgång. IR håller källtext intakt medan du bär stil/länk spänner över så att chunking och rendering kan vara konsekvent över alla kanaler.Mål
- Konsekvens: ett parssteg, flera renderare.
- Säker chunking: dela text före rendering så att inline-formatering aldrig bryts mellan chunkar.
- Kanalanpassning: mappa samma IR till Slack mrkdwn, Telegram HTML och Signal-stilintervall utan att parsa Markdown på nytt.
Pipeline
- Parsa Markdown -> IR
- IR är vanlig text plus stilspann (fet/kursiv/genomstruken/kod/spoiler) och länkspann.
- Offsetar är UTF-16-kodenheter så att Signal-stilintervall linjerar med dess API.
- Tabeller parsas endast när en kanal väljer att delta i tabellkonvertering.
- Chunka IR (format-först)
- Chunking sker på IR-texten före rendering.
- Inline-formatering delas inte mellan chunkar; spann skärs per chunk.
- Rendera per kanal
- Slack: mrkdwn-tokens (fet/kursiv/genomstruken/kod), länkar som
<url|label>. - Telegram: HTML-taggar (
<b>,<i>,<s>,<code>,<pre><code>,<a href>). - Signal: vanlig text +
text-style-intervall; länkar blirlabel (url)när etiketten skiljer sig.
- Slack: mrkdwn-tokens (fet/kursiv/genomstruken/kod), länkar som
IR-exempel
Indata Markdown:Var den används
- Utgående adaptrar för Slack, Telegram och Signal renderar från IR.
- Andra kanaler (WhatsApp, iMessage, MS Teams, Discord) använder fortfarande vanlig text eller sina egna formateringsregler, med Markdown-tabellkonvertering tillämpad före chunking när den är aktiverad.
Tabellhantering
Markdown-tabeller stöds inte konsekvent över chattklienter. Användmarkdown.tables för att kontrollera konvertering per kanal (och per konto).
code: rendera tabeller som kodblock (standard för de flesta kanaler).bullets: konvertera varje rad till punktlistor (standard för Signal + WhatsApp).off: inaktivera tabellparsning och konvertering; rå tabelltext passerar igenom.
Chunking-regler
- Chunkgränser kommer från kanaladaptrar/konfig och tillämpas på IR-texten.
- Kodstaket bevaras som ett enda block med en avslutande nyrad så att kanaler renderar dem korrekt.
- Listprefix och blockquote-prefix är en del av IR-texten, så chunking delar inte mitt i ett prefix.
- Inline-stilar (fet/kursiv/genomstruken/inline-kod/spoiler) delas aldrig mellan chunkar; renderaren öppnar stilar igen inuti varje chunk.
Länkpolicy
- Slack:
[label](url)-><url|label>; nakna webbadresser förblir bla. Autolink är inaktiverat under tolk för att undvika dubbelkoppling. - Telegram:
[label](url)-><a href="url">label</a>(HTML-parsläge). - Signal:
[label](url)->label (url)om inte etiketten matchar URL:en.
Spoilers
Spoilermarkörer (<unk> spoiler<unk> ) tolkas endast för Signal, där de kartlägger
SPOILER stilintervall. Andra kanaler behandlar dem som ren text.
Hur man lägger till eller uppdaterar en kanalformatterare
- Parsa en gång: använd den delade hjälparen
markdownToIR(...)med kanal-lämpliga alternativ (autolänkning, rubrikstil, blockquote-prefix). - Rendera: implementera en renderare med
renderMarkdownWithMarkers(...)och en stilmärkesmapp (eller Signal-stilintervall). - Chunka: anropa
chunkMarkdownIR(...)före rendering; rendera varje chunk. - Koppla adapter: uppdatera den utgående kanaladaptern för att använda den nya chunkern och renderaren.
- Testa: lägg till eller uppdatera format-tester och ett utgående leveranstest om kanalen använder chunking.
Vanliga fallgropar
- Slack-vinkelparentes-tokens (
<@U123>,<#C123>,<https://...>) måste bevaras; escapa rå HTML säkert. - Telegram HTML kräver escapning av text utanför taggar för att undvika trasig markup.
- Signal-stilintervall beror på UTF-16-offsetar; använd inte kodpunkts-offsetar.
- Bevara avslutande nyrader för inhägnade kodblock så att stängningsmarkörer hamnar på sin egen rad.