From 3c526c9bd9b426242cd11cbb6169885a745d50a5 Mon Sep 17 00:00:00 2001 From: Andrew Strong Peters Date: Fri, 6 Mar 2026 08:52:32 -0800 Subject: [PATCH 1/4] Update mermaid.js to use modern mermaid v10+ async render API --- js/mermaid.js | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/js/mermaid.js b/js/mermaid.js index 4d4a3c6..b23e3f3 100644 --- a/js/mermaid.js +++ b/js/mermaid.js @@ -1,4 +1,4 @@ -const uml = className => { +const uml = async className => { // Custom element to encapsulate Mermaid content. class MermaidDiv extends HTMLElement { @@ -68,9 +68,8 @@ const uml = className => { messageFontSize: "16px" } } - + // Load up the config - mermaid.mermaidAPI.globalReset() const config = (typeof mermaidConfig === "undefined") ? defaultConfig : mermaidConfig mermaid.initialize(config) @@ -95,27 +94,21 @@ const uml = className => { surrogate.appendChild(temp) try { - mermaid.mermaidAPI.render( - `_diagram_${i}`, - getFromCode(parentEl), - content => { - const el = document.createElement("div") - el.className = className - el.innerHTML = content + const { svg } = await mermaid.render(`_diagram_${i}`, getFromCode(parentEl)) - // Insert the render where we want it and remove the original text source. - // Mermaid will clean up the temporary element. - const shadow = document.createElement("diagram-div") - shadow.shadowRoot.appendChild(el) - block.parentNode.insertBefore(shadow, block) - parentEl.style.display = "none" - shadow.shadowRoot.appendChild(parentEl) - if (parentEl !== block) { - block.parentNode.removeChild(block) - } - }, - temp - ) + const el = document.createElement("div") + el.className = className + el.innerHTML = svg + + // Insert the render where we want it and remove the original text source. + const shadow = document.createElement("diagram-div") + shadow.shadowRoot.appendChild(el) + block.parentNode.insertBefore(shadow, block) + parentEl.style.display = "none" + shadow.shadowRoot.appendChild(parentEl) + if (parentEl !== block) { + block.parentNode.removeChild(block) + } } catch (err) {} // eslint-disable-line no-empty if (surrogate.contains(temp)) { @@ -125,4 +118,4 @@ const uml = className => { } // This should be run on document load -document.addEventListener("DOMContentLoaded", () => {uml("mermaid")}) +document.addEventListener("DOMContentLoaded", () => { uml("mermaid") }) From 7f0af88738ea81c6f9b738e5708549423e05e498 Mon Sep 17 00:00:00 2001 From: Andrew Strong Peters Date: Fri, 6 Mar 2026 08:52:55 -0800 Subject: [PATCH 2/4] Update gitlab_config.js to use modern mermaid v10+ async render API --- js/gitlab_config.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/js/gitlab_config.js b/js/gitlab_config.js index 24ce893..c13b8ee 100644 --- a/js/gitlab_config.js +++ b/js/gitlab_config.js @@ -35,19 +35,24 @@ function syntaxHighlight(el) { el.classList.add(HIGHLIGHT_THEME); } -function renderMermaid(el) { +async function renderMermaid(el) { const source = el.textContent; // Remove any extra spans added by the backend syntax highlighting. Object.assign(el, { textContent: source }); - mermaid.init(undefined, el, (id) => { - const svg = document.getElementById(id); + try { + const id = `mermaid-${Math.random().toString(36).slice(2)}`; + const { svg } = await mermaid.render(id, source); + + const svgContainer = document.createElement('div'); + svgContainer.innerHTML = svg; + const svgEl = svgContainer.querySelector('svg'); - svg.classList.add('mermaid'); + svgEl.classList.add('mermaid'); // `pre > code > svg` - svg.closest('pre').replaceWith(svg); + el.closest('pre').replaceWith(svgEl); // We need to add the original source into the DOM to allow Copy-as-GFM // to access it. @@ -56,14 +61,16 @@ function renderMermaid(el) { sourceEl.setAttribute('display', 'none'); sourceEl.textContent = source; - svg.appendChild(sourceEl); - }); + svgEl.appendChild(sourceEl); + } catch (err) { + console.error('Mermaid rendering failed:', err); + } } function renderGFM(el) { el.querySelectorAll('.js-syntax-highlight').forEach(syntaxHighlight); el.querySelectorAll('.js-render-math').forEach(renderMath); - el.querySelectorAll('.js-render-mermaid').forEach(renderMermaid); + el.querySelectorAll('.js-render-mermaid').forEach(el => renderMermaid(el)); }; document.addEventListener("DOMContentLoaded", () => { From e3a403d0c05544c60d547057b798a39bc931b5d7 Mon Sep 17 00:00:00 2001 From: Andrew Strong Peters Date: Fri, 6 Mar 2026 08:53:04 -0800 Subject: [PATCH 3/4] Add mermaid to MarkdownCompiler default_js and bump CDN to v11 --- markdown_preview.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/markdown_preview.py b/markdown_preview.py index 5182a58..738fed4 100644 --- a/markdown_preview.py +++ b/markdown_preview.py @@ -798,7 +798,7 @@ class GitlabCompiler(OnlineCompiler): ] default_js = [ "https://cdn.jsdelivr.net/npm/katex@0.10.0-alpha/dist/katex.min.js", - "https://unpkg.com/mermaid@8.0.0-rc.8/dist/mermaid.min.js", + "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js", # Calling `mermaid.initialize` at the first lines of `gitlab_config.js` # should come immediately after `mermaid.js.` "res://MarkdownPreview/js/gitlab_config.js" @@ -901,6 +901,11 @@ class MarkdownCompiler(Compiler): compiler_name = "markdown" default_css = ["res://MarkdownPreview/css/markdown.css"] + default_js = [ + "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js", + "res://MarkdownPreview/js/mermaid_config.js", + "res://MarkdownPreview/js/mermaid.js" + ] def set_highlight(self, pygments_style, css_class): """Set the Pygments CSS.""" From fb724eeb44421ce5788e13e589db268a23bfead5 Mon Sep 17 00:00:00 2001 From: Andrew Strong Peters Date: Fri, 6 Mar 2026 08:53:15 -0800 Subject: [PATCH 4/4] Update docs and examples for built-in mermaid support and mermaid v11 --- docs/src/markdown/extras.md | 58 +++++++++++++++++++++++-------------- examples/test.md | 2 +- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/docs/src/markdown/extras.md b/docs/src/markdown/extras.md index ea49c2b..ff63d7b 100644 --- a/docs/src/markdown/extras.md +++ b/docs/src/markdown/extras.md @@ -128,16 +128,18 @@ you can include the following libraries to transform `sequence` and `flow` block and [flowchart.js][flow] respectively. ```js - "js": [ - // Required libraries to transform UML notation - "https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js", - "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js", - "https://cdnjs.cloudflare.com/ajax/libs/js-sequence-diagrams/1.0.6/sequence-diagram-min.js", - "https://cdnjs.cloudflare.com/ajax/libs/flowchart/1.6.5/flowchart.min.js", - - // This library applies the above libraries to the fenced code blocks `flow` and `sequence`. - "res://MarkdownPreview/js/uml.js" - ] + "js": { + "markdown": [ + // Required libraries to transform UML notation + "https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js", + "https://cdnjs.cloudflare.com/ajax/libs/js-sequence-diagrams/1.0.6/sequence-diagram-min.js", + "https://cdnjs.cloudflare.com/ajax/libs/flowchart/1.6.5/flowchart.min.js", + + // This library applies the above libraries to the fenced code blocks `flow` and `sequence`. + "res://MarkdownPreview/js/uml.js" + ] + } ``` Please see the `MarkdownPreview.sublime-settings` file to see how custom fences are configured in case you need to @@ -145,20 +147,32 @@ configure them manually. Check out our [example file][example] if using YAML fro ## Mermaid UML Support -Mermaid is an alternate approach for rendering UML in a browser. Like the aforementioned [UML Support](#uml-support), it -also uses [SuperFences extension][superfences] to create special, custom fences. Then we can just add the needed -libraries, are custom loader, and configuration file. If you would like to tweak the configuration file, you can create -your own and load it instead. +Mermaid is an alternate approach for rendering UML in a browser. It uses [SuperFences extension][superfences] to create +special, custom fences. Mermaid support is included by default for the `markdown` parser — no additional configuration +is required. Simply use fenced code blocks with the `mermaid` language identifier: + +```` +```mermaid +graph TD; + A-->B; + A-->C; + B-->D; + C-->D; +``` +```` + +The default configuration is provided in `MarkdownPreview/js/mermaid_config.js`. If you would like to tweak the +configuration, you can create your own and reference it in the `js` setting: ```js - "js": [ - // Mermaid library - "https://unpkg.com/mermaid@8.8.4/dist/mermaid.min.js", - // User configuration, should be loaded before the loader - "res://MarkdownPreview/js/mermaid_config.js", - // Mermaid loader - "res://MarkdownPreview/js/mermaid.js" - ] + "js": { + "markdown": [ + "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js", + // Your custom configuration, should be loaded before the loader + "/path/to/your/mermaid_config.js", + "res://MarkdownPreview/js/mermaid.js" + ] + } ``` Please see the `MarkdownPreview.sublime-settings` file to see how custom fences are configured in case you need to diff --git a/examples/test.md b/examples/test.md index 48e83a4..fc0ba8c 100644 --- a/examples/test.md +++ b/examples/test.md @@ -21,7 +21,7 @@ - https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js - https://cdnjs.cloudflare.com/ajax/libs/js-sequence-diagrams/1.0.6/sequence-diagram-min.js - https://cdnjs.cloudflare.com/ajax/libs/flowchart/1.6.5/flowchart.min.js - - https://unpkg.com/mermaid@8.8.4/dist/mermaid.min.js + - https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js - res://MarkdownPreview/js/uml.js - https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js - res://MarkdownPreview/js/math_config.js