Skip to content

Commit 4857a2c

Browse files
authored
Merge pull request #17 from mambax7/master
marmaid
2 parents 6a979a5 + 0d6d557 commit 4857a2c

2 files changed

Lines changed: 44 additions & 12 deletions

File tree

apps/docs-27/public/mermaid-init.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// Mermaid diagram renderer for XOOPS Docs
22
// Loaded as a static asset — no build step, no npm dependency.
3+
//
34
// Starlight uses expressive-code, which renders mermaid blocks as:
45
// <div class="expressive-code">
5-
// <figure><pre data-language="mermaid"><code>...</code></pre></figure>
6+
// <figure><pre data-language="mermaid"><code>
7+
// <div class="ec-line"><div class="code">...</div></div>
8+
// ...
9+
// </code></pre></figure>
610
// </div>
7-
// We target that structure, extract the raw source via textContent,
8-
// replace the whole expressive-code container with the rendered SVG,
9-
// and re-render when the user toggles dark/light mode.
11+
//
12+
// IMPORTANT: textContent on the <code> element concatenates ec-line divs
13+
// without newlines, producing invalid Mermaid source. We must join each
14+
// .ec-line's textContent with '\n' to reconstruct the original diagram.
1015

1116
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
1217

@@ -16,14 +21,24 @@ function currentTheme() {
1621
: 'dark';
1722
}
1823

24+
function extractSource(code) {
25+
// expressive-code wraps each line in .ec-line; join them to restore newlines
26+
const lines = code.querySelectorAll('.ec-line');
27+
if (lines.length) {
28+
return Array.from(lines).map(l => l.textContent).join('\n').trim();
29+
}
30+
// Fallback for plain <code> blocks (no expressive-code)
31+
return code.textContent.trim();
32+
}
33+
1934
async function renderMermaid() {
2035
const codeBlocks = document.querySelectorAll('pre[data-language="mermaid"] code');
2136
if (!codeBlocks.length) return;
2237

2338
mermaid.initialize({ startOnLoad: false, theme: currentTheme() });
2439

2540
for (const code of codeBlocks) {
26-
const src = code.textContent.trim();
41+
const src = extractSource(code);
2742
// Replace the whole expressive-code wrapper, falling back to the <pre>
2843
const container = code.closest('.expressive-code') || code.closest('pre');
2944
const wrapper = document.createElement('div');
@@ -34,7 +49,8 @@ async function renderMermaid() {
3449
const id = 'mmd-' + Math.random().toString(36).slice(2, 9);
3550
const { svg } = await mermaid.render(id, src);
3651
wrapper.innerHTML = svg;
37-
} catch {
52+
} catch (e) {
53+
console.error('Mermaid render error:', e, '\nSource:\n', src);
3854
wrapper.textContent = src;
3955
}
4056
container.replaceWith(wrapper);

apps/docs-4x/public/mermaid-init.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// Mermaid diagram renderer for XOOPS Docs
22
// Loaded as a static asset — no build step, no npm dependency.
3+
//
34
// Starlight uses expressive-code, which renders mermaid blocks as:
45
// <div class="expressive-code">
5-
// <figure><pre data-language="mermaid"><code>...</code></pre></figure>
6+
// <figure><pre data-language="mermaid"><code>
7+
// <div class="ec-line"><div class="code">...</div></div>
8+
// ...
9+
// </code></pre></figure>
610
// </div>
7-
// We target that structure, extract the raw source via textContent,
8-
// replace the whole expressive-code container with the rendered SVG,
9-
// and re-render when the user toggles dark/light mode.
11+
//
12+
// IMPORTANT: textContent on the <code> element concatenates ec-line divs
13+
// without newlines, producing invalid Mermaid source. We must join each
14+
// .ec-line's textContent with '\n' to reconstruct the original diagram.
1015

1116
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
1217

@@ -16,14 +21,24 @@ function currentTheme() {
1621
: 'dark';
1722
}
1823

24+
function extractSource(code) {
25+
// expressive-code wraps each line in .ec-line; join them to restore newlines
26+
const lines = code.querySelectorAll('.ec-line');
27+
if (lines.length) {
28+
return Array.from(lines).map(l => l.textContent).join('\n').trim();
29+
}
30+
// Fallback for plain <code> blocks (no expressive-code)
31+
return code.textContent.trim();
32+
}
33+
1934
async function renderMermaid() {
2035
const codeBlocks = document.querySelectorAll('pre[data-language="mermaid"] code');
2136
if (!codeBlocks.length) return;
2237

2338
mermaid.initialize({ startOnLoad: false, theme: currentTheme() });
2439

2540
for (const code of codeBlocks) {
26-
const src = code.textContent.trim();
41+
const src = extractSource(code);
2742
// Replace the whole expressive-code wrapper, falling back to the <pre>
2843
const container = code.closest('.expressive-code') || code.closest('pre');
2944
const wrapper = document.createElement('div');
@@ -34,7 +49,8 @@ async function renderMermaid() {
3449
const id = 'mmd-' + Math.random().toString(36).slice(2, 9);
3550
const { svg } = await mermaid.render(id, src);
3651
wrapper.innerHTML = svg;
37-
} catch {
52+
} catch (e) {
53+
console.error('Mermaid render error:', e, '\nSource:\n', src);
3854
wrapper.textContent = src;
3955
}
4056
container.replaceWith(wrapper);

0 commit comments

Comments
 (0)