Skip to content

Commit d0b592b

Browse files
authored
fix: handle multiple mermaid diagram in a single file (#67)
relates : #62 Fixes #62
1 parent ebc63cd commit d0b592b

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

cmd/template.html

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,6 @@
128128
}
129129
MathJax.typeset();
130130
});
131-
$('div.highlight-source-mermaid > pre').each(function(i, pre) {
132-
pre.textContent = pre.textContent;
133-
});
134-
135131
{{ if eq .Mode "dark" }}
136132
const mermaidJsTheme = 'dark';
137133
{{ else if eq .Mode "light" }}
@@ -140,19 +136,49 @@
140136
const mermaidJsTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default';
141137
{{ end }}
142138
mermaid.initialize({ startOnLoad: false, theme: mermaidJsTheme });
143-
mermaid.run({
144-
querySelector: 'div.highlight-source-mermaid > pre',
139+
140+
$('div.highlight-source-mermaid > pre').each(async function(i, pre) {
141+
const originalText = pre.textContent;
142+
const id = 'mermaid-diagram-' + i;
143+
try {
144+
const { svg } = await mermaid.render(id, originalText);
145+
$(pre).html(svg);
146+
// Store original text for copy functionality
147+
$(pre).data('original-text', originalText);
148+
// Add copy button after rendering
149+
const button = $(`<button class="copy-button" aria-label="Copy mermaid code to clipboard">${copyIcon}</button>`);
150+
$(pre).css("position", "relative").append(button);
151+
button.on('click', function () {
152+
navigator.clipboard.writeText(originalText).then(function () {
153+
button.html(tickIcon);
154+
setTimeout(() => {
155+
button.html(copyIcon)
156+
}, 1000);
157+
}, function () {
158+
alert('Failed to copy');
159+
});
160+
});
161+
} catch (error) {
162+
console.error('Mermaid rendering error:', error);
163+
$(pre).html('<div style="color: red;">Error rendering diagram</div>');
164+
}
145165
});
146166
const copyIcon= `<svg class="copy-icon" aria-hidden="true" fill="none" height="18" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" width="18" style="color:"currentColor";"><path d="M8 17.929H6c-1.105 0-2-.912-2-2.036V5.036C4 3.91 4.895 3 6 3h8c1.105 0 2 .911 2 2.036v1.866m-6 .17h8c1.105 0 2 .91 2 2.035v10.857C20 21.09 19.105 22 18 22h-8c-1.105 0-2-.911-2-2.036V9.107c0-1.124.895-2.036 2-2.036z"></path></svg>`;
147167
const tickIcon = `<svg class="tick-icon" aria-hidden="true" fill="none" height="18" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" width="18" style="color: "currentColor";"><path d="M5 13l4 4L19 7"></path></svg>`;
148168
$('.markdown-body pre').each(function () {
149169
const pre = $(this);
170+
// Skip if this is a Mermaid diagram (already has copy button)
171+
if ($(pre).closest('div.highlight-source-mermaid').length > 0) {
172+
return;
173+
}
150174
const code = pre.find('code');
151175
const button = $(`<button class="copy-button" aria-label="Copy code to clipboard">${copyIcon}</button>`);
152176
pre.css("position", "relative");
153177
pre.append(button);
154178
button.on('click', function () {
155-
navigator.clipboard.writeText(code.text()).then(function () {
179+
// Get text from code element if it exists, otherwise from pre element directly
180+
const textToCopy = code.length > 0 ? code.text() : pre.text().replace(/Copy.*$/, '').trim();
181+
navigator.clipboard.writeText(textToCopy).then(function () {
156182
button.html(tickIcon);
157183
setTimeout(() => {
158184
button.html(copyIcon)

0 commit comments

Comments
 (0)