Skip to content

Commit 31b9e55

Browse files
committed
Enables Mermaid diagram rendering
Adds support for rendering Mermaid diagrams within Obsidian notes. This enhancement allows users to create and display diagrams directly from Mermaid syntax within their markdown files, providing a richer note-taking and documentation experience. Also, removes a redundant "fa:fa-car" prefix from the "Car" label in the example Mermaid diagram.
1 parent 7606d98 commit 31b9e55

File tree

4 files changed

+3878
-64
lines changed

4 files changed

+3878
-64
lines changed

md/test-md-file.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ Mama -> Günter
3131
Gerald -> Mama
3232
Günter -> Gerald
3333
```
34+
3435
## Test Mermaid
3536
```mermaid
3637
flowchart TD
3738
A[Christmas] -->|Get money| B(Go shopping)
3839
B --> C{Let me think}
3940
C -->|One| D[Laptop]
4041
C -->|Two| E[iPhone]
41-
C -->|Three| F[fa:fa-car Car]
42+
C -->|Three| F[Car]
4243
```
4344

4445
## Test Code Tags

obsidian.js

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ export async function preParse(md, req) {
379379
let r = md;
380380
r = await removeForbiddenContent(r, req);
381381
r = await preReplacePlantUml(r, req);
382+
r = await preReplaceMermaid(r, req);
382383
r = preMarkCode(r);
383384
r = preReplaceObsidianFileLinks(r, req);
384385
r = preMarkCallouts(r);
@@ -552,8 +553,6 @@ function postprocessFragments(html) {
552553
return document.body.innerHTML;
553554
}
554555

555-
556-
557556
function preReplaceObsidianFileLinks(html, req) {
558557
const regex = /(?<!\!)\[\[([^\]\n]+)\]\]/g;
559558

@@ -599,6 +598,20 @@ function preReplaceObsidianFileLinks(html, req) {
599598
});
600599
}
601600

601+
export async function preReplaceMermaid(md, req) {
602+
let regex = /^\s*```+\s*(mermaid)$/gim;
603+
let match;
604+
while ((match = regex.exec(md)) !== null) {
605+
// PlantUML
606+
const start = match.index + match[0].length;
607+
const end = md.indexOf("```", start);
608+
const mermaid = md.substring(start, end);
609+
md = md.substring(0, match.index) + '<pre class="mermaid">' + mermaid + '</pre>' + md.substring(end + 3);
610+
regex = /^\s*```+\s*(mermaid)$/gim;
611+
}
612+
return md;
613+
}
614+
602615
export async function preReplacePlantUml(md, req) {
603616
let regex = /^\s*```+\s*(plantuml)$/gim;
604617
let match;
@@ -1299,6 +1312,37 @@ async function getSideBar(startPage, req) {
12991312
`;
13001313
}
13011314

1315+
function getMermaidScriptEntry() {
1316+
return `<script type="module">
1317+
import mermaid from "/node_modules/mermaid/dist/mermaid.esm.min.mjs";
1318+
1319+
mermaid.initialize({
1320+
startOnLoad: false,
1321+
logLevel: 'debug'
1322+
});
1323+
1324+
function decodeEntities(str) {
1325+
const txt = document.createElement('textarea');
1326+
txt.innerHTML = str;
1327+
return txt.value;
1328+
}
1329+
1330+
// wenn Reveal „ready“ ist, oder einfach bei DOMContentLoaded
1331+
document.addEventListener("DOMContentLoaded", () => {
1332+
document.querySelectorAll("pre.mermaid").forEach(async (el, i) => {
1333+
const raw = el.textContent;
1334+
const code = decodeEntities(raw);
1335+
try {
1336+
const { svg } = await mermaid.render("m" + i, code);
1337+
el.innerHTML = svg;
1338+
} catch (e) {
1339+
console.error("Mermaid render failed", e);
1340+
}
1341+
});
1342+
});
1343+
</script>`;
1344+
}
1345+
13021346
export async function wrapInPage(html, startPage, req) {
13031347
const pre = `
13041348
<!DOCTYPE html>
@@ -1328,6 +1372,7 @@ export async function wrapInPage(html, startPage, req) {
13281372
</div>
13291373
</div>
13301374
<script src="/obsidian-page.js"></script>
1375+
${getMermaidScriptEntry()}
13311376
<script lang="javascript">
13321377
initFonts('${JSON.stringify(mainFontsArray)}', '${JSON.stringify(
13331378
navFontsArray
@@ -1362,6 +1407,7 @@ export async function wrapAsDocument(html, req) {
13621407
</div>
13631408
</div>
13641409
<script src="/obsidian-page.js"></script>
1410+
${getMermaidScriptEntry()}
13651411
<script lang="javascript">
13661412
initFonts('${JSON.stringify(mainFontsArray)}', '${JSON.stringify(
13671413
navFontsArray
@@ -1430,7 +1476,9 @@ export async function wrapInReveal(reveal, req) {
14301476
<!-- Theme used for syntax highlighting of code -->
14311477
<!-- <link rel="stylesheet" href="lib/css/zenburn.css"> -->
14321478
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/tomorrow.min.css"> -->
1433-
1479+
1480+
${getMermaidScriptEntry()}
1481+
14341482
<!-- Printing and PDF exports -->
14351483
<script>
14361484
var link = document.createElement('link');

0 commit comments

Comments
 (0)