@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
@@ -0,0 +1,694 @@
1
+ import { readFile as A, writeFile as O } from "node:fs/promises";
2
+ import * as b from "node:process";
3
+ import * as l from "node:path";
4
+ import { fileURLToPath as he } from "node:url";
5
+ import { fromXml as x } from "xast-util-from-xml";
6
+ import { toXml as $ } from "xast-util-to-xml";
7
+ import { injectRevealBridge as me } from "./reveal.js";
8
+ import { injectThemeBridge as pe } from "./theme.js";
9
+ async function Q(e, r) {
10
+ const t = l.resolve(e), n = l.resolve(t, `.${l.posix.normalize(r)}`);
11
+ if (n !== t && !n.startsWith(t + l.sep)) {
12
+ console.error(
13
+ `pretext-html: refusing to serve ${r} from outside ${t}`
14
+ );
15
+ return;
16
+ }
17
+ try {
18
+ return new Uint8Array(await A(n));
19
+ } catch {
20
+ return;
21
+ }
22
+ }
23
+ async function j(e) {
24
+ try {
25
+ return await A(e, "utf8");
26
+ } catch {
27
+ return;
28
+ }
29
+ }
30
+ let K;
31
+ function st(e) {
32
+ K = e;
33
+ }
34
+ function I() {
35
+ return K ?? process.env.PRETEXT_HTML_ASSETS ?? l.resolve(l.dirname(he(import.meta.url)), "..", "assets");
36
+ }
37
+ function we(e, r) {
38
+ return l.join(e, r);
39
+ }
40
+ const X = /* @__PURE__ */ new Map(), ee = /* @__PURE__ */ new Map();
41
+ let M, be = 0, te = Q;
42
+ function it(e) {
43
+ te = e;
44
+ }
45
+ function ge(e, r) {
46
+ const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, n = ee.get(t);
47
+ if (n !== void 0)
48
+ return Promise.resolve(new Response(n, { status: 200 }));
49
+ let o;
50
+ try {
51
+ o = new URL(t).host;
52
+ } catch {
53
+ o = "";
54
+ }
55
+ const s = X.get(o);
56
+ return s !== void 0 ? ye(s, t) : M(e, r);
57
+ }
58
+ const ve = '<?xml version="1.0"?><pretext-preview-missing-file/>';
59
+ async function ye(e, r) {
60
+ const t = decodeURIComponent(new URL(r).pathname), n = await te(e, t);
61
+ if (n === void 0)
62
+ return new Response(ve, { status: 200 });
63
+ const o = typeof n == "string" ? n : new Uint8Array(n);
64
+ return new Response(o, { status: 200 });
65
+ }
66
+ function re() {
67
+ M || (M = globalThis.fetch, globalThis.fetch = ge);
68
+ }
69
+ function ne(e) {
70
+ re();
71
+ const r = `mnt${++be}.ptx.invalid`;
72
+ return X.set(r, e), `http://${r}`;
73
+ }
74
+ function xe(e) {
75
+ X.delete(new URL(e).host);
76
+ }
77
+ function Te(e, r) {
78
+ re(), ee.set(e, r);
79
+ }
80
+ const R = `<?xml version="1.0" encoding="UTF-8"?>
81
+ <publication>
82
+ <source>
83
+ <directories external="../assets" generated="../generated-assets" />
84
+ </source>
85
+ <html>
86
+ <platform portable="yes"/>
87
+ </html>
88
+ </publication>
89
+ `, Ee = ["theme", "style", "shell"];
90
+ function w(e, r) {
91
+ for (const t of e.children)
92
+ if (t.type === "element" && t.name === r)
93
+ return t;
94
+ }
95
+ function g(e, r) {
96
+ let t = w(e, r);
97
+ return t || (t = { type: "element", name: r, attributes: {}, children: [] }, e.children.push(t)), t;
98
+ }
99
+ function $e(e, r) {
100
+ const t = w(e, "css");
101
+ if (t && Ee.some((o) => t.attributes?.[o]))
102
+ return;
103
+ const n = t ?? g(e, "css");
104
+ n.attributes = { ...n.attributes, theme: r };
105
+ }
106
+ function Se(e, r) {
107
+ const t = w(e, "appearance");
108
+ if (t?.attributes?.theme)
109
+ return;
110
+ const n = t ?? g(e, "appearance");
111
+ n.attributes = { ...n.attributes, theme: r };
112
+ }
113
+ function Pe(e) {
114
+ const r = g(e, "resources");
115
+ r.attributes = {
116
+ ...r.attributes,
117
+ host: "cdn",
118
+ math: "online"
119
+ };
120
+ }
121
+ function ke(e, r = {}) {
122
+ const t = r.cssTheme?.trim(), n = r.revealTheme?.trim(), o = r.target === "slides";
123
+ if (!e && !t && !o)
124
+ return R;
125
+ const s = x(e ?? R), a = w(s, "publication");
126
+ if (!a)
127
+ throw new Error(
128
+ "Invalid publication file: no root <publication> element found"
129
+ );
130
+ const i = g(a, "html"), u = g(i, "platform");
131
+ if (u.attributes = { ...u.attributes, portable: "yes" }, t && $e(i, t), o) {
132
+ const c = g(a, "revealjs");
133
+ Pe(c), n && Se(c, n);
134
+ }
135
+ return $(s);
136
+ }
137
+ function H(e) {
138
+ if (!(e === void 0 || e === "" || e.startsWith("/")))
139
+ return e.endsWith("/") ? e : `${e}/`;
140
+ }
141
+ function De(e) {
142
+ const r = x(e ?? R), t = w(r, "publication"), n = t && w(t, "source"), o = n && w(n, "directories"), s = H(
143
+ o?.attributes?.external ?? void 0
144
+ ), a = H(
145
+ o?.attributes?.generated ?? void 0
146
+ );
147
+ return {
148
+ external: s,
149
+ generated: a,
150
+ managed: s !== void 0 && a !== void 0
151
+ };
152
+ }
153
+ const oe = "http://www.w3.org/2001/XInclude", N = 64;
154
+ async function Ie(e, r, t) {
155
+ return e.includes("include") ? (await se(e, r, t)).content : e;
156
+ }
157
+ async function se(e, r, t) {
158
+ const n = x(e), o = {
159
+ projectDir: l.resolve(t),
160
+ stack: [l.resolve(r)]
161
+ }, s = await y(
162
+ n,
163
+ l.dirname(l.resolve(r)),
164
+ { "": "" },
165
+ o
166
+ );
167
+ return { tree: n, content: s ? $(n) : e };
168
+ }
169
+ function Me(e) {
170
+ return e.data?.ptxIncludedFile;
171
+ }
172
+ function Re(e, r) {
173
+ const t = e.data ?? (e.data = {});
174
+ t.ptxIncludedFile = r;
175
+ }
176
+ function S(e, r) {
177
+ let t = e;
178
+ for (const [n, o] of Object.entries(r.attributes))
179
+ (n === "xmlns" || n.startsWith("xmlns:")) && (t === e && (t = { ...e }), t[n === "xmlns" ? "" : n.slice(6)] = o ?? "");
180
+ return t;
181
+ }
182
+ function ie(e, r) {
183
+ const t = e.name.indexOf(":"), n = t === -1 ? "" : e.name.slice(0, t);
184
+ return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && r[n] === oe;
185
+ }
186
+ async function y(e, r, t, n) {
187
+ let o = !1;
188
+ for (let s = 0; s < e.children.length; s++) {
189
+ const a = e.children[s];
190
+ if (a.type !== "element")
191
+ continue;
192
+ const i = S(t, a);
193
+ if (ie(a, i)) {
194
+ const u = await ae(
195
+ a,
196
+ r,
197
+ i,
198
+ n
199
+ );
200
+ e.children.splice(s, 1, ...u), s += u.length - 1, o = !0;
201
+ } else await y(a, r, i, n) && (o = !0);
202
+ }
203
+ return o;
204
+ }
205
+ async function ae(e, r, t, n) {
206
+ const o = n.stack[n.stack.length - 1];
207
+ if (e.attributes.xpointer)
208
+ throw new Error(
209
+ `xi:include with xpointer is not supported by the JS preview build (in ${o})`
210
+ );
211
+ const s = e.attributes.href;
212
+ if (!s)
213
+ throw new Error(`xi:include without href (in ${o})`);
214
+ let a = s;
215
+ try {
216
+ a = decodeURIComponent(s);
217
+ } catch {
218
+ }
219
+ const i = l.resolve(r, a);
220
+ if (i !== n.projectDir && !i.startsWith(n.projectDir + l.sep))
221
+ throw new Error(
222
+ `xi:include escapes the project directory: ${s} (in ${o})`
223
+ );
224
+ if (n.stack.includes(i))
225
+ throw new Error(
226
+ `Circular xi:include: ${[...n.stack, i].join(" -> ")}`
227
+ );
228
+ if (n.stack.length >= N)
229
+ throw new Error(`xi:include nesting exceeds ${N} levels`);
230
+ const u = await j(i);
231
+ if (u === void 0) {
232
+ const h = je(e, t);
233
+ if (h)
234
+ return await y(h, r, t, n), h.children;
235
+ throw new Error(`xi:include target not found: ${s} (in ${o})`);
236
+ }
237
+ if (e.attributes.parse === "text")
238
+ return [{ type: "text", value: u }];
239
+ let c;
240
+ try {
241
+ c = x(u);
242
+ } catch (h) {
243
+ throw new Error(
244
+ `Could not parse xi:include target ${i} as XML: ${h instanceof Error ? h.message : h}. (Included files must be well-formed, with a single root element.)`
245
+ );
246
+ }
247
+ n.stack.push(i);
248
+ try {
249
+ await y(c, l.dirname(i), { "": "" }, n);
250
+ } finally {
251
+ n.stack.pop();
252
+ }
253
+ const f = c.children.filter(
254
+ (h) => h.type === "element"
255
+ );
256
+ for (const h of f)
257
+ Re(h, i);
258
+ return f;
259
+ }
260
+ function J(e) {
261
+ return e.name === "docinfo";
262
+ }
263
+ async function Ae(e, r, t) {
264
+ try {
265
+ const o = x(e).children.find(
266
+ (c) => c.type === "element"
267
+ );
268
+ if (!o)
269
+ return;
270
+ const s = l.resolve(r), a = l.dirname(s), i = {
271
+ projectDir: l.resolve(t),
272
+ stack: [s]
273
+ }, u = S({ "": "" }, o);
274
+ for (const c of o.children) {
275
+ if (c.type !== "element")
276
+ continue;
277
+ const f = S(u, c);
278
+ if (J(c))
279
+ return await y(c, a, f, i), $(c);
280
+ if (ie(c, f)) {
281
+ const m = (await ae(
282
+ c,
283
+ a,
284
+ f,
285
+ i
286
+ )).find(
287
+ (p) => p.type === "element" && J(p)
288
+ );
289
+ if (m)
290
+ return $(m);
291
+ continue;
292
+ }
293
+ break;
294
+ }
295
+ return;
296
+ } catch {
297
+ return;
298
+ }
299
+ }
300
+ function je(e, r) {
301
+ for (const t of e.children) {
302
+ if (t.type !== "element")
303
+ continue;
304
+ const n = S(r, t), o = t.name.indexOf(":"), s = o === -1 ? "" : t.name.slice(0, o);
305
+ if ((o === -1 ? t.name : t.name.slice(o + 1)) === "fallback" && n[s] === oe)
306
+ return t;
307
+ }
308
+ }
309
+ function ce(e) {
310
+ return typeof e == "object" && e !== null && e.type === "element";
311
+ }
312
+ function Xe(e) {
313
+ return /^(pf|xhtml):/.test(e.name);
314
+ }
315
+ function Le(e, r, t) {
316
+ const n = [], o = e.children.find(ce);
317
+ if (o) {
318
+ const s = t?.parentId ?? "root";
319
+ le(o, s, t?.position ?? 1, r, s, n);
320
+ }
321
+ return n;
322
+ }
323
+ function le(e, r, t, n, o, s) {
324
+ const a = Me(e) ?? n;
325
+ let i, u;
326
+ if (Xe(e))
327
+ u = "root";
328
+ else {
329
+ const f = e.attributes.label ?? e.attributes["xml:id"];
330
+ i = f ?? `${r}-${t}`, s.push({
331
+ id: i,
332
+ file: a,
333
+ line: e.position?.start.line ?? 1,
334
+ column: e.position?.start.column ?? 1,
335
+ endLine: e.position?.end.line ?? e.position?.start.line ?? 1,
336
+ parent: o
337
+ }), u = i;
338
+ }
339
+ let c = 0;
340
+ for (const f of e.children)
341
+ ce(f) && (c += 1, le(
342
+ f,
343
+ u,
344
+ c,
345
+ a,
346
+ i ?? o,
347
+ s
348
+ ));
349
+ }
350
+ function at(e, r) {
351
+ let t;
352
+ for (const n of e)
353
+ n.line <= r && (t = n);
354
+ return t ?? e[0];
355
+ }
356
+ function Fe(e) {
357
+ const r = e.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, " ");
358
+ return /<\s*slide(?:show)?[\s/>]/.test(r) ? "slides" : "html";
359
+ }
360
+ function Ce() {
361
+ return we(I(), "xsl");
362
+ }
363
+ function Ue() {
364
+ return "Suspending" in WebAssembly;
365
+ }
366
+ function We() {
367
+ if (!Ue())
368
+ throw new Error(
369
+ "WebAssembly JSPI is not enabled. Run Node with --experimental-wasm-jspi (or use the pretext-html CLI, which re-launches itself with the flag)."
370
+ );
371
+ }
372
+ function z(e) {
373
+ return e.includes("'") ? e.includes('"') ? `concat(${e.split("'").map((t) => `'${t}'`).join(`, "'", `)})` : `"${e}"` : `'${e}'`;
374
+ }
375
+ function Be(e) {
376
+ return e.replace(
377
+ /from '\.\/(https:\/\/[^']+)'/g,
378
+ (r, t) => `from '${t}'`
379
+ );
380
+ }
381
+ const _e = "https://cdn.jsdelivr.net/gh/PreTeXtBook/html-static@latest/dist/";
382
+ function Oe(e) {
383
+ return e.replace(
384
+ /(<link\b[^>]*\bhref=["'])_static\//gi,
385
+ `$1${_e}_static/`
386
+ );
387
+ }
388
+ function He(e) {
389
+ return e.slice(0, 65536).replace(/<\?[\s\S]*?\?>/g, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<!DOCTYPE[^>]*>/gi, " ").match(/<\s*([A-Za-z][\w:-]*)/)?.[1];
390
+ }
391
+ async function V(e) {
392
+ const r = await j(e);
393
+ if (r === void 0)
394
+ throw new Error(
395
+ `Could not read ${e}. (In the browser build only absolute URLs are readable — pass sourceContent instead of relying on sourcePath.)`
396
+ );
397
+ return r;
398
+ }
399
+ async function Ne(e, r) {
400
+ const t = l.resolve(e), n = await j(t);
401
+ if (n !== void 0)
402
+ return Ae(n, t, r);
403
+ }
404
+ function Je(e, r, t, n) {
405
+ const o = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), s = t === "slides" ? "slideshow" : r === "chapter" || r === "part" ? "book" : "article";
406
+ return `<pretext>
407
+ ${n?.trim() ? `${n.trim()}
408
+ ` : ""}<${s}>
409
+ <title/>
410
+ ${o}
411
+ </${s}>
412
+ </pretext>
413
+ `;
414
+ }
415
+ let ue = !1;
416
+ function ze(e) {
417
+ return e instanceof Error && /\bAborted\(/.test(e.message);
418
+ }
419
+ function Ve(e) {
420
+ return e instanceof Error && /memory access|out of bounds/i.test(e.message);
421
+ }
422
+ function Ye() {
423
+ if (ue)
424
+ throw new Error(
425
+ "The WebAssembly renderer aborted earlier in this process and cannot be reused. Restart the process (or reload the page) to render again."
426
+ );
427
+ }
428
+ function Y(e) {
429
+ if (ze(e))
430
+ throw ue = !0, new Error(
431
+ "The WebAssembly renderer aborted and cannot be reused. Restart the process (or reload the page) to render again.",
432
+ { cause: e }
433
+ );
434
+ if (Ve(e))
435
+ throw new Error(
436
+ "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.",
437
+ { cause: e }
438
+ );
439
+ }
440
+ let k;
441
+ async function de() {
442
+ return k || (k = (async () => {
443
+ const [e, r] = await Promise.all([
444
+ import("@pretextbook/libxslt-wasm"),
445
+ import("@pretextbook/libxslt-wasm/exslt")
446
+ ]);
447
+ return r.registerAll(), e;
448
+ })()), k;
449
+ }
450
+ const D = /* @__PURE__ */ new Map(), qe = {
451
+ html: "preview-html.xsl",
452
+ slides: "preview-revealjs.xsl"
453
+ };
454
+ async function Ge(e, r) {
455
+ const t = qe[r], n = `${r}\0${e}`;
456
+ let o = D.get(n);
457
+ return o || (o = (async () => {
458
+ const { XmlDocument: s, XsltStylesheet: a } = await de(), i = ne(e), u = await Q(I(), `/${t}`);
459
+ if (u === void 0)
460
+ throw new Error(
461
+ `Could not read ${t} from ${I()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
462
+ );
463
+ const c = new TextDecoder().decode(u), f = await s.fromString(c, {
464
+ url: `${i}/${t}`,
465
+ options: { noEnt: !0, dtdLoad: !0, huge: !0 }
466
+ });
467
+ return a.fromXmlDocument(f);
468
+ })(), D.set(n, o), o.catch(() => D.delete(n))), o;
469
+ }
470
+ let q = Promise.resolve();
471
+ function Ze(e) {
472
+ const r = q.then(
473
+ () => G(e),
474
+ () => G(e)
475
+ );
476
+ return q = r.catch(() => {
477
+ }), r;
478
+ }
479
+ async function G(e) {
480
+ We(), Ye();
481
+ const { XmlDocument: r } = await de(), t = l.resolve(e.sourcePath), n = l.resolve(
482
+ e.projectDir ?? l.dirname(t)
483
+ ), o = e.sourceContent ?? await V(t), s = l.relative(n, t);
484
+ if (s.startsWith(".."))
485
+ throw new Error(
486
+ `sourcePath (${t}) must live inside projectDir (${n})`
487
+ );
488
+ const a = l.relative(
489
+ n,
490
+ l.resolve(e.mainSourcePath ?? t)
491
+ ), i = a.startsWith("..") ? s : a, u = ne(n);
492
+ try {
493
+ let c, f = `${u}/__pretext-preview-publication.xml`;
494
+ if (e.publicationPath) {
495
+ const d = l.resolve(e.publicationPath);
496
+ c = await V(d);
497
+ const v = l.relative(n, d);
498
+ v.startsWith("..") || (f = `${u}/${v.split(l.sep).join("/")}`);
499
+ }
500
+ let h, m;
501
+ if (e.sourceMap) {
502
+ const d = await se(
503
+ o,
504
+ t,
505
+ n
506
+ );
507
+ h = d.tree, m = d.content;
508
+ } else
509
+ m = await Ie(
510
+ o,
511
+ t,
512
+ n
513
+ );
514
+ const p = e.target ?? Fe(m), fe = await Ge(e.xslDir ?? Ce(), p), L = ke(c, {
515
+ cssTheme: e.cssTheme,
516
+ revealTheme: e.revealTheme,
517
+ target: p
518
+ });
519
+ Te(f, L);
520
+ const T = De(L), F = l.dirname(l.resolve(n, i)), C = T.external !== void 0 && T.generated !== void 0 ? {
521
+ external: l.resolve(F, T.external),
522
+ generated: l.resolve(F, T.generated)
523
+ } : void 0, E = He(m);
524
+ let U = { parentId: "root", position: 1 };
525
+ if (E !== "pretext" && E !== "mathbook")
526
+ if (e.fragment) {
527
+ const d = e.docinfo ?? (e.docinfoSourcePath ? await Ne(e.docinfoSourcePath, n) : void 0);
528
+ m = Je(
529
+ m,
530
+ E,
531
+ p,
532
+ d
533
+ ), U = { parentId: d?.trim() ? "root-1-2" : "root-1-1", position: 2 };
534
+ } else
535
+ throw new Error(
536
+ `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.`
537
+ );
538
+ const W = h ? Le(h, t, U) : void 0, B = await r.fromString(m, {
539
+ url: `${u}/${i.split(l.sep).join("/")}`,
540
+ options: { noEnt: !0, dtdLoad: !0, huge: !0 }
541
+ }), _ = {
542
+ publisher: z(f)
543
+ };
544
+ for (const [d, v] of Object.entries(e.stringParams ?? {}))
545
+ _[d] = z(v);
546
+ let P;
547
+ try {
548
+ P = await fe.apply(B, _);
549
+ } catch (d) {
550
+ throw Y(d), new Error(
551
+ "PreTeXt XSLT transform failed; see the PTX:ERROR/PTX:FATAL messages on stderr for details.",
552
+ { cause: d }
553
+ );
554
+ } finally {
555
+ B.delete();
556
+ }
557
+ try {
558
+ let d = Be(P.toHtmlString());
559
+ return p === "slides" ? (d = Oe(d), d = me(d, e.revealView ?? "scroll", {
560
+ zoom: e.revealZoom
561
+ })) : e.theme && (d = pe(d, e.theme)), {
562
+ html: d,
563
+ target: p,
564
+ ...W ? { sourceMap: W } : {},
565
+ ...C ? { assetDirs: C } : {}
566
+ };
567
+ } catch (d) {
568
+ throw Y(d), d;
569
+ } finally {
570
+ P.delete();
571
+ }
572
+ } finally {
573
+ xe(u);
574
+ }
575
+ }
576
+ const Z = `Usage: pretext-html <source.ptx> [options]
577
+
578
+ Render a PreTeXt document to a single standalone HTML page (portable build:
579
+ one page, css/js/MathJax from CDN). No PreTeXt installation required.
580
+
581
+ Options:
582
+ -o, --output <file> Write HTML to a file instead of stdout
583
+ --publication <file> Publication file (portable html is forced on)
584
+ --css-theme <name> HTML theme to use when the publication file names
585
+ none of its own: default-modern (PreTeXt's default),
586
+ denver, tacoma, salem, greeley or boulder
587
+ --project-dir <dir> Directory served to the transform for xi:includes
588
+ (default: the source file's directory)
589
+ --param <name=value> Extra XSLT string parameter (repeatable)
590
+ --xsl-dir <dir> Use PreTeXt stylesheets from this directory
591
+ instead of the vendored copy
592
+ --fragment Allow a non-root source file: wrap the fragment
593
+ in a minimal <pretext> document (an <article>,
594
+ or a <book> for <chapter>/<part> fragments)
595
+ --docinfo <file> File whose contents (a <docinfo> element) are
596
+ injected into the wrapper in --fragment mode, so
597
+ the fragment keeps the project's LaTeX macros
598
+ --docinfo-source <file> Complete source file (e.g. main.ptx) to lift the
599
+ <docinfo> from for --fragment mode, resolving
600
+ xi:includes (used when --docinfo is not given)
601
+ --source-map <file> Also write a JSON source map: HTML id → source
602
+ file/line for every element (for editor sync)
603
+ -h, --help Show this help
604
+ `;
605
+ function Qe(e) {
606
+ let r, t, n, o;
607
+ const s = {}, a = {};
608
+ for (let i = 0; i < e.length; i++) {
609
+ const u = e[i], c = () => {
610
+ if (i += 1, i >= e.length)
611
+ throw new Error(`Missing value for ${u}`);
612
+ return e[i];
613
+ };
614
+ switch (u) {
615
+ case "-h":
616
+ case "--help":
617
+ b.stdout.write(Z), b.exit(0);
618
+ break;
619
+ case "-o":
620
+ case "--output":
621
+ t = c();
622
+ break;
623
+ case "--publication":
624
+ s.publicationPath = c();
625
+ break;
626
+ case "--css-theme":
627
+ s.cssTheme = c();
628
+ break;
629
+ case "--project-dir":
630
+ s.projectDir = c();
631
+ break;
632
+ case "--xsl-dir":
633
+ s.xslDir = c();
634
+ break;
635
+ case "--fragment":
636
+ s.fragment = !0;
637
+ break;
638
+ case "--docinfo":
639
+ n = c();
640
+ break;
641
+ case "--docinfo-source":
642
+ s.docinfoSourcePath = c();
643
+ break;
644
+ case "--source-map":
645
+ o = c(), s.sourceMap = !0;
646
+ break;
647
+ case "--param": {
648
+ const f = c(), h = f.indexOf("=");
649
+ if (h === -1)
650
+ throw new Error(`--param expects name=value, got: ${f}`);
651
+ a[f.slice(0, h)] = f.slice(h + 1);
652
+ break;
653
+ }
654
+ default:
655
+ if (u.startsWith("-"))
656
+ throw new Error(`Unknown option: ${u}`);
657
+ if (r)
658
+ throw new Error(`Unexpected extra argument: ${u}`);
659
+ r = u;
660
+ }
661
+ }
662
+ if (!r)
663
+ throw new Error(`No source file given.
664
+
665
+ ` + Z);
666
+ return Object.keys(a).length > 0 && (s.stringParams = a), {
667
+ options: { ...s, sourcePath: r },
668
+ output: t,
669
+ docinfoPath: n,
670
+ sourceMapPath: o
671
+ };
672
+ }
673
+ async function ct(e) {
674
+ const { options: r, output: t, docinfoPath: n, sourceMapPath: o } = Qe(e);
675
+ n && (r.docinfo = await A(n, "utf8"));
676
+ const s = Date.now(), { html: a, sourceMap: i } = await Ze(r);
677
+ b.stderr.write(`pretext-html: rendered in ${Date.now() - s}ms
678
+ `), o && i && (await O(o, JSON.stringify(i, null, 2)), b.stderr.write(`pretext-html: wrote ${o}
679
+ `)), t ? (await O(t, a), b.stderr.write(`pretext-html: wrote ${t}
680
+ `)) : b.stdout.write(a);
681
+ }
682
+ export {
683
+ Fe as a,
684
+ ke as b,
685
+ it as c,
686
+ Ce as d,
687
+ at as f,
688
+ Ue as i,
689
+ ct as m,
690
+ Qe as p,
691
+ Ze as r,
692
+ st as s,
693
+ z as x
694
+ };
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "node:fs/promises";
2
2
  import "node:process";
3
- import { m as o, p as s } from "./cli-Cp6C0sif.js";
3
+ import { m as o, p as s } from "./cli-DZsyZERX.js";
4
4
  export {
5
5
  o as main,
6
6
  s as parseArgs
@@ -22,6 +22,11 @@ export type { RenderOptions, RenderResult } from './renderer.js';
22
22
  export { findSourceMapEntry } from './sourcemap.js';
23
23
  export type { PtxSourceMap, SourceMapEntry } from './sourcemap.js';
24
24
  export { forcePortablePublication } from './publication.js';
25
+ export type { PublicationOverrides } from './publication.js';
26
+ export { detectRenderTarget } from './target.js';
27
+ export type { RenderTarget } from './target.js';
28
+ export { injectRevealBridge, isRevealView, revealBridgeScript, } from './reveal.js';
29
+ export type { RevealView, RevealViewOptions } from './reveal.js';
25
30
  export { PREVIEW_THEME_MESSAGE, isPreviewTheme, previewThemeMessage, themeBridgeScript, injectThemeBridge, } from './theme.js';
26
31
  export type { PreviewTheme, PreviewThemeMessage } from './theme.js';
27
32
  export { setAssetsBase } from './host.js';