@pretextbook/pretext-html 0.1.1 → 0.3.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 (121) hide show
  1. package/README.md +82 -1
  2. package/assets/preview-html.xsl +0 -0
  3. package/assets/upstream.json +0 -0
  4. package/assets/xsl/README.md +0 -0
  5. package/assets/xsl/entities.ent +0 -0
  6. package/assets/xsl/extract-asymptote.xsl +0 -0
  7. package/assets/xsl/extract-biblio-csl.xsl +0 -0
  8. package/assets/xsl/extract-datafile.xsl +0 -0
  9. package/assets/xsl/extract-dynamic.xsl +0 -0
  10. package/assets/xsl/extract-identity.xsl +0 -0
  11. package/assets/xsl/extract-interactive.xsl +0 -0
  12. package/assets/xsl/extract-latex-image.xsl +0 -0
  13. package/assets/xsl/extract-mermaid.xsl +0 -0
  14. package/assets/xsl/extract-mom.xsl +0 -0
  15. package/assets/xsl/extract-pg.xsl +0 -0
  16. package/assets/xsl/extract-prefigure.xsl +0 -0
  17. package/assets/xsl/extract-qrcode.xsl +0 -0
  18. package/assets/xsl/extract-runestone-page-template.xsl +0 -0
  19. package/assets/xsl/extract-sageplot.xsl +0 -0
  20. package/assets/xsl/extract-stack.xsl +0 -0
  21. package/assets/xsl/extract-trace.xsl +0 -0
  22. package/assets/xsl/extract-youtube.xsl +0 -0
  23. package/assets/xsl/html-symbols.xsl +0 -0
  24. package/assets/xsl/latex/pretext-latex-AIM.xsl +0 -0
  25. package/assets/xsl/latex/pretext-latex-CLP.xsl +0 -0
  26. package/assets/xsl/latex/pretext-latex-chaos.xsl +0 -0
  27. package/assets/xsl/latex/pretext-latex-dyslexic-font.xsl +0 -0
  28. package/assets/xsl/latex/pretext-latex-guide.xsl +0 -0
  29. package/assets/xsl/latex/pretext-latex-texstyle.xsl +0 -0
  30. package/assets/xsl/localizations/README.md +0 -0
  31. package/assets/xsl/localizations/af-ZA.xml +0 -0
  32. package/assets/xsl/localizations/bg-BG.xml +0 -0
  33. package/assets/xsl/localizations/ca-ES.xml +0 -0
  34. package/assets/xsl/localizations/cs-CZ.xml +0 -0
  35. package/assets/xsl/localizations/de-DE.xml +0 -0
  36. package/assets/xsl/localizations/en-US.xml +0 -0
  37. package/assets/xsl/localizations/es-ES.xml +0 -0
  38. package/assets/xsl/localizations/fi-FI.xml +0 -0
  39. package/assets/xsl/localizations/fr-CA.xml +0 -0
  40. package/assets/xsl/localizations/fr-FR.xml +0 -0
  41. package/assets/xsl/localizations/hu-HU.xml +0 -0
  42. package/assets/xsl/localizations/it-IT.xml +0 -0
  43. package/assets/xsl/localizations/ku-CKB.xml +0 -0
  44. package/assets/xsl/localizations/localizations.xml +0 -0
  45. package/assets/xsl/localizations/nl-NL.xml +0 -0
  46. package/assets/xsl/localizations/pt-BR.xml +0 -0
  47. package/assets/xsl/localizations/pt-PT.xml +0 -0
  48. package/assets/xsl/localizations/zh-HANS.xml +0 -0
  49. package/assets/xsl/pretext-assembly.xsl +0 -0
  50. package/assets/xsl/pretext-basic-html.xsl +0 -0
  51. package/assets/xsl/pretext-beamer.xsl +0 -0
  52. package/assets/xsl/pretext-braille-preprint.xsl +0 -0
  53. package/assets/xsl/pretext-common.xsl +0 -0
  54. package/assets/xsl/pretext-dynamic.xsl +0 -0
  55. package/assets/xsl/pretext-epub.xsl +0 -0
  56. package/assets/xsl/pretext-fo.xsl +0 -0
  57. package/assets/xsl/pretext-html.xsl +0 -0
  58. package/assets/xsl/pretext-json-manifest.xsl +0 -0
  59. package/assets/xsl/pretext-jupyter.xsl +0 -0
  60. package/assets/xsl/pretext-latex-classic.xsl +0 -0
  61. package/assets/xsl/pretext-latex-common.xsl +0 -0
  62. package/assets/xsl/pretext-latex.xsl +0 -0
  63. package/assets/xsl/pretext-litprog.xsl +0 -0
  64. package/assets/xsl/pretext-merge.xsl +0 -0
  65. package/assets/xsl/pretext-numbers.xsl +0 -0
  66. package/assets/xsl/pretext-revealjs.xsl +0 -0
  67. package/assets/xsl/pretext-runestone-fitb.xsl +0 -0
  68. package/assets/xsl/pretext-runestone-static.xsl +0 -0
  69. package/assets/xsl/pretext-runestone.xsl +0 -0
  70. package/assets/xsl/pretext-sage-doctest.xsl +0 -0
  71. package/assets/xsl/pretext-smc.xsl +0 -0
  72. package/assets/xsl/pretext-solution-manual-latex.xsl +0 -0
  73. package/assets/xsl/pretext-text-utilities.xsl +0 -0
  74. package/assets/xsl/pretext-text.xsl +0 -0
  75. package/assets/xsl/pretext-units.xsl +0 -0
  76. package/assets/xsl/pretext-view-source.xsl +0 -0
  77. package/assets/xsl/pretext-ww-problem-sets.xsl +0 -0
  78. package/assets/xsl/publisher-variables.xsl +0 -0
  79. package/assets/xsl/support/README.md +0 -0
  80. package/assets/xsl/support/extract-math.xsl +0 -0
  81. package/assets/xsl/support/package-math.xsl +0 -0
  82. package/assets/xsl/support/play-button/README.md +0 -0
  83. package/assets/xsl/support/play-button/play-button.png +0 -0
  84. package/assets/xsl/support/play-button/play-button.svg +0 -0
  85. package/assets/xsl/support/pretext-pg-macros.xsl +0 -0
  86. package/assets/xsl/support/webpack_static_imports.xml +0 -0
  87. package/assets/xsl/tests/README.md +0 -0
  88. package/assets/xsl/tests/null.xml +0 -0
  89. package/assets/xsl/tests/pretext-text-utilities-test.xsl +0 -0
  90. package/assets/xsl/utilities/README.md +0 -0
  91. package/assets/xsl/utilities/author-report.xsl +0 -0
  92. package/assets/xsl/utilities/deprecate-autoname.sed +0 -0
  93. package/assets/xsl/utilities/deprecate-index.sed +0 -0
  94. package/assets/xsl/utilities/fix-deprecations.xsl +0 -0
  95. package/assets/xsl/utilities/pretext-enhanced-source.xsl +0 -0
  96. package/assets/xsl/utilities/report-publisher-variables.xsl +0 -0
  97. package/assets/xsl/xml-to-json.xsl +0 -0
  98. package/assets/xsl/xml-to-string.xsl +0 -0
  99. package/assets/xsl-bundle.json +1 -0
  100. package/dist/assets.d.ts +43 -0
  101. package/dist/assets.js +76 -0
  102. package/dist/cli-CzoinNle.js +639 -0
  103. package/dist/cli.d.ts +0 -0
  104. package/dist/cli.js +1 -1
  105. package/dist/host.browser.d.ts +29 -0
  106. package/dist/host.d.ts +41 -0
  107. package/dist/index.browser.d.ts +29 -0
  108. package/dist/index.browser.js +701 -0
  109. package/dist/index.d.ts +8 -0
  110. package/dist/index.js +20 -13
  111. package/dist/internal/posix-path.d.ts +59 -0
  112. package/dist/missing-asset.d.ts +31 -0
  113. package/dist/mounts.d.ts +18 -0
  114. package/dist/publication.d.ts +27 -0
  115. package/dist/renderer.d.ts +33 -1
  116. package/dist/sourcemap.d.ts +0 -0
  117. package/dist/theme.d.ts +0 -0
  118. package/dist/theme.js +0 -0
  119. package/dist/xinclude.d.ts +0 -0
  120. package/package.json +17 -3
  121. package/dist/cli-BQizBK0N.js +0 -555
