Mermaid 图示
以 Mermaid 文本编写流程图、时序图、饼图和甘特图,编辑器会把它们绘制为文档中的一个块。Mermaid 本身不属于编辑器:由您的页面加载它,或者由您的服务器渲染图示。

启用
该功能由 mermaiddiagram.js 插件提供(也包含在 plugins/all_plugins.js 中)。工具栏项为 insertdiagram(工具提示为 "Diagram")。默认工具栏把它放在 "More"(⋮)菜单中;在您自己的工具栏中请添加 insertdiagram。要在浏览器中绘制图示,请在创建编辑器之前加载 Mermaid:
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<script src="https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.min.js"></script>
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/mermaiddiagram.js"></script>
<div id="div_editor1"><p>How a change ships:</p></div>
<script>
mermaid.initialize({ startOnLoad: false });
var editor1 = new RichTextEditor("#div_editor1", {
toolbar: "custom",
toolbar_custom: "{bold,italic,underline}|{insertdiagram}|{undo,redo}"
});
</script>
图形从哪里来
插件不会从网络加载任何内容。对于每个图示,它使用以下可用项中的第一个:
diagramResolver,即您的函数。它接收 Mermaid 源代码,返回一个解析为{ svg: "<svg…" }或{ imageUrl: "…" }的 Promise。可以用它在服务器上渲染(例如使用 Kroki 或 mermaid-cli)。- 页面(或其父窗口)上的
window.mermaid。插件同时支持返回字符串的旧版mermaid.render(版本 8 和 9)和返回 Promise 的版本(10 及更高版本);这些页面使用 11.4.1 进行了测试。 - 两者都没有:块以代码形式显示源代码,对话框提示 "No Mermaid renderer detected on the page"(页面上未检测到 Mermaid 渲染器)。源代码会被保留,因此之后仍可绘制图示。

选项
| 选项 | 默认值 | 作用 |
|---|---|---|
diagramResolver | null | 您的渲染器,优先于 window.mermaid 使用。如果它被拒绝,会显示源代码和错误消息。 |
diagramSamples | 四个示例:流程图(graph TD)、sequenceDiagram、pie 和 gantt | 对话框中的示例按钮。每个按钮显示其示例的第一行。 |
text_insertdiagram、text_insertdiagramtitle、text_insertdiagramlabel、text_insertdiagrampreview | "Diagram"、"Insert / edit diagram"、"Mermaid"、"Preview" | 按钮工具提示、对话框标题和标签。 |
服务器端解析器如下所示(URL 是您自己的):
diagramResolver: function (source) {
return fetch("/api/diagram", { method: "POST", body: source })
.then(function (r) { return r.text(); })
.then(function (svg) { return { svg: svg }; });
}
使用方法
- 点击按钮、调用
editor1.execCommand("insertdiagram"),或者在斜杠菜单中选择 "Diagram"。输入源代码或选择一个示例,然后点击 Insert。 - 编辑。双击图示,会以其源代码重新打开对话框;此时按钮显示为 Update。
- 删除。把鼠标悬停在块上并点击角上的圆形 ×,或者在光标位于块中时按 Delete 或 Backspace。
- 错误。如果 Mermaid 无法解析源代码,预览会以红色显示源代码和 Mermaid 的消息("Parse error on line 3 …")。
editor1.renderDiagrams()会重新绘制每个图示块,并返回找到的数量。用setHTMLCode加载了尚未绘制的内容之后,请调用它。
注意事项
- 保存的块在
data-diagram中保留源代码,并在其内部包含图形(此处已缩短):
使用 Mermaid 时,图形是内联 SVG(上面的流程图约 4 KB);没有 Mermaid 时,则是一个<div class="rte-mermaid" data-rte-diagram="1" data-diagram="graph LR A[Pull request] --> B{Review} …" contenteditable="false" style=""><button type="button" class="rte-mermaid-remove" data-rte-mermaid-remove="1" aria-label="Remove diagram" title="Remove diagram">x</button><div class="rte-mermaid-render"><svg …>…</svg></div></div><pre class="rte-mermaid-src">。 - × 删除按钮会随内容一起保存。请在显示 HTML 的地方隐藏它,否则它会在您的页面上显示为一个 "x"。
- 用 Update 编辑图示之后,它的
data-diagram会被 HTML 编码两次(-->被保存为--&gt;)。编辑器能读取两种形式,但您自己的代码需要再解码一次。 - 块的外框样式只存在于编辑器内部。要显示保存的图示,请隐藏按钮并根据源代码重新绘制;这对新建的块和编辑过的块都有效:
<style>.rte-mermaid-remove { display: none; }</style> <script src="https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.min.js"></script> <script> mermaid.initialize({ startOnLoad: false }); function decode(s) { return s.replace(/"/g, '"').replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&"); } document.querySelectorAll(".rte-mermaid[data-diagram]").forEach(function (block, i) { var target = block.querySelector(".rte-mermaid-render") || block; mermaid.render("saved-diagram-" + i, decode(block.getAttribute("data-diagram"))) .then(function (result) { target.innerHTML = result.svg; }); }); </script> - 净化程序必须保留上面
div的各个属性,并且要么允许内联 SVG,要么去除它并像上面那样根据data-diagram重新绘制。 mermaid.min.js11.4.1 约为 2.6 MB。请只在编辑或显示图示的页面上加载它;如果页面必须离线工作,请自行托管。