Concept internals

Formatação Markdown

OpenClaw converte o Markdown de saída em uma representação intermediária (IR) compartilhada antes de renderizar a saída específica de cada canal. A IR mantém texto simples e intervalos de estilo/links, de modo que uma única etapa de análise alimente todos os canais e a divisão em partes nunca separe a formatação no meio de um intervalo.

Pipeline

  1. Analisar Markdown em IR (markdownToIR) - texto simples e intervalos de estilo (negrito, itálico, tachado, código, bloco de código, spoiler, citação em bloco, cabeçalho 1-6) e intervalos de links. Os deslocamentos são unidades de código UTF-16, para que os intervalos de estilo do Signal se alinhem diretamente à sua API. As tabelas são analisadas somente quando o canal adota um modo de tabela.
  2. Dividir a IR em partes (chunkMarkdownIR / renderMarkdownIRChunksWithinLimit)
    • a divisão ocorre no texto da IR antes da renderização, portanto os estilos embutidos e links são segmentados por parte, em vez de serem interrompidos em um limite.
  3. Renderizar por canal (renderMarkdownWithMarkers) - um mapa de marcadores de estilo transforma os intervalos na marcação nativa do canal.
Canal Renderizador Observações
Slack tokens mrkdwn (*bold*, _italic_, `code`, delimitadores de código) Links se tornam <url|label>; links automáticos são desativados durante a análise para evitar duplicação
Telegram tags HTML (<b>, <i>, <s>, <code>, <pre><code>, <a href>, <tg-spoiler>) Também oferece suporte a tabelas e cabeçalhos de mensagens avançadas (<h1>-<h6>) quando richMessages está ativado
Signal texto simples + intervalos text-style Links são renderizados como label (url) quando o rótulo é diferente da URL
Discord, WhatsApp, iMessage, Microsoft Teams e outros canais texto simples Sem estilos baseados em IR; a conversão de tabelas Markdown ainda ocorre via convertMarkdownTables

Exemplo de IR

Markdown de entrada: OC_I18N_900000 IR (esquemática): OC_I18N_900001

Tratamento de tabelas

markdown.tables controla como um canal converte tabelas Markdown, por canal e, opcionalmente, por conta:

Modo Comportamento
code Renderiza como uma tabela ASCII alinhada dentro de um bloco de código (padrão de contingência)
bullets Converte cada linha em itens de lista no formato label: value
block Mantém tabelas nativas quando o transporte oferece suporte; caso contrário, usa code
off Desativa a análise de tabelas; o texto bruto da tabela é transmitido sem alterações

Padrões de Plugin por canal: Signal, WhatsApp e Matrix usam bullets por padrão; Mattermost usa off; Telegram usa block por padrão (que é resolvido como code, a menos que a conta tenha richMessages ativado). Qualquer canal sem um padrão explícito do Plugin usa code. OC_I18N_900002

Regras de divisão em partes

  • Os limites das partes vêm dos adaptadores/configurações do canal e se aplicam ao texto da IR, não à saída renderizada.
  • Blocos de código delimitados são mantidos como um único bloco com uma nova linha ao final, para que os canais renderizem corretamente o delimitador de fechamento.
  • Prefixos de listas e citações em bloco fazem parte do texto da IR, portanto a divisão nunca ocorre no meio de um prefixo.
  • Estilos embutidos nunca são divididos entre partes; o renderizador reabre um estilo aberto no início da parte seguinte.

Consulte Streaming e divisão em partes para saber mais sobre limites de partes e o comportamento de entrega entre canais.

  • Slack: [label](url) -> <url|label>; URLs simples permanecem simples.
  • Telegram: [label](url) -> <a href="url">label</a> (modo de análise HTML).
  • Signal: [label](url) -> label (url), a menos que o rótulo já corresponda à URL.

Spoilers

Marcadores de spoiler (||spoiler||) são analisados para o Signal (mapeados para intervalos de estilo SPOILER) e o Telegram (mapeados para <tg-spoiler>). Outros canais tratam ||...|| como texto simples.

Adicionar ou atualizar um formatador de canal

  1. Analise uma única vez com markdownToIR(...), fornecendo opções apropriadas ao canal (autolink, headingStyle, blockquotePrefix, tableMode).
  2. Renderize com renderMarkdownWithMarkers(...) e um mapa de marcadores de estilo (ou lógica personalizada de intervalos de estilo para transportes como o Signal).
  3. Divida em partes com chunkMarkdownIR(...) ou renderMarkdownIRChunksWithinLimit(...) antes de renderizar cada parte.
  4. Conecte o adaptador para chamar o novo divisor e renderizador a partir do caminho de envio de saída.
  5. Teste com testes de formatação e um teste de entrega de saída, caso o canal divida mensagens em partes.

Armadilhas comuns

  • Tokens entre sinais de maior e menor do Slack (<@U123>, <#C123>, <https://...>) devem sobreviver ao escape; HTML bruto ainda precisa ser escapado com segurança.
  • O HTML do Telegram exige o escape do texto fora das tags para evitar marcação inválida.
  • Os intervalos de estilo do Signal usam deslocamentos UTF-16, não deslocamentos de pontos de código.
  • Preserve as novas linhas finais em blocos de código delimitados, para que o marcador de fechamento fique em sua própria linha.

Relacionado

Was this useful?
On this page

On this page