تفاصيل المفاهيم الداخلية
تنسيق Markdown
يقوم OpenClaw بتنسيق Markdown الصادر عن طريق تحويله إلى تمثيل وسيط مشترك (IR) قبل عرض الناتج الخاص بكل قناة. يحافظ التمثيل الوسيط على نص المصدر سليماً بينما يحمل نطاقات الأنماط/الروابط بحيث يظل التقسيم والعرض متسقين عبر القنوات.
الأهداف
- الاتساق: خطوة تحليل واحدة، وعارضات متعددة.
- تقسيم آمن: تقسيم النص قبل العرض بحيث لا تنقطع التنسيقات المضمنة عبر الأجزاء.
- ملاءمة القناة: تعيين نفس التمثيل الوسيط إلى Slack mrkdwn وTelegram HTML ونطاقات أنماط Signal دون إعادة تحليل Markdown.
خطوات المعالجة
- تحليل Markdown -> تمثيل وسيط (IR)
- التمثيل الوسيط هو نص عادي بالإضافة إلى نطاقات الأنماط (عريض/مائل/مشطوب/كود/إخفاء) ونطاقات الروابط.
- الإزاحات (Offsets) هي وحدات رمز UTF-16 بحيث تتماشى نطاقات أنماط Signal مع واجهة برمجة التطبيقات الخاصة بها.
- يتم تحليل الجداول فقط عندما تختار القناة تحويل الجداول.
- تقسيم التمثيل الوسيط إلى أجزاء (تنسيق أولاً)
- يحدث التقسيم على نص التمثيل الوسيط قبل العرض.
- لا تنقطع التنسيقات المضمنة عبر الأجزاء؛ يتم تقسيم النطاقات حسب كل جزء.
- العرض حسب القناة
- Slack: رموز mrkdwn (عريض/مائل/مشطوب/كود)، الروابط كـ
<url|label>. - Telegram: وسوم HTML (
<b>,<i>,<s>,<code>,<pre><code>,<a href>). - Signal: نص عادي + نطاقات
text-style؛ تتحول الروابط إلىlabel (url)عندما يختلف التسمية.
- Slack: رموز mrkdwn (عريض/مائل/مشطوب/كود)، الروابط كـ
مثال على التمثيل الوسيط
مدخل Markdown:
Hello **world** — see [docs](https://docs.openclaw.ai).
التمثيل الوسيط (مخططي):
{
"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 الصادرة من التمثيل الوسيط.
- القنوات الأخرى (WhatsApp وiMessage وMS Teams وDiscord) لا تزال تستخدم نصاً عادياً أو قواعد التنسيق الخاصة بها، مع تطبيق تحويل جداول Markdown قبل التقسيم عند التمكين.
معالجة الجداول
جداول Markdown غير مدعومة بشكل متسق عبر عملاء الدردشة. استخدم markdown.tables للتحكم في التحويل لكل قناة (ولكل حساب).
code: عرض الجداول ككتل كود (الإعداد الافتراضي لمعظم القنوات).bullets: تحويل كل صف إلى نقاط تعداد نقطي (الإعداد الافتراضي لـ Signal وWhatsApp).off: تعطيل تحليل وتحويل الجداول؛ يمر نص الجدول الخام كما هو.
مفاتيح التكوين:
channels:
discord:
markdown:
tables: code
accounts:
work:
markdown:
tables: off
قواعد التقسيم إلى أجزاء
- تأتي حدود الأجزاء من محولات/تكوين القناة ويتم تطبيقها على نص التمثيل الوسيط.
- يتم الحفاظ على حدود الكود (Code fences) ككتلة واحدة مع سطر جديد في النهاية حتى تعرضها القنوات بشكل صحيح.
- بادئات القوائم وبادئات الاقتباس هي جزء من نص التمثيل الوسيط، لذلك لا يقسم التقسيم منتصف البادئة.
- لا تنقطع الأنماط المضمنة (عريض/مائل/مشطوب/كود مضمن/إخفاء) عبر الأجزاء أبداً؛ يعيد العارض فتح الأنماط داخل كل جزء.
إذا كنت بحاجة إلى المزيد حول سلوك التقسيم عبر القنوات، راجع البث + التقسيم.
سياسة الروابط
- Slack:
[label](url)-><url|label>؛ تبقى الروابط العارية (bare URLs) عارية. يتم تعطيل الربط التلقائي (Autolink) أثناء التحليل لتجنب الازدواجية. - Telegram:
[label](url)-><a href="url">label</a>(وضع تحليل HTML). - Signal:
[label](url)->label (url)إلا إذا تطابقت التسمية مع الرابط.
المحتوى المخفي (Spoilers)
يتم تحليل علامات المحتوى المخفي (||spoiler||) فقط لـ Signal، حيث يتم تعيينها إلى نطاقات أنماط SPOILER. تعامل القنوات الأخرى معها كنص عادي.
كيفية إضافة أو تحديث مُنسِّق قناة
- تحليل مرة واحدة: استخدم الدالة المساعدة المشتركة
markdownToIR(...)مع الخيارات المناسبة للقناة (ربط تلقائي، نمط العناوين، بادئة الاقتباس). - العرض: نفذ عارضاً باستخدام
renderMarkdownWithMarkers(...)وخريطة علامات الأنماط (أو نطاقات أنماط Signal). - التقسيم: استدعِ
chunkMarkdownIR(...)قبل العرض؛ اعرض كل جزء. - ربط المحول: قم بتحديث محول الإرسال الصادر للقناة لاستخدام مُقسِّم وعارض الجديد.
- الاختبار: أضف أو حدّث اختبارات التنسيق واختبار إرسال صادر إذا كانت القناة تستخدم التقسيم.
الأخطاء الشائعة
- يجب الحفاظ على رموز الأقواس الزاوية في Slack (
<@U123>,<#C123>,<https://...>)؛ قم بإخراج HTML الخام بأمان. - يتطلب HTML في Telegram إخراج النص خارج الوسوم لتجنب تلف الترميز.
- تعتمد نطاقات أنماط Signal على إزاحات UTF-16؛ لا تستخدم إزاحات نقاط الرمز (code point offsets).
- احتفظ بأسطر جديدة في نهاية كتل الكود المحددة (fenced code blocks) بحيث تقع العلامات الختامية في سطرها الخاص.