كيف أضيف دعم محرر النصوص المنسقة إلى امتداد markdown الخاص بي؟

لقد أنشأت ملحقًا يضيف بعض علامات bbcode لعرض snapblocks. عندما تم تقديم محرر النصوص المنسقة، أدى ذلك إلى كسر الملحق الخاص بي، أو على الأقل جعله غير قابل للاستخدام مع محرر النصوص المنسقة. أريد إضافة دعم لمحرر النصوص المنسقة، لذلك نظرت في الملحق المعطوب لمعرفة كيفية عمله، وقد نجحت حاليًا في جعله يعمل إلى حد ما. يمكنني بالفعل إدراج snapblocks في المنشور في محرر النصوص المنسقة، ولكن لا يبدو أنني أستطيع تحويل علامات snapblocks الموجودة إلى محرر النصوص المنسقة.

إليك ما لدي حتى الآن.

أركز حاليًا على التحويل الفعلي. لدي تخمين أساسي حول كيفية عمله، ولكن حتى الآن لم أحصل على أي نتائج. فكيف يمكنني جعل التحليل يعمل؟

إعجاب واحد (1)

بعد الكثير من الصداع وإضافة العديد من console.log()s إلى discourse، اكتشفت سبب عدم عمله، وكيفية جعله يعمل.

لا يتم التحليل باستخدام html المعروض، بل باستخدام رموز markdownit. كنت أستخدم state.push(html_raw) في دالة replace() لعرض علامات bbcode الخاصة بي [snapblocks].

// assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js

export function(helper) {
  md.block.bbcode.ruler.push("snapblocks", {
      tag: "snapblocks",
      replace(state, tagInfo, content) {
        let token = state.push('html_raw', '', 0)
        token.content = `<pre class="snapblocks-blocks">${content}</pre>`
      },
    });
}

كانت المشكلة هي أن نوع الرمز html_raw يتم تجاهله بواسطة محول محرر النصوص الغنية. مما يعني أنه لا يمكنك استخدام هذا إذا كنت تريد دعم محرر النصوص الغنية.

اكتشفت أنه باستخدام bbcode_open و text و bbcode_close، يمكنني جعله يعمل.

// assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js

export function(helper) {
  md.block.bbcode.ruler.push("snapblocks", {
      tag: "snapblocks",
      replace(state, tagInfo, content) {
        let token = state.push('bbcode_open', 'pre', 1)
        token.attrs = [['class', 'snapblocks-discourse']]

        token = state.push('text', '', 0)
        token.content = content

        token = token.push('bbcode_close', 'pre', -1)
        token.attrs = [['class', 'snapblocks-discourse']] // needed for later checks
      },
    });
}

بمجرد الانتهاء من ذلك، لن يتم تجاهل هذا بعد الآن.

بالانتقال إلى rich-text-editor-extension.js، ثم تقوم بذلك.

// assets/javascripts/lib/rich-text-editor-extension.js

import { i18n } from "discourse-i18n";

const SNAPBLOCKS_NODES = ["inline_snapblocks", "snapblocks"];

/** @type {RichEditorExtension} */
const extension = {
    snapblocks: {
      attrs: { rendered: { default: true } },
      code: true,
      group: "block",
      content: "text*", // This is needed
      createGapCursor: true,
      parseDOM:[{ tag: "pre.snapblocks-blocks" }],
      toDOM: () => ["pre", { class: "snapblocks-blocks" }, 0],
    },
  },
  parse: {
    bbcode_open(state, token) {
      // The token here is the same `bbcode_open` token object
      // from the previous code
      if (token.attrGet('class') === 'snapblocks-blocks') {
        state.openNode(state.schema.nodes.snapblocks, {
          open: token.attrGet("open") !== null,
        });
        return true;
      }
    },
    bbcode_close(state, token) {
      if (token.attrGet('class') === 'snapblocks-blocks') {
        state.closeNode();
        return true;
      }
    },
  },
  serializeNode: {
    snapblocks(state, node) {
      // This just converts it back to plain text markdown
      state.write("[snapblocks]\n");
      state.renderContent(node);
      state.write("\n[/snapblocks]\n\n");
    },
  },
}

المفاتيح في خاصية parse هي محللات لنوع الرمز الذي يمكن استخدامه في محلل markdown.

هناك بالتأكيد المزيد من التفاصيل حول هذا الأمر، ولكن على الأقل هذا يوضح الأمور بشكل أفضل بكثير من ذي قبل.

إعجاب واحد (1)

ليس بالضبط، ولكن لدينا بالفعل امتداد html-block الذي يتعامل مع رموز html_raw الخاصة بـ markdown-it، وهي طريقة عامة للتعامل مع محتوى تمرير.

يمكنك التحقق من جميع أنواع الامتدادات المسموح بها عبر registerRichEditorExtension، وهناك العديد من الامتدادات من الإضافات بالإضافة إلى تلك التي يتم تسجيلها افتراضيًا والتي يمكن استخدامها كمصدر إلهام.

يرجى إعلامنا إذا كان لديك أي أسئلة.

3 إعجابات

شكراً للتوضيح.


أواجه الآن مشكلة حيث أن التبديل بين الإصدار الكتلي لا يعمل. يمكنني تبديل الكتل المضمنة ولكن ليس العقدة على مستوى الكتلة.

في مرحلة ما، أود أن يتم عرض الكتل عندما لا يكون المؤشر عليها، ولكن أعتقد أن هذا يمكن أن يأتي بعد مجرد جعلها تعمل.

عذرًا، لا أفهم. ماذا تقصد بـ “تبديل الإصدار الكتلي”؟

علامة bbcode الخاصة بي تحتوي على [snapblocks] و [sb]، حيث [sb] هو في السطر، و [snapblocks] هو على مستوى الكتلة. عند الضغط على زر شريط الأدوات، فإنه يقوم بتبديل العلامة المضمنة بشكل جيد، ولكنه لا يقوم بتبديل العلامة على مستوى الكتلة عند تحديد كتلة من النص.