docs/docs/fa/concepts/markdown-formatting.md
2026-04-29 23:52:03 +00:00

7.8 KiB
Raw Blame History

read_when summary title x-i18n
شما در حال تغییر قالب‌بندی مارک‌داون یا بخش‌بندی برای کانال‌های خروجی هستید
شما در حال افزودن یک قالب‌بند کانال یا نگاشت سبک جدید هستید
شما در حال اشکال‌زدایی پس‌رفت‌های قالب‌بندی در سراسر کانال‌ها هستید
خط لوله قالب‌بندی Markdown برای کانال‌های خروجی قالب‌بندی مارک‌داون
generated_at model provider source_hash source_path workflow
2026-04-29T22:43:24Z gpt-5.5 openai cf052e11fe9fd075a4337ffa555391c7003a346240b57bb65054c3f08401dfd9 concepts/markdown-formatting.md 16

OpenClaw با تبدیل Markdown خروجی به یک نمایش میانی مشترک (IR) پیش از رندر خروجی ویژهٔ هر کانال، آن را قالب‌بندی می‌کند. IR متن مبدأ را دست‌نخورده نگه می‌دارد و هم‌زمان spanهای سبک/پیوند را حمل می‌کند تا قطعه‌بندی و رندر در کانال‌ها یکسان بماند.

اهداف

  • یکنواختی: یک مرحلهٔ parse، چند renderer.
  • قطعه‌بندی ایمن: متن را پیش از رندر جدا می‌کند تا قالب‌بندی inline هرگز میان قطعه‌ها نشکند.
  • تناسب با کانال: همان IR را بدون parse دوبارهٔ Markdown به Slack mrkdwn، HTML در Telegram، و محدوده‌های سبک در Signal نگاشت می‌کند.

Pipeline

  1. Parse Markdown -> IR
    • IR متن ساده به‌همراه spanهای سبک (bold/italic/strike/code/spoiler) و spanهای پیوند است.
    • offsetها واحدهای کد UTF-16 هستند تا محدوده‌های سبک Signal با API آن هم‌تراز باشند.
    • جدول‌ها فقط زمانی parse می‌شوند که یک کانال وارد تبدیل جدول شده باشد.
  2. قطعه‌بندی IR (اول قالب)
    • قطعه‌بندی روی متن IR و پیش از رندر انجام می‌شود.
    • قالب‌بندی inline میان قطعه‌ها جدا نمی‌شود؛ spanها برای هر قطعه برش می‌خورند.
  3. رندر برای هر کانال
    • Slack: توکن‌های mrkdwn (bold/italic/strike/code)، پیوندها به‌شکل <url|label>.
    • Telegram: تگ‌های HTML (<b>, <i>, <s>, <code>, <pre><code>, <a href>).
    • Signal: متن ساده + محدوده‌های text-style؛ وقتی label متفاوت باشد، پیوندها به label (url) تبدیل می‌شوند.

نمونهٔ IR

Markdown ورودی:

