Concept internals

Форматування Markdown

OpenClaw перетворює вихідний Markdown на спільне проміжне представлення (IR), перш ніж формувати вивід для конкретного каналу. IR зберігає звичайний текст разом з діапазонами стилів і посилань, тому один етап синтаксичного аналізу обслуговує всі канали, а поділ на частини ніколи не розділяє форматування всередині діапазону.

Конвеєр

  1. Перетворення Markdown на IR (markdownToIR) — звичайний текст разом із діапазонами стилів (жирний, курсив, закреслений, код, блок коду, спойлер, цитата, заголовки 1–6) і діапазонами посилань. Зміщення вимірюються кодовими одиницями UTF-16, тому діапазони стилів Signal безпосередньо узгоджуються з його API. Таблиці аналізуються лише тоді, коли канал використовує режим таблиць.
  2. Поділ IR на частини (chunkMarkdownIR / renderMarkdownIRChunksWithinLimit) — поділ виконується над текстом IR до формування виводу, тому вбудовані стилі та посилання розрізаються для кожної частини, а не розриваються на межі.
  3. Формування виводу для кожного каналу (renderMarkdownWithMarkers) — мапа маркерів стилів перетворює діапазони на нативну розмітку каналу.
Канал Засіб формування виводу Примітки
Slack токени mrkdwn (*жирний*, _курсив_, `код`, огорожі коду) Посилання перетворюються на <url|label>; автоматичні посилання вимкнено під час аналізу, щоб уникнути дублювання
Telegram HTML-теги (<b>, <i>, <s>, <code>, <pre><code>, <a href>, <tg-spoiler>) Також підтримує таблиці та заголовки форматованих повідомлень (<h1><h6>), коли ввімкнено richMessages
Signal звичайний текст + діапазони text-style Посилання відображаються як label (url), якщо підпис відрізняється від URL
Discord, WhatsApp, iMessage, Microsoft Teams та інші канали звичайний текст Стилізація на основі IR відсутня; перетворення таблиць Markdown усе одно виконується через convertMarkdownTables

Приклад IR

Вхідний Markdown: OC_I18N_900000 IR (схематично): OC_I18N_900001

Обробка таблиць

markdown.tables визначає, як канал перетворює таблиці Markdown, окремо для кожного каналу та, за потреби, для кожного облікового запису:

Режим Поведінка
code Формувати вирівняну ASCII-таблицю всередині блока коду (типове резервне значення)
bullets Перетворювати кожен рядок на марковані пункти label: value
block Зберігати нативні таблиці там, де транспорт їх підтримує; інакше використовувати code
off Вимкнути аналіз таблиць; необроблений текст таблиці передається без змін

Типові значення Plugin для кожного каналу: Signal, WhatsApp і Matrix типово використовують bullets; Mattermost типово використовує off; Telegram типово використовує block (який перетворюється на code, якщо для облікового запису не ввімкнено richMessages). Будь-який канал без явно заданого типового значення Plugin використовує code. OC_I18N_900002

Правила поділу на частини

  • Обмеження розміру частин надходять від адаптерів або конфігурації каналів і застосовуються до тексту IR, а не до сформованого виводу.
  • Огороджені блоки коду зберігаються як один блок із завершальним символом нового рядка, щоб канали правильно відображали завершальну огорожу.
  • Префікси списків і цитат є частиною тексту IR, тому поділ на частини ніколи не розриває префікс.
  • Вбудовані стилі ніколи не розділяються між частинами; засіб формування виводу повторно відкриває активний стиль на початку наступної частини.

Докладніше про межі частин і поведінку доставлення в різних каналах див. у розділі Потокове передавання та поділ на частини.

Політика посилань

  • Slack: [label](url) -> <url|label>; URL без підпису залишаються без змін.
  • Telegram: [label](url) -> <a href="url">label</a> (режим аналізу HTML).
  • Signal: [label](url) -> label (url), якщо підпис ще не збігається з URL.

Спойлери

Маркери спойлерів (||spoiler||) аналізуються для Signal (перетворюються на діапазони стилю SPOILER) і Telegram (перетворюються на <tg-spoiler>). Інші канали сприймають ||...|| як звичайний текст.

Додавання або оновлення засобу форматування каналу

  1. Виконайте аналіз один раз за допомогою markdownToIR(...), передавши доречні для каналу параметри (autolink, headingStyle, blockquotePrefix, tableMode).
  2. Сформуйте вивід за допомогою renderMarkdownWithMarkers(...) і мапи маркерів стилів (або спеціальної логіки діапазонів стилів для транспортів на кшталт Signal).
  3. Поділіть на частини за допомогою chunkMarkdownIR(...) або renderMarkdownIRChunksWithinLimit(...) перед формуванням виводу кожної частини.
  4. Підключіть адаптер, щоб він викликав новий засіб поділу на частини та формування виводу зі шляху вихідного надсилання.
  5. Протестуйте за допомогою тестів форматування та тесту вихідного доставлення, якщо канал ділить повідомлення на частини.

Поширені проблеми

  • Токени Slack у кутових дужках (<@U123>, <#C123>, <https://...>) мають зберігатися під час екранування; необроблений HTML усе одно потрібно безпечно екранувати.
  • HTML у Telegram потребує екранування тексту поза тегами, щоб уникнути пошкодженої розмітки.
  • Діапазони стилів Signal використовують зміщення UTF-16, а не зміщення кодових точок.
  • Зберігайте завершальні символи нового рядка в огороджених блоках коду, щоб завершальний маркер опинявся в окремому рядку.

Пов’язані матеріали

Was this useful?
On this page

On this page