@pretextbook/pretext-html 0.10.1 → 0.11.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,26 +1,27 @@
1
- import { readFile as W, writeFile as Z } from "node:fs/promises";
2
- import * as y from "node:process";
3
- import * as u from "node:path";
4
- import { fileURLToPath as Ae } from "node:url";
1
+ import { readFile as W, writeFile as Q } from "node:fs/promises";
2
+ import * as b from "node:process";
3
+ import { listPrintouts as je, rootPrintoutId as Me, injectPrintPreview as fe } from "./printout.js";
4
+ import * as f from "node:path";
5
+ import { fileURLToPath as _e } from "node:url";
5
6
  import { fromXml as E } from "xast-util-from-xml";
6
7
  import { toXml as I } from "xast-util-to-xml";
7
- import { injectRevealBridge as Le } from "./reveal.js";
8
- import { injectThemeBridge as Me } from "./theme.js";
9
- const _e = "ptxPreviewBannerDismissed", je = "About live preview";
10
- function Q(e) {
8
+ import { injectRevealBridge as Be } from "./reveal.js";
9
+ import { injectThemeBridge as Oe } from "./theme.js";
10
+ const Ce = "ptxPreviewBannerDismissed", Fe = "About live preview";
11
+ function ee(e) {
11
12
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12
13
  }
13
- function Be(e) {
14
+ function Ne(e) {
14
15
  return [
15
16
  '<div id="ptx-preview-banner" class="ptx-preview-banner" role="note">',
16
- ` <span class="ptx-preview-banner-text">${Q(e)}</span>`,
17
+ ` <span class="ptx-preview-banner-text">${ee(e)}</span>`,
17
18
  ' <button type="button" class="ptx-preview-banner-dismiss" aria-label="Dismiss">&times;</button>',
18
19
  "</div>",
19
- `<button type="button" id="ptx-preview-banner-restore" class="ptx-preview-banner-restore" hidden>${Q(je)}</button>`
20
+ `<button type="button" id="ptx-preview-banner-restore" class="ptx-preview-banner-restore" hidden>${ee(Fe)}</button>`
20
21
  ].join(`
21
22
  `);
22
23
  }
23
- function Oe() {
24
+ function Xe() {
24
25
  return [
25
26
  "<style>",
26
27
  ".ptx-preview-banner {",
@@ -77,15 +78,23 @@ function Oe() {
77
78
  ".ptx-preview-banner-restore:hover {",
78
79
  " opacity: 0.85;",
79
80
  "}",
81
+ // Printing a preview is a real workflow — the print-preview layout exists
82
+ // to be printed from (see printout.ts) — and a warning about the preview
83
+ // has no business on the paper.
84
+ "@media print {",
85
+ " .ptx-preview-banner, .ptx-preview-banner-restore {",
86
+ " display: none !important;",
87
+ " }",
88
+ "}",
80
89
  "</style>"
81
90
  ].join(`
82
91
  `);
83
92
  }
84
- function Ce() {
93
+ function Ue() {
85
94
  return [
86
95
  "<script>",
87
96
  "(function () {",
88
- " var KEY = " + JSON.stringify(_e) + ";",
97
+ " var KEY = " + JSON.stringify(Ce) + ";",
89
98
  ' var banner = document.getElementById("ptx-preview-banner");',
90
99
  ' var restore = document.getElementById("ptx-preview-banner-restore");',
91
100
  " if (!banner || !restore) { return; }",
@@ -122,22 +131,22 @@ function Ce() {
122
131
  ].join(`
123
132
  `);
124
133
  }
125
- const Fe = "<!--ptx-preview-banner-->", Ne = "<!--/ptx-preview-banner-->", Xe = /\n?<!--ptx-preview-banner-->[\s\S]*?<!--\/ptx-preview-banner-->/;
126
- function Ue(e, r) {
127
- const t = Xe.exec(e), n = t ? e.slice(0, t.index) + e.slice(t.index + t[0].length) : e;
134
+ const We = "<!--ptx-preview-banner-->", He = "<!--/ptx-preview-banner-->", Je = /\n?<!--ptx-preview-banner-->[\s\S]*?<!--\/ptx-preview-banner-->/;
135
+ function ze(e, r) {
136
+ const t = Je.exec(e), n = t ? e.slice(0, t.index) + e.slice(t.index + t[0].length) : e;
128
137
  if (!/<body[^>]*>/i.test(n))
129
138
  return n;
130
139
  const o = `
131
- ${Fe}
132
- ${Oe()}
133
- ${Be(r.message)}
134
- ${Ce()}
135
- ${Ne}`;
140
+ ${We}
141
+ ${Xe()}
142
+ ${Ne(r.message)}
143
+ ${Ue()}
144
+ ${He}`;
136
145
  return n.replace(/<body([^>]*)>/i, `<body$1>${o}`);
137
146
  }
138
- async function de(e, r) {
139
- const t = u.resolve(e), n = u.resolve(t, `.${u.posix.normalize(r)}`);
140
- if (n !== t && !n.startsWith(t + u.sep)) {
147
+ async function pe(e, r) {
148
+ const t = f.resolve(e), n = f.resolve(t, `.${f.posix.normalize(r)}`);
149
+ if (n !== t && !n.startsWith(t + f.sep)) {
141
150
  console.error(
142
151
  `pretext-html: refusing to serve ${r} from outside ${t}`
143
152
  );
@@ -149,59 +158,59 @@ async function de(e, r) {
149
158
  return;
150
159
  }
151
160
  }
152
- async function M(e) {
161
+ async function j(e) {
153
162
  try {
154
163
  return await W(e, "utf8");
155
164
  } catch {
156
165
  return;
157
166
  }
158
167
  }
159
- let fe;
160
- function en(e) {
161
- fe = e;
168
+ let he;
169
+ function sn(e) {
170
+ he = e;
162
171
  }
163
172
  function C() {
164
- return fe ?? process.env.PRETEXT_HTML_ASSETS ?? u.resolve(u.dirname(Ae(import.meta.url)), "..", "assets");
173
+ return he ?? process.env.PRETEXT_HTML_ASSETS ?? f.resolve(f.dirname(_e(import.meta.url)), "..", "assets");
165
174
  }
166
- function We(e, r) {
167
- return u.join(e, r);
175
+ function Ke(e, r) {
176
+ return f.join(e, r);
168
177
  }
169
- const pe = "2.49.1", He = "8.2.4", Je = [
178
+ const me = "2.49.1", Ve = "8.2.4", Ge = [
170
179
  "prefix-runtime.40bd1420d3277749.bundle.js",
171
180
  "prefix-926.5c7038c8ef173faf.bundle.js",
172
181
  "prefix-runestone.b388362b5f43738a.bundle.js"
173
- ], ze = [
182
+ ], Ye = [
174
183
  "prefix-926.229729d09512acc9.css",
175
184
  "prefix-runestone.8086b62682b271d1.css"
176
- ], Ke = "born-hidden-knowl", Ve = /<details\b([^>]*)>(\s*)(?:<summary\b([^>]*)>)?/g;
177
- function Ge(e) {
185
+ ], qe = "born-hidden-knowl", Ze = /<details\b([^>]*)>(\s*)(?:<summary\b([^>]*)>)?/g;
186
+ function Qe(e) {
178
187
  const r = /\bclass="([^"]*)"/.exec(e);
179
188
  return r ? r[1].trim().split(/\s+/) : [];
180
189
  }
181
- function Ye(e) {
190
+ function et(e) {
182
191
  return /(^|\s)open(\s|=|$)/.test(e);
183
192
  }
184
- function ee(e) {
185
- return Ye(e) ? e : ` open${e}`;
193
+ function te(e) {
194
+ return et(e) ? e : ` open${e}`;
186
195
  }
187
- function qe(e) {
196
+ function tt(e) {
188
197
  return e.replace(
189
- Ve,
198
+ Ze,
190
199
  (r, t, n, o) => {
191
- if (!Ge(t).includes(Ke))
200
+ if (!Qe(t).includes(qe))
192
201
  return r;
193
- const i = `<details${ee(t)}>`;
194
- return o === void 0 ? `${i}${n}` : `${i}${n}<summary${ee(o)}>`;
202
+ const i = `<details${te(t)}>`;
203
+ return o === void 0 ? `${i}${n}` : `${i}${n}<summary${te(o)}>`;
195
204
  }
196
205
  );
197
206
  }
198
- const H = /* @__PURE__ */ new Map(), me = /* @__PURE__ */ new Map();
199
- let F, Ze = 0, he = de;
200
- function tn(e) {
201
- he = e;
207
+ const H = /* @__PURE__ */ new Map(), we = /* @__PURE__ */ new Map();
208
+ let F, nt = 0, be = pe;
209
+ function an(e) {
210
+ be = e;
202
211
  }
203
- function Qe(e, r) {
204
- const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, n = me.get(t);
212
+ function rt(e, r) {
213
+ const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, n = we.get(t);
205
214
  if (n !== void 0)
206
215
  return Promise.resolve(new Response(n, { status: 200 }));
207
216
  let o;
@@ -211,29 +220,29 @@ function Qe(e, r) {
211
220
  o = "";
212
221
  }
213
222
  const i = H.get(o);
214
- return i !== void 0 ? tt(i, t) : F(e, r);
223
+ return i !== void 0 ? it(i, t) : F(e, r);
215
224
  }
216
- const et = '<?xml version="1.0"?><pretext-preview-missing-file/>';
217
- async function tt(e, r) {
218
- const t = decodeURIComponent(new URL(r).pathname), n = await he(e, t);
225
+ const ot = '<?xml version="1.0"?><pretext-preview-missing-file/>';
226
+ async function it(e, r) {
227
+ const t = decodeURIComponent(new URL(r).pathname), n = await be(e, t);
219
228
  if (n === void 0)
220
- return new Response(et, { status: 200 });
229
+ return new Response(ot, { status: 200 });
221
230
  const o = typeof n == "string" ? n : new Uint8Array(n);
222
231
  return new Response(o, { status: 200 });
223
232
  }
224
- function we() {
225
- F || (F = globalThis.fetch, globalThis.fetch = Qe);
233
+ function ve() {
234
+ F || (F = globalThis.fetch, globalThis.fetch = rt);
226
235
  }
227
- function be(e) {
228
- we();
229
- const r = `mnt${++Ze}.ptx.invalid`;
236
+ function ge(e) {
237
+ ve();
238
+ const r = `mnt${++nt}.ptx.invalid`;
230
239
  return H.set(r, e), `http://${r}`;
231
240
  }
232
- function nt(e) {
241
+ function st(e) {
233
242
  H.delete(new URL(e).host);
234
243
  }
235
- function rt(e, r) {
236
- we(), me.set(e, r);
244
+ function at(e, r) {
245
+ ve(), we.set(e, r);
237
246
  }
238
247
  const N = `<?xml version="1.0" encoding="UTF-8"?>
239
248
  <publication>
@@ -244,31 +253,31 @@ const N = `<?xml version="1.0" encoding="UTF-8"?>
244
253
  <platform portable="yes"/>
245
254
  </html>
246
255
  </publication>
247
- `, ot = ["theme", "style", "shell"];
248
- function x(e, r) {
256
+ `, ct = ["theme", "style", "shell"];
257
+ function y(e, r) {
249
258
  for (const t of e.children)
250
259
  if (t.type === "element" && t.name === r)
251
260
  return t;
252
261
  }
253
262
  function T(e, r) {
254
- let t = x(e, r);
263
+ let t = y(e, r);
255
264
  return t || (t = { type: "element", name: r, attributes: {}, children: [] }, e.children.push(t)), t;
256
265
  }
257
- function it(e, r) {
258
- const t = x(e, "css");
259
- if (t && ot.some((o) => t.attributes?.[o]))
266
+ function lt(e, r) {
267
+ const t = y(e, "css");
268
+ if (t && ct.some((o) => t.attributes?.[o]))
260
269
  return;
261
270
  const n = t ?? T(e, "css");
262
271
  n.attributes = { ...n.attributes, theme: r };
263
272
  }
264
- function st(e, r) {
265
- const t = x(e, "appearance");
273
+ function ut(e, r) {
274
+ const t = y(e, "appearance");
266
275
  if (t?.attributes?.theme)
267
276
  return;
268
277
  const n = t ?? T(e, "appearance");
269
278
  n.attributes = { ...n.attributes, theme: r };
270
279
  }
271
- function at(e) {
280
+ function dt(e) {
272
281
  const r = T(e, "resources");
273
282
  r.attributes = {
274
283
  ...r.attributes,
@@ -276,30 +285,30 @@ function at(e) {
276
285
  math: "online"
277
286
  };
278
287
  }
279
- function ct(e, r = {}) {
288
+ function ft(e, r = {}) {
280
289
  const t = r.cssTheme?.trim(), n = r.revealTheme?.trim(), o = r.target === "slides";
281
290
  if (!e && !t && !o)
282
291
  return N;
283
- const i = E(e ?? N), s = x(i, "publication");
292
+ const i = E(e ?? N), s = y(i, "publication");
284
293
  if (!s)
285
294
  throw new Error(
286
295
  "Invalid publication file: no root <publication> element found"
287
296
  );
288
- const a = T(s, "html"), l = T(a, "platform");
289
- if (l.attributes = { ...l.attributes, portable: "yes" }, t && it(a, t), o) {
290
- const c = T(s, "revealjs");
291
- at(c), n && st(c, n);
297
+ const a = T(s, "html"), c = T(a, "platform");
298
+ if (c.attributes = { ...c.attributes, portable: "yes" }, t && lt(a, t), o) {
299
+ const l = T(s, "revealjs");
300
+ dt(l), n && ut(l, n);
292
301
  }
293
302
  return I(i);
294
303
  }
295
- function te(e) {
304
+ function ne(e) {
296
305
  if (!(e === void 0 || e === "" || e.startsWith("/")))
297
306
  return e.endsWith("/") ? e : `${e}/`;
298
307
  }
299
- function lt(e) {
300
- const r = E(e ?? N), t = x(r, "publication"), n = t && x(t, "source"), o = n && x(n, "directories"), i = te(
308
+ function pt(e) {
309
+ const r = E(e ?? N), t = y(r, "publication"), n = t && y(t, "source"), o = n && y(n, "directories"), i = ne(
301
310
  o?.attributes?.external ?? void 0
302
- ), s = te(
311
+ ), s = ne(
303
312
  o?.attributes?.generated ?? void 0
304
313
  );
305
314
  return {
@@ -308,26 +317,26 @@ function lt(e) {
308
317
  managed: i !== void 0 && s !== void 0
309
318
  };
310
319
  }
311
- const ge = "http://www.w3.org/2001/XInclude", ne = 64;
312
- async function ut(e, r, t) {
320
+ const xe = "http://www.w3.org/2001/XInclude", re = 64;
321
+ async function ht(e, r, t) {
313
322
  return e.includes("include") ? (await J(e, r, t)).content : e;
314
323
  }
315
324
  async function J(e, r, t) {
316
325
  const n = E(e), o = {
317
- projectDir: u.resolve(t),
318
- stack: [u.resolve(r)]
319
- }, i = await P(
326
+ projectDir: f.resolve(t),
327
+ stack: [f.resolve(r)]
328
+ }, i = await R(
320
329
  n,
321
- u.dirname(u.resolve(r)),
330
+ f.dirname(f.resolve(r)),
322
331
  { "": "" },
323
332
  o
324
333
  );
325
334
  return { tree: n, content: i ? I(n) : e };
326
335
  }
327
- function dt(e) {
336
+ function mt(e) {
328
337
  return e.data?.ptxIncludedFile;
329
338
  }
330
- function ft(e, r) {
339
+ function wt(e, r) {
331
340
  const t = e.data ?? (e.data = {});
332
341
  t.ptxIncludedFile = r;
333
342
  }
@@ -337,30 +346,30 @@ function L(e, r) {
337
346
  (n === "xmlns" || n.startsWith("xmlns:")) && (t === e && (t = { ...e }), t[n === "xmlns" ? "" : n.slice(6)] = o ?? "");
338
347
  return t;
339
348
  }
340
- function ve(e, r) {
349
+ function ye(e, r) {
341
350
  const t = e.name.indexOf(":"), n = t === -1 ? "" : e.name.slice(0, t);
342
- return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && r[n] === ge;
351
+ return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && r[n] === xe;
343
352
  }
344
- async function P(e, r, t, n) {
353
+ async function R(e, r, t, n) {
345
354
  let o = !1;
346
355
  for (let i = 0; i < e.children.length; i++) {
347
356
  const s = e.children[i];
348
357
  if (s.type !== "element")
349
358
  continue;
350
359
  const a = L(t, s);
351
- if (ve(s, a)) {
352
- const l = await xe(
360
+ if (ye(s, a)) {
361
+ const c = await Te(
353
362
  s,
354
363
  r,
355
364
  a,
356
365
  n
357
366
  );
358
- e.children.splice(i, 1, ...l), i += l.length - 1, o = !0;
359
- } else await P(s, r, a, n) && (o = !0);
367
+ e.children.splice(i, 1, ...c), i += c.length - 1, o = !0;
368
+ } else await R(s, r, a, n) && (o = !0);
360
369
  }
361
370
  return o;
362
371
  }
363
- async function xe(e, r, t, n) {
372
+ async function Te(e, r, t, n) {
364
373
  const o = n.stack[n.stack.length - 1];
365
374
  if (e.attributes.xpointer)
366
375
  throw new Error(
@@ -374,8 +383,8 @@ async function xe(e, r, t, n) {
374
383
  s = decodeURIComponent(i);
375
384
  } catch {
376
385
  }
377
- const a = u.resolve(r, s);
378
- if (a !== n.projectDir && !a.startsWith(n.projectDir + u.sep))
386
+ const a = f.resolve(r, s);
387
+ if (a !== n.projectDir && !a.startsWith(n.projectDir + f.sep))
379
388
  throw new Error(
380
389
  `xi:include escapes the project directory: ${i} (in ${o})`
381
390
  );
@@ -383,20 +392,20 @@ async function xe(e, r, t, n) {
383
392
  throw new Error(
384
393
  `Circular xi:include: ${[...n.stack, a].join(" -> ")}`
385
394
  );
386
- if (n.stack.length >= ne)
387
- throw new Error(`xi:include nesting exceeds ${ne} levels`);
388
- const l = await M(a);
389
- if (l === void 0) {
390
- const p = mt(e, t);
395
+ if (n.stack.length >= re)
396
+ throw new Error(`xi:include nesting exceeds ${re} levels`);
397
+ const c = await j(a);
398
+ if (c === void 0) {
399
+ const p = vt(e, t);
391
400
  if (p)
392
- return await P(p, r, t, n), p.children;
401
+ return await R(p, r, t, n), p.children;
393
402
  throw new Error(`xi:include target not found: ${i} (in ${o})`);
394
403
  }
395
404
  if (e.attributes.parse === "text")
396
- return [{ type: "text", value: l }];
397
- let c;
405
+ return [{ type: "text", value: c }];
406
+ let l;
398
407
  try {
399
- c = E(l);
408
+ l = E(c);
400
409
  } catch (p) {
401
410
  throw new Error(
402
411
  `Could not parse xi:include target ${a} as XML: ${p instanceof Error ? p.message : p}. (Included files must be well-formed, with a single root element.)`
@@ -404,48 +413,48 @@ async function xe(e, r, t, n) {
404
413
  }
405
414
  n.stack.push(a);
406
415
  try {
407
- await P(c, u.dirname(a), { "": "" }, n);
416
+ await R(l, f.dirname(a), { "": "" }, n);
408
417
  } finally {
409
418
  n.stack.pop();
410
419
  }
411
- const f = c.children.filter(
420
+ const u = l.children.filter(
412
421
  (p) => p.type === "element"
413
422
  );
414
- for (const p of f)
415
- ft(p, a);
416
- return f;
423
+ for (const p of u)
424
+ wt(p, a);
425
+ return u;
417
426
  }
418
- function re(e) {
427
+ function oe(e) {
419
428
  return e.name === "docinfo";
420
429
  }
421
- async function pt(e, r, t) {
430
+ async function bt(e, r, t) {
422
431
  try {
423
432
  const o = E(e).children.find(
424
- (c) => c.type === "element"
433
+ (l) => l.type === "element"
425
434
  );
426
435
  if (!o)
427
436
  return;
428
- const i = u.resolve(r), s = u.dirname(i), a = {
429
- projectDir: u.resolve(t),
437
+ const i = f.resolve(r), s = f.dirname(i), a = {
438
+ projectDir: f.resolve(t),
430
439
  stack: [i]
431
- }, l = L({ "": "" }, o);
432
- for (const c of o.children) {
433
- if (c.type !== "element")
440
+ }, c = L({ "": "" }, o);
441
+ for (const l of o.children) {
442
+ if (l.type !== "element")
434
443
  continue;
435
- const f = L(l, c);
436
- if (re(c))
437
- return await P(c, s, f, a), I(c);
438
- if (ve(c, f)) {
439
- const m = (await xe(
440
- c,
444
+ const u = L(c, l);
445
+ if (oe(l))
446
+ return await R(l, s, u, a), I(l);
447
+ if (ye(l, u)) {
448
+ const h = (await Te(
449
+ l,
441
450
  s,
442
- f,
451
+ u,
443
452
  a
444
453
  )).find(
445
- (h) => h.type === "element" && re(h)
454
+ (m) => m.type === "element" && oe(m)
446
455
  );
447
- if (m)
448
- return I(m);
456
+ if (h)
457
+ return I(h);
449
458
  continue;
450
459
  }
451
460
  break;
@@ -455,67 +464,67 @@ async function pt(e, r, t) {
455
464
  return;
456
465
  }
457
466
  }
458
- function mt(e, r) {
467
+ function vt(e, r) {
459
468
  for (const t of e.children) {
460
469
  if (t.type !== "element")
461
470
  continue;
462
471
  const n = L(r, t), o = t.name.indexOf(":"), i = o === -1 ? "" : t.name.slice(0, o);
463
- if ((o === -1 ? t.name : t.name.slice(o + 1)) === "fallback" && n[i] === ge)
472
+ if ((o === -1 ? t.name : t.name.slice(o + 1)) === "fallback" && n[i] === xe)
464
473
  return t;
465
474
  }
466
475
  }
467
- function ye(e) {
476
+ function Ee(e) {
468
477
  return typeof e == "object" && e !== null && e.type === "element";
469
478
  }
470
- function ht(e) {
479
+ function gt(e) {
471
480
  return /^(pf|xhtml):/.test(e.name);
472
481
  }
473
- function wt(e, r, t) {
474
- const n = [], o = e.children.find(ye);
482
+ function xt(e, r, t) {
483
+ const n = [], o = e.children.find(Ee);
475
484
  if (o) {
476
485
  const i = t?.parentId ?? "root";
477
- Te(o, i, t?.position ?? 1, r, i, n);
486
+ Se(o, i, t?.position ?? 1, r, i, n);
478
487
  }
479
488
  return n;
480
489
  }
481
- function Te(e, r, t, n, o, i) {
482
- const s = dt(e) ?? n;
483
- let a, l;
484
- if (ht(e))
485
- l = "root";
490
+ function Se(e, r, t, n, o, i) {
491
+ const s = mt(e) ?? n;
492
+ let a, c;
493
+ if (gt(e))
494
+ c = "root";
486
495
  else {
487
- const f = e.attributes.label ?? e.attributes["xml:id"];
488
- a = f ?? `${r}-${t}`, i.push({
496
+ const u = e.attributes.label ?? e.attributes["xml:id"];
497
+ a = u ?? `${r}-${t}`, i.push({
489
498
  id: a,
490
499
  file: s,
491
500
  line: e.position?.start.line ?? 1,
492
501
  column: e.position?.start.column ?? 1,
493
502
  endLine: e.position?.end.line ?? e.position?.start.line ?? 1,
494
503
  parent: o
495
- }), l = a;
504
+ }), c = a;
496
505
  }
497
- let c = 0;
498
- for (const f of e.children)
499
- ye(f) && (c += 1, Te(
500
- f,
501
- l,
506
+ let l = 0;
507
+ for (const u of e.children)
508
+ Ee(u) && (l += 1, Se(
509
+ u,
502
510
  c,
511
+ l,
503
512
  s,
504
513
  a ?? o,
505
514
  i
506
515
  ));
507
516
  }
508
- function nn(e, r) {
517
+ function cn(e, r) {
509
518
  let t;
510
519
  for (const n of e)
511
520
  n.line <= r && (t = n);
512
521
  return t ?? e[0];
513
522
  }
514
- function bt(e) {
523
+ function yt(e) {
515
524
  const r = e.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, " ");
516
525
  return /<\s*slide(?:show)?[\s/>]/.test(r) ? "slides" : "html";
517
526
  }
518
- const Ee = /* @__PURE__ */ new Set([
527
+ const ke = /* @__PURE__ */ new Set([
519
528
  "colophon",
520
529
  "biography",
521
530
  "dedication",
@@ -535,19 +544,19 @@ const Ee = /* @__PURE__ */ new Set([
535
544
  "glossary",
536
545
  "worksheet",
537
546
  "handout"
538
- ]), Se = /* @__PURE__ */ new Set([
547
+ ]), $e = /* @__PURE__ */ new Set([
539
548
  "book",
540
549
  "article",
541
550
  "slideshow",
542
551
  "letter",
543
552
  "memo"
544
- ]), ke = /* @__PURE__ */ new Set([
545
- ...Se,
546
- ...Ee,
553
+ ]), Pe = /* @__PURE__ */ new Set([
554
+ ...$e,
555
+ ...ke,
547
556
  "part",
548
557
  "frontmatter",
549
558
  "backmatter"
550
- ]), gt = /* @__PURE__ */ new Set(["docinfo"]), $e = /* @__PURE__ */ new Set([
559
+ ]), Tt = /* @__PURE__ */ new Set(["docinfo"]), Ie = /* @__PURE__ */ new Set([
551
560
  "title",
552
561
  "shorttitle",
553
562
  "plaintitle",
@@ -557,13 +566,13 @@ const Ee = /* @__PURE__ */ new Set([
557
566
  function g(e) {
558
567
  return e.type === "element";
559
568
  }
560
- function Ie(e) {
569
+ function Re(e) {
561
570
  return e.attributes["xml:id"] ?? void 0;
562
571
  }
563
572
  function X(e, r) {
564
573
  for (const t of e.children) {
565
574
  if (!g(t)) continue;
566
- if (Ie(t) === r) return t;
575
+ if (Re(t) === r) return t;
567
576
  const n = X(t, r);
568
577
  if (n) return n;
569
578
  }
@@ -576,28 +585,28 @@ function A(e, r) {
576
585
  if (n) return [t, ...n];
577
586
  }
578
587
  }
579
- function vt(e, r) {
588
+ function Et(e, r) {
580
589
  let t = 0;
581
590
  for (const [n, o] of e.entries()) {
582
591
  const i = n === 0 ? void 0 : e[n - 1];
583
- Se.has(o.name) ? t = 0 : o.name === "frontmatter" || o.name === "backmatter" || o.name === "part" ? t = i?.name === "book" && r ? 1 : 0 : Ee.has(o.name) && (t += 1);
592
+ $e.has(o.name) ? t = 0 : o.name === "frontmatter" || o.name === "backmatter" || o.name === "part" ? t = i?.name === "book" && r ? 1 : 0 : ke.has(o.name) && (t += 1);
584
593
  }
585
594
  return t;
586
595
  }
587
- function Pe(e) {
588
- if (!$e.has(e.name)) {
596
+ function De(e) {
597
+ if (!Ie.has(e.name)) {
589
598
  e.children = e.children.filter(g);
590
599
  for (const r of e.children)
591
- Pe(r);
600
+ De(r);
592
601
  }
593
602
  }
594
603
  function U(e, r) {
595
604
  const t = [];
596
605
  for (const n of e.children)
597
- g(n) && (r.has(n) || gt.has(n.name) || $e.has(n.name) ? t.push(n) : ke.has(n.name) && (U(n, r), t.push(n)));
606
+ g(n) && (r.has(n) || Tt.has(n.name) || Ie.has(n.name) ? t.push(n) : Pe.has(n.name) && (U(n, r), t.push(n)));
598
607
  e.children = t;
599
608
  }
600
- function xt(e) {
609
+ function St(e) {
601
610
  const r = /* @__PURE__ */ new Set(), t = (n) => {
602
611
  if (n.name === "xref") {
603
612
  const o = [
@@ -614,11 +623,11 @@ function xt(e) {
614
623
  };
615
624
  return t(e), r;
616
625
  }
617
- function yt(e, r, t) {
626
+ function kt(e, r, t) {
618
627
  const n = (o) => {
619
628
  for (const [i, s] of o.children.entries())
620
629
  if (g(s)) {
621
- if (Ie(s) === r)
630
+ if (Re(s) === r)
622
631
  return o.children[i] = t, !0;
623
632
  if (n(s)) return !0;
624
633
  }
@@ -626,49 +635,49 @@ function yt(e, r, t) {
626
635
  };
627
636
  return n(e);
628
637
  }
629
- function Tt(e, r) {
638
+ function $t(e, r) {
630
639
  const t = X(e, r);
631
640
  if (!t) return;
632
641
  const n = A(e, t);
633
642
  if (!n) return;
634
643
  const o = n.filter(
635
- (m) => m.name !== "pretext" && m.name !== "mathbook"
644
+ (h) => h.name !== "pretext" && h.name !== "mathbook"
636
645
  ), i = o[0], s = i?.name === "book" && i.children.some(
637
- (m) => g(m) && m.name === "part"
638
- ), a = vt(o, s), l = new Set(n), c = xt(t), f = /* @__PURE__ */ new Set();
639
- if (c.size > 0)
640
- for (const m of c) {
641
- const h = X(e, m);
642
- if (!h || h === t) continue;
643
- const R = A(e, h);
644
- if (!R) continue;
645
- const v = [...R].reverse().find((b) => ke.has(b.name));
646
- if (v && v !== t) {
647
- f.add(v);
648
- for (const b of A(e, v) ?? [])
649
- l.add(b);
646
+ (h) => g(h) && h.name === "part"
647
+ ), a = Et(o, s), c = new Set(n), l = St(t), u = /* @__PURE__ */ new Set();
648
+ if (l.size > 0)
649
+ for (const h of l) {
650
+ const m = X(e, h);
651
+ if (!m || m === t) continue;
652
+ const D = A(e, m);
653
+ if (!D) continue;
654
+ const x = [...D].reverse().find((v) => Pe.has(v.name));
655
+ if (x && x !== t) {
656
+ u.add(x);
657
+ for (const v of A(e, x) ?? [])
658
+ c.add(v);
650
659
  }
651
660
  }
652
- for (const m of n) {
653
- if (m === t) break;
654
- U(m, l);
661
+ for (const h of n) {
662
+ if (h === t) break;
663
+ U(h, c);
655
664
  }
656
- for (const m of f)
657
- Pe(m);
665
+ for (const h of u)
666
+ De(h);
658
667
  const p = e.children.find(g);
659
- return p && !n.includes(p) && U(p, l), { content: I(e), divisionId: r, level: a };
668
+ return p && !n.includes(p) && U(p, c), { content: I(e), divisionId: r, level: a };
660
669
  }
661
- const Et = "This live preview shows a single division, so links into the rest of the document do not work here.", St = /<a\b([^>]*)>/g, kt = /\sid="([^"]*)"/g, j = /\shref="([^"]*)"/, $t = /\\href\{([^{}]*)\}/g, oe = /\stitle="([^"]*)"/;
662
- function It(e) {
670
+ const Pt = "This live preview shows a single division, so links into the rest of the document do not work here.", It = /<a\b([^>]*)>/g, Rt = /\sid="([^"]*)"/g, _ = /\shref="([^"]*)"/, Dt = /\\href\{([^{}]*)\}/g, ie = /\stitle="([^"]*)"/;
671
+ function At(e) {
663
672
  const r = /* @__PURE__ */ new Set();
664
- for (const t of e.matchAll(kt))
673
+ for (const t of e.matchAll(Rt))
665
674
  r.add(t[1]);
666
675
  return r;
667
676
  }
668
- function Pt(e) {
677
+ function Lt(e) {
669
678
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
670
679
  }
671
- function ie(e, r) {
680
+ function se(e, r) {
672
681
  if (e.startsWith("#") || e === "") return { kind: "keep" };
673
682
  if (/^[a-z][a-z0-9+.-]*:/i.test(e) || e.startsWith("//"))
674
683
  return { kind: "keep" };
@@ -677,73 +686,73 @@ function ie(e, r) {
677
686
  const n = e.slice(t + 1);
678
687
  return r.has(n) && n !== "" ? { kind: "same-page", id: n } : { kind: "off-page" };
679
688
  }
680
- function Rt(e, r = {}) {
681
- const t = r.offPageMessage ?? Et, n = It(e);
682
- return e.replace(St, (i, s) => {
683
- const a = j.exec(s);
689
+ function jt(e, r = {}) {
690
+ const t = r.offPageMessage ?? Pt, n = At(e);
691
+ return e.replace(It, (i, s) => {
692
+ const a = _.exec(s);
684
693
  if (!a) return i;
685
- const l = ie(a[1], n);
686
- if (l.kind === "keep") return i;
687
- if (l.kind === "same-page")
688
- return `<a${s.replace(j, ` href="#${l.id}"`)}>`;
689
- const c = oe.exec(s), f = Pt(t), p = c ? `${c[1]} — ${f}` : f;
690
- return `<a${s.replace(j, "").replace(oe, "")} title="${p}" aria-disabled="true" style="cursor:default">`;
691
- }).replace($t, (i, s) => {
692
- const a = ie(s, n);
694
+ const c = se(a[1], n);
695
+ if (c.kind === "keep") return i;
696
+ if (c.kind === "same-page")
697
+ return `<a${s.replace(_, ` href="#${c.id}"`)}>`;
698
+ const l = ie.exec(s), u = Lt(t), p = l ? `${l[1]} — ${u}` : u;
699
+ return `<a${s.replace(_, "").replace(ie, "")} title="${p}" aria-disabled="true" style="cursor:default">`;
700
+ }).replace(Dt, (i, s) => {
701
+ const a = se(s, n);
693
702
  return a.kind === "same-page" ? `\\href{#${a.id}}` : i;
694
703
  });
695
704
  }
696
- function Dt() {
697
- return We(C(), "xsl");
705
+ function Mt() {
706
+ return Ke(C(), "xsl");
698
707
  }
699
- function At() {
708
+ function _t() {
700
709
  return "Suspending" in WebAssembly;
701
710
  }
702
- function Lt() {
703
- if (!At())
711
+ function Bt() {
712
+ if (!_t())
704
713
  throw new Error(
705
714
  "WebAssembly JSPI is not enabled. Run Node with --experimental-wasm-jspi (or use the pretext-html CLI, which re-launches itself with the flag)."
706
715
  );
707
716
  }
708
- function $(e) {
717
+ function P(e) {
709
718
  return e.includes("'") ? e.includes('"') ? `concat(${e.split("'").map((t) => `'${t}'`).join(`, "'", `)})` : `"${e}"` : `'${e}'`;
710
719
  }
711
- function Mt(e) {
720
+ function Ot(e) {
712
721
  return e.replace(
713
722
  /from '\.\/(https:\/\/[^']+)'/g,
714
723
  (r, t) => `from '${t}'`
715
724
  );
716
725
  }
717
- const _t = `https://cdn.jsdelivr.net/gh/PreTeXtBook/html-static@${pe}/dist/`, jt = {
718
- "cli.version": pe,
726
+ const Ct = `https://cdn.jsdelivr.net/gh/PreTeXtBook/html-static@${me}/dist/`, Ft = {
727
+ "cli.version": me,
719
728
  // Colon-delimited: pretext-runestone.xsl splits them with str:tokenize.
720
- "rs-js": Je.join(":"),
721
- "rs-css": ze.join(":"),
722
- "rs-version": He
729
+ "rs-js": Ge.join(":"),
730
+ "rs-css": Ye.join(":"),
731
+ "rs-version": Ve
723
732
  };
724
- function Bt(e) {
733
+ function Nt(e) {
725
734
  return e.replace(
726
735
  /(<link\b[^>]*\bhref=["'])_static\//gi,
727
- `$1${_t}_static/`
736
+ `$1${Ct}_static/`
728
737
  );
729
738
  }
730
- function Ot(e) {
739
+ function Xt(e) {
731
740
  return e.slice(0, 65536).replace(/<\?[\s\S]*?\?>/g, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<!DOCTYPE[^>]*>/gi, " ").match(/<\s*([A-Za-z][\w:-]*)/)?.[1];
732
741
  }
733
- async function se(e) {
734
- const r = await M(e);
742
+ async function ae(e) {
743
+ const r = await j(e);
735
744
  if (r === void 0)
736
745
  throw new Error(
737
746
  `Could not read ${e}. (In the browser build only absolute URLs are readable — pass sourceContent instead of relying on sourcePath.)`
738
747
  );
739
748
  return r;
740
749
  }
741
- async function Ct(e, r) {
742
- const t = u.resolve(e), n = await M(t);
750
+ async function Ut(e, r) {
751
+ const t = f.resolve(e), n = await j(t);
743
752
  if (n !== void 0)
744
- return pt(n, t, r);
753
+ return bt(n, t, r);
745
754
  }
746
- function Ft(e, r, t, n) {
755
+ function Wt(e, r, t, n) {
747
756
  const o = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), i = t === "slides" ? "slideshow" : r === "chapter" || r === "part" ? "book" : "article";
748
757
  return `<pretext>
749
758
  ${n?.trim() ? `${n.trim()}
@@ -754,51 +763,51 @@ ${o}
754
763
  </pretext>
755
764
  `;
756
765
  }
757
- async function Nt(e, r, t, n) {
766
+ async function Ht(e, r, t, n) {
758
767
  const o = E(e).children.find(
759
- (f) => f.type === "element"
768
+ (u) => u.type === "element"
760
769
  ), i = o?.attributes["xml:id"];
761
770
  if (!o || !i) return;
762
- const s = u.resolve(r), a = n ?? await M(s);
771
+ const s = f.resolve(r), a = n ?? await j(s);
763
772
  if (a === void 0) return;
764
- let l;
773
+ let c;
765
774
  try {
766
- l = (await J(a, s, t)).tree;
775
+ c = (await J(a, s, t)).tree;
767
776
  } catch {
768
777
  return;
769
778
  }
770
- if (!yt(l, i, o)) return;
771
- const c = Tt(l, i);
772
- if (c)
773
- return { ...c, tree: l };
779
+ if (!kt(c, i, o)) return;
780
+ const l = $t(c, i);
781
+ if (l)
782
+ return { ...l, tree: c };
774
783
  }
775
- let Re = !1;
776
- function Xt(e) {
784
+ let Ae = !1;
785
+ function Jt(e) {
777
786
  return e instanceof Error && /\bAborted\(/.test(e.message);
778
787
  }
779
- function Ut(e) {
788
+ function zt(e) {
780
789
  return e instanceof Error && /memory access|out of bounds/i.test(e.message);
781
790
  }
782
- function Wt() {
783
- if (Re)
791
+ function Kt() {
792
+ if (Ae)
784
793
  throw new Error(
785
794
  "The WebAssembly renderer aborted earlier in this process and cannot be reused. Restart the process (or reload the page) to render again."
786
795
  );
787
796
  }
788
- function ae(e) {
789
- if (Xt(e))
790
- throw Re = !0, new Error(
797
+ function ce(e) {
798
+ if (Jt(e))
799
+ throw Ae = !0, new Error(
791
800
  "The WebAssembly renderer aborted and cannot be reused. Restart the process (or reload the page) to render again.",
792
801
  { cause: e }
793
802
  );
794
- if (Ut(e))
803
+ if (zt(e))
795
804
  throw new Error(
796
805
  "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.",
797
806
  { cause: e }
798
807
  );
799
808
  }
800
809
  let B;
801
- async function De() {
810
+ async function Le() {
802
811
  return B || (B = (async () => {
803
812
  const [e, r] = await Promise.all([
804
813
  import("@pretextbook/libxslt-wasm"),
@@ -807,121 +816,121 @@ async function De() {
807
816
  return r.registerAll(), e;
808
817
  })()), B;
809
818
  }
810
- const O = /* @__PURE__ */ new Map(), Ht = {
819
+ const O = /* @__PURE__ */ new Map(), Vt = {
811
820
  html: "preview-html.xsl",
812
821
  slides: "preview-revealjs.xsl"
813
822
  };
814
- async function Jt(e, r) {
815
- const t = Ht[r], n = `${r}\0${e}`;
823
+ async function Gt(e, r) {
824
+ const t = Vt[r], n = `${r}\0${e}`;
816
825
  let o = O.get(n);
817
826
  return o || (o = (async () => {
818
- const { XmlDocument: i, XsltStylesheet: s } = await De(), a = be(e), l = await de(C(), `/${t}`);
819
- if (l === void 0)
827
+ const { XmlDocument: i, XsltStylesheet: s } = await Le(), a = ge(e), c = await pe(C(), `/${t}`);
828
+ if (c === void 0)
820
829
  throw new Error(
821
830
  `Could not read ${t} from ${C()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
822
831
  );
823
- const c = new TextDecoder().decode(l), f = await i.fromString(c, {
832
+ const l = new TextDecoder().decode(c), u = await i.fromString(l, {
824
833
  url: `${a}/${t}`,
825
834
  options: { noEnt: !0, dtdLoad: !0, huge: !0 }
826
835
  });
827
- return s.fromXmlDocument(f);
836
+ return s.fromXmlDocument(u);
828
837
  })(), O.set(n, o), o.catch(() => O.delete(n))), o;
829
838
  }
830
- let ce = Promise.resolve();
831
- function zt(e) {
832
- const r = ce.then(
833
- () => le(e),
834
- () => le(e)
839
+ let le = Promise.resolve();
840
+ function Yt(e) {
841
+ const r = le.then(
842
+ () => ue(e),
843
+ () => ue(e)
835
844
  );
836
- return ce = r.catch(() => {
845
+ return le = r.catch(() => {
837
846
  }), r;
838
847
  }
839
- async function le(e) {
840
- Lt(), Wt();
841
- const { XmlDocument: r } = await De(), t = u.resolve(e.sourcePath), n = u.resolve(
842
- e.projectDir ?? u.dirname(t)
843
- ), o = e.sourceContent ?? await se(t), i = u.relative(n, t);
848
+ async function ue(e) {
849
+ Bt(), Kt();
850
+ const { XmlDocument: r } = await Le(), t = f.resolve(e.sourcePath), n = f.resolve(
851
+ e.projectDir ?? f.dirname(t)
852
+ ), o = e.sourceContent ?? await ae(t), i = f.relative(n, t);
844
853
  if (i.startsWith(".."))
845
854
  throw new Error(
846
855
  `sourcePath (${t}) must live inside projectDir (${n})`
847
856
  );
848
- const s = u.relative(
857
+ const s = f.relative(
849
858
  n,
850
- u.resolve(e.mainSourcePath ?? t)
851
- ), a = s.startsWith("..") ? i : s, l = be(n);
859
+ f.resolve(e.mainSourcePath ?? t)
860
+ ), a = s.startsWith("..") ? i : s, c = ge(n);
852
861
  try {
853
- let c, f = `${l}/__pretext-preview-publication.xml`;
862
+ let l, u = `${c}/__pretext-preview-publication.xml`;
854
863
  if (e.publicationPath) {
855
- const d = u.resolve(e.publicationPath);
856
- c = await se(d);
857
- const w = u.relative(n, d);
858
- w.startsWith("..") || (f = `${l}/${w.split(u.sep).join("/")}`);
864
+ const d = f.resolve(e.publicationPath);
865
+ l = await ae(d);
866
+ const w = f.relative(n, d);
867
+ w.startsWith("..") || (u = `${c}/${w.split(f.sep).join("/")}`);
859
868
  }
860
- let p, m;
869
+ let p, h;
861
870
  if (e.sourceMap) {
862
871
  const d = await J(
863
872
  o,
864
873
  t,
865
874
  n
866
875
  );
867
- p = d.tree, m = d.content;
876
+ p = d.tree, h = d.content;
868
877
  } else
869
- m = await ut(
878
+ h = await ht(
870
879
  o,
871
880
  t,
872
881
  n
873
882
  );
874
- const h = e.target ?? bt(m), R = await Jt(e.xslDir ?? Dt(), h), v = ct(c, {
883
+ const m = e.target ?? yt(h), D = await Gt(e.xslDir ?? Mt(), m), x = ft(l, {
875
884
  cssTheme: e.cssTheme,
876
885
  revealTheme: e.revealTheme,
877
- target: h
886
+ target: m
878
887
  });
879
- rt(f, v);
880
- const b = lt(v), z = u.dirname(u.resolve(n, a)), K = b.external !== void 0 && b.generated !== void 0 ? {
881
- external: u.resolve(z, b.external),
882
- generated: u.resolve(z, b.generated)
883
- } : void 0, D = Ot(m);
884
- let V = { parentId: "root", position: 1 }, S, G = t;
885
- if (D !== "pretext" && D !== "mathbook") {
888
+ at(u, x);
889
+ const v = pt(x), z = f.dirname(f.resolve(n, a)), K = v.external !== void 0 && v.generated !== void 0 ? {
890
+ external: f.resolve(z, v.external),
891
+ generated: f.resolve(z, v.generated)
892
+ } : void 0, S = Xt(h);
893
+ let V = { parentId: "root", position: 1 }, k, G = t;
894
+ if (S !== "pretext" && S !== "mathbook") {
886
895
  if (!e.fragment)
887
896
  throw new Error(
888
- `The document root is <${D ?? "?"}>, not <pretext> — this looks like an xi:included fragment. Render the project's main source file instead, or pass the fragment option.`
897
+ `The document root is <${S ?? "?"}>, not <pretext> — this looks like an xi:included fragment. Render the project's main source file instead, or pass the fragment option.`
889
898
  );
890
899
  if (e.contextSourcePath || e.contextSourceContent) {
891
- const d = e.contextSourcePath ?? u.join(u.dirname(t), "__pretext-preview-context.ptx"), w = await Nt(
892
- m,
900
+ const d = e.contextSourcePath ?? f.join(f.dirname(t), "__pretext-preview-context.ptx"), w = await Ht(
901
+ h,
893
902
  d,
894
903
  n,
895
904
  e.contextSourceContent
896
905
  );
897
- w && (m = w.content, p = e.sourceMap ? w.tree : void 0, G = u.resolve(d), S = { divisionId: w.divisionId, level: w.level });
906
+ w && (h = w.content, p = e.sourceMap ? w.tree : void 0, G = f.resolve(d), k = { divisionId: w.divisionId, level: w.level });
898
907
  }
899
- if (!S) {
900
- const d = e.docinfo ?? (e.docinfoSourcePath ? await Ct(e.docinfoSourcePath, n) : void 0);
901
- m = Ft(
902
- m,
903
- D,
908
+ if (!k) {
909
+ const d = e.docinfo ?? (e.docinfoSourcePath ? await Ut(e.docinfoSourcePath, n) : void 0);
910
+ h = Wt(
904
911
  h,
912
+ S,
913
+ m,
905
914
  d
906
915
  ), V = { parentId: d?.trim() ? "root-1-2" : "root-1-1", position: 2 };
907
916
  }
908
917
  }
909
- const Y = p ? wt(p, G, V) : void 0, q = await r.fromString(m, {
910
- url: `${l}/${a.split(u.sep).join("/")}`,
918
+ const Y = p ? xt(p, G, V) : void 0, q = await r.fromString(h, {
919
+ url: `${c}/${a.split(f.sep).join("/")}`,
911
920
  options: { noEnt: !0, dtdLoad: !0, huge: !0 }
912
- }), k = {
913
- publisher: $(f)
921
+ }), $ = {
922
+ publisher: P(u)
914
923
  };
915
- for (const [d, w] of Object.entries(jt))
916
- k[d] = $(w);
917
- S && (k.subtree = $(S.divisionId), k["subtree-level"] = $(String(S.level)));
924
+ for (const [d, w] of Object.entries(Ft))
925
+ $[d] = P(w);
926
+ k && ($.subtree = P(k.divisionId), $["subtree-level"] = P(String(k.level)));
918
927
  for (const [d, w] of Object.entries(e.stringParams ?? {}))
919
- k[d] = $(w);
920
- let _;
928
+ $[d] = P(w);
929
+ let M;
921
930
  try {
922
- _ = await R.apply(q, k);
931
+ M = await D.apply(q, $);
923
932
  } catch (d) {
924
- throw ae(d), new Error(
933
+ throw ce(d), new Error(
925
934
  "PreTeXt XSLT transform failed; see the PTX:ERROR/PTX:FATAL messages on stderr for details.",
926
935
  { cause: d }
927
936
  );
@@ -929,27 +938,31 @@ async function le(e) {
929
938
  q.delete();
930
939
  }
931
940
  try {
932
- let d = Mt(_.toHtmlString());
933
- return d = Rt(d, {
941
+ let d = Ot(M.toHtmlString());
942
+ d = jt(d, {
934
943
  ...e.offPageMessage !== void 0 ? { offPageMessage: e.offPageMessage } : {}
935
- }), (e.openKnowls ?? !0) && (d = qe(d)), h === "slides" ? (d = Bt(d), d = Le(d, e.revealView ?? "scroll", {
944
+ }), (e.openKnowls ?? !0) && (d = tt(d)), m === "slides" ? (d = Nt(d), d = Be(d, e.revealView ?? "scroll", {
936
945
  zoom: e.revealZoom
937
- })) : e.theme && (d = Me(d, e.theme)), e.previewBanner && (d = Ue(d, e.previewBanner)), {
946
+ })) : e.theme && (d = Oe(d, e.theme)), e.previewBanner && (d = ze(d, e.previewBanner));
947
+ const w = m === "slides" ? [] : je(d), Z = Me(w, S);
948
+ return e.printPreview && (d = fe(d, e.printPreview)), {
938
949
  html: d,
939
- target: h,
950
+ target: m,
951
+ printouts: w,
940
952
  ...Y ? { sourceMap: Y } : {},
941
- ...K ? { assetDirs: K } : {}
953
+ ...K ? { assetDirs: K } : {},
954
+ ...Z ? { rootPrintout: Z } : {}
942
955
  };
943
956
  } catch (d) {
944
- throw ae(d), d;
957
+ throw ce(d), d;
945
958
  } finally {
946
- _.delete();
959
+ M.delete();
947
960
  }
948
961
  } finally {
949
- nt(l);
962
+ st(c);
950
963
  }
951
964
  }
952
- const ue = `Usage: pretext-html <source.ptx> [options]
965
+ const de = `Usage: pretext-html <source.ptx> [options]
953
966
 
954
967
  Render a PreTeXt document to a single standalone HTML page (portable build:
955
968
  one page, css/js/MathJax from CDN). No PreTeXt installation required.
@@ -987,67 +1000,82 @@ Options:
987
1000
  knowls collapsed, as a real PreTeXt build does.
988
1001
  They are expanded by default, since these pages
989
1002
  are previews of work in progress
1003
+ --print-preview[=id] Open the page in the print-preview layout: the
1004
+ named printout paginated to a paper size, with
1005
+ workspaces at their true height. Without an id, the
1006
+ document's own printout is used (a lone worksheet
1007
+ or handout), or failing that its first. The page's
1008
+ printouts are listed on stderr
990
1009
  -h, --help Show this help
991
1010
  `;
992
- function Kt(e) {
993
- let r, t, n, o;
994
- const i = {}, s = {};
995
- for (let a = 0; a < e.length; a++) {
996
- const l = e[a], c = () => {
997
- if (a += 1, a >= e.length)
1011
+ function qt(e) {
1012
+ let r, t, n, o, i;
1013
+ const s = {}, a = {};
1014
+ for (let c = 0; c < e.length; c++) {
1015
+ const l = e[c], u = () => {
1016
+ if (c += 1, c >= e.length)
998
1017
  throw new Error(`Missing value for ${l}`);
999
- return e[a];
1018
+ return e[c];
1000
1019
  };
1001
1020
  switch (l) {
1002
1021
  case "-h":
1003
1022
  case "--help":
1004
- y.stdout.write(ue), y.exit(0);
1023
+ b.stdout.write(de), b.exit(0);
1005
1024
  break;
1006
1025
  case "-o":
1007
1026
  case "--output":
1008
- t = c();
1027
+ t = u();
1009
1028
  break;
1010
1029
  case "--publication":
1011
- i.publicationPath = c();
1030
+ s.publicationPath = u();
1012
1031
  break;
1013
1032
  case "--css-theme":
1014
- i.cssTheme = c();
1033
+ s.cssTheme = u();
1015
1034
  break;
1016
1035
  case "--project-dir":
1017
- i.projectDir = c();
1036
+ s.projectDir = u();
1018
1037
  break;
1019
1038
  case "--xsl-dir":
1020
- i.xslDir = c();
1039
+ s.xslDir = u();
1021
1040
  break;
1022
1041
  case "--fragment":
1023
- i.fragment = !0;
1042
+ s.fragment = !0;
1024
1043
  break;
1025
1044
  case "--no-open-knowls":
1026
- i.openKnowls = !1;
1045
+ s.openKnowls = !1;
1027
1046
  break;
1028
1047
  case "--docinfo":
1029
- n = c();
1048
+ n = u();
1030
1049
  break;
1031
1050
  case "--docinfo-source":
1032
- i.docinfoSourcePath = c();
1051
+ s.docinfoSourcePath = u();
1033
1052
  break;
1034
1053
  case "--context":
1035
- i.contextSourcePath = c();
1054
+ s.contextSourcePath = u();
1036
1055
  break;
1037
1056
  case "--off-page-message":
1038
- i.offPageMessage = c();
1057
+ s.offPageMessage = u();
1039
1058
  break;
1040
1059
  case "--source-map":
1041
- o = c(), i.sourceMap = !0;
1060
+ o = u(), s.sourceMap = !0;
1061
+ break;
1062
+ // Attached form only (--print-preview=<id>), so that a bare
1063
+ // --print-preview cannot swallow the source file as its id.
1064
+ case "--print-preview":
1065
+ i = !0;
1042
1066
  break;
1043
1067
  case "--param": {
1044
- const f = c(), p = f.indexOf("=");
1045
- if (p === -1)
1046
- throw new Error(`--param expects name=value, got: ${f}`);
1047
- s[f.slice(0, p)] = f.slice(p + 1);
1068
+ const p = u(), h = p.indexOf("=");
1069
+ if (h === -1)
1070
+ throw new Error(`--param expects name=value, got: ${p}`);
1071
+ a[p.slice(0, h)] = p.slice(h + 1);
1048
1072
  break;
1049
1073
  }
1050
1074
  default:
1075
+ if (l.startsWith("--print-preview=")) {
1076
+ i = l.slice(16);
1077
+ break;
1078
+ }
1051
1079
  if (l.startsWith("-"))
1052
1080
  throw new Error(`Unknown option: ${l}`);
1053
1081
  if (r)
@@ -1058,42 +1086,57 @@ function Kt(e) {
1058
1086
  if (!r)
1059
1087
  throw new Error(`No source file given.
1060
1088
 
1061
- ` + ue);
1062
- return Object.keys(s).length > 0 && (i.stringParams = s), {
1063
- options: { ...i, sourcePath: r },
1089
+ ` + de);
1090
+ return Object.keys(a).length > 0 && (s.stringParams = a), {
1091
+ options: { ...s, sourcePath: r },
1064
1092
  output: t,
1065
1093
  docinfoPath: n,
1066
- sourceMapPath: o
1094
+ sourceMapPath: o,
1095
+ printPreview: i
1067
1096
  };
1068
1097
  }
1069
- async function rn(e) {
1070
- const { options: r, output: t, docinfoPath: n, sourceMapPath: o } = Kt(e);
1098
+ async function ln(e) {
1099
+ const { options: r, output: t, docinfoPath: n, sourceMapPath: o, printPreview: i } = qt(e);
1071
1100
  n && (r.docinfo = await W(n, "utf8"));
1072
- const i = Date.now(), { html: s, sourceMap: a } = await zt(r);
1073
- y.stderr.write(`pretext-html: rendered in ${Date.now() - i}ms
1074
- `), o && a && (await Z(o, JSON.stringify(a, null, 2)), y.stderr.write(`pretext-html: wrote ${o}
1075
- `)), t ? (await Z(t, s), y.stderr.write(`pretext-html: wrote ${t}
1076
- `)) : y.stdout.write(s);
1101
+ const s = Date.now(), a = await Yt(r), { sourceMap: c, printouts: l, rootPrintout: u } = a;
1102
+ let p = a.html;
1103
+ if (b.stderr.write(`pretext-html: rendered in ${Date.now() - s}ms
1104
+ `), i !== void 0) {
1105
+ for (const m of l)
1106
+ b.stderr.write(
1107
+ `pretext-html: printout ${m.id} - ${m.label}
1108
+ `
1109
+ );
1110
+ const h = typeof i == "string" ? i : u ?? l[0]?.id;
1111
+ h ? (b.stderr.write(`pretext-html: print preview of ${h}
1112
+ `), p = fe(p, h)) : b.stderr.write(
1113
+ `pretext-html: --print-preview: this document has no printouts (worksheet, handout, or project with a workspace); writing the ordinary page.
1114
+ `
1115
+ );
1116
+ }
1117
+ o && c && (await Q(o, JSON.stringify(c, null, 2)), b.stderr.write(`pretext-html: wrote ${o}
1118
+ `)), t ? (await Q(t, p), b.stderr.write(`pretext-html: wrote ${t}
1119
+ `)) : b.stdout.write(p);
1077
1120
  }
1078
1121
  export {
1079
- Et as O,
1080
- _e as P,
1081
- bt as a,
1082
- Tt as b,
1083
- vt as c,
1084
- Dt as d,
1085
- ct as e,
1086
- nn as f,
1087
- At as g,
1088
- yt as h,
1089
- Ue as i,
1090
- Rt as j,
1091
- tn as k,
1092
- Kt as l,
1093
- rn as m,
1094
- qe as o,
1095
- Ce as p,
1096
- zt as r,
1097
- en as s,
1098
- $ as x
1122
+ Pt as O,
1123
+ Ce as P,
1124
+ yt as a,
1125
+ $t as b,
1126
+ Et as c,
1127
+ Mt as d,
1128
+ ft as e,
1129
+ cn as f,
1130
+ _t as g,
1131
+ kt as h,
1132
+ ze as i,
1133
+ jt as j,
1134
+ an as k,
1135
+ qt as l,
1136
+ ln as m,
1137
+ tt as o,
1138
+ Ue as p,
1139
+ Yt as r,
1140
+ sn as s,
1141
+ P as x
1099
1142
  };