Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions docs/src/markdown/extras.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,37 +128,51 @@ 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
configure them manually. Check out our [example file][example] if using YAML frontmatter to define custom fences.

## 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
Expand Down
2 changes: 1 addition & 1 deletion examples/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 15 additions & 8 deletions js/gitlab_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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", () => {
Expand Down
41 changes: 17 additions & 24 deletions js/mermaid.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const uml = className => {
const uml = async className => {

// Custom element to encapsulate Mermaid content.
class MermaidDiv extends HTMLElement {
Expand Down Expand Up @@ -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)

Expand All @@ -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)) {
Expand All @@ -125,4 +118,4 @@ const uml = className => {
}

// This should be run on document load
document.addEventListener("DOMContentLoaded", () => {uml("mermaid")})
document.addEventListener("DOMContentLoaded", () => { uml("mermaid") })
7 changes: 6 additions & 1 deletion markdown_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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."""
Expand Down