@pretextbook/pretext-html 0.4.0 → 0.5.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.
Files changed (42) hide show
  1. package/README.md +86 -1
  2. package/assets/preview-revealjs.xsl +85 -0
  3. package/assets/upstream.json +1 -1
  4. package/assets/xsl/LICENSE-pretext +16 -0
  5. package/assets/xsl/entities.ent +7 -0
  6. package/assets/xsl/extract-biblio-csl.xsl +5 -3
  7. package/assets/xsl/extract-dynamic.xsl +14 -12
  8. package/assets/xsl/extract-interactive.xsl +2 -2
  9. package/assets/xsl/extract-pg.xsl +12 -9
  10. package/assets/xsl/extract-qrcode.xsl +1 -1
  11. package/assets/xsl/extract-trace.xsl +3 -3
  12. package/assets/xsl/extract-youtube.xsl +1 -1
  13. package/assets/xsl/latex/pretext-latex-texstyle.xsl +3 -3
  14. package/assets/xsl/pretext-assembly.xsl +362 -357
  15. package/assets/xsl/pretext-braille-preprint.xsl +1 -1
  16. package/assets/xsl/pretext-common.xsl +101 -90
  17. package/assets/xsl/pretext-epub.xsl +17 -6
  18. package/assets/xsl/pretext-fo.xsl +10 -10
  19. package/assets/xsl/pretext-html.xsl +83 -60
  20. package/assets/xsl/pretext-latex-common.xsl +8 -8
  21. package/assets/xsl/pretext-numbers.xsl +35 -35
  22. package/assets/xsl/pretext-revealjs.xsl +1 -1
  23. package/assets/xsl/pretext-runestone-fitb.xsl +14 -13
  24. package/assets/xsl/pretext-runestone-static.xsl +17 -17
  25. package/assets/xsl/pretext-runestone.xsl +33 -31
  26. package/assets/xsl/pretext-view-source.xsl +5 -3
  27. package/assets/xsl/pretext-ww-problem-sets.xsl +6 -1
  28. package/assets/xsl/publisher-variables.xsl +23 -47
  29. package/assets/xsl-bundle.json +1 -1
  30. package/dist/cli-DZsyZERX.js +694 -0
  31. package/dist/cli.js +1 -1
  32. package/dist/index.browser.d.ts +5 -0
  33. package/dist/index.browser.js +402 -256
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.js +23 -18
  36. package/dist/publication.d.ts +25 -19
  37. package/dist/renderer.d.ts +48 -0
  38. package/dist/reveal.d.ts +77 -0
  39. package/dist/reveal.js +110 -0
  40. package/dist/target.d.ts +34 -0
  41. package/package.json +12 -1
  42. package/dist/cli-Cp6C0sif.js +0 -654
