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