|
128 | 128 | } |
129 | 129 | MathJax.typeset(); |
130 | 130 | }); |
131 | | - $('div.highlight-source-mermaid > pre').each(function(i, pre) { |
132 | | - pre.textContent = pre.textContent; |
133 | | - }); |
134 | | - |
135 | 131 | {{ if eq .Mode "dark" }} |
136 | 132 | const mermaidJsTheme = 'dark'; |
137 | 133 | {{ else if eq .Mode "light" }} |
|
140 | 136 | const mermaidJsTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default'; |
141 | 137 | {{ end }} |
142 | 138 | 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 | + } |
145 | 165 | }); |
146 | 166 | 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>`; |
147 | 167 | 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>`; |
148 | 168 | $('.markdown-body pre').each(function () { |
149 | 169 | 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 | + } |
150 | 174 | const code = pre.find('code'); |
151 | 175 | const button = $(`<button class="copy-button" aria-label="Copy code to clipboard">${copyIcon}</button>`); |
152 | 176 | pre.css("position", "relative"); |
153 | 177 | pre.append(button); |
154 | 178 | 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 () { |
156 | 182 | button.html(tickIcon); |
157 | 183 | setTimeout(() => { |
158 | 184 | button.html(copyIcon) |
|
0 commit comments