Concept internals

การจัดรูปแบบ Markdown

OpenClaw แปลง Markdown ขาออกเป็นตัวแทนข้อมูลกลางร่วม (IR) ก่อนเรนเดอร์ผลลัพธ์เฉพาะช่องทาง IR เก็บข้อความธรรมดาพร้อม ช่วงรูปแบบ/ลิงก์ ดังนั้นการแยกวิเคราะห์เพียงครั้งเดียวจึงใช้ได้กับทุกช่องทาง และการแบ่งส่วนจะไม่ ตัดการจัดรูปแบบกลางช่วง

ไปป์ไลน์

  1. แยกวิเคราะห์ Markdown เป็น IR (markdownToIR) - ข้อความธรรมดาพร้อมช่วงรูปแบบ (ตัวหนา ตัวเอียง ขีดฆ่า โค้ด บล็อกโค้ด สปอยเลอร์ ข้อความอ้างอิงแบบบล็อก หัวเรื่องระดับ 1-6) และช่วงลิงก์ ออฟเซ็ตใช้หน่วยโค้ด UTF-16 เพื่อให้ช่วงรูปแบบของ Signal สอดคล้องกับ API ของ Signal โดยตรง ตารางจะถูกแยกวิเคราะห์เฉพาะเมื่อช่องทาง เลือกใช้โหมดตาราง
  2. แบ่ง IR เป็นส่วน (chunkMarkdownIR / renderMarkdownIRChunksWithinLimit)
    • การแบ่งจะเกิดขึ้นกับข้อความ IR ก่อนเรนเดอร์ ดังนั้นรูปแบบอินไลน์และ ลิงก์จะถูกตัดตามแต่ละส่วนแทนที่จะขาดตรงขอบเขต
  3. เรนเดอร์แยกตามช่องทาง (renderMarkdownWithMarkers) - แมปเครื่องหมายรูปแบบ จะแปลงช่วงต่าง ๆ เป็นมาร์กอัปแบบเนทีฟของช่องทาง
ช่องทาง ตัวเรนเดอร์ หมายเหตุ
Slack โทเค็น mrkdwn (*bold*, _italic_, `code`, รั้วโค้ด) ลิงก์จะกลายเป็น <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 เปล่าจะคงเป็น 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