@farberg/reveal-template 1.1.13 → 1.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farberg/reveal-template",
3
- "version": "1.1.13",
3
+ "version": "1.1.14",
4
4
  "homepage": "https://github.com/pfisterer/reveal-template",
5
5
  "description": "Reveal.js template for Dennis' lectures",
6
6
  "main": "index.js",
@@ -14,6 +14,7 @@ export default {
14
14
  mermaid.initialize({
15
15
  'startOnLoad': false,
16
16
  'theme': 'base',
17
+ 'fontSize': 13,
17
18
  'themeVariables': {
18
19
  'textColor': '#000',
19
20
  'primaryColor': '#e2001a',
@@ -31,38 +32,75 @@ export default {
31
32
  },
32
33
  'flowchart': {
33
34
  'useMaxWidth': true,
34
- 'htmlLabels': true
35
+ 'padding': 6
35
36
  }
36
37
  });
37
38
 
38
39
  function fixSvgScaling(el) {
39
- el.querySelectorAll('pre.mermaid svg').forEach(svg => {
40
- // mermaid v10+ sets style="max-width: Xpx" which constrains width —
41
- // remove it and let the container CSS drive the size instead
40
+ el.querySelectorAll('.mermaid svg').forEach(svg => {
41
+ // Ensure viewBox so width:100% scales content proportionally
42
+ if (!svg.getAttribute('viewBox')) {
43
+ const w = parseFloat(svg.getAttribute('width'));
44
+ const h = parseFloat(svg.getAttribute('height'));
45
+ if (w && h) svg.setAttribute('viewBox', `0 0 ${w} ${h}`);
46
+ }
47
+ svg.setAttribute('width', '100%');
48
+ svg.removeAttribute('height');
42
49
  svg.style.maxWidth = '100%';
43
50
  svg.style.width = '100%';
44
51
  svg.style.height = 'auto';
52
+
53
+ // mermaid v11 measures text before the document font is loaded,
54
+ // producing foreignObjects that are too narrow for the actual rendered text.
55
+ // Measure the real content width and expand each foreignObject to fit,
56
+ // then shift the label group by half the difference to keep it centered.
57
+ svg.querySelectorAll('foreignObject').forEach(fo => {
58
+ fo.setAttribute('overflow', 'visible');
59
+ const inner = fo.firstElementChild;
60
+ if (!inner) return;
61
+ const actualWidth = inner.scrollWidth;
62
+ const foWidth = parseFloat(fo.getAttribute('width')) || 0;
63
+ if (actualWidth > foWidth) {
64
+ const extra = actualWidth - foWidth;
65
+ fo.setAttribute('width', actualWidth);
66
+ const labelG = fo.parentElement;
67
+ if (labelG && labelG.hasAttribute('transform')) {
68
+ const m = labelG.getAttribute('transform')
69
+ .match(/translate\((-?[\d.]+),\s*(-?[\d.]+)\)/);
70
+ if (m) {
71
+ labelG.setAttribute('transform',
72
+ `translate(${parseFloat(m[1]) - extra / 2}, ${m[2]})`);
73
+ }
74
+ }
75
+ }
76
+ });
45
77
  });
46
78
  }
47
79
 
48
- function handle(el) {
49
- // Convert ```mermaid code blocks into pre.mermaid elements.
50
- // highlight.js processes them first (adding spans, encoding arrows as >),
51
- // so we read textContent to strip spans and decode HTML entities back to raw source.
80
+ async function handle(el) {
81
+ // Convert ```mermaid code blocks to .mermaid elements.
82
+ // highlight.js runs first: adds <span> tags and encodes --> as &gt;.
83
+ // textContent strips spans and decodes HTML entities back to raw mermaid source.
52
84
  el.querySelectorAll('code.mermaid').forEach(code => {
53
- if (code.closest('pre.mermaid')) return; // already converted
54
- const pre = code.parentElement;
55
- pre.className = 'mermaid';
56
- pre.textContent = code.textContent;
85
+ const oldPre = code.parentElement;
86
+ if (oldPre.classList.contains('mermaid')) return;
87
+ const newPre = document.createElement('pre');
88
+ newPre.className = 'mermaid';
89
+ newPre.textContent = code.textContent;
90
+ oldPre.replaceWith(newPre);
57
91
  });
58
92
 
59
- const mermaids = el.querySelectorAll('pre.mermaid');
60
- const result = mermaid.run({ nodes: mermaids });
61
- if (result && typeof result.then === 'function') {
62
- result.then(() => fixSvgScaling(el));
63
- } else {
64
- setTimeout(() => fixSvgScaling(el), 100);
65
- }
93
+ // Yield so DOM mutations are flushed before mermaid reads them
94
+ await new Promise(resolve => requestAnimationFrame(resolve));
95
+
96
+ // Skip elements already rendered (contain an SVG)
97
+ const unrendered = [...el.querySelectorAll('.mermaid')].filter(
98
+ node => !node.querySelector('svg') && node.textContent.trim().length > 0
99
+ );
100
+ if (unrendered.length === 0) return;
101
+
102
+ await mermaid.run({ nodes: unrendered, suppressErrors: true });
103
+ fixSvgScaling(el);
66
104
  }
67
105
 
68
106
  deck.on('ready', event => {
@@ -77,22 +115,29 @@ export default {
77
115
  text-align: center;
78
116
  overflow: visible;
79
117
  }
80
- pre.mermaid svg {
118
+ .mermaid svg {
81
119
  max-width: 100%;
82
120
  height: auto;
83
121
  }
122
+ .mermaid svg foreignObject {
123
+ overflow: visible;
124
+ }
125
+ .mermaid svg foreignObject * {
126
+ font-size: 13px !important;
127
+ font-family: arial, sans-serif !important;
128
+ line-height: 1.5 !important;
129
+ }
84
130
  `;
85
131
  document.head.appendChild(style);
86
132
 
87
133
  const print = window.location.search.match(/print-pdf/gi);
88
-
89
134
  if (print) {
90
- console.log("print-pdf detected, rendering mermaid diagrams")
135
+ console.log("print-pdf detected, rendering mermaid diagrams");
91
136
  handle(document);
92
137
  } else {
93
138
  deck.addEventListener('slidechanged', e => handle(e.currentSlide));
94
139
  handle(event.currentSlide);
95
140
  }
96
- })
141
+ });
97
142
  }
98
143
  }