添加自定义Markdown引用BBCode标签

我正在开发一个 Discourse 扩展来显示 snapblocks。我成功添加了将被替换为 blocks 的 bbcode 标签,但不幸的是,如果您选择引用 blocks,您将获得 block 中的文本,而不是原始的 bbcode 标签,而是显示在代码块中。

我尝试查看 spoiler 插件的源代码,但我无法弄清楚它是如何允许引用 spoiler 的。

有没有办法解决这个问题,并在自定义 bbcode 标签内添加原始的 block 代码文本?

这是我正在开发的插件的源代码。

真正让我烦恼的是,没有易于查阅的标准文档,这使得我的插件开发变得更加困难。

1 个赞

我认为是 DecorateCallBack 函数:

相关测试:

为了通过在核心文件中此行之后 console.log(_selectedText); 来帮助调试,您可以返回选中文本的内容:

A screenshot of a browser console interface with various textual elements and a navigation bar. (Captioned by AI)

3 个赞

我测试了一下,它确实允许我在文本周围添加 [sb],但遗憾的是,它只添加了元素上的文本。我希望它能引用原始文本,因为原始文本包含了重建块所需的一切。

我目前正在尝试让实际的 SVG 不可选中,只在 SVG 下方放置一个隐藏的可选元素,其中包含原始源代码。

我通过创建一个包含两个元素的容器来实现这一点:SVG 和源代码。我试图让 SVG 具有 position: relative,以便将其移出文档流并置于源代码文本之上,同时让容器与 SVG 大小相同,使其看起来就像 SVG 仍然在文本内部一样。此外,源代码文本将具有 opacity: 0 并且字号非常小,以便在可能溢出 SVG 时不可见。

我想知道是否有更简单的方法可以做到这一点,因为我尝试的方法需要重新烘焙所有帖子,而且感觉像是一种笨拙的解决方案,而我认为这个问题不应该需要这样做。

编辑:在查看了 addTagDecorateCallback() 函数的代码后,我发现我可以在回调中返回文本来替换它将使用的任何文本。这实际上会有很大帮助,因为我希望不再需要处理我一直在研究的那个糟糕的笨拙系统。

1 个赞

我通过将源文本保留在 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, // block bbcode tags
  addTagDecorateCallback, // inline bbcode tags
} 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() 即可。

现在,不幸的是,如果我想让旧的 snapblocks 代码片段可以引用,我将不得不重新烘焙帖子。这也无法处理你选择 SVG 上的文本的情况,它只在你选择 SVG 文本之前和/或之后的一些文本以及至少一部分 SVG 文本时才有效。

3 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.