> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Formatowanie Markdown

OpenClaw formatuje wychodzący Markdown, konwertując go do wspólnej reprezentacji
pośredniej (IR) przed renderowaniem danych wyjściowych specyficznych dla kanału. IR zachowuje
tekst źródłowy bez zmian, jednocześnie przenosząc zakresy stylów/linków, dzięki czemu dzielenie na fragmenty i renderowanie mogą
pozostawać spójne między kanałami.

## Cele

* **Spójność:** jeden etap parsowania, wiele rendererów.
* **Bezpieczne dzielenie na fragmenty:** dziel tekst przed renderowaniem, aby formatowanie inline nigdy
  nie urywało się między fragmentami.
* **Dopasowanie do kanału:** mapuj ten sam IR na Slack mrkdwn, HTML Telegram oraz zakresy stylów
  Signal bez ponownego parsowania Markdown.

## Pipeline

1. **Parsuj Markdown -> IR**
   * IR to zwykły tekst oraz zakresy stylów (bold/italic/strike/code/spoiler) i zakresy linków.
   * Przesunięcia są jednostkami kodu UTF-16, aby zakresy stylów Signal były zgodne z jego API.
   * Tabele są parsowane tylko wtedy, gdy kanał włącza konwersję tabel.
2. **Dziel IR na fragmenty (najpierw format)**
   * Dzielenie odbywa się na tekście IR przed renderowaniem.
   * Formatowanie inline nie jest dzielone między fragmentami; zakresy są przycinane dla każdego fragmentu.
3. **Renderuj dla każdego kanału**
   * **Slack:** tokeny mrkdwn (bold/italic/strike/code), linki jako `<url|label>`.
   * **Telegram:** tagi HTML (`<b>`, `<i>`, `<s>`, `<code>`, `<pre><code>`, `<a href>`).
   * **Signal:** zwykły tekst + zakresy `text-style`; linki stają się `label (url)`, gdy etykieta się różni.

## Przykład IR

Wejściowy Markdown:

```markdown theme={"theme":{"light":"min-light","dark":"min-dark"}}
Hello **world** - see [docs](https://docs.openclaw.ai).
```

IR (schematycznie):

```json theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  "text": "Hello world - see docs.",
  "styles": [{ "start": 6, "end": 11, "style": "bold" }],
  "links": [{ "start": 19, "end": 23, "href": "https://docs.openclaw.ai" }]
}
```

## Gdzie jest używany

* Adaptery wychodzące Slack, Telegram i Signal renderują z IR.
* Inne kanały (WhatsApp, iMessage, Microsoft Teams, Discord) nadal używają zwykłego tekstu lub
  własnych reguł formatowania, z konwersją tabel Markdown stosowaną przed
  dzieleniem na fragmenty, gdy jest włączona.

## Obsługa tabel

Tabele Markdown nie są spójnie obsługiwane we wszystkich klientach czatu. Użyj
`markdown.tables`, aby kontrolować konwersję dla kanału (i konta).

* `code`: renderuj tabele jako bloki kodu (domyślnie dla większości kanałów).
* `bullets`: konwertuj każdy wiersz na punkty listy (domyślnie dla Matrix, Signal i WhatsApp).
* `off`: wyłącz parsowanie i konwersję tabel; surowy tekst tabeli przechodzi dalej.

Klucze konfiguracji:

```yaml theme={"theme":{"light":"min-light","dark":"min-dark"}}
channels:
  discord:
    markdown:
      tables: code
    accounts:
      work:
        markdown:
          tables: off
```

## Reguły dzielenia na fragmenty

* Limity fragmentów pochodzą z adapterów/konfiguracji kanałów i są stosowane do tekstu IR.
* Ogrodzenia kodu są zachowywane jako pojedynczy blok z końcowym znakiem nowego wiersza, aby kanały
  renderowały je poprawnie.
* Prefiksy list i prefiksy cytatów blokowych są częścią tekstu IR, więc dzielenie na fragmenty
  nie rozdziela tekstu w środku prefiksu.
* Style inline (bold/italic/strike/inline-code/spoiler) nigdy nie są dzielone między
  fragmentami; renderer ponownie otwiera style wewnątrz każdego fragmentu.

Jeśli potrzebujesz więcej informacji o zachowaniu dzielenia na fragmenty między kanałami, zobacz
[Streaming + dzielenie na fragmenty](/pl/concepts/streaming).

## Polityka linków

* **Slack:** `[label](url)` -> `<url|label>`; gołe adresy URL pozostają gołe. Autolink
  jest wyłączony podczas parsowania, aby uniknąć podwójnego linkowania.
* **Telegram:** `[label](url)` -> `<a href="url">label</a>` (tryb parsowania HTML).
* **Signal:** `[label](url)` -> `label (url)`, chyba że etykieta pasuje do URL.

## Spoilery

Znaczniki spoilerów (`||spoiler||`) są parsowane tylko dla Signal, gdzie mapują się na
zakresy stylu SPOILER. Inne kanały traktują je jako zwykły tekst.

## Jak dodać lub zaktualizować formatter kanału

1. **Parsuj raz:** użyj współdzielonego helpera `markdownToIR(...)` z opcjami odpowiednimi
   dla kanału (autolink, styl nagłówków, prefiks cytatu blokowego).
2. **Renderuj:** zaimplementuj renderer z `renderMarkdownWithMarkers(...)` i mapą
   znaczników stylu (lub zakresami stylów Signal).
3. **Dziel na fragmenty:** wywołaj `chunkMarkdownIR(...)` przed renderowaniem; renderuj każdy fragment.
4. **Podłącz adapter:** zaktualizuj adapter wychodzący kanału, aby używał nowego mechanizmu dzielenia na fragmenty
   i renderera.
5. **Testuj:** dodaj lub zaktualizuj testy formatowania oraz test dostarczania wychodzącego, jeśli
   kanał używa dzielenia na fragmenty.

## Częste pułapki

* Tokeny Slack w nawiasach kątowych (`<@U123>`, `<#C123>`, `<https://...>`) muszą być
  zachowane; bezpiecznie escapuj surowy HTML.
* HTML Telegram wymaga escapowania tekstu poza tagami, aby uniknąć uszkodzonego znacznikowania.
* Zakresy stylów Signal zależą od przesunięć UTF-16; nie używaj przesunięć punktów kodowych.
* Zachowuj końcowe znaki nowego wiersza dla ogrodzonych bloków kodu, aby znaczniki zamykające trafiały do
  własnego wiersza.

## Powiązane

<CardGroup cols={2}>
  <Card title="Streaming i dzielenie na fragmenty" href="/pl/concepts/streaming" icon="bars-staggered">
    Zachowanie streamingu wychodzącego, granice fragmentów i dostarczanie specyficzne dla kanału.
  </Card>

  <Card title="Prompt systemowy" href="/pl/concepts/system-prompt" icon="message-lines">
    Co model widzi przed rozmową, w tym wstrzyknięte pliki obszaru roboczego.
  </Card>
</CardGroup>
