deckrun 1.3.0 → 1.6.0
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/README.md +217 -35
- package/dist/editor-content.js +86 -1
- package/dist/editor.js +528 -216
- package/dist/fragments.js +71 -0
- package/dist/generate.js +1040 -45
- package/dist/index.js +353 -53
- package/dist/lint.js +218 -0
- package/dist/parser.js +85 -0
- package/dist/pdf.js +5 -1
- package/dist/presentation-options.js +287 -0
- package/dist/preview.js +125 -7
- package/dist/rich-content.js +170 -0
- package/dist/themes.js +8 -5
- package/package.json +5 -2
package/dist/preview.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { RESET_CSS, SLIDE_CSS, DECOR_CSS } from "./generate.js";
|
|
2
2
|
import { findFont, FONT_IDS, fontOverrideCss, SIZE_IDS, DEFAULT_SIZE, DEFAULT_THEME, decorMapJson, decorOf, googleFontsHref, hljsHref, hljsMapJson, resolveSizeName, sizeSwitchableCss, themeSwitchableCss, } from "./themes.js";
|
|
3
|
+
import { DEFAULT_TEMPLATE, DEFAULT_TRANSITION, resolveTemplateName, resolveTransitionName, TEMPLATE_CSS, TRANSITION_CSS, } from "./presentation-options.js";
|
|
4
|
+
import { RICH_CONTENT_CSS, RICH_CONTENT_RUNTIME, richContentHead, } from "./rich-content.js";
|
|
5
|
+
import { FRAGMENT_CSS, FRAGMENT_RUNTIME } from "./fragments.js";
|
|
3
6
|
/** Virtual viewport the preview renders at, so `vw` sizing matches a projector. */
|
|
4
7
|
export const PREVIEW_WIDTH = 1600;
|
|
5
8
|
export const PREVIEW_HEIGHT = 900;
|
|
@@ -8,21 +11,24 @@ export const PREVIEW_HEIGHT = 900;
|
|
|
8
11
|
* own stylesheet, so what the editor shows is what `deckrun file.md` renders.
|
|
9
12
|
* Slides arrive over postMessage; nothing is fetched or parsed in here.
|
|
10
13
|
*/
|
|
11
|
-
export function generatePreviewHtml(initialTheme = DEFAULT_THEME, initialSize = DEFAULT_SIZE, fonts = {}) {
|
|
14
|
+
export function generatePreviewHtml(initialTheme = DEFAULT_THEME, initialSize = DEFAULT_SIZE, fonts = {}, initialTemplate = DEFAULT_TEMPLATE, initialTransition = DEFAULT_TRANSITION) {
|
|
12
15
|
const size = resolveSizeName(initialSize);
|
|
16
|
+
const template = resolveTemplateName(initialTemplate);
|
|
17
|
+
const transition = resolveTransitionName(initialTransition);
|
|
13
18
|
const head = findFont(fonts.head);
|
|
14
19
|
const body = findFont(fonts.body);
|
|
15
20
|
const fontAttrs = (head ? ` data-head="${head}"` : "") + (body ? ` data-body="${body}"` : "");
|
|
16
21
|
return `<!DOCTYPE html>
|
|
17
|
-
<html lang="en" data-theme="${initialTheme}" data-decor="${decorOf(initialTheme)}" data-size="${size}"${fontAttrs}>
|
|
22
|
+
<html lang="en" data-theme="${initialTheme}" data-decor="${decorOf(initialTheme)}" data-size="${size}" data-template="${template}" data-transition="${transition}"${fontAttrs}>
|
|
18
23
|
<head>
|
|
19
24
|
<meta charset="UTF-8">
|
|
20
|
-
<title>preview</title>
|
|
25
|
+
<title>preview · deckrun</title>
|
|
21
26
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
22
27
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
23
28
|
<link href="${googleFontsHref()}" rel="stylesheet">
|
|
24
29
|
<link rel="stylesheet" id="hljs-theme" href="${hljsHref(initialTheme)}">
|
|
25
30
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
31
|
+
${richContentHead({ math: true, mermaid: true }, "local")}
|
|
26
32
|
<style>
|
|
27
33
|
${RESET_CSS}
|
|
28
34
|
|
|
@@ -34,6 +40,14 @@ ${fontOverrideCss()}
|
|
|
34
40
|
|
|
35
41
|
${SLIDE_CSS}
|
|
36
42
|
|
|
43
|
+
${TEMPLATE_CSS}
|
|
44
|
+
|
|
45
|
+
${TRANSITION_CSS}
|
|
46
|
+
|
|
47
|
+
${FRAGMENT_CSS}
|
|
48
|
+
|
|
49
|
+
${RICH_CONTENT_CSS}
|
|
50
|
+
|
|
37
51
|
${DECOR_CSS}
|
|
38
52
|
|
|
39
53
|
/* ── Preview overrides ────────────────────────────────────────────────── */
|
|
@@ -119,6 +133,11 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
119
133
|
<div id="presentation"></div>
|
|
120
134
|
<div id="pv-empty">nothing to preview yet</div>
|
|
121
135
|
<script>
|
|
136
|
+
${FRAGMENT_RUNTIME}
|
|
137
|
+
|
|
138
|
+
${RICH_CONTENT_RUNTIME}
|
|
139
|
+
</script>
|
|
140
|
+
<script>
|
|
122
141
|
(function () {
|
|
123
142
|
'use strict';
|
|
124
143
|
|
|
@@ -144,7 +163,7 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
144
163
|
|
|
145
164
|
function highlight(root) {
|
|
146
165
|
if (!window.hljs) return;
|
|
147
|
-
var blocks = root.querySelectorAll('pre code');
|
|
166
|
+
var blocks = root.querySelectorAll('pre code:not(.language-mermaid):not(.lang-mermaid)');
|
|
148
167
|
for (var i = 0; i < blocks.length; i++) {
|
|
149
168
|
if (!blocks[i].dataset.highlighted) {
|
|
150
169
|
try { window.hljs.highlightElement(blocks[i]); } catch (e) {}
|
|
@@ -157,7 +176,19 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
157
176
|
if (mode !== 'single') return;
|
|
158
177
|
var content = stage.querySelector('.slide__content');
|
|
159
178
|
var over = false;
|
|
160
|
-
if (content)
|
|
179
|
+
if (content) {
|
|
180
|
+
over = content.scrollHeight - content.clientHeight > 6 ||
|
|
181
|
+
content.scrollWidth - content.clientWidth > 6;
|
|
182
|
+
|
|
183
|
+
// KaTeX display equations and Mermaid hosts deliberately hide their own
|
|
184
|
+
// overflow to keep a projected slide tidy. Inspect them separately so a
|
|
185
|
+
// clipped formula or diagram still triggers the editor's overflow nudge.
|
|
186
|
+
var rich = content.querySelectorAll('.katex-display, .mermaid');
|
|
187
|
+
for (var i = 0; !over && i < rich.length; i++) {
|
|
188
|
+
over = rich[i].scrollHeight - rich[i].clientHeight > 6 ||
|
|
189
|
+
rich[i].scrollWidth - rich[i].clientWidth > 6;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
161
192
|
send({ type: 'overflow', index: index, overflow: over });
|
|
162
193
|
}
|
|
163
194
|
|
|
@@ -166,8 +197,10 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
166
197
|
stage.innerHTML = slides[index] || '';
|
|
167
198
|
var el = stage.querySelector('.slide');
|
|
168
199
|
if (el) el.classList.add('is-active');
|
|
200
|
+
if (window.deckrunPrepareFragments) window.deckrunPrepareFragments(stage, true);
|
|
169
201
|
highlight(stage);
|
|
170
|
-
|
|
202
|
+
var rich = window.deckrunRenderRichContent ? window.deckrunRenderRichContent(stage) : Promise.resolve();
|
|
203
|
+
rich.then(function () { requestAnimationFrame(reportOverflow); });
|
|
171
204
|
}
|
|
172
205
|
|
|
173
206
|
function renderGrid() {
|
|
@@ -195,7 +228,10 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
195
228
|
});
|
|
196
229
|
stage.appendChild(frag);
|
|
197
230
|
scaleThumbs();
|
|
231
|
+
if (window.deckrunPrepareFragments) window.deckrunPrepareFragments(stage, true);
|
|
198
232
|
highlight(stage);
|
|
233
|
+
var rich = window.deckrunRenderRichContent ? window.deckrunRenderRichContent(stage) : Promise.resolve();
|
|
234
|
+
rich.then(scaleThumbs);
|
|
199
235
|
}
|
|
200
236
|
|
|
201
237
|
function scaleThumbs() {
|
|
@@ -220,6 +256,86 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
220
256
|
if (thumb) send({ type: 'goto', index: parseInt(thumb.dataset.index, 10) });
|
|
221
257
|
});
|
|
222
258
|
|
|
259
|
+
window.addEventListener('keydown', function (e) {
|
|
260
|
+
var mod = e.metaKey || e.ctrlKey;
|
|
261
|
+
if (mod) {
|
|
262
|
+
var k = e.key.toLowerCase();
|
|
263
|
+
if (k === 'enter') { e.preventDefault(); send({ type: 'action', action: 'present' }); }
|
|
264
|
+
else if (k === 'k' && !e.shiftKey) { e.preventDefault(); send({ type: 'action', action: 'palette' }); }
|
|
265
|
+
else if (k === 'g') { e.preventDefault(); send({ type: 'action', action: 'grid' }); }
|
|
266
|
+
else if (k === 'o') { e.preventDefault(); send({ type: 'action', action: 'decks' }); }
|
|
267
|
+
else if (k === '/') { e.preventDefault(); send({ type: 'action', action: 'guide' }); }
|
|
268
|
+
else if (k === 'p' || (k === 's' && e.shiftKey)) { e.preventDefault(); send({ type: 'action', action: 'pdf' }); }
|
|
269
|
+
else if (k === 's') { e.preventDefault(); send({ type: 'action', action: 'download' }); }
|
|
270
|
+
else if (k === 'l' && e.shiftKey) { e.preventDefault(); send({ type: 'action', action: 'theme' }); }
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (mode === 'grid') {
|
|
275
|
+
var thumbs = stage.querySelectorAll('.pv-thumb');
|
|
276
|
+
if (!thumbs.length) return;
|
|
277
|
+
var cols = 1;
|
|
278
|
+
if (thumbs.length > 1) {
|
|
279
|
+
var firstTop = thumbs[0].offsetTop;
|
|
280
|
+
for (var c = 1; c < thumbs.length; c++) {
|
|
281
|
+
if (thumbs[c].offsetTop !== firstTop) { cols = c; break; }
|
|
282
|
+
}
|
|
283
|
+
if (cols === 1 && thumbs.length > 1 && thumbs[1].offsetTop === firstTop) {
|
|
284
|
+
cols = thumbs.length;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
var step = 0;
|
|
288
|
+
if (e.key === 'ArrowRight') step = 1;
|
|
289
|
+
else if (e.key === 'ArrowLeft') step = -1;
|
|
290
|
+
else if (e.key === 'ArrowDown') step = cols;
|
|
291
|
+
else if (e.key === 'ArrowUp') step = -cols;
|
|
292
|
+
else if (e.key === 'Home') { e.preventDefault(); send({ type: 'goto', index: 0 }); return; }
|
|
293
|
+
else if (e.key === 'End') { e.preventDefault(); send({ type: 'goto', index: slides.length - 1 }); return; }
|
|
294
|
+
else if (e.key === 'Enter') { e.preventDefault(); send({ type: 'goto', index: index }); return; }
|
|
295
|
+
else if (e.key === 'Escape') { e.preventDefault(); send({ type: 'goto', index: index }); return; }
|
|
296
|
+
else return;
|
|
297
|
+
|
|
298
|
+
e.preventDefault();
|
|
299
|
+
var next = Math.max(0, Math.min(slides.length - 1, index + step));
|
|
300
|
+
index = next;
|
|
301
|
+
var cur = stage.querySelector('.pv-thumb.is-current');
|
|
302
|
+
if (cur) cur.classList.remove('is-current');
|
|
303
|
+
var nextThumb = stage.querySelector('.pv-thumb[data-index="' + index + '"]');
|
|
304
|
+
if (nextThumb) {
|
|
305
|
+
nextThumb.classList.add('is-current');
|
|
306
|
+
nextThumb.scrollIntoView({ block: 'nearest' });
|
|
307
|
+
}
|
|
308
|
+
send({ type: 'index-select', index: index });
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Single mode: Alt navigation or standard keys
|
|
313
|
+
if (e.altKey) {
|
|
314
|
+
if (e.key === 'ArrowDown' || e.key === 'ArrowRight' || e.key === 'PageDown') {
|
|
315
|
+
e.preventDefault();
|
|
316
|
+
send({ type: 'nav', delta: 1 });
|
|
317
|
+
} else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft' || e.key === 'PageUp') {
|
|
318
|
+
e.preventDefault();
|
|
319
|
+
send({ type: 'nav', delta: -1 });
|
|
320
|
+
}
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === ' ' || e.key === 'PageDown') {
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
send({ type: 'nav', delta: 1 });
|
|
327
|
+
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp' || e.key === 'PageUp') {
|
|
328
|
+
e.preventDefault();
|
|
329
|
+
send({ type: 'nav', delta: -1 });
|
|
330
|
+
} else if (e.key === 'Home') {
|
|
331
|
+
e.preventDefault();
|
|
332
|
+
send({ type: 'goto', index: 0 });
|
|
333
|
+
} else if (e.key === 'End') {
|
|
334
|
+
e.preventDefault();
|
|
335
|
+
send({ type: 'goto', index: slides.length - 1 });
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
223
339
|
window.addEventListener('resize', function () {
|
|
224
340
|
if (mode === 'grid') scaleThumbs();
|
|
225
341
|
});
|
|
@@ -250,9 +366,11 @@ body.is-empty #pv-empty { display: flex; }
|
|
|
250
366
|
// theme, which delete does and an assignment of '' would not.
|
|
251
367
|
applyFont('head', m.head);
|
|
252
368
|
applyFont('body', m.body);
|
|
369
|
+
if (m.template) document.documentElement.dataset.template = m.template;
|
|
370
|
+
if (m.transition) document.documentElement.dataset.transition = m.transition;
|
|
253
371
|
// Type size and face both change how tall a slide's content runs, so the
|
|
254
372
|
// editor's overflow warning has to be re-measured against them.
|
|
255
|
-
|
|
373
|
+
render();
|
|
256
374
|
} else if (m.type === 'index') {
|
|
257
375
|
index = m.index;
|
|
258
376
|
if (mode === 'grid') {
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
export function richContentFeatures(slides) {
|
|
2
|
+
let math = false;
|
|
3
|
+
let mermaid = false;
|
|
4
|
+
for (const slide of slides) {
|
|
5
|
+
if (!math && (slide.html.includes('class="math-source"') || slide.html.includes("math-source"))) {
|
|
6
|
+
math = true;
|
|
7
|
+
}
|
|
8
|
+
if (!mermaid &&
|
|
9
|
+
(slide.html.includes("language-mermaid") ||
|
|
10
|
+
slide.html.includes("lang-mermaid") ||
|
|
11
|
+
slide.html.includes('class="mermaid"'))) {
|
|
12
|
+
mermaid = true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return { math, mermaid };
|
|
16
|
+
}
|
|
17
|
+
export function richContentHead(features, source = "local") {
|
|
18
|
+
const parts = [];
|
|
19
|
+
if (features.math) {
|
|
20
|
+
if (source === "cdn") {
|
|
21
|
+
parts.push('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.18.4/dist/katex.min.css">');
|
|
22
|
+
parts.push('<script src="https://cdn.jsdelivr.net/npm/katex@0.18.4/dist/katex.min.js"></script>');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
parts.push('<link rel="stylesheet" href="/__vendor/katex.min.css">');
|
|
26
|
+
parts.push('<script src="/__vendor/katex.min.js"></script>');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (features.mermaid) {
|
|
30
|
+
if (source === "cdn") {
|
|
31
|
+
parts.push('<script src="https://cdn.jsdelivr.net/npm/mermaid@11.17.2/dist/mermaid.min.js"></script>');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
parts.push('<script src="/__vendor/mermaid.min.js"></script>');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return parts.join("\n ");
|
|
38
|
+
}
|
|
39
|
+
export const RICH_CONTENT_CSS = `/* ── Rich Content (Math & Diagrams) ─────────────────────────────────────── */
|
|
40
|
+
|
|
41
|
+
.math-source {
|
|
42
|
+
font-family: inherit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
div.math-source {
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
margin: 1.2em 0;
|
|
49
|
+
overflow-x: auto;
|
|
50
|
+
overflow-y: hidden;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
span.math-source {
|
|
54
|
+
display: inline;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.katex-display {
|
|
58
|
+
margin: 0.8em 0;
|
|
59
|
+
overflow-x: auto;
|
|
60
|
+
overflow-y: hidden;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.katex {
|
|
64
|
+
font-size: 1.15em;
|
|
65
|
+
text-rendering: auto;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.math-error {
|
|
69
|
+
color: var(--maroon, #f38ba8);
|
|
70
|
+
background: var(--surface0, rgba(255, 0, 0, 0.1));
|
|
71
|
+
padding: 2px 6px;
|
|
72
|
+
border-radius: 4px;
|
|
73
|
+
font-family: var(--font-mono, monospace);
|
|
74
|
+
font-size: 0.85em;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.mermaid {
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
align-items: center;
|
|
81
|
+
margin: 1.2em auto;
|
|
82
|
+
max-width: 100%;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.mermaid svg {
|
|
87
|
+
max-width: 100%;
|
|
88
|
+
height: auto;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.mermaid-error {
|
|
92
|
+
color: var(--maroon, #f38ba8);
|
|
93
|
+
background: var(--surface0, rgba(255, 0, 0, 0.1));
|
|
94
|
+
border: 1px solid var(--maroon, #f38ba8);
|
|
95
|
+
border-radius: 6px;
|
|
96
|
+
padding: 12px 16px;
|
|
97
|
+
font-family: var(--font-mono, monospace);
|
|
98
|
+
font-size: 0.9em;
|
|
99
|
+
white-space: pre-wrap;
|
|
100
|
+
margin: 1em 0;
|
|
101
|
+
}
|
|
102
|
+
`;
|
|
103
|
+
export const RICH_CONTENT_RUNTIME = `(function () {
|
|
104
|
+
window.deckrunRenderRichContent = function (root) {
|
|
105
|
+
if (!root) return Promise.resolve();
|
|
106
|
+
|
|
107
|
+
// 1. Render KaTeX math
|
|
108
|
+
if (window.katex) {
|
|
109
|
+
var mathNodes = root.querySelectorAll('.math-source:not([data-rendered])');
|
|
110
|
+
for (var i = 0; i < mathNodes.length; i++) {
|
|
111
|
+
var el = mathNodes[i];
|
|
112
|
+
var tex = el.textContent || '';
|
|
113
|
+
var isDisplay = el.dataset.display === 'true';
|
|
114
|
+
try {
|
|
115
|
+
window.katex.render(tex, el, {
|
|
116
|
+
displayMode: isDisplay,
|
|
117
|
+
throwOnError: false,
|
|
118
|
+
output: 'htmlAndMathml'
|
|
119
|
+
});
|
|
120
|
+
el.setAttribute('data-rendered', 'true');
|
|
121
|
+
} catch (err) {
|
|
122
|
+
el.innerHTML = '<span class="math-error">' + (err && err.message ? err.message : 'Math rendering error') + '</span>';
|
|
123
|
+
el.setAttribute('data-rendered', 'true');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 2. Render Mermaid diagrams
|
|
129
|
+
var mermaidPromises = [];
|
|
130
|
+
var codeBlocks = root.querySelectorAll('pre code.language-mermaid, pre code.lang-mermaid');
|
|
131
|
+
if (codeBlocks.length > 0 && window.mermaid) {
|
|
132
|
+
try {
|
|
133
|
+
window.mermaid.initialize({
|
|
134
|
+
startOnLoad: false,
|
|
135
|
+
theme: 'dark',
|
|
136
|
+
securityLevel: 'loose'
|
|
137
|
+
});
|
|
138
|
+
} catch (e) {}
|
|
139
|
+
|
|
140
|
+
for (var j = 0; j < codeBlocks.length; j++) {
|
|
141
|
+
(function (codeEl) {
|
|
142
|
+
var preEl = codeEl.closest('pre');
|
|
143
|
+
if (!preEl || preEl.dataset.rendered) return;
|
|
144
|
+
preEl.dataset.rendered = 'true';
|
|
145
|
+
var code = codeEl.textContent || '';
|
|
146
|
+
var container = document.createElement('div');
|
|
147
|
+
container.className = 'mermaid';
|
|
148
|
+
preEl.parentNode.insertBefore(container, preEl);
|
|
149
|
+
preEl.style.display = 'none';
|
|
150
|
+
|
|
151
|
+
var id = 'mermaid-' + Math.random().toString(36).slice(2, 10);
|
|
152
|
+
var p = window.mermaid.render(id, code)
|
|
153
|
+
.then(function (res) {
|
|
154
|
+
container.innerHTML = res.svg;
|
|
155
|
+
preEl.remove();
|
|
156
|
+
})
|
|
157
|
+
.catch(function (err) {
|
|
158
|
+
container.className = 'mermaid-error';
|
|
159
|
+
container.textContent = 'Mermaid Error: ' + (err && err.message ? err.message : String(err));
|
|
160
|
+
preEl.remove();
|
|
161
|
+
});
|
|
162
|
+
mermaidPromises.push(p);
|
|
163
|
+
})(codeBlocks[j]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return Promise.all(mermaidPromises).then(function () {});
|
|
168
|
+
};
|
|
169
|
+
})();
|
|
170
|
+
`;
|
package/dist/themes.js
CHANGED
|
@@ -53,7 +53,7 @@ export function fontName(key) {
|
|
|
53
53
|
}
|
|
54
54
|
const SANS = "system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif";
|
|
55
55
|
const SERIF = "Georgia, 'Times New Roman', serif";
|
|
56
|
-
const MONO = "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
|
|
56
|
+
const MONO = "'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
|
|
57
57
|
export const FONTS = {
|
|
58
58
|
inter: { param: "Inter:wght@300;400;500;600;700;800", stack: `'Inter', ${SANS}`, kind: "sans" },
|
|
59
59
|
spaceGrotesk: { param: "Space+Grotesk:wght@400;500;600;700", stack: `'Space Grotesk', ${SANS}`, kind: "sans" },
|
|
@@ -71,7 +71,7 @@ export const FONTS = {
|
|
|
71
71
|
newsreader: { param: "Newsreader:ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400", stack: `'Newsreader', ${SERIF}`, kind: "serif" },
|
|
72
72
|
lora: { param: "Lora:ital,wght@0,400;0,500;0,600;0,700;1,400", stack: `'Lora', ${SERIF}`, kind: "serif" },
|
|
73
73
|
plexMono: { param: "IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400", stack: `'IBM Plex Mono', ${MONO}`, kind: "mono" },
|
|
74
|
-
jetbrains: { param: "JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400", stack: `'JetBrains Mono', ${MONO}`, kind: "mono" },
|
|
74
|
+
jetbrains: { param: "JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400", stack: `'JetBrains Mono', ${MONO}`, kind: "mono" },
|
|
75
75
|
firaCode: { param: "Fira+Code:wght@400;500;600;700", stack: `'Fira Code', ${MONO}`, kind: "mono" },
|
|
76
76
|
spaceMono: { param: "Space+Mono:ital,wght@0,400;0,700;1,400", stack: `'Space Mono', ${MONO}`, kind: "mono" },
|
|
77
77
|
sourceCodePro: { param: "Source+Code+Pro:ital,wght@0,400;0,500;0,600;0,700;1,400", stack: `'Source Code Pro', ${MONO}`, kind: "mono" },
|
|
@@ -85,6 +85,7 @@ export const FONTS = {
|
|
|
85
85
|
*/
|
|
86
86
|
export function googleFontsHref(themes = THEME_IDS.slice(), extra = []) {
|
|
87
87
|
const wanted = new Set();
|
|
88
|
+
wanted.add("jetbrains");
|
|
88
89
|
for (const input of themes) {
|
|
89
90
|
const t = THEMES[resolveThemeName(input)];
|
|
90
91
|
wanted.add(t.type.display);
|
|
@@ -162,7 +163,7 @@ const SPECS = {
|
|
|
162
163
|
red: "#bf616a", mauve: "#b48ead", pink: "#d3a3c6",
|
|
163
164
|
},
|
|
164
165
|
roles: { accent: "sapphire", accent2: "blue", accent3: "teal" },
|
|
165
|
-
type: { display: "
|
|
166
|
+
type: { display: "jetbrains", body: "jetbrains", mono: "jetbrains", weight: 700, tracking: "-0.025em" },
|
|
166
167
|
decor: "waves",
|
|
167
168
|
hljs: `${HL}nord.min.css`,
|
|
168
169
|
},
|
|
@@ -399,7 +400,7 @@ export const THEME_IDS = [
|
|
|
399
400
|
export const THEMES = Object.fromEntries(THEME_IDS.map((id) => [id, { id, ...SPECS[id] }]));
|
|
400
401
|
/** `dark` and `light` predate the registry and still name the two originals. */
|
|
401
402
|
const ALIASES = {
|
|
402
|
-
dark: "
|
|
403
|
+
dark: "nord",
|
|
403
404
|
light: "daylight",
|
|
404
405
|
mocha: "midnight",
|
|
405
406
|
latte: "daylight",
|
|
@@ -407,7 +408,7 @@ const ALIASES = {
|
|
|
407
408
|
"rose-pine": "rosepine",
|
|
408
409
|
"rose-quartz": "rosequartz",
|
|
409
410
|
};
|
|
410
|
-
export const DEFAULT_THEME = "
|
|
411
|
+
export const DEFAULT_THEME = "nord";
|
|
411
412
|
/** A theme id from untrusted input, or `null` if it names nothing. */
|
|
412
413
|
export function findTheme(input) {
|
|
413
414
|
if (!input)
|
|
@@ -498,6 +499,8 @@ function themeVars(t) {
|
|
|
498
499
|
["glow", alpha(accent, dark ? 0.34 : 0.22)],
|
|
499
500
|
["gradient", `linear-gradient(115deg, ${accent}, ${accent2} 58%, ${accent3})`],
|
|
500
501
|
["accent-fade", `linear-gradient(90deg, ${accent}, ${alpha(accent, 0.45)} 62%, transparent)`],
|
|
502
|
+
["selection-bg", alpha(accent, dark ? 0.22 : 0.18)],
|
|
503
|
+
["selection-text", "inherit"],
|
|
501
504
|
["surface-soft", alpha(n.surface0, dark ? 0.34 : 0.42)],
|
|
502
505
|
["crust-overlay", alpha(n.crust, dark ? 0.84 : 0.88)],
|
|
503
506
|
["scrim", dark ? "rgba(0, 0, 0, 0.5)" : alpha(n.text, 0.26)],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deckrun",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A local-first presentation tool for writing, editing, presenting, and exporting Markdown slides or self-contained HTML docs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,11 +11,14 @@
|
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc && chmod +x dist/index.js",
|
|
14
|
-
"dev": "tsx src/index.ts"
|
|
14
|
+
"dev": "tsx src/index.ts",
|
|
15
|
+
"test": "npm run build && node --test"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
18
|
"commander": "^11.1.0",
|
|
19
|
+
"katex": "^0.18.4",
|
|
18
20
|
"marked": "^9.1.6",
|
|
21
|
+
"mermaid": "^11.17.2",
|
|
19
22
|
"open": "^9.1.0"
|
|
20
23
|
},
|
|
21
24
|
"devDependencies": {
|