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