Skip to content

Commit 3beb573

Browse files
committed
fix: mermaid and KaTeX incompatibility.
1 parent cfa46cb commit 3beb573

3 files changed

Lines changed: 41 additions & 11 deletions

File tree

blog/content/snippets/diagrams/mermaid-class-uml.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,8 @@ classDiagram
541541
%% Abstract base class
542542
class PaymentProcessor {
543543
<<abstract>>
544-
+process_payment(amount)* bool
545-
+refund(transaction_id)* bool
544+
+process_payment(amount) bool*
545+
+refund(transaction_id) bool*
546546
}
547547
548548
%% Concrete implementations (Inheritance)
@@ -635,8 +635,8 @@ classDiagram
635635
%% Abstract base class
636636
class PaymentProcessor {
637637
<<abstract>>
638-
+process_payment(amount)* bool
639-
+refund(transaction_id)* bool
638+
+process_payment(amount) bool*
639+
+refund(transaction_id) bool*
640640
}
641641
642642
%% Concrete implementations (Inheritance)
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
1-
<div class="mermaid">
2-
{{- .Inner | safeHTML }}
3-
</div>
1+
<div class="mermaid" data-mermaid-content="{{ .Inner | htmlEscape }}"></div>
42
{{ .Page.Store.Set "hasMermaid" true }}

blog/layouts/partials/hooks/head-end.html

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
onload="
66
// Fix Goldmark's em/strong tag conversion in math blocks before rendering
77
// This is a workaround for Hugo < 0.132 which lacks passthrough extension
8+
// IMPORTANT: Protect Mermaid blocks from KaTeX processing
9+
// Save Mermaid blocks and replace with placeholders before DOM manipulation
10+
const mermaidPlaceholders = new Map();
11+
document.querySelectorAll('.mermaid, .mermaid[data-mermaid-content]').forEach((el, idx) => {
12+
const placeholderId = 'mermaid-ph-' + idx;
13+
const placeholder = document.createElement('div');
14+
placeholder.id = placeholderId;
15+
placeholder.className = 'mermaid-placeholder';
16+
placeholder.style.display = 'none';
17+
mermaidPlaceholders.set(placeholderId, el.outerHTML);
18+
if (el.parentNode) {
19+
el.parentNode.replaceChild(placeholder, el);
20+
}
21+
});
22+
23+
// Now do KaTeX processing on the modified DOM (Mermaid blocks are protected)
824
document.body.innerHTML = document.body.innerHTML
925
// Fix display math blocks ($$...$$)
1026
.replace(/(\$\$[\s\S]*?\$\$)/g, function(match) {
@@ -22,6 +38,14 @@
2238
.replace(/<\/?strong>/g, '**') + '$';
2339
});
2440
41+
// Restore Mermaid blocks
42+
mermaidPlaceholders.forEach((html, id) => {
43+
const placeholder = document.getElementById(id);
44+
if (placeholder && placeholder.parentNode) {
45+
placeholder.outerHTML = html;
46+
}
47+
});
48+
2549
renderMathInElement(document.body, {
2650
delimiters: [
2751
{left: '$$', right: '$$', display: true},
@@ -32,16 +56,24 @@
3256
throwOnError: false,
3357
trust: true,
3458
strict: false,
35-
// Ignore text in script, noscript, style, textarea, pre, code, option tags
36-
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'option']
59+
// Ignore text in script, noscript, style, textarea, pre, code, option, and mermaid tags
60+
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'option'],
61+
ignoredClasses: ['mermaid']
3762
});
3863
"></script>
3964

4065
<!-- Mermaid rendering -->
4166
{{ if .Page.Store.Get "hasMermaid" }}
42-
<script src="https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js"></script>
67+
<script src="https://cdn.jsdelivr.net/npm/mermaid@11.10.0/dist/mermaid.min.js"></script>
4368
<script>
44-
mermaid.initialize({ startOnLoad: true });
69+
mermaid.initialize({
70+
startOnLoad: true,
71+
theme: 'default',
72+
securityLevel: 'loose',
73+
flowchart: { useMaxWidth: true },
74+
classDiagram: { useMaxWidth: true },
75+
logLevel: 'error'
76+
});
4577
</script>
4678
{{ end }}
4779

0 commit comments

Comments
 (0)