@@ -0,0 +1,639 @@
1
+ import { readFile as A, writeFile as C } from "node:fs/promises";
2
+ import * as w from "node:process";
3
+ import * as a from "node:path";
4
+ import { fileURLToPath as fe } from "node:url";
5
+ import { fromXml as v } from "xast-util-from-xml";
6
+ import { toXml as $ } from "xast-util-to-xml";
7
+ import { injectThemeBridge as he } from "./theme.js";
8
+ async function V(e, r) {
9
+ const t = a.resolve(e), n = a.resolve(t, `.${a.posix.normalize(r)}`);
10
+ if (n !== t && !n.startsWith(t + a.sep)) {
11
+ console.error(
12
+ `pretext-html: refusing to serve ${r} from outside ${t}`
13
+ );
14
+ return;
15
+ }
16
+ try {
17
+ return new Uint8Array(await A(n));
18
+ } catch {
19
+ return;
20
+ }
21
+ }
22
+ async function X(e) {
23
+ try {
24
+ return await A(e, "utf8");
25
+ } catch {
26
+ return;
27
+ }
28
+ }
29
+ let Z;
30
+ function qe(e) {
31
+ Z = e;
32
+ }
33
+ function I() {
34
+ return Z ?? process.env.PRETEXT_HTML_ASSETS ?? a.resolve(a.dirname(fe(import.meta.url)), "..", "assets");
35
+ }
36
+ function me(e, r) {
37
+ return a.join(e, r);
38
+ }
39
+ const j = /* @__PURE__ */ new Map(), K = /* @__PURE__ */ new Map();
40
+ let M, pe = 0, ee = V;
41
+ function Ge(e) {
42
+ ee = e;
43
+ }
44
+ function we(e, r) {
45
+ const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, n = K.get(t);
46
+ if (n !== void 0)
47
+ return Promise.resolve(new Response(n, { status: 200 }));
48
+ let o;
49
+ try {
50
+ o = new URL(t).host;
51
+ } catch {
52
+ o = "";
53
+ }
54
+ const i = j.get(o);
55
+ return i !== void 0 ? ge(i, t) : M(e, r);
56
+ }
57
+ const be = '<?xml version="1.0"?><pretext-preview-missing-file/>';
58
+ async function ge(e, r) {
59
+ const t = decodeURIComponent(new URL(r).pathname), n = await ee(e, t);
60
+ if (n === void 0)
61
+ return new Response(be, { status: 200 });
62
+ const o = typeof n == "string" ? n : new Uint8Array(n);
63
+ return new Response(o, { status: 200 });
64
+ }
65
+ function te() {
66
+ M || (M = globalThis.fetch, globalThis.fetch = we);
67
+ }
68
+ function re(e) {
69
+ te();
70
+ const r = `mnt${++pe}.ptx.invalid`;
71
+ return j.set(r, e), `http://${r}`;
72
+ }
73
+ function ye(e) {
74
+ j.delete(new URL(e).host);
75
+ }
76
+ function xe(e, r) {
77
+ te(), K.set(e, r);
78
+ }
79
+ const ne = `<?xml version="1.0" encoding="UTF-8"?>
80
+ <publication>
81
+ <source>
82
+ <directories external="../assets" generated="../generated-assets" />
83
+ </source>
84
+ <html>
85
+ <platform portable="yes"/>
86
+ </html>
87
+ </publication>
88
+ `;
89
+ function y(e, r) {
90
+ for (const t of e.children)
91
+ if (t.type === "element" && t.name === r)
92
+ return t;
93
+ }
94
+ function B(e, r) {
95
+ let t = y(e, r);
96
+ return t || (t = { type: "element", name: r, attributes: {}, children: [] }, e.children.push(t)), t;
97
+ }
98
+ function O(e) {
99
+ if (!e)
100
+ return ne;
101
+ const r = v(e), t = y(r, "publication");
102
+ if (!t)
103
+ throw new Error(
104
+ "Invalid publication file: no root <publication> element found"
105
+ );
106
+ const n = B(t, "html"), o = B(n, "platform");
107
+ return o.attributes = { ...o.attributes, portable: "yes" }, $(r);
108
+ }
109
+ function N(e) {
110
+ if (!(e === void 0 || e === "" || e.startsWith("/")))
111
+ return e.endsWith("/") ? e : `${e}/`;
112
+ }
113
+ function ve(e) {
114
+ const r = v(e ?? ne), t = y(r, "publication"), n = t && y(t, "source"), o = n && y(n, "directories"), i = N(
115
+ o?.attributes?.external ?? void 0
116
+ ), c = N(
117
+ o?.attributes?.generated ?? void 0
118
+ );
119
+ return {
120
+ external: i,
121
+ generated: c,
122
+ managed: i !== void 0 && c !== void 0
123
+ };
124
+ }
125
+ const oe = "http://www.w3.org/2001/XInclude", _ = 64;
126
+ async function Ee(e, r, t) {
127
+ return e.includes("include") ? (await ie(e, r, t)).content : e;
128
+ }
129
+ async function ie(e, r, t) {
130
+ const n = v(e), o = {
131
+ projectDir: a.resolve(t),
132
+ stack: [a.resolve(r)]
133
+ }, i = await x(
134
+ n,
135
+ a.dirname(a.resolve(r)),
136
+ { "": "" },
137
+ o
138
+ );
139
+ return { tree: n, content: i ? $(n) : e };
140
+ }
141
+ function $e(e) {
142
+ return e.data?.ptxIncludedFile;
143
+ }
144
+ function Pe(e, r) {
145
+ const t = e.data ?? (e.data = {});
146
+ t.ptxIncludedFile = r;
147
+ }
148
+ function P(e, r) {
149
+ let t = e;
150
+ for (const [n, o] of Object.entries(r.attributes))
151
+ (n === "xmlns" || n.startsWith("xmlns:")) && (t === e && (t = { ...e }), t[n === "xmlns" ? "" : n.slice(6)] = o ?? "");
152
+ return t;
153
+ }
154
+ function se(e, r) {
155
+ const t = e.name.indexOf(":"), n = t === -1 ? "" : e.name.slice(0, t);
156
+ return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && r[n] === oe;
157
+ }
158
+ async function x(e, r, t, n) {
159
+ let o = !1;
160
+ for (let i = 0; i < e.children.length; i++) {
161
+ const c = e.children[i];
162
+ if (c.type !== "element")
163
+ continue;
164
+ const s = P(t, c);
165
+ if (se(c, s)) {
166
+ const u = await ae(
167
+ c,
168
+ r,
169
+ s,
170
+ n
171
+ );
172
+ e.children.splice(i, 1, ...u), i += u.length - 1, o = !0;
173
+ } else await x(c, r, s, n) && (o = !0);
174
+ }
175
+ return o;
176
+ }
177
+ async function ae(e, r, t, n) {
178
+ const o = n.stack[n.stack.length - 1];
179
+ if (e.attributes.xpointer)
180
+ throw new Error(
181
+ `xi:include with xpointer is not supported by the JS preview build (in ${o})`
182
+ );
183
+ const i = e.attributes.href;
184
+ if (!i)
185
+ throw new Error(`xi:include without href (in ${o})`);
186
+ let c = i;
187
+ try {
188
+ c = decodeURIComponent(i);
189
+ } catch {
190
+ }
191
+ const s = a.resolve(r, c);
192
+ if (s !== n.projectDir && !s.startsWith(n.projectDir + a.sep))
193
+ throw new Error(
194
+ `xi:include escapes the project directory: ${i} (in ${o})`
195
+ );
196
+ if (n.stack.includes(s))
197
+ throw new Error(
198
+ `Circular xi:include: ${[...n.stack, s].join(" -> ")}`
199
+ );
200
+ if (n.stack.length >= _)
201
+ throw new Error(`xi:include nesting exceeds ${_} levels`);
202
+ const u = await X(s);
203
+ if (u === void 0) {
204
+ const f = ke(e, t);
205
+ if (f)
206
+ return await x(f, r, t, n), f.children;
207
+ throw new Error(`xi:include target not found: ${i} (in ${o})`);
208
+ }
209
+ if (e.attributes.parse === "text")
210
+ return [{ type: "text", value: u }];
211
+ let l;
212
+ try {
213
+ l = v(u);
214
+ } catch (f) {
215
+ throw new Error(
216
+ `Could not parse xi:include target ${s} as XML: ${f instanceof Error ? f.message : f}. (Included files must be well-formed, with a single root element.)`
217
+ );
218
+ }
219
+ n.stack.push(s);
220
+ try {
221
+ await x(l, a.dirname(s), { "": "" }, n);
222
+ } finally {
223
+ n.stack.pop();
224
+ }
225
+ const d = l.children.filter(
226
+ (f) => f.type === "element"
227
+ );
228
+ for (const f of d)
229
+ Pe(f, s);
230
+ return d;
231
+ }
232
+ function H(e) {
233
+ return e.name === "docinfo";
234
+ }
235
+ async function Te(e, r, t) {
236
+ try {
237
+ const o = v(e).children.find(
238
+ (l) => l.type === "element"
239
+ );
240
+ if (!o)
241
+ return;
242
+ const i = a.resolve(r), c = a.dirname(i), s = {
243
+ projectDir: a.resolve(t),
244
+ stack: [i]
245
+ }, u = P({ "": "" }, o);
246
+ for (const l of o.children) {
247
+ if (l.type !== "element")
248
+ continue;
249
+ const d = P(u, l);
250
+ if (H(l))
251
+ return await x(l, c, d, s), $(l);
252
+ if (se(l, d)) {
253
+ const m = (await ae(
254
+ l,
255
+ c,
256
+ d,
257
+ s
258
+ )).find(
259
+ (b) => b.type === "element" && H(b)
260
+ );
261
+ if (m)
262
+ return $(m);
263
+ continue;
264
+ }
265
+ break;
266
+ }
267
+ return;
268
+ } catch {
269
+ return;
270
+ }
271
+ }
272
+ function ke(e, r) {
273
+ for (const t of e.children) {
274
+ if (t.type !== "element")
275
+ continue;
276
+ const n = P(r, t), o = t.name.indexOf(":"), i = o === -1 ? "" : t.name.slice(0, o);
277
+ if ((o === -1 ? t.name : t.name.slice(o + 1)) === "fallback" && n[i] === oe)
278
+ return t;
279
+ }
280
+ }
281
+ function ce(e) {
282
+ return typeof e == "object" && e !== null && e.type === "element";
283
+ }
284
+ function Se(e) {
285
+ return /^(pf|xhtml):/.test(e.name);
286
+ }
287
+ function De(e, r, t) {
288
+ const n = [], o = e.children.find(ce);
289
+ if (o) {
290
+ const i = t?.parentId ?? "root";
291
+ le(o, i, t?.position ?? 1, r, i, n);
292
+ }
293
+ return n;
294
+ }
295
+ function le(e, r, t, n, o, i) {
296
+ const c = $e(e) ?? n;
297
+ let s, u;
298
+ if (Se(e))
299
+ u = "root";
300
+ else {
301
+ const d = e.attributes.label ?? e.attributes["xml:id"];
302
+ s = d ?? `${r}-${t}`, i.push({
303
+ id: s,
304
+ file: c,
305
+ line: e.position?.start.line ?? 1,
306
+ column: e.position?.start.column ?? 1,
307
+ endLine: e.position?.end.line ?? e.position?.start.line ?? 1,
308
+ parent: o
309
+ }), u = s;
310
+ }
311
+ let l = 0;
312
+ for (const d of e.children)
313
+ ce(d) && (l += 1, le(
314
+ d,
315
+ u,
316
+ l,
317
+ c,
318
+ s ?? o,
319
+ i
320
+ ));
321
+ }
322
+ function Ye(e, r) {
323
+ let t;
324
+ for (const n of e)
325
+ n.line <= r && (t = n);
326
+ return t ?? e[0];
327
+ }
328
+ function Ie() {
329
+ return me(I(), "xsl");
330
+ }
331
+ function Me() {
332
+ return "Suspending" in WebAssembly;
333
+ }
334
+ function Ae() {
335
+ if (!Me())
336
+ throw new Error(
337
+ "WebAssembly JSPI is not enabled. Run Node with --experimental-wasm-jspi (or use the pretext-html CLI, which re-launches itself with the flag)."
338
+ );
339
+ }
340
+ function J(e) {
341
+ return e.includes("'") ? e.includes('"') ? `concat(${e.split("'").map((t) => `'${t}'`).join(`, "'", `)})` : `"${e}"` : `'${e}'`;
342
+ }
343
+ function Xe(e) {
344
+ return e.replace(
345
+ /from '\.\/(https:\/\/[^']+)'/g,
346
+ (r, t) => `from '${t}'`
347
+ );
348
+ }
349
+ function je(e) {
350
+ return e.slice(0, 65536).replace(/<\?[\s\S]*?\?>/g, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<!DOCTYPE[^>]*>/gi, " ").match(/<\s*([A-Za-z][\w:-]*)/)?.[1];
351
+ }
352
+ async function z(e) {
353
+ const r = await X(e);
354
+ if (r === void 0)
355
+ throw new Error(
356
+ `Could not read ${e}. (In the browser build only absolute URLs are readable — pass sourceContent instead of relying on sourcePath.)`
357
+ );
358
+ return r;
359
+ }
360
+ async function Fe(e, r) {
361
+ const t = a.resolve(e), n = await X(t);
362
+ if (n !== void 0)
363
+ return Te(n, t, r);
364
+ }
365
+ function Le(e, r, t) {
366
+ const n = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), o = r === "chapter" || r === "part" ? "book" : "article";
367
+ return `<pretext>
368
+ ${t?.trim() ? `${t.trim()}
369
+ ` : ""}<${o}>
370
+ <title/>
371
+ ${n}
372
+ </${o}>
373
+ </pretext>
374
+ `;
375
+ }
376
+ let ue = !1;
377
+ function Re(e) {
378
+ return e instanceof Error && /\bAborted\(/.test(e.message);
379
+ }
380
+ function Ue(e) {
381
+ return e instanceof Error && /memory access|out of bounds/i.test(e.message);
382
+ }
383
+ function We() {
384
+ if (ue)
385
+ throw new Error(
386
+ "The WebAssembly renderer aborted earlier in this process and cannot be reused. Restart the process (or reload the page) to render again."
387
+ );
388
+ }
389
+ function q(e) {
390
+ if (Re(e))
391
+ throw ue = !0, new Error(
392
+ "The WebAssembly renderer aborted and cannot be reused. Restart the process (or reload the page) to render again.",
393
+ { cause: e }
394
+ );
395
+ if (Ue(e))
396
+ throw new Error(
397
+ "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.",
398
+ { cause: e }
399
+ );
400
+ }
401
+ let S;
402
+ async function de() {
403
+ return S || (S = (async () => {
404
+ const [e, r] = await Promise.all([
405
+ import("@pretextbook/libxslt-wasm"),
406
+ import("@pretextbook/libxslt-wasm/exslt")
407
+ ]);
408
+ return r.registerAll(), e;
409
+ })()), S;
410
+ }
411
+ const D = /* @__PURE__ */ new Map();
412
+ async function Ce(e) {
413
+ const r = e;
414
+ let t = D.get(r);
415
+ return t || (t = (async () => {
416
+ const { XmlDocument: n, XsltStylesheet: o } = await de(), i = re(r), c = await V(
417
+ I(),
418
+ "/preview-html.xsl"
419
+ );
420
+ if (c === void 0)
421
+ throw new Error(
422
+ `Could not read preview-html.xsl from ${I()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
423
+ );
424
+ const s = new TextDecoder().decode(c), u = await n.fromString(s, {
425
+ url: `${i}/preview-html.xsl`,
426
+ options: { noEnt: !0, dtdLoad: !0, huge: !0 }
427
+ });
428
+ return o.fromXmlDocument(u);
429
+ })(), D.set(r, t), t.catch(() => D.delete(r))), t;
430
+ }
431
+ let G = Promise.resolve();
432
+ function Be(e) {
433
+ const r = G.then(
434
+ () => Y(e),
435
+ () => Y(e)
436
+ );
437
+ return G = r.catch(() => {
438
+ }), r;
439
+ }
440
+ async function Y(e) {
441
+ Ae(), We();
442
+ const { XmlDocument: r } = await de(), t = await Ce(e.xslDir ?? Ie()), n = a.resolve(e.sourcePath), o = a.resolve(
443
+ e.projectDir ?? a.dirname(n)
444
+ ), i = e.sourceContent ?? await z(n), c = a.relative(o, n);
445
+ if (c.startsWith(".."))
446
+ throw new Error(
447
+ `sourcePath (${n}) must live inside projectDir (${o})`
448
+ );
449
+ const s = a.relative(
450
+ o,
451
+ a.resolve(e.mainSourcePath ?? n)
452
+ ), u = s.startsWith("..") ? c : s, l = re(o);
453
+ try {
454
+ let d, f = `${l}/__pretext-preview-publication.xml`;
455
+ if (e.publicationPath) {
456
+ const h = a.resolve(e.publicationPath);
457
+ d = O(
458
+ await z(h)
459
+ );
460
+ const g = a.relative(o, h);
461
+ g.startsWith("..") || (f = `${l}/${g.split(a.sep).join("/")}`);
462
+ } else
463
+ d = O();
464
+ xe(f, d);
465
+ const m = ve(d), b = a.dirname(a.resolve(o, u)), F = m.external !== void 0 && m.generated !== void 0 ? {
466
+ external: a.resolve(b, m.external),
467
+ generated: a.resolve(b, m.generated)
468
+ } : void 0;
469
+ let T, p;
470
+ if (e.sourceMap) {
471
+ const h = await ie(
472
+ i,
473
+ n,
474
+ o
475
+ );
476
+ T = h.tree, p = h.content;
477
+ } else
478
+ p = await Ee(
479
+ i,
480
+ n,
481
+ o
482
+ );
483
+ const E = je(p);
484
+ let L = { parentId: "root", position: 1 };
485
+ if (E !== "pretext" && E !== "mathbook")
486
+ if (e.fragment) {
487
+ const h = e.docinfo ?? (e.docinfoSourcePath ? await Fe(e.docinfoSourcePath, o) : void 0);
488
+ p = Le(p, E, h), L = { parentId: h?.trim() ? "root-1-2" : "root-1-1", position: 2 };
489
+ } else
490
+ throw new Error(
491
+ `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.`
492
+ );
493
+ const R = T ? De(T, n, L) : void 0, U = await r.fromString(p, {
494
+ url: `${l}/${u.split(a.sep).join("/")}`,
495
+ options: { noEnt: !0, dtdLoad: !0, huge: !0 }
496
+ }), W = {
497
+ publisher: J(f)
498
+ };
499
+ for (const [h, g] of Object.entries(e.stringParams ?? {}))
500
+ W[h] = J(g);
501
+ let k;
502
+ try {
503
+ k = await t.apply(U, W);
504
+ } catch (h) {
505
+ throw q(h), new Error(
506
+ "PreTeXt XSLT transform failed; see the PTX:ERROR/PTX:FATAL messages on stderr for details.",
507
+ { cause: h }
508
+ );
509
+ } finally {
510
+ U.delete();
511
+ }
512
+ try {
513
+ let h = Xe(k.toHtmlString());
514
+ return e.theme && (h = he(h, e.theme)), {
515
+ html: h,
516
+ ...R ? { sourceMap: R } : {},
517
+ ...F ? { assetDirs: F } : {}
518
+ };
519
+ } catch (h) {
520
+ throw q(h), h;
521
+ } finally {
522
+ k.delete();
523
+ }
524
+ } finally {
525
+ ye(l);
526
+ }
527
+ }
528
+ const Q = `Usage: pretext-html <source.ptx> [options]
529
+
530
+ Render a PreTeXt document to a single standalone HTML page (portable build:
531
+ one page, css/js/MathJax from CDN). No PreTeXt installation required.
532
+
533
+ Options:
534
+ -o, --output <file> Write HTML to a file instead of stdout
535
+ --publication <file> Publication file (portable html is forced on)
536
+ --project-dir <dir> Directory served to the transform for xi:includes
537
+ (default: the source file's directory)
538
+ --param <name=value> Extra XSLT string parameter (repeatable)
539
+ --xsl-dir <dir> Use PreTeXt stylesheets from this directory
540
+ instead of the vendored copy
541
+ --fragment Allow a non-root source file: wrap the fragment
542
+ in a minimal <pretext> document (an <article>,
543
+ or a <book> for <chapter>/<part> fragments)
544
+ --docinfo <file> File whose contents (a <docinfo> element) are
545
+ injected into the wrapper in --fragment mode, so
546
+ the fragment keeps the project's LaTeX macros
547
+ --docinfo-source <file> Complete source file (e.g. main.ptx) to lift the
548
+ <docinfo> from for --fragment mode, resolving
549
+ xi:includes (used when --docinfo is not given)
550
+ --source-map <file> Also write a JSON source map: HTML id → source
551
+ file/line for every element (for editor sync)
552
+ -h, --help Show this help
553
+ `;
554
+ function Oe(e) {
555
+ let r, t, n, o;
556
+ const i = {}, c = {};
557
+ for (let s = 0; s < e.length; s++) {
558
+ const u = e[s], l = () => {
559
+ if (s += 1, s >= e.length)
560
+ throw new Error(`Missing value for ${u}`);
561
+ return e[s];
562
+ };
563
+ switch (u) {
564
+ case "-h":
565
+ case "--help":
566
+ w.stdout.write(Q), w.exit(0);
567
+ break;
568
+ case "-o":
569
+ case "--output":
570
+ t = l();
571
+ break;
572
+ case "--publication":
573
+ i.publicationPath = l();
574
+ break;
575
+ case "--project-dir":
576
+ i.projectDir = l();
577
+ break;
578
+ case "--xsl-dir":
579
+ i.xslDir = l();
580
+ break;
581
+ case "--fragment":
582
+ i.fragment = !0;
583
+ break;
584
+ case "--docinfo":
585
+ n = l();
586
+ break;
587
+ case "--docinfo-source":
588
+ i.docinfoSourcePath = l();
589
+ break;
590
+ case "--source-map":
591
+ o = l(), i.sourceMap = !0;
592
+ break;
593
+ case "--param": {
594
+ const d = l(), f = d.indexOf("=");
595
+ if (f === -1)
596
+ throw new Error(`--param expects name=value, got: ${d}`);
597
+ c[d.slice(0, f)] = d.slice(f + 1);
598
+ break;
599
+ }
600
+ default:
601
+ if (u.startsWith("-"))
602
+ throw new Error(`Unknown option: ${u}`);
603
+ if (r)
604
+ throw new Error(`Unexpected extra argument: ${u}`);
605
+ r = u;
606
+ }
607
+ }
608
+ if (!r)
609
+ throw new Error(`No source file given.
610
+
611
+ ` + Q);
612
+ return Object.keys(c).length > 0 && (i.stringParams = c), {
613
+ options: { ...i, sourcePath: r },
614
+ output: t,
615
+ docinfoPath: n,
616
+ sourceMapPath: o
617
+ };
618
+ }
619
+ async function Qe(e) {
620
+ const { options: r, output: t, docinfoPath: n, sourceMapPath: o } = Oe(e);
621
+ n && (r.docinfo = await A(n, "utf8"));
622
+ const i = Date.now(), { html: c, sourceMap: s } = await Be(r);
623
+ w.stderr.write(`pretext-html: rendered in ${Date.now() - i}ms
624
+ `), o && s && (await C(o, JSON.stringify(s, null, 2)), w.stderr.write(`pretext-html: wrote ${o}
625
+ `)), t ? (await C(t, c), w.stderr.write(`pretext-html: wrote ${t}
626
+ `)) : w.stdout.write(c);
627
+ }
628
+ export {
629
+ O as a,
630
+ Ge as b,
631
+ Ie as d,
632
+ Ye as f,
633
+ Me as i,
634
+ Qe as m,
635
+ Oe as p,
636
+ Be as r,
637
+ qe as s,
638
+ J as x
639
+ };
package/dist/cli.d.ts CHANGED
File without changes
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-BQizBK0N.js";
3
+ import { m as o, p as s } from "./cli-CzoinNle.js";
4
4
  export {
5
5
  o as main,
6
6
  s as parseArgs
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Browser implementation of the platform seam (see host.ts for the contract
3
+ * and host.node's counterpart). Substituted for `./host.js` when this package
4
+ * is built for the browser; vite.config.ts wires the alias.
5
+ *
6
+ * There is no filesystem here, so:
7
+ *
8
+ * - Mount roots are base URLs rather than directories, and `readMount` is a
9
+ * `fetch`. Containment is enforced by resolving against the base and
10
+ * checking the result still sits under it.
11
+ * - `readSource` can only read things that are actually addressable, i.e.
12
+ * absolute URLs. A browser caller naming a virtual path (`/main.ptx`) gets
13
+ * `undefined`, which means **`sourceContent` is effectively required** and
14
+ * `xi:include`s cannot be resolved from disk. Pre-resolve includes, or
15
+ * pass the merged document as `sourceContent`.
16
+ * - `assetsBase()` defaults to the version-pinned jsDelivr copy of this
17
+ * package, so an embedder needs no build configuration at all. Call
18
+ * `setAssetsBase()` to self-host.
19
+ */
20
+ /**
21
+ * Serve this package's `assets/` from somewhere other than jsDelivr — a
22
+ * self-hosted copy, an offline bundle, a same-origin path. Must be called
23
+ * before the first render; the compiled stylesheet is cached per root.
24
+ */
25
+ export declare function setAssetsBase(base: string): void;
26
+ export declare function assetsBase(): string;
27
+ export declare function joinPath(root: string, child: string): string;
28
+ export declare function readMount(root: string, relPath: string): Promise<Uint8Array | undefined>;
29
+ export declare function readSource(location: string): Promise<string | undefined>;