@@ -1,7 +1,7 @@
1
- import { fromXml as x } from "xast-util-from-xml";
2
- import { toXml as T } from "xast-util-to-xml";
3
- const _ = "/";
4
- function me(e) {
1
+ import { fromXml as E } from "xast-util-from-xml";
2
+ import { toXml as S } from "xast-util-to-xml";
3
+ const D = "/";
4
+ function ge(e) {
5
5
  if (!e)
6
6
  return ".";
7
7
  const n = e.startsWith("/"), t = e.length > 1 && e.endsWith("/"), r = [];
@@ -17,7 +17,7 @@ function me(e) {
17
17
  let i = r.join("/");
18
18
  return n && (i = `/${i}`), i ? (t && !i.endsWith("/") && (i += "/"), i) : n ? "/" : ".";
19
19
  }
20
- function f(...e) {
20
+ function h(...e) {
21
21
  let n = "";
22
22
  for (let r = e.length - 1; r >= 0; r--) {
23
23
  const i = e[r];
@@ -25,43 +25,43 @@ function f(...e) {
25
25
  break;
26
26
  }
27
27
  n.startsWith("/") || (n = `/${n}`);
28
- const t = me(n);
28
+ const t = ge(n);
29
29
  return t.length > 1 && t.endsWith("/") ? t.slice(0, -1) : t;
30
30
  }
31
- function y(e) {
31
+ function b(e) {
32
32
  const n = e.replace(/\/+$/, "");
33
33
  if (!n)
34
34
  return e.startsWith("/") ? "/" : ".";
35
35
  const t = n.lastIndexOf("/");
36
36
  return t < 0 ? "." : t === 0 ? "/" : n.slice(0, t);
37
37
  }
38
- function S(e, n) {
39
- const t = f(e).split("/").filter(Boolean), r = f(n).split("/").filter(Boolean);
38
+ function k(e, n) {
39
+ const t = h(e).split("/").filter(Boolean), r = h(n).split("/").filter(Boolean);
40
40
  let i = 0;
41
41
  for (; i < t.length && i < r.length && t[i] === r[i]; )
42
42
  i += 1;
43
43
  return [...new Array(t.length - i).fill(".."), ...r.slice(i)].join("/");
44
44
  }
45
- const pe = "https://cdn.jsdelivr.net/npm/@pretextbook/pretext-html@0.4.0/assets";
46
- let Q;
47
- function Ve(e) {
48
- Q = e.replace(/\/+$/, "");
45
+ const ve = "https://cdn.jsdelivr.net/npm/@pretextbook/pretext-html@0.5.0/assets";
46
+ let Z;
47
+ function bt(e) {
48
+ Z = e.replace(/\/+$/, "");
49
49
  }
50
50
  function $() {
51
- return Q ?? pe;
51
+ return Z ?? ve;
52
52
  }
53
- function Z(e, n) {
53
+ function Q(e, n) {
54
54
  return `${e.replace(/\/+$/, "")}/${n.replace(/^\/+/, "")}`;
55
55
  }
56
- const O = /* @__PURE__ */ new Map();
57
- function we(e) {
56
+ const U = /* @__PURE__ */ new Map();
57
+ function be(e) {
58
58
  return `${e.replace(/\/+$/, "")}-bundle.json`;
59
59
  }
60
- function ge(e) {
61
- let n = O.get(e);
60
+ function ye(e) {
61
+ let n = U.get(e);
62
62
  return n || (n = (async () => {
63
63
  try {
64
- const t = await fetch(we(e));
64
+ const t = await fetch(be(e));
65
65
  if (!t.ok)
66
66
  return /* @__PURE__ */ new Map();
67
67
  const r = await t.json();
@@ -69,14 +69,14 @@ function ge(e) {
69
69
  } catch {
70
70
  return /* @__PURE__ */ new Map();
71
71
  }
72
- })(), O.set(e, n)), n;
72
+ })(), U.set(e, n)), n;
73
73
  }
74
- function be(e) {
75
- return e === Z($(), "xsl");
74
+ function Ee(e) {
75
+ return e === Q($(), "xsl");
76
76
  }
77
77
  async function ee(e, n) {
78
- if (be(e)) {
79
- const o = (await ge(e)).get(n.replace(/^\/+/, ""));
78
+ if (Ee(e)) {
79
+ const o = (await ye(e)).get(n.replace(/^\/+/, ""));
80
80
  if (o !== void 0)
81
81
  return new TextEncoder().encode(o);
82
82
  }
@@ -100,7 +100,7 @@ async function ee(e, n) {
100
100
  return;
101
101
  }
102
102
  }
103
- async function R(e) {
103
+ async function P(e) {
104
104
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(e))
105
105
  try {
106
106
  const n = await fetch(e);
@@ -109,12 +109,12 @@ async function R(e) {
109
109
  return;
110
110
  }
111
111
  }
112
- const j = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map();
113
- let P, ye = 0, ne = ee;
114
- function Qe(e) {
112
+ const C = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map();
113
+ let L, xe = 0, ne = ee;
114
+ function yt(e) {
115
115
  ne = e;
116
116
  }
117
- function ve(e, n) {
117
+ function Te(e, n) {
118
118
  const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, r = te.get(t);
119
119
  if (r !== void 0)
120
120
  return Promise.resolve(new Response(r, { status: 200 }));
@@ -124,32 +124,32 @@ function ve(e, n) {
124
124
  } catch {
125
125
  i = "";
126
126
  }
127
- const o = j.get(i);
128
- return o !== void 0 ? Ee(o, t) : P(e, n);
127
+ const o = C.get(i);
128
+ return o !== void 0 ? $e(o, t) : L(e, n);
129
129
  }
130
- const xe = '<?xml version="1.0"?><pretext-preview-missing-file/>';
131
- async function Ee(e, n) {
130
+ const Se = '<?xml version="1.0"?><pretext-preview-missing-file/>';
131
+ async function $e(e, n) {
132
132
  const t = decodeURIComponent(new URL(n).pathname), r = await ne(e, t);
133
133
  if (r === void 0)
134
- return new Response(xe, { status: 200 });
134
+ return new Response(Se, { status: 200 });
135
135
  const i = typeof r == "string" ? r : new Uint8Array(r);
136
136
  return new Response(i, { status: 200 });
137
137
  }
138
138
  function re() {
139
- P || (P = globalThis.fetch, globalThis.fetch = ve);
139
+ L || (L = globalThis.fetch, globalThis.fetch = Te);
140
140
  }
141
141
  function ie(e) {
142
142
  re();
143
- const n = `mnt${++ye}.ptx.invalid`;
144
- return j.set(n, e), `http://${n}`;
143
+ const n = `mnt${++xe}.ptx.invalid`;
144
+ return C.set(n, e), `http://${n}`;
145
145
  }
146
- function Te(e) {
147
- j.delete(new URL(e).host);
146
+ function _e(e) {
147
+ C.delete(new URL(e).host);
148
148
  }
149
- function $e(e, n) {
149
+ function Re(e, n) {
150
150
  re(), te.set(e, n);
151
151
  }
152
- const L = `<?xml version="1.0" encoding="UTF-8"?>
152
+ const A = `<?xml version="1.0" encoding="UTF-8"?>
153
153
  <publication>
154
154
  <source>
155
155
  <directories external="../assets" generated="../generated-assets" />
@@ -158,43 +158,62 @@ const L = `<?xml version="1.0" encoding="UTF-8"?>
158
158
  <platform portable="yes"/>
159
159
  </html>
160
160
  </publication>
161
- `, Me = ["theme", "style", "shell"];
161
+ `, ke = ["theme", "style", "shell"];
162
162
  function w(e, n) {
163
163
  for (const t of e.children)
164
164
  if (t.type === "element" && t.name === n)
165
165
  return t;
166
166
  }
167
- function F(e, n) {
167
+ function g(e, n) {
168
168
  let t = w(e, n);
169
169
  return t || (t = { type: "element", name: n, attributes: {}, children: [] }, e.children.push(t)), t;
170
170
  }
171
- function ke(e, n) {
171
+ function Ie(e, n) {
172
172
  const t = w(e, "css");
173
- if (t && Me.some((i) => t.attributes?.[i]))
173
+ if (t && ke.some((i) => t.attributes?.[i]))
174
+ return;
175
+ const r = t ?? g(e, "css");
176
+ r.attributes = { ...r.attributes, theme: n };
177
+ }
178
+ function Me(e, n) {
179
+ const t = w(e, "appearance");
180
+ if (t?.attributes?.theme)
174
181
  return;
175
- const r = t ?? F(e, "css");
182
+ const r = t ?? g(e, "appearance");
176
183
  r.attributes = { ...r.attributes, theme: n };
177
184
  }
178
- function De(e, n) {
179
- const t = n?.trim();
180
- if (!e && !t)
181
- return L;
182
- const r = x(e ?? L), i = w(r, "publication");
183
- if (!i)
185
+ function De(e) {
186
+ const n = g(e, "resources");
187
+ n.attributes = {
188
+ ...n.attributes,
189
+ host: "cdn",
190
+ math: "online"
191
+ };
192
+ }
193
+ function Le(e, n = {}) {
194
+ const t = n.cssTheme?.trim(), r = n.revealTheme?.trim(), i = n.target === "slides";
195
+ if (!e && !t && !i)
196
+ return A;
197
+ const o = E(e ?? A), s = w(o, "publication");
198
+ if (!s)
184
199
  throw new Error(
185
200
  "Invalid publication file: no root <publication> element found"
186
201
  );
187
- const o = F(i, "html"), s = F(o, "platform");
188
- return s.attributes = { ...s.attributes, portable: "yes" }, t && ke(o, t), T(r);
202
+ const a = g(s, "html"), u = g(a, "platform");
203
+ if (u.attributes = { ...u.attributes, portable: "yes" }, t && Ie(a, t), i) {
204
+ const c = g(s, "revealjs");
205
+ De(c), r && Me(c, r);
206
+ }
207
+ return S(o);
189
208
  }
190
- function N(e) {
209
+ function V(e) {
191
210
  if (!(e === void 0 || e === "" || e.startsWith("/")))
192
211
  return e.endsWith("/") ? e : `${e}/`;
193
212
  }
194
- function Se(e) {
195
- const n = x(e ?? L), t = w(n, "publication"), r = t && w(t, "source"), i = r && w(r, "directories"), o = N(
213
+ function Ae(e) {
214
+ const n = E(e ?? A), t = w(n, "publication"), r = t && w(t, "source"), i = r && w(r, "directories"), o = V(
196
215
  i?.attributes?.external ?? void 0
197
- ), s = N(
216
+ ), s = V(
198
217
  i?.attributes?.generated ?? void 0
199
218
  );
200
219
  return {
@@ -203,59 +222,163 @@ function Se(e) {
203
222
  managed: o !== void 0 && s !== void 0
204
223
  };
205
224
  }
206
- const oe = "http://www.w3.org/2001/XInclude", z = 64;
207
- async function Ie(e, n, t) {
208
- return e.includes("include") ? (await se(e, n, t)).content : e;
225
+ function Et(e) {
226
+ return e === "slides" || e === "scroll";
209
227
  }
210
- async function se(e, n, t) {
211
- const r = x(e), i = {
212
- projectDir: f(t),
213
- stack: [f(n)]
214
- }, o = await v(
228
+ const oe = 960, se = 700, Pe = 1, Ce = 0.04;
229
+ function je(e) {
230
+ const n = typeof e == "number" && isFinite(e) ? e : Pe, t = Math.min(1, Math.max(0.25, n));
231
+ return {
232
+ width: Math.round(oe / t),
233
+ height: Math.round(se / t)
234
+ };
235
+ }
236
+ function Fe(e) {
237
+ return {
238
+ view: "scroll",
239
+ scrollLayout: "compact",
240
+ scrollSnap: !1,
241
+ scrollProgress: !0,
242
+ fragments: !1,
243
+ controls: !1,
244
+ controlsTutorial: !1,
245
+ hash: !1,
246
+ ...je(e.zoom),
247
+ margin: Ce
248
+ };
249
+ }
250
+ function We() {
251
+ return {
252
+ // Explicitly null rather than absent: the same page may have been
253
+ // delivered in scroll view a moment ago, and an embedder that re-injects
254
+ // over already-injected HTML would otherwise leave the old value standing.
255
+ view: null,
256
+ // See scrollViewConfig; the webview objection to hash applies either way.
257
+ hash: !1,
258
+ // The nominal size matters just as much here: a deck previewed at pane
259
+ // size with a percentage width renders its text far larger, relative to
260
+ // the slide, than the same deck will on a projector. No zoom margin
261
+ // though — presenting means filling whatever it is shown in.
262
+ width: oe,
263
+ height: se
264
+ };
265
+ }
266
+ const Be = [
267
+ "<style>",
268
+ ".reveal-viewport.reveal-scroll .scroll-page section {",
269
+ " box-shadow: inset 0 0 0 calc(1px / var(--slide-scale, 1))",
270
+ " rgba(128, 128, 128, 0.5);",
271
+ "}",
272
+ "</style>"
273
+ ].join(`
274
+ `), Oe = [
275
+ " var paused = document.querySelectorAll('.reveal .fragment');",
276
+ " for (var i = 0; i < paused.length; i++) {",
277
+ " paused[i].classList.remove('fragment');",
278
+ " }"
279
+ ];
280
+ function Xe(e, n = {}) {
281
+ const t = e === "scroll" ? Fe(n) : We();
282
+ return [
283
+ "<script>",
284
+ "(function () {",
285
+ " var OVERRIDES = " + JSON.stringify(t) + ";",
286
+ // Nothing to wrap if reveal.js failed to load (offline, CDN blocked). The
287
+ // deck is broken either way, but throwing here would replace the browser's
288
+ // useful network error with a confusing one from an injected script.
289
+ " if (typeof Reveal === 'undefined' || !Reveal.initialize) { return; }",
290
+ // Guard against double-wrapping: an embedder may inject into HTML that was
291
+ // already injected into, and wrapping a wrapper would still work but grows
292
+ // a chain on every redelivery.
293
+ " if (Reveal.__ptxViewWrapped) {",
294
+ " Reveal.__ptxViewOverrides = OVERRIDES;",
295
+ " return;",
296
+ " }",
297
+ " Reveal.__ptxViewWrapped = true;",
298
+ " Reveal.__ptxViewOverrides = OVERRIDES;",
299
+ " var initialize = Reveal.initialize.bind(Reveal);",
300
+ " Reveal.initialize = function (config) {",
301
+ " var merged = {};",
302
+ " var key;",
303
+ " for (key in config || {}) { merged[key] = config[key]; }",
304
+ " var o = Reveal.__ptxViewOverrides;",
305
+ " for (key in o) { merged[key] = o[key]; }",
306
+ // Inside the wrapper rather than at top level: this script sits in <head>,
307
+ // where the slides have not been parsed yet, but the deck calls initialize
308
+ // from the end of the document, by which time they have.
309
+ ...e === "scroll" ? Oe : [],
310
+ " return initialize(merged);",
311
+ " };",
312
+ "})();",
313
+ "<\/script>"
314
+ ].join(`
315
+ `);
316
+ }
317
+ const He = /<script\b[^>]*\bsrc=["'][^"']*\breveal\.js["'][^>]*>\s*<\/script>/i, Ue = "<!--ptx-reveal-view-->", Ve = "<!--/ptx-reveal-view-->", Ne = /\n?<!--ptx-reveal-view-->[\s\S]*?<!--\/ptx-reveal-view-->/;
318
+ function ze(e, n, t = {}) {
319
+ const r = Ne.exec(e), i = r ? e.slice(0, r.index) + e.slice(r.index + r[0].length) : e, o = He.exec(i);
320
+ if (!o)
321
+ return i;
322
+ const s = o.index + o[0].length, a = `
323
+ ${Ue}
324
+ ${Be}
325
+ ${Xe(n, t)}
326
+ ${Ve}`;
327
+ return i.slice(0, s) + a + i.slice(s);
328
+ }
329
+ const ae = "http://www.w3.org/2001/XInclude", N = 64;
330
+ async function Je(e, n, t) {
331
+ return e.includes("include") ? (await ce(e, n, t)).content : e;
332
+ }
333
+ async function ce(e, n, t) {
334
+ const r = E(e), i = {
335
+ projectDir: h(t),
336
+ stack: [h(n)]
337
+ }, o = await y(
215
338
  r,
216
- y(f(n)),
339
+ b(h(n)),
217
340
  { "": "" },
218
341
  i
219
342
  );
220
- return { tree: r, content: o ? T(r) : e };
343
+ return { tree: r, content: o ? S(r) : e };
221
344
  }
222
- function Ae(e) {
345
+ function Ge(e) {
223
346
  return e.data?.ptxIncludedFile;
224
347
  }
225
- function _e(e, n) {
348
+ function Ye(e, n) {
226
349
  const t = e.data ?? (e.data = {});
227
350
  t.ptxIncludedFile = n;
228
351
  }
229
- function M(e, n) {
352
+ function _(e, n) {
230
353
  let t = e;
231
354
  for (const [r, i] of Object.entries(n.attributes))
232
355
  (r === "xmlns" || r.startsWith("xmlns:")) && (t === e && (t = { ...e }), t[r === "xmlns" ? "" : r.slice(6)] = i ?? "");
233
356
  return t;
234
357
  }
235
- function ae(e, n) {
358
+ function le(e, n) {
236
359
  const t = e.name.indexOf(":"), r = t === -1 ? "" : e.name.slice(0, t);
237
- return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && n[r] === oe;
360
+ return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && n[r] === ae;
238
361
  }
239
- async function v(e, n, t, r) {
362
+ async function y(e, n, t, r) {
240
363
  let i = !1;
241
364
  for (let o = 0; o < e.children.length; o++) {
242
365
  const s = e.children[o];
243
366
  if (s.type !== "element")
244
367
  continue;
245
- const a = M(t, s);
246
- if (ae(s, a)) {
247
- const u = await ce(
368
+ const a = _(t, s);
369
+ if (le(s, a)) {
370
+ const u = await ue(
248
371
  s,
249
372
  n,
250
373
  a,
251
374
  r
252
375
  );
253
376
  e.children.splice(o, 1, ...u), o += u.length - 1, i = !0;
254
- } else await v(s, n, a, r) && (i = !0);
377
+ } else await y(s, n, a, r) && (i = !0);
255
378
  }
256
379
  return i;
257
380
  }
258
- async function ce(e, n, t, r) {
381
+ async function ue(e, n, t, r) {
259
382
  const i = r.stack[r.stack.length - 1];
260
383
  if (e.attributes.xpointer)
261
384
  throw new Error(
@@ -269,8 +392,8 @@ async function ce(e, n, t, r) {
269
392
  s = decodeURIComponent(o);
270
393
  } catch {
271
394
  }
272
- const a = f(n, s);
273
- if (a !== r.projectDir && !a.startsWith(r.projectDir + _))
395
+ const a = h(n, s);
396
+ if (a !== r.projectDir && !a.startsWith(r.projectDir + D))
274
397
  throw new Error(
275
398
  `xi:include escapes the project directory: ${o} (in ${i})`
276
399
  );
@@ -278,69 +401,69 @@ async function ce(e, n, t, r) {
278
401
  throw new Error(
279
402
  `Circular xi:include: ${[...r.stack, a].join(" -> ")}`
280
403
  );
281
- if (r.stack.length >= z)
282
- throw new Error(`xi:include nesting exceeds ${z} levels`);
283
- const u = await R(a);
404
+ if (r.stack.length >= N)
405
+ throw new Error(`xi:include nesting exceeds ${N} levels`);
406
+ const u = await P(a);
284
407
  if (u === void 0) {
285
- const d = Le(e, t);
286
- if (d)
287
- return await v(d, n, t, r), d.children;
408
+ const f = qe(e, t);
409
+ if (f)
410
+ return await y(f, n, t, r), f.children;
288
411
  throw new Error(`xi:include target not found: ${o} (in ${i})`);
289
412
  }
290
413
  if (e.attributes.parse === "text")
291
414
  return [{ type: "text", value: u }];
292
415
  let c;
293
416
  try {
294
- c = x(u);
295
- } catch (d) {
417
+ c = E(u);
418
+ } catch (f) {
296
419
  throw new Error(
297
- `Could not parse xi:include target ${a} as XML: ${d instanceof Error ? d.message : d}. (Included files must be well-formed, with a single root element.)`
420
+ `Could not parse xi:include target ${a} as XML: ${f instanceof Error ? f.message : f}. (Included files must be well-formed, with a single root element.)`
298
421
  );
299
422
  }
300
423
  r.stack.push(a);
301
424
  try {
302
- await v(c, y(a), { "": "" }, r);
425
+ await y(c, b(a), { "": "" }, r);
303
426
  } finally {
304
427
  r.stack.pop();
305
428
  }
306
- const h = c.children.filter(
307
- (d) => d.type === "element"
429
+ const d = c.children.filter(
430
+ (f) => f.type === "element"
308
431
  );
309
- for (const d of h)
310
- _e(d, a);
311
- return h;
432
+ for (const f of d)
433
+ Ye(f, a);
434
+ return d;
312
435
  }
313
- function J(e) {
436
+ function z(e) {
314
437
  return e.name === "docinfo";
315
438
  }
316
- async function Pe(e, n, t) {
439
+ async function Ke(e, n, t) {
317
440
  try {
318
- const i = x(e).children.find(
441
+ const i = E(e).children.find(
319
442
  (c) => c.type === "element"
320
443
  );
321
444
  if (!i)
322
445
  return;
323
- const o = f(n), s = y(o), a = {
324
- projectDir: f(t),
446
+ const o = h(n), s = b(o), a = {
447
+ projectDir: h(t),
325
448
  stack: [o]
326
- }, u = M({ "": "" }, i);
449
+ }, u = _({ "": "" }, i);
327
450
  for (const c of i.children) {
328
451
  if (c.type !== "element")
329
452
  continue;
330
- const h = M(u, c);
331
- if (J(c))
332
- return await v(c, s, h, a), T(c);
333
- if (ae(c, h)) {
334
- const g = (await ce(
453
+ const d = _(u, c);
454
+ if (z(c))
455
+ return await y(c, s, d, a), S(c);
456
+ if (le(c, d)) {
457
+ const p = (await ue(
335
458
  c,
336
459
  s,
337
- h,
460
+ d,
338
461
  a
339
462
  )).find(
340
- (m) => m.type === "element" && J(m)
463
+ (m) => m.type === "element" && z(m)
341
464
  );
342
- if (g)
343
- return T(g);
465
+ if (p)
466
+ return S(p);
344
467
  continue;
345
468
  }
346
469
  break;
@@ -350,37 +473,37 @@ async function Pe(e, n, t) {
350
473
  return;
351
474
  }
352
475
  }
353
- function Le(e, n) {
476
+ function qe(e, n) {
354
477
  for (const t of e.children) {
355
478
  if (t.type !== "element")
356
479
  continue;
357
- const r = M(n, t), i = t.name.indexOf(":"), o = i === -1 ? "" : t.name.slice(0, i);
358
- if ((i === -1 ? t.name : t.name.slice(i + 1)) === "fallback" && r[o] === oe)
480
+ const r = _(n, t), i = t.name.indexOf(":"), o = i === -1 ? "" : t.name.slice(0, i);
481
+ if ((i === -1 ? t.name : t.name.slice(i + 1)) === "fallback" && r[o] === ae)
359
482
  return t;
360
483
  }
361
484
  }
362
- function le(e) {
485
+ function de(e) {
363
486
  return typeof e == "object" && e !== null && e.type === "element";
364
487
  }
365
- function Fe(e) {
488
+ function Ze(e) {
366
489
  return /^(pf|xhtml):/.test(e.name);
367
490
  }
368
- function Re(e, n, t) {
369
- const r = [], i = e.children.find(le);
491
+ function Qe(e, n, t) {
492
+ const r = [], i = e.children.find(de);
370
493
  if (i) {
371
494
  const o = t?.parentId ?? "root";
372
- ue(i, o, t?.position ?? 1, n, o, r);
495
+ fe(i, o, t?.position ?? 1, n, o, r);
373
496
  }
374
497
  return r;
375
498
  }
376
- function ue(e, n, t, r, i, o) {
377
- const s = Ae(e) ?? r;
499
+ function fe(e, n, t, r, i, o) {
500
+ const s = Ge(e) ?? r;
378
501
  let a, u;
379
- if (Fe(e))
502
+ if (Ze(e))
380
503
  u = "root";
381
504
  else {
382
- const h = e.attributes.label ?? e.attributes["xml:id"];
383
- a = h ?? `${n}-${t}`, o.push({
505
+ const d = e.attributes.label ?? e.attributes["xml:id"];
506
+ a = d ?? `${n}-${t}`, o.push({
384
507
  id: a,
385
508
  file: s,
386
509
  line: e.position?.start.line ?? 1,
@@ -390,9 +513,9 @@ function ue(e, n, t, r, i, o) {
390
513
  }), u = a;
391
514
  }
392
515
  let c = 0;
393
- for (const h of e.children)
394
- le(h) && (c += 1, ue(
395
- h,
516
+ for (const d of e.children)
517
+ de(d) && (c += 1, fe(
518
+ d,
396
519
  u,
397
520
  c,
398
521
  s,
@@ -400,24 +523,28 @@ function ue(e, n, t, r, i, o) {
400
523
  o
401
524
  ));
402
525
  }
403
- function Ze(e, n) {
526
+ function xt(e, n) {
404
527
  let t;
405
528
  for (const r of e)
406
529
  r.line <= n && (t = r);
407
530
  return t ?? e[0];
408
531
  }
409
- const de = "pretext-html:set-theme";
410
532
  function et(e) {
533
+ const n = e.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, " ");
534
+ return /<\s*slide(?:show)?[\s/>]/.test(n) ? "slides" : "html";
535
+ }
536
+ const he = "pretext-html:set-theme";
537
+ function Tt(e) {
411
538
  return e === "dark" || e === "light" || e === "system";
412
539
  }
413
- function tt(e) {
414
- return { type: de, theme: e };
540
+ function St(e) {
541
+ return { type: he, theme: e };
415
542
  }
416
- function je(e) {
543
+ function tt(e) {
417
544
  return [
418
545
  "<script>",
419
546
  "(function () {",
420
- " var CFG = " + JSON.stringify({ msg: de, initial: e }) + ";",
547
+ " var CFG = " + JSON.stringify({ msg: he, initial: e }) + ";",
421
548
  // Where the last requested theme is remembered so it survives an in-place
422
549
  // document rewrite (same Window) and outranks the baked initial value.
423
550
  " var KEY = '__ptxPreviewTheme';",
@@ -487,86 +614,93 @@ function je(e) {
487
614
  ].join(`
488
615
  `);
489
616
  }
490
- function We(e, n) {
491
- const t = je(n);
617
+ function nt(e, n) {
618
+ const t = tt(n);
492
619
  return /<head[^>]*>/i.test(e) ? e.replace(/<head([^>]*)>/i, `<head$1>
493
620
  ${t}`) : e;
494
621
  }
495
- function Be() {
496
- return Z($(), "xsl");
622
+ function rt() {
623
+ return Q($(), "xsl");
497
624
  }
498
- function Ce() {
625
+ function it() {
499
626
  return "Suspending" in WebAssembly;
500
627
  }
501
- function Xe() {
502
- if (!Ce())
628
+ function ot() {
629
+ if (!it())
503
630
  throw new Error(
504
631
  "WebAssembly JSPI is not enabled. Run Node with --experimental-wasm-jspi (or use the pretext-html CLI, which re-launches itself with the flag)."
505
632
  );
506
633
  }
507
- function Y(e) {
634
+ function J(e) {
508
635
  return e.includes("'") ? e.includes('"') ? `concat(${e.split("'").map((t) => `'${t}'`).join(`, "'", `)})` : `"${e}"` : `'${e}'`;
509
636
  }
510
- function Ue(e) {
637
+ function st(e) {
511
638
  return e.replace(
512
639
  /from '\.\/(https:\/\/[^']+)'/g,
513
640
  (n, t) => `from '${t}'`
514
641
  );
515
642
  }
516
- function He(e) {
643
+ const at = "https://cdn.jsdelivr.net/gh/PreTeXtBook/html-static@latest/dist/";
644
+ function ct(e) {
645
+ return e.replace(
646
+ /(<link\b[^>]*\bhref=["'])_static\//gi,
647
+ `$1${at}_static/`
648
+ );
649
+ }
650
+ function lt(e) {
517
651
  return e.slice(0, 65536).replace(/<\?[\s\S]*?\?>/g, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<!DOCTYPE[^>]*>/gi, " ").match(/<\s*([A-Za-z][\w:-]*)/)?.[1];
518
652
  }
519
653
  async function G(e) {
520
- const n = await R(e);
654
+ const n = await P(e);
521
655
  if (n === void 0)
522
656
  throw new Error(
523
657
  `Could not read ${e}. (In the browser build only absolute URLs are readable — pass sourceContent instead of relying on sourcePath.)`
524
658
  );
525
659
  return n;
526
660
  }
527
- async function Oe(e, n) {
528
- const t = f(e), r = await R(t);
661
+ async function ut(e, n) {
662
+ const t = h(e), r = await P(t);
529
663
  if (r !== void 0)
530
- return Pe(r, t, n);
664
+ return Ke(r, t, n);
531
665
  }
532
- function Ne(e, n, t) {
533
- const r = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), i = n === "chapter" || n === "part" ? "book" : "article";
666
+ function dt(e, n, t, r) {
667
+ const i = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), o = t === "slides" ? "slideshow" : n === "chapter" || n === "part" ? "book" : "article";
534
668
  return `<pretext>
535
- ${t?.trim() ? `${t.trim()}
536
- ` : ""}<${i}>
669
+ ${r?.trim() ? `${r.trim()}
670
+ ` : ""}<${o}>
537
671
  <title/>
538
- ${r}
539
- </${i}>
672
+ ${i}
673
+ </${o}>
540
674
  </pretext>
541
675
  `;
542
676
  }
543
- let fe = !1;
544
- function ze(e) {
677
+ let pe = !1;
678
+ function ft(e) {
545
679
  return e instanceof Error && /\bAborted\(/.test(e.message);
546
680
  }
547
- function Je(e) {
681
+ function ht(e) {
548
682
  return e instanceof Error && /memory access|out of bounds/i.test(e.message);
549
683
  }
550
- function Ye() {
551
- if (fe)
684
+ function pt() {
685
+ if (pe)
552
686
  throw new Error(
553
687
  "The WebAssembly renderer aborted earlier in this process and cannot be reused. Restart the process (or reload the page) to render again."
554
688
  );
555
689
  }
556
- function K(e) {
557
- if (ze(e))
558
- throw fe = !0, new Error(
690
+ function Y(e) {
691
+ if (ft(e))
692
+ throw pe = !0, new Error(
559
693
  "The WebAssembly renderer aborted and cannot be reused. Restart the process (or reload the page) to render again.",
560
694
  { cause: e }
561
695
  );
562
- if (Je(e))
696
+ if (ht(e))
563
697
  throw new Error(
564
698
  "The WebAssembly renderer hit a memory fault. Most often the document is too large for this build's stack — whole-book builds are a known limitation, so try a smaller document, or see the README about rebuilding libxslt-wasm with a larger stack. The same fault also results from running two renders concurrently against the shared libxslt state.",
565
699
  { cause: e }
566
700
  );
567
701
  }
568
702
  let I;
569
- async function he() {
703
+ async function me() {
570
704
  return I || (I = (async () => {
571
705
  const [e, n] = await Promise.all([
572
706
  import("@pretextbook/libxslt-wasm"),
@@ -575,136 +709,148 @@ async function he() {
575
709
  return n.registerAll(), e;
576
710
  })()), I;
577
711
  }
578
- const A = /* @__PURE__ */ new Map();
579
- async function Ge(e) {
580
- const n = e;
581
- let t = A.get(n);
582
- return t || (t = (async () => {
583
- const { XmlDocument: r, XsltStylesheet: i } = await he(), o = ie(n), s = await ee(
584
- $(),
585
- "/preview-html.xsl"
586
- );
587
- if (s === void 0)
712
+ const M = /* @__PURE__ */ new Map(), mt = {
713
+ html: "preview-html.xsl",
714
+ slides: "preview-revealjs.xsl"
715
+ };
716
+ async function wt(e, n) {
717
+ const t = mt[n], r = `${n}\0${e}`;
718
+ let i = M.get(r);
719
+ return i || (i = (async () => {
720
+ const { XmlDocument: o, XsltStylesheet: s } = await me(), a = ie(e), u = await ee($(), `/${t}`);
721
+ if (u === void 0)
588
722
  throw new Error(
589
- `Could not read preview-html.xsl from ${$()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
723
+ `Could not read ${t} from ${$()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
590
724
  );
591
- const a = new TextDecoder().decode(s), u = await r.fromString(a, {
592
- url: `${o}/preview-html.xsl`,
725
+ const c = new TextDecoder().decode(u), d = await o.fromString(c, {
726
+ url: `${a}/${t}`,
593
727
  options: { noEnt: !0, dtdLoad: !0, huge: !0 }
594
728
  });
595
- return i.fromXmlDocument(u);
596
- })(), A.set(n, t), t.catch(() => A.delete(n))), t;
597
- }
598
- let q = Promise.resolve();
599
- function nt(e) {
600
- const n = q.then(
601
- () => V(e),
602
- () => V(e)
729
+ return s.fromXmlDocument(d);
730
+ })(), M.set(r, i), i.catch(() => M.delete(r))), i;
731
+ }
732
+ let K = Promise.resolve();
733
+ function $t(e) {
734
+ const n = K.then(
735
+ () => q(e),
736
+ () => q(e)
603
737
  );
604
- return q = n.catch(() => {
738
+ return K = n.catch(() => {
605
739
  }), n;
606
740
  }
607
- async function V(e) {
608
- Xe(), Ye();
609
- const { XmlDocument: n } = await he(), t = await Ge(e.xslDir ?? Be()), r = f(e.sourcePath), i = f(
610
- e.projectDir ?? y(r)
611
- ), o = e.sourceContent ?? await G(r), s = S(i, r);
612
- if (s.startsWith(".."))
741
+ async function q(e) {
742
+ ot(), pt();
743
+ const { XmlDocument: n } = await me(), t = h(e.sourcePath), r = h(
744
+ e.projectDir ?? b(t)
745
+ ), i = e.sourceContent ?? await G(t), o = k(r, t);
746
+ if (o.startsWith(".."))
613
747
  throw new Error(
614
- `sourcePath (${r}) must live inside projectDir (${i})`
748
+ `sourcePath (${t}) must live inside projectDir (${r})`
615
749
  );
616
- const a = S(
617
- i,
618
- f(e.mainSourcePath ?? r)
619
- ), u = a.startsWith("..") ? s : a, c = ie(i);
750
+ const s = k(
751
+ r,
752
+ h(e.mainSourcePath ?? t)
753
+ ), a = s.startsWith("..") ? o : s, u = ie(r);
620
754
  try {
621
- let h, d = `${c}/__pretext-preview-publication.xml`;
755
+ let c, d = `${u}/__pretext-preview-publication.xml`;
622
756
  if (e.publicationPath) {
623
- const l = f(e.publicationPath);
624
- h = await G(l);
625
- const b = S(i, l);
626
- b.startsWith("..") || (d = `${c}/${b.split(_).join("/")}`);
757
+ const l = h(e.publicationPath);
758
+ c = await G(l);
759
+ const v = k(r, l);
760
+ v.startsWith("..") || (d = `${u}/${v.split(D).join("/")}`);
627
761
  }
628
- const g = De(
629
- h,
630
- e.cssTheme
631
- );
632
- $e(d, g);
633
- const m = Se(g), W = y(f(i, u)), B = m.external !== void 0 && m.generated !== void 0 ? {
634
- external: f(W, m.external),
635
- generated: f(W, m.generated)
636
- } : void 0;
637
- let k, p;
762
+ let f, p;
638
763
  if (e.sourceMap) {
639
- const l = await se(
640
- o,
641
- r,
642
- i
764
+ const l = await ce(
765
+ i,
766
+ t,
767
+ r
643
768
  );
644
- k = l.tree, p = l.content;
769
+ f = l.tree, p = l.content;
645
770
  } else
646
- p = await Ie(
647
- o,
648
- r,
649
- i
771
+ p = await Je(
772
+ i,
773
+ t,
774
+ r
650
775
  );
651
- const E = He(p);
652
- let C = { parentId: "root", position: 1 };
653
- if (E !== "pretext" && E !== "mathbook")
776
+ const m = e.target ?? et(p), we = await wt(e.xslDir ?? rt(), m), j = Le(c, {
777
+ cssTheme: e.cssTheme,
778
+ revealTheme: e.revealTheme,
779
+ target: m
780
+ });
781
+ Re(d, j);
782
+ const x = Ae(j), F = b(h(r, a)), W = x.external !== void 0 && x.generated !== void 0 ? {
783
+ external: h(F, x.external),
784
+ generated: h(F, x.generated)
785
+ } : void 0, T = lt(p);
786
+ let B = { parentId: "root", position: 1 };
787
+ if (T !== "pretext" && T !== "mathbook")
654
788
  if (e.fragment) {
655
- const l = e.docinfo ?? (e.docinfoSourcePath ? await Oe(e.docinfoSourcePath, i) : void 0);
656
- p = Ne(p, E, l), C = { parentId: l?.trim() ? "root-1-2" : "root-1-1", position: 2 };
789
+ const l = e.docinfo ?? (e.docinfoSourcePath ? await ut(e.docinfoSourcePath, r) : void 0);
790
+ p = dt(
791
+ p,
792
+ T,
793
+ m,
794
+ l
795
+ ), B = { parentId: l?.trim() ? "root-1-2" : "root-1-1", position: 2 };
657
796
  } else
658
797
  throw new Error(
659
- `The document root is <${E ?? "?"}>, not <pretext> — this looks like an xi:included fragment. Render the project's main source file instead, or pass the fragment option.`
798
+ `The document root is <${T ?? "?"}>, not <pretext> — this looks like an xi:included fragment. Render the project's main source file instead, or pass the fragment option.`
660
799
  );
661
- const X = k ? Re(k, r, C) : void 0, U = await n.fromString(p, {
662
- url: `${c}/${u.split(_).join("/")}`,
800
+ const O = f ? Qe(f, t, B) : void 0, X = await n.fromString(p, {
801
+ url: `${u}/${a.split(D).join("/")}`,
663
802
  options: { noEnt: !0, dtdLoad: !0, huge: !0 }
664
803
  }), H = {
665
- publisher: Y(d)
804
+ publisher: J(d)
666
805
  };
667
- for (const [l, b] of Object.entries(e.stringParams ?? {}))
668
- H[l] = Y(b);
669
- let D;
806
+ for (const [l, v] of Object.entries(e.stringParams ?? {}))
807
+ H[l] = J(v);
808
+ let R;
670
809
  try {
671
- D = await t.apply(U, H);
810
+ R = await we.apply(X, H);
672
811
  } catch (l) {
673
- throw K(l), new Error(
812
+ throw Y(l), new Error(
674
813
  "PreTeXt XSLT transform failed; see the PTX:ERROR/PTX:FATAL messages on stderr for details.",
675
814
  { cause: l }
676
815
  );
677
816
  } finally {
678
- U.delete();
817
+ X.delete();
679
818
  }
680
819
  try {
681
- let l = Ue(D.toHtmlString());
682
- return e.theme && (l = We(l, e.theme)), {
820
+ let l = st(R.toHtmlString());
821
+ return m === "slides" ? (l = ct(l), l = ze(l, e.revealView ?? "scroll", {
822
+ zoom: e.revealZoom
823
+ })) : e.theme && (l = nt(l, e.theme)), {
683
824
  html: l,
684
- ...X ? { sourceMap: X } : {},
685
- ...B ? { assetDirs: B } : {}
825
+ target: m,
826
+ ...O ? { sourceMap: O } : {},
827
+ ...W ? { assetDirs: W } : {}
686
828
  };
687
829
  } catch (l) {
688
- throw K(l), l;
830
+ throw Y(l), l;
689
831
  } finally {
690
- D.delete();
832
+ R.delete();
691
833
  }
692
834
  } finally {
693
- Te(c);
835
+ _e(u);
694
836
  }
695
837
  }
696
838
  export {
697
- de as PREVIEW_THEME_MESSAGE,
698
- Be as defaultXslDir,
699
- Ze as findSourceMapEntry,
700
- De as forcePortablePublication,
701
- We as injectThemeBridge,
702
- Ce as isJspiAvailable,
703
- et as isPreviewTheme,
704
- tt as previewThemeMessage,
705
- nt as renderHtml,
706
- Ve as setAssetsBase,
707
- Qe as setMountReader,
708
- je as themeBridgeScript,
709
- Y as xpathStringLiteral
839
+ he as PREVIEW_THEME_MESSAGE,
840
+ rt as defaultXslDir,
841
+ et as detectRenderTarget,
842
+ xt as findSourceMapEntry,
843
+ Le as forcePortablePublication,
844
+ ze as injectRevealBridge,
845
+ nt as injectThemeBridge,
846
+ it as isJspiAvailable,
847
+ Tt as isPreviewTheme,
848
+ Et as isRevealView,
849
+ St as previewThemeMessage,
850
+ $t as renderHtml,
851
+ Xe as revealBridgeScript,
852
+ bt as setAssetsBase,
853
+ yt as setMountReader,
854
+ tt as themeBridgeScript,
855
+ J as xpathStringLiteral
710
856
  };