Добавить пользовательские теги bbcode для цитат в markdown

Мне удалось заставить это работать, сохранив исходный текст в атрибуте HTML, а затем в функции обратного вызова addTagDecorateCallback() просто возвращая его, чтобы получить исходный текст.

Вот фрагмент кода для тех, кто хочет узнать, что я сделал.

В файле assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js, где инициализируются теги bbcode, я изменил код так, чтобы он сохранял исходный текст внутри атрибута snapblocks-source, чтобы я мог получить его позже.

В файле assets\javascripts\discourse\initializers\snapblocks-discourse.js я добавил код для обработки цитирования.

// assets\javascripts\discourse\initializers\snapblocks-discourse.js

import {
  addBlockDecorateCallback, // теги bbcode блоков
  addTagDecorateCallback, // встроенные теги bbcode
} from "discourse/lib/to-markdown";

function initializeSnapblocks(api, siteSettings) {
  addTagDecorateCallback(function () {
    // this.element не является HTML-элементом,
    // но он содержит все атрибуты HTML
    const { attributes } = this.element;

    // Обычно вы проверяете, совпадает ли "class" с вашим классом,
    // но здесь мне нужен только "snapblocks-source"
    if (attributes["snapblocks-source"]) {
      let prefix = "[sb";

      // Добавление атрибутов к тегу bbcode (которые также хранятся
      // в элементе как атрибуты).
      const attrs = [
        "blockstyle",
        "wrap",
        "wrapsize",
        "zebra",
        "showspaces",
        "santa",
      ];
      for (const attr of attrs) {
        if (attributes[attr]) {
          prefix += ` ${attr}=${attributes[attr]}`;
        }
      }

      prefix += "]";

      this.prefix = prefix;
      this.suffix = "[/sb]";
      // если вы возвращаете текст, он будет использован вместо выбранного текста
      return attributes["snapblocks-source"];
    }
  });
}

Для тегов bbcode блоков это работает аналогично, только нужно использовать addBlockDecorateCallback() вместо этого.

К сожалению, мне придется пересоздать (rebake) сообщения, если я хочу, чтобы старые фрагменты snapblocks можно было цитировать. Также это не работает, если вы выделяете текст на SVG-элементе; это срабатывает только в том случае, если вы выделяете текст до и/или после, а также хотя бы часть текста самого SVG.