Concept internals
تنسيق Markdown
ينسّق OpenClaw Markdown الصادر عبر تحويله إلى تمثيل وسيط مشترك (IR) قبل عرض المخرجات الخاصة بكل قناة. يحافظ IR على النص المصدر سليمًا مع حمل نطاقات الأنماط/الروابط حتى يبقى التقسيم إلى أجزاء والعرض متسقين عبر القنوات.
الأهداف
- الاتساق: خطوة تحليل واحدة، وعدة عارضات.
- تقسيم آمن إلى أجزاء: تقسيم النص قبل العرض حتى لا ينكسر التنسيق المضمن عبر الأجزاء.
- ملاءمة القناة: تحويل IR نفسه إلى Slack mrkdwn، وTelegram HTML، ونطاقات أنماط Signal من دون إعادة تحليل Markdown.
خط الأنابيب
- تحليل Markdown -> IR
- IR هو نص عادي مع نطاقات أنماط (bold/italic/strike/code/spoiler) ونطاقات روابط.
- الإزاحات هي وحدات ترميز UTF-16 حتى تتوافق نطاقات أنماط Signal مع API الخاص به.
- لا تُحلَّل الجداول إلا عندما تختار قناة تحويل الجداول.
- تقسيم IR إلى أجزاء (التنسيق أولًا)
- يحدث التقسيم إلى أجزاء على نص IR قبل العرض.
- لا ينقسم التنسيق المضمن عبر الأجزاء؛ تُجزَّأ النطاقات لكل جزء.
- العرض لكل قناة
- Slack: رموز mrkdwn (bold/italic/strike/code)، والروابط بصيغة
<url|label>. - Telegram: وسوم HTML (
<b>,<i>,<s>,<code>,<pre><code>,<a href>). - Signal: نص عادي + نطاقات
text-style؛ تتحول الروابط إلىlabel (url)عندما تختلف التسمية.
- Slack: رموز mrkdwn (bold/italic/strike/code)، والروابط بصيغة
مثال 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" }]
}
أين يُستخدم
- تعرض محولات Slack وTelegram وSignal الصادرة من IR.
- لا تزال القنوات الأخرى (WhatsApp، وiMessage، وMicrosoft Teams، وDiscord) تستخدم نصًا عاديًا أو قواعد التنسيق الخاصة بها، مع تطبيق تحويل جداول Markdown قبل التقسيم إلى أجزاء عند تفعيله.
التعامل مع الجداول
لا تُدعَم جداول Markdown باتساق عبر عملاء الدردشة. استخدم
markdown.tables للتحكم في التحويل لكل قناة (ولكل حساب).
code: عرض الجداول ككتل شيفرة (الافتراضي لمعظم القنوات).bullets: تحويل كل صف إلى نقاط تعداد (الافتراضي لـ Signal + WhatsApp).off: تعطيل تحليل الجداول وتحويلها؛ يمر نص الجدول الخام كما هو.
مفاتيح التكوين:
channels:
discord:
markdown:
tables: code
accounts:
work:
markdown:
tables: off
قواعد التقسيم إلى أجزاء
- تأتي حدود الأجزاء من محولات/تكوين القنوات وتُطبَّق على نص IR.
- تُحفَظ أسوار الشيفرة ككتلة واحدة مع سطر جديد لاحق حتى تعرضها القنوات بشكل صحيح.
- تُعد بادئات القوائم وبادئات الاقتباسات الكتلية جزءًا من نص IR، لذلك لا يقسم التقسيم داخل البادئة.
- لا تُقسَّم الأنماط المضمنة (bold/italic/strike/inline-code/spoiler) أبدًا عبر الأجزاء؛ يعيد العارض فتح الأنماط داخل كل جزء.
إذا كنت تحتاج إلى مزيد من التفاصيل عن سلوك التقسيم إلى أجزاء عبر القنوات، فراجع البث + التقسيم إلى أجزاء.
سياسة الروابط
- Slack:
[label](url)-><url|label>؛ تبقى عناوين URL المجردة كما هي. يُعطَّل Autolink أثناء التحليل لتجنب ربط الروابط مرتين. - Telegram:
[label](url)-><a href="url">label</a>(وضع تحليل HTML). - Signal:
[label](url)->label (url)إلا إذا طابقت التسمية عنوان URL.
النصوص المخفية
لا تُحلَّل علامات النص المخفي (||spoiler||) إلا لـ Signal، حيث تُحوَّل إلى
نطاقات أنماط SPOILER. تتعامل معها القنوات الأخرى كنص عادي.
كيفية إضافة منسق قناة أو تحديثه
- حلّل مرة واحدة: استخدم مساعد
markdownToIR(...)المشترك مع الخيارات المناسبة للقناة (autolink، نمط العنوان، بادئة الاقتباس الكتلي). - اعرض: نفّذ عارضًا باستخدام
renderMarkdownWithMarkers(...)وخريطة علامات الأنماط (أو نطاقات أنماط Signal). - قسّم إلى أجزاء: استدعِ
chunkMarkdownIR(...)قبل العرض؛ واعرض كل جزء. - وصّل المحول: حدّث محول القناة الصادر لاستخدام مقسّم الأجزاء والعارض الجديدين.
- اختبر: أضف اختبارات تنسيق أو حدّثها، وأضف اختبار تسليم صادر إذا كانت القناة تستخدم التقسيم إلى أجزاء.
أخطاء شائعة
- يجب الحفاظ على رموز Slack ذات الأقواس الزاوية (
<@U123>,<#C123>,<https://...>)؛ واهرب من HTML الخام بأمان. - يتطلب Telegram HTML تهريب النص خارج الوسوم لتجنب ترميز معطّل.
- تعتمد نطاقات أنماط Signal على إزاحات UTF-16؛ لا تستخدم إزاحات نقاط الترميز.
- حافظ على الأسطر الجديدة اللاحقة لكتل الشيفرة المسيّجة حتى تقع علامات الإغلاق في سطرها الخاص.