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