@farberg/reveal-template 1.1.12 → 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.
@@ -2,9 +2,11 @@
2
2
 
3
3
  <head>
4
4
  <meta charset="utf-8">
5
+ <meta name="mobile-web-app-capable" content="yes" />
5
6
  <meta name="apple-mobile-web-app-capable" content="yes" />
6
7
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, minimal-ui">
8
+ <meta name="viewport"
9
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, minimal-ui">
8
10
 
9
11
  <script type="module">
10
12
  import { initReveal } from '../init-reveal.js'
package/init-reveal.js CHANGED
@@ -35,7 +35,7 @@ const externalJsLibs = [
35
35
 
36
36
  const extraStylesheets = [
37
37
  { href: 'node_modules/reveal.js/dist/reveal.css' },
38
- { href: 'node_modules/reveal.js/plugin/highlight/zenburn.css' },
38
+ { href: 'node_modules/reveal.js/dist/plugin/highlight/zenburn.css' },
39
39
  { href: 'node_modules/asciinema-player/dist/bundle/asciinema-player.css' },
40
40
  { href: 'node_modules/reveal.js-plugins/customcontrols/style.css' },
41
41
  { href: 'node_modules/reveal.js-plugins/chalkboard/style.css' },
@@ -126,19 +126,19 @@ function windowOnLoadPromise() {
126
126
  // Load reveal and its plugins
127
127
  function loadRevealAndPlugins(options) {
128
128
  const imports = [
129
- "dist/reveal.esm.js" /*must be the first one*/,
130
- "plugin/markdown/markdown.esm.js",
131
- "plugin/highlight/highlight.esm.js",
132
- "plugin/search/search.esm.js",
133
- "plugin/notes/notes.esm.js",
134
- "plugin/math/math.esm.js",
135
- "plugin/zoom/zoom.esm.js"
129
+ "dist/reveal.mjs" /*must be the first one*/,
130
+ "dist/plugin/markdown.mjs",
131
+ "dist/plugin/highlight.mjs",
132
+ "dist/plugin/search.mjs",
133
+ "dist/plugin/notes.mjs",
134
+ "dist/plugin/math.mjs",
135
+ "dist/plugin/zoom.mjs"
136
136
  ]
137
137
 
138
138
  if (options.verbose)
139
139
  console.log("Importing the following plugins: ", imports)
140
140
 
141
- return Promise.all(imports.map(i => import(options.revealPath + "/" + i)))
141
+ return Promise.all(imports.map(i => import(options.revealPath + i)))
142
142
  }
143
143
 
144
144
  // Add js tags to the header and resolve
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farberg/reveal-template",
3
- "version": "1.1.12",
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",
@@ -1,11 +1,20 @@
1
- import mermaid from '../../../mermaid/dist/mermaid.esm.min.mjs';
1
+ // When installed as an npm package the plugin lives at node_modules/@farberg/reveal-template/plugins/
2
+ // and mermaid is 3 levels up. When running from the template root directly it is 1 level up.
3
+ const mermaidUrl = new URL(
4
+ new URL(import.meta.url).pathname.includes('/node_modules/')
5
+ ? '../../../mermaid/dist/mermaid.esm.min.mjs'
6
+ : '../node_modules/mermaid/dist/mermaid.esm.min.mjs',
7
+ import.meta.url
8
+ ).href;
2
9
 
3
10
  export default {
4
11
  id: 'mermaid',
5
- init: (deck) => {
12
+ init: async (deck) => {
13
+ const { default: mermaid } = await import(mermaidUrl);
6
14
  mermaid.initialize({
7
15
  'startOnLoad': false,
8
16
  'theme': 'base',
17
+ 'fontSize': 13,
9
18
  'themeVariables': {
10
19
  'textColor': '#000',
11
20
  'primaryColor': '#e2001a',
@@ -23,38 +32,75 @@ export default {
23
32
  },
24
33
  'flowchart': {
25
34
  'useMaxWidth': true,
26
- 'htmlLabels': true
35
+ 'padding': 6
27
36
  }
28
37
  });
29
38
 
30
39
  function fixSvgScaling(el) {
31
- el.querySelectorAll('pre.mermaid svg').forEach(svg => {
32
- // mermaid v10+ sets style="max-width: Xpx" which constrains width —
33
- // 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');
34
49
  svg.style.maxWidth = '100%';
35
50
  svg.style.width = '100%';
36
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
+ });
37
77
  });
38
78
  }
39
79
 
40
- function handle(el) {
41
- // Convert ```mermaid code blocks into pre.mermaid elements.
42
- // highlight.js processes them first (adding spans, encoding arrows as &gt;),
43
- // 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.
44
84
  el.querySelectorAll('code.mermaid').forEach(code => {
45
- if (code.closest('pre.mermaid')) return; // already converted
46
- const pre = code.parentElement;
47
- pre.className = 'mermaid';
48
- 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);
49
91
  });
50
92
 
51
- const mermaids = el.querySelectorAll('pre.mermaid');
52
- const result = mermaid.run({ nodes: mermaids });
53
- if (result && typeof result.then === 'function') {
54
- result.then(() => fixSvgScaling(el));
55
- } else {
56
- setTimeout(() => fixSvgScaling(el), 100);
57
- }
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);
58
104
  }
59
105
 
60
106
  deck.on('ready', event => {
@@ -69,22 +115,29 @@ export default {
69
115
  text-align: center;
70
116
  overflow: visible;
71
117
  }
72
- pre.mermaid svg {
118
+ .mermaid svg {
73
119
  max-width: 100%;
74
120
  height: auto;
75
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
+ }
76
130
  `;
77
131
  document.head.appendChild(style);
78
132
 
79
133
  const print = window.location.search.match(/print-pdf/gi);
80
-
81
134
  if (print) {
82
- console.log("print-pdf detected, rendering mermaid diagrams")
135
+ console.log("print-pdf detected, rendering mermaid diagrams");
83
136
  handle(document);
84
137
  } else {
85
138
  deck.addEventListener('slidechanged', e => handle(e.currentSlide));
86
139
  handle(event.currentSlide);
87
140
  }
88
- })
141
+ });
89
142
  }
90
143
  }