Hello **world** — see [docs](https://docs.openclaw.ai).

IR (شماتیک):

{
  "text": "Hello world — see docs.",
  "styles": [{ "start": 6, "end": 11, "style": "bold" }],
  "links": [{ "start": 19, "end": 23, "href": "https://docs.openclaw.ai" }]
}

کجا استفاده می‌شود

  • adapterهای خروجی Slack، Telegram، و Signal از IR رندر می‌کنند.
  • کانال‌های دیگر (WhatsApp، iMessage، Microsoft Teams، Discord) هنوز از متن ساده یا قواعد قالب‌بندی خودشان استفاده می‌کنند، و در صورت فعال بودن، تبدیل جدول Markdown پیش از قطعه‌بندی اعمال می‌شود.

مدیریت جدول

جدول‌های Markdown در همهٔ کلاینت‌های چت به‌طور یکسان پشتیبانی نمی‌شوند. از markdown.tables برای کنترل تبدیل در هر کانال (و هر حساب) استفاده کنید.

  • code: جدول‌ها را به‌صورت بلوک‌های کد رندر می‌کند (پیش‌فرض برای بیشتر کانال‌ها).
  • bullets: هر ردیف را به bullet point تبدیل می‌کند (پیش‌فرض برای Signal + WhatsApp).
  • off: parse و تبدیل جدول را غیرفعال می‌کند؛ متن خام جدول عبور داده می‌شود.

کلیدهای پیکربندی:

channels:
  discord:
    markdown:
      tables: code
    accounts:
      work:
        markdown:
          tables: off

قواعد قطعه‌بندی

  • محدودیت‌های قطعه از adapterها/پیکربندی کانال می‌آیند و روی متن IR اعمال می‌شوند.
  • code fenceها به‌صورت یک بلوک واحد با newline پایانی حفظ می‌شوند تا کانال‌ها آن‌ها را درست رندر کنند.
  • پیشوندهای فهرست و پیشوندهای blockquote بخشی از متن IR هستند، پس قطعه‌بندی وسط پیشوند را جدا نمی‌کند.
  • سبک‌های inline (bold/italic/strike/inline-code/spoiler) هرگز میان قطعه‌ها جدا نمی‌شوند؛ renderer سبک‌ها را داخل هر قطعه دوباره باز می‌کند.

اگر دربارهٔ رفتار قطعه‌بندی در کانال‌ها اطلاعات بیشتری لازم دارید، ببینید استریمینگ + قطعه‌بندی.

سیاست پیوند

  • Slack: [label](url) -> <url|label>؛ URLهای bare به همان شکل bare می‌مانند. Autolink هنگام parse غیرفعال است تا از دوبار پیونددهی جلوگیری شود.
  • Telegram: [label](url) -> <a href="url">label</a> (حالت parse HTML).
  • Signal: [label](url) -> label (url) مگر اینکه label با URL برابر باشد.

Spoilerها

نشانگرهای Spoiler (||spoiler||) فقط برای Signal parse می‌شوند، جایی که به محدوده‌های سبک SPOILER نگاشت می‌شوند. کانال‌های دیگر با آن‌ها مثل متن ساده رفتار می‌کنند.

چگونه قالب‌کنندهٔ یک کانال را اضافه یا به‌روزرسانی کنیم

  1. یک‌بار parse کنید: از helper مشترک markdownToIR(...) با گزینه‌های مناسب کانال استفاده کنید (autolink، سبک heading، پیشوند blockquote).
  2. رندر کنید: یک renderer با renderMarkdownWithMarkers(...) و یک نگاشت marker سبک (یا محدوده‌های سبک Signal) پیاده‌سازی کنید.
  3. قطعه‌بندی کنید: پیش از رندر chunkMarkdownIR(...) را فراخوانی کنید؛ هر قطعه را رندر کنید.
  4. adapter را متصل کنید: adapter خروجی کانال را به‌روزرسانی کنید تا از chunker و renderer جدید استفاده کند.
  5. تست کنید: تست‌های قالب را اضافه یا به‌روزرسانی کنید و اگر کانال از قطعه‌بندی استفاده می‌کند، یک تست تحویل خروجی اضافه کنید.

دام‌های رایج

  • توکن‌های angle-bracket در Slack (<@U123>, <#C123>, <https://...>) باید حفظ شوند؛ HTML خام را با ایمنی escape کنید.
  • HTML در Telegram نیاز دارد متن بیرون از تگ‌ها escape شود تا markup خراب نشود.
  • محدوده‌های سبک Signal به offsetهای UTF-16 وابسته‌اند؛ از offsetهای code point استفاده نکنید.
  • newlineهای پایانی را برای بلوک‌های کد fenceشده حفظ کنید تا markerهای پایانی روی خط خودشان قرار بگیرند.

مرتبط