@pretextbook/pretext-html 0.16.1 → 0.18.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.
- package/README.md +163 -18
- package/assets/preview-html.xsl +81 -14
- package/assets/preview-revealjs.xsl +7 -2
- package/dist/assets.d.ts +9 -5
- package/dist/banner.d.ts +2 -2
- package/dist/cli-CKAOX3L6.js +1494 -0
- package/dist/cli.d.ts +12 -1
- package/dist/cli.js +8 -3
- package/dist/index.browser.d.ts +10 -5
- package/dist/index.browser.js +1182 -856
- package/dist/index.d.ts +10 -4
- package/dist/index.js +49 -44
- package/dist/publication.d.ts +75 -21
- package/dist/renderer.d.ts +151 -23
- package/dist/skeleton.d.ts +68 -7
- package/dist/source-cache.d.ts +36 -0
- package/dist/sourcemap.d.ts +11 -1
- package/dist/subtree.d.ts +79 -0
- package/dist/target.d.ts +1 -1
- package/dist/xinclude.d.ts +40 -3
- package/package.json +1 -1
- package/dist/cli-DzlCZymu.js +0 -1145
|
@@ -0,0 +1,1494 @@
|
|
|
1
|
+
import { existsSync as lt } from "node:fs";
|
|
2
|
+
import { readFile as de, writeFile as Te } from "node:fs/promises";
|
|
3
|
+
import * as f from "node:path";
|
|
4
|
+
import * as L from "node:process";
|
|
5
|
+
import { fileURLToPath as ut, pathToFileURL as dt } from "node:url";
|
|
6
|
+
import { rewriteAssetUrls as ft, missingAssetPlaceholder as ht } from "./assets.js";
|
|
7
|
+
import { listPrintouts as pt, rootPrintoutId as mt, injectPrintPreview as Ce } from "./printout.js";
|
|
8
|
+
import { fromXml as B } from "xast-util-from-xml";
|
|
9
|
+
import { toXml as N } from "xast-util-to-xml";
|
|
10
|
+
import { injectRevealBridge as vt } from "./reveal.js";
|
|
11
|
+
import { injectThemeBridge as bt } from "./theme.js";
|
|
12
|
+
const wt = "ptxPreviewBannerDismissed", gt = "About live preview";
|
|
13
|
+
function Se(e) {
|
|
14
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
15
|
+
}
|
|
16
|
+
function xt(e) {
|
|
17
|
+
return [
|
|
18
|
+
'<div id="ptx-preview-banner" class="ptx-preview-banner" role="note">',
|
|
19
|
+
` <span class="ptx-preview-banner-text">${Se(e)}</span>`,
|
|
20
|
+
' <button type="button" class="ptx-preview-banner-dismiss" aria-label="Dismiss">×</button>',
|
|
21
|
+
"</div>",
|
|
22
|
+
`<button type="button" id="ptx-preview-banner-restore" class="ptx-preview-banner-restore" hidden>${Se(gt)}</button>`
|
|
23
|
+
].join(`
|
|
24
|
+
`);
|
|
25
|
+
}
|
|
26
|
+
function yt() {
|
|
27
|
+
return [
|
|
28
|
+
"<style>",
|
|
29
|
+
".ptx-preview-banner {",
|
|
30
|
+
" display: flex;",
|
|
31
|
+
" align-items: center;",
|
|
32
|
+
" gap: 0.75em;",
|
|
33
|
+
" padding: 0.5em 1em;",
|
|
34
|
+
" font-size: 0.9em;",
|
|
35
|
+
" background: #fff8e1;",
|
|
36
|
+
" color: #6b5300;",
|
|
37
|
+
" border-bottom: 1px solid #f0c36d;",
|
|
38
|
+
"}",
|
|
39
|
+
// The [hidden] content attribute only hides an element via the
|
|
40
|
+
// user-agent stylesheet's `[hidden] { display: none }` rule, and a
|
|
41
|
+
// normal-priority *author* rule always wins over a normal-priority UA
|
|
42
|
+
// rule regardless of selector specificity — so the unconditional
|
|
43
|
+
// `display: flex` above would otherwise keep the banner visible even
|
|
44
|
+
// after previewBannerScript sets `banner.hidden = true`.
|
|
45
|
+
".ptx-preview-banner[hidden] {",
|
|
46
|
+
" display: none;",
|
|
47
|
+
"}",
|
|
48
|
+
".ptx-preview-banner-text {",
|
|
49
|
+
" flex: 1 1 auto;",
|
|
50
|
+
"}",
|
|
51
|
+
".ptx-preview-banner-dismiss {",
|
|
52
|
+
" flex: 0 0 auto;",
|
|
53
|
+
" background: transparent;",
|
|
54
|
+
" border: none;",
|
|
55
|
+
" font-size: 1.2em;",
|
|
56
|
+
" line-height: 1;",
|
|
57
|
+
" cursor: pointer;",
|
|
58
|
+
" color: inherit;",
|
|
59
|
+
" padding: 0 0.25em;",
|
|
60
|
+
"}",
|
|
61
|
+
"html.dark-mode .ptx-preview-banner {",
|
|
62
|
+
" background: #3a2f00;",
|
|
63
|
+
" color: #f2d27a;",
|
|
64
|
+
" border-bottom-color: #6b5300;",
|
|
65
|
+
"}",
|
|
66
|
+
".ptx-preview-banner-restore {",
|
|
67
|
+
" position: fixed;",
|
|
68
|
+
" right: 0.5em;",
|
|
69
|
+
" bottom: 0.5em;",
|
|
70
|
+
" z-index: 1000;",
|
|
71
|
+
" background: transparent;",
|
|
72
|
+
" border: none;",
|
|
73
|
+
" padding: 0.15em 0.4em;",
|
|
74
|
+
" font-size: 0.75em;",
|
|
75
|
+
" color: inherit;",
|
|
76
|
+
" opacity: 0.45;",
|
|
77
|
+
" text-decoration: underline;",
|
|
78
|
+
" cursor: pointer;",
|
|
79
|
+
"}",
|
|
80
|
+
".ptx-preview-banner-restore:hover {",
|
|
81
|
+
" opacity: 0.85;",
|
|
82
|
+
"}",
|
|
83
|
+
// Printing a preview is a real workflow — the print-preview layout exists
|
|
84
|
+
// to be printed from (see printout.ts) — and a warning about the preview
|
|
85
|
+
// has no business on the paper.
|
|
86
|
+
"@media print {",
|
|
87
|
+
" .ptx-preview-banner, .ptx-preview-banner-restore {",
|
|
88
|
+
" display: none !important;",
|
|
89
|
+
" }",
|
|
90
|
+
"}",
|
|
91
|
+
"</style>"
|
|
92
|
+
].join(`
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
function Tt() {
|
|
96
|
+
return [
|
|
97
|
+
"<script>",
|
|
98
|
+
"(function () {",
|
|
99
|
+
" var KEY = " + JSON.stringify(wt) + ";",
|
|
100
|
+
' var banner = document.getElementById("ptx-preview-banner");',
|
|
101
|
+
' var restore = document.getElementById("ptx-preview-banner-restore");',
|
|
102
|
+
" if (!banner || !restore) { return; }",
|
|
103
|
+
// localStorage can throw (disabled cookies/storage, sandboxed iframe);
|
|
104
|
+
// fall back to always showing the banner rather than crashing the page.
|
|
105
|
+
" function isDismissed() {",
|
|
106
|
+
" try { return window.localStorage.getItem(KEY) === '1'; }",
|
|
107
|
+
" catch (e) { return false; }",
|
|
108
|
+
" }",
|
|
109
|
+
" function setDismissed(value) {",
|
|
110
|
+
" try {",
|
|
111
|
+
" if (value) { window.localStorage.setItem(KEY, '1'); }",
|
|
112
|
+
" else { window.localStorage.removeItem(KEY); }",
|
|
113
|
+
" } catch (e) {}",
|
|
114
|
+
" }",
|
|
115
|
+
" function apply(dismissed) {",
|
|
116
|
+
" banner.hidden = dismissed;",
|
|
117
|
+
" restore.hidden = !dismissed;",
|
|
118
|
+
" }",
|
|
119
|
+
" apply(isDismissed());",
|
|
120
|
+
' var dismissBtn = banner.querySelector(".ptx-preview-banner-dismiss");',
|
|
121
|
+
" if (dismissBtn) {",
|
|
122
|
+
" dismissBtn.addEventListener('click', function () {",
|
|
123
|
+
" setDismissed(true);",
|
|
124
|
+
" apply(true);",
|
|
125
|
+
" });",
|
|
126
|
+
" }",
|
|
127
|
+
" restore.addEventListener('click', function () {",
|
|
128
|
+
" setDismissed(false);",
|
|
129
|
+
" apply(false);",
|
|
130
|
+
" });",
|
|
131
|
+
"})();",
|
|
132
|
+
"<\/script>"
|
|
133
|
+
].join(`
|
|
134
|
+
`);
|
|
135
|
+
}
|
|
136
|
+
const St = "<!--ptx-preview-banner-->", Et = "<!--/ptx-preview-banner-->", kt = /\n?<!--ptx-preview-banner-->[\s\S]*?<!--\/ptx-preview-banner-->/;
|
|
137
|
+
function Pt(e, n) {
|
|
138
|
+
const t = kt.exec(e), r = t ? e.slice(0, t.index) + e.slice(t.index + t[0].length) : e;
|
|
139
|
+
if (!/<body[^>]*>/i.test(r))
|
|
140
|
+
return r;
|
|
141
|
+
const i = `
|
|
142
|
+
${St}
|
|
143
|
+
${yt()}
|
|
144
|
+
${xt(n.message)}
|
|
145
|
+
${Tt()}
|
|
146
|
+
${Et}`;
|
|
147
|
+
return r.replace(/<body([^>]*)>/i, `<body$1>${i}`);
|
|
148
|
+
}
|
|
149
|
+
async function Me(e, n) {
|
|
150
|
+
const t = f.resolve(e), r = f.resolve(t, `.${f.posix.normalize(n)}`);
|
|
151
|
+
if (r !== t && !r.startsWith(t + f.sep)) {
|
|
152
|
+
console.error(
|
|
153
|
+
`pretext-html: refusing to serve ${n} from outside ${t}`
|
|
154
|
+
);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
return new Uint8Array(await de(r));
|
|
159
|
+
} catch {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async function $t(e) {
|
|
164
|
+
try {
|
|
165
|
+
return await de(e, "utf8");
|
|
166
|
+
} catch {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
let Oe;
|
|
171
|
+
function Zn(e) {
|
|
172
|
+
Oe = e;
|
|
173
|
+
}
|
|
174
|
+
function ae() {
|
|
175
|
+
return Oe ?? process.env.PRETEXT_HTML_ASSETS ?? f.resolve(f.dirname(ut(import.meta.url)), "..", "assets");
|
|
176
|
+
}
|
|
177
|
+
function It(e, n) {
|
|
178
|
+
return f.join(e, n);
|
|
179
|
+
}
|
|
180
|
+
const _e = "2.55.0", Lt = "8.3.3", Dt = [
|
|
181
|
+
"prefix-runtime.dd07797f77620576.bundle.js",
|
|
182
|
+
"prefix-926.5c7038c8ef173faf.bundle.js",
|
|
183
|
+
"prefix-runestone.11d27cdc38930c2c.bundle.js"
|
|
184
|
+
], Rt = [
|
|
185
|
+
"prefix-926.229729d09512acc9.css",
|
|
186
|
+
"prefix-runestone.347e2ecdeacfed99.css"
|
|
187
|
+
], At = "born-hidden-knowl", jt = /<details\b([^>]*)>(\s*)(?:<summary\b([^>]*)>)?/g;
|
|
188
|
+
function Ct(e) {
|
|
189
|
+
const n = /\bclass="([^"]*)"/.exec(e);
|
|
190
|
+
return n ? n[1].trim().split(/\s+/) : [];
|
|
191
|
+
}
|
|
192
|
+
function Mt(e) {
|
|
193
|
+
return /(^|\s)open(\s|=|$)/.test(e);
|
|
194
|
+
}
|
|
195
|
+
function Ee(e) {
|
|
196
|
+
return Mt(e) ? e : ` open${e}`;
|
|
197
|
+
}
|
|
198
|
+
function Ot(e) {
|
|
199
|
+
return e.replace(
|
|
200
|
+
jt,
|
|
201
|
+
(n, t, r, i) => {
|
|
202
|
+
if (!Ct(t).includes(At))
|
|
203
|
+
return n;
|
|
204
|
+
const o = `<details${Ee(t)}>`;
|
|
205
|
+
return i === void 0 ? `${o}${r}` : `${o}${r}<summary${Ee(i)}>`;
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
const fe = /* @__PURE__ */ new Map(), Ne = /* @__PURE__ */ new Map();
|
|
210
|
+
let ce, _t = 0, Be = Me;
|
|
211
|
+
function Qn(e) {
|
|
212
|
+
Be = e;
|
|
213
|
+
}
|
|
214
|
+
function Nt(e, n) {
|
|
215
|
+
const t = typeof e == "string" ? e : e instanceof URL ? e.href : e.url, r = Ne.get(t);
|
|
216
|
+
if (r !== void 0)
|
|
217
|
+
return Promise.resolve(new Response(r, { status: 200 }));
|
|
218
|
+
let i;
|
|
219
|
+
try {
|
|
220
|
+
i = new URL(t).host;
|
|
221
|
+
} catch {
|
|
222
|
+
i = "";
|
|
223
|
+
}
|
|
224
|
+
const o = fe.get(i);
|
|
225
|
+
return o !== void 0 ? Ft(o, t) : ce(e, n);
|
|
226
|
+
}
|
|
227
|
+
const Bt = '<?xml version="1.0"?><pretext-preview-missing-file/>';
|
|
228
|
+
async function Ft(e, n) {
|
|
229
|
+
const t = decodeURIComponent(new URL(n).pathname), r = await Be(e, t);
|
|
230
|
+
if (r === void 0)
|
|
231
|
+
return new Response(Bt, { status: 200 });
|
|
232
|
+
const i = typeof r == "string" ? r : new Uint8Array(r);
|
|
233
|
+
return new Response(i, { status: 200 });
|
|
234
|
+
}
|
|
235
|
+
function Fe() {
|
|
236
|
+
ce || (ce = globalThis.fetch, globalThis.fetch = Nt);
|
|
237
|
+
}
|
|
238
|
+
function Ue(e) {
|
|
239
|
+
Fe();
|
|
240
|
+
const n = `mnt${++_t}.ptx.invalid`;
|
|
241
|
+
return fe.set(n, e), `http://${n}`;
|
|
242
|
+
}
|
|
243
|
+
function Ut(e) {
|
|
244
|
+
fe.delete(new URL(e).host);
|
|
245
|
+
}
|
|
246
|
+
function Xt(e, n) {
|
|
247
|
+
Fe(), Ne.set(e, n);
|
|
248
|
+
}
|
|
249
|
+
const he = `<?xml version="1.0" encoding="UTF-8"?>
|
|
250
|
+
<publication>
|
|
251
|
+
<source>
|
|
252
|
+
<directories external="../assets" generated="../generated-assets" />
|
|
253
|
+
</source>
|
|
254
|
+
<common>
|
|
255
|
+
<tableofcontents level="0"/>
|
|
256
|
+
</common>
|
|
257
|
+
</publication>
|
|
258
|
+
`, Wt = [
|
|
259
|
+
[["html", "resources"], "host", "cdn"],
|
|
260
|
+
[["html", "platform"], "portable", "no"],
|
|
261
|
+
[["html", "cross-references"], "knowled", "never"],
|
|
262
|
+
[["common", "chunking"], "level", "0"]
|
|
263
|
+
], Ht = ["theme", "style", "shell"];
|
|
264
|
+
function E(e, n) {
|
|
265
|
+
for (const t of e.children)
|
|
266
|
+
if (t.type === "element" && t.name === n)
|
|
267
|
+
return t;
|
|
268
|
+
}
|
|
269
|
+
function _(e, n) {
|
|
270
|
+
let t = E(e, n);
|
|
271
|
+
return t || (t = { type: "element", name: n, attributes: {}, children: [] }, e.children.push(t)), t;
|
|
272
|
+
}
|
|
273
|
+
function zt(e, n) {
|
|
274
|
+
const t = E(e, "css");
|
|
275
|
+
if (t && Ht.some((i) => t.attributes?.[i]))
|
|
276
|
+
return;
|
|
277
|
+
const r = t ?? _(e, "css");
|
|
278
|
+
r.attributes = { ...r.attributes, theme: n };
|
|
279
|
+
}
|
|
280
|
+
function Jt(e, n) {
|
|
281
|
+
const t = E(e, "appearance");
|
|
282
|
+
if (t?.attributes?.theme)
|
|
283
|
+
return;
|
|
284
|
+
const r = t ?? _(e, "appearance");
|
|
285
|
+
r.attributes = { ...r.attributes, theme: n };
|
|
286
|
+
}
|
|
287
|
+
function Kt(e) {
|
|
288
|
+
const n = _(e, "resources");
|
|
289
|
+
n.attributes = {
|
|
290
|
+
...n.attributes,
|
|
291
|
+
host: "cdn",
|
|
292
|
+
math: "online"
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function Xe(e, n = {}) {
|
|
296
|
+
const t = n.cssTheme?.trim(), r = n.revealTheme?.trim(), i = n.target === "slides", o = B(e ?? he), s = E(o, "publication");
|
|
297
|
+
if (!s)
|
|
298
|
+
throw new Error(
|
|
299
|
+
"Invalid publication file: no root <publication> element found"
|
|
300
|
+
);
|
|
301
|
+
for (const [c, d, u] of Wt) {
|
|
302
|
+
const l = c.reduce(
|
|
303
|
+
(m, b) => _(m, b),
|
|
304
|
+
s
|
|
305
|
+
);
|
|
306
|
+
l.attributes = { ...l.attributes, [d]: u };
|
|
307
|
+
}
|
|
308
|
+
const a = _(s, "html");
|
|
309
|
+
if (t && zt(a, t), i) {
|
|
310
|
+
const c = _(s, "revealjs");
|
|
311
|
+
Kt(c), r && Jt(c, r);
|
|
312
|
+
}
|
|
313
|
+
return N(o);
|
|
314
|
+
}
|
|
315
|
+
const er = Xe, Vt = "generated/";
|
|
316
|
+
function ne(e) {
|
|
317
|
+
if (!(e === void 0 || e === "" || e.startsWith("/")))
|
|
318
|
+
return e.endsWith("/") ? e : `${e}/`;
|
|
319
|
+
}
|
|
320
|
+
function ke(e) {
|
|
321
|
+
const n = e?.attributes?.level;
|
|
322
|
+
if (n == null || n === "") return;
|
|
323
|
+
const t = Number(n);
|
|
324
|
+
return Number.isFinite(t) && t >= 0 ? t : void 0;
|
|
325
|
+
}
|
|
326
|
+
function Gt(e) {
|
|
327
|
+
const n = B(e ?? he), t = E(n, "publication"), r = t && E(t, "common"), i = r && E(r, "tableofcontents"), o = t && E(t, "numbering");
|
|
328
|
+
let s, a;
|
|
329
|
+
for (const c of o?.children ?? []) {
|
|
330
|
+
if (c.type !== "element") continue;
|
|
331
|
+
const d = ke(c);
|
|
332
|
+
d !== void 0 && (c.name === "divisions" ? a = d : s = Math.max(s ?? 0, d));
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
tocLevel: ke(i),
|
|
336
|
+
numberingLevel: s,
|
|
337
|
+
maxNumberingLevel: a
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function Yt(e, n) {
|
|
341
|
+
const t = B(e ?? he), r = E(t, "publication"), i = r && E(r, "source"), o = i && E(i, "directories"), s = (d) => {
|
|
342
|
+
const u = o?.attributes?.[d];
|
|
343
|
+
return u == null ? void 0 : String(u);
|
|
344
|
+
}, a = ne(n !== void 0 ? n : s("external")), c = ne(s("generated")) ?? Vt;
|
|
345
|
+
return a === void 0 ? { generated: c } : { external: a, generated: c };
|
|
346
|
+
}
|
|
347
|
+
function z(e) {
|
|
348
|
+
if (typeof e == "string")
|
|
349
|
+
try {
|
|
350
|
+
return z(B(e));
|
|
351
|
+
} catch {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const n = e.children.find(
|
|
355
|
+
(o) => o.type === "element"
|
|
356
|
+
), t = n?.name === "docinfo" ? n : n && E(n, "docinfo"), i = (t && E(t, "directories"))?.attributes?.external;
|
|
357
|
+
return i == null ? void 0 : String(i);
|
|
358
|
+
}
|
|
359
|
+
const We = "http://www.w3.org/2001/XInclude", Pe = 64;
|
|
360
|
+
async function q(e, n) {
|
|
361
|
+
return (e?.readSource ? await e.readSource(n) : void 0) ?? await $t(n);
|
|
362
|
+
}
|
|
363
|
+
function pe(e, n, t) {
|
|
364
|
+
return e.cache ? e.cache.parse(n, t) : B(t);
|
|
365
|
+
}
|
|
366
|
+
async function me(e, n, t, r = {}) {
|
|
367
|
+
const i = f.resolve(n), o = pe(r, i, e), s = {
|
|
368
|
+
...r,
|
|
369
|
+
projectDir: f.resolve(t),
|
|
370
|
+
stack: [i],
|
|
371
|
+
files: [i],
|
|
372
|
+
bytes: e.length
|
|
373
|
+
}, a = await X(
|
|
374
|
+
o,
|
|
375
|
+
f.dirname(i),
|
|
376
|
+
{ "": "" },
|
|
377
|
+
s
|
|
378
|
+
);
|
|
379
|
+
return {
|
|
380
|
+
tree: o,
|
|
381
|
+
content: a ? N(o) : e,
|
|
382
|
+
files: s.files,
|
|
383
|
+
bytes: s.bytes
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function He(e) {
|
|
387
|
+
return e.data?.ptxIncludedFile;
|
|
388
|
+
}
|
|
389
|
+
function ze(e, n) {
|
|
390
|
+
const t = e.data ?? (e.data = {});
|
|
391
|
+
t.ptxIncludedFile = n;
|
|
392
|
+
}
|
|
393
|
+
function J(e, n) {
|
|
394
|
+
let t = e;
|
|
395
|
+
for (const [r, i] of Object.entries(n.attributes))
|
|
396
|
+
(r === "xmlns" || r.startsWith("xmlns:")) && (t === e && (t = { ...e }), t[r === "xmlns" ? "" : r.slice(6)] = i ?? "");
|
|
397
|
+
return t;
|
|
398
|
+
}
|
|
399
|
+
function Je(e, n) {
|
|
400
|
+
const t = e.name.indexOf(":"), r = t === -1 ? "" : e.name.slice(0, t);
|
|
401
|
+
return (t === -1 ? e.name : e.name.slice(t + 1)) === "include" && n[r] === We;
|
|
402
|
+
}
|
|
403
|
+
async function X(e, n, t, r) {
|
|
404
|
+
let i = !1;
|
|
405
|
+
for (let o = 0; o < e.children.length; o++) {
|
|
406
|
+
const s = e.children[o];
|
|
407
|
+
if (s.type !== "element")
|
|
408
|
+
continue;
|
|
409
|
+
const a = J(t, s);
|
|
410
|
+
if (Je(s, a)) {
|
|
411
|
+
const c = await Ke(
|
|
412
|
+
s,
|
|
413
|
+
n,
|
|
414
|
+
a,
|
|
415
|
+
r
|
|
416
|
+
);
|
|
417
|
+
e.children.splice(o, 1, ...c), o += c.length - 1, i = !0;
|
|
418
|
+
} else await X(s, n, a, r) && (i = !0);
|
|
419
|
+
}
|
|
420
|
+
return i;
|
|
421
|
+
}
|
|
422
|
+
async function Ke(e, n, t, r) {
|
|
423
|
+
const i = r.stack[r.stack.length - 1];
|
|
424
|
+
if (e.attributes.xpointer)
|
|
425
|
+
throw new Error(
|
|
426
|
+
`xi:include with xpointer is not supported by the JS preview build (in ${i})`
|
|
427
|
+
);
|
|
428
|
+
const o = e.attributes.href;
|
|
429
|
+
if (!o)
|
|
430
|
+
throw new Error(`xi:include without href (in ${i})`);
|
|
431
|
+
let s = o;
|
|
432
|
+
try {
|
|
433
|
+
s = decodeURIComponent(o);
|
|
434
|
+
} catch {
|
|
435
|
+
}
|
|
436
|
+
const a = f.resolve(n, s);
|
|
437
|
+
if (a !== r.projectDir && !a.startsWith(r.projectDir + f.sep))
|
|
438
|
+
throw new Error(
|
|
439
|
+
`xi:include escapes the project directory: ${o} (in ${i})`
|
|
440
|
+
);
|
|
441
|
+
if (r.stack.includes(a))
|
|
442
|
+
throw new Error(
|
|
443
|
+
`Circular xi:include: ${[...r.stack, a].join(" -> ")}`
|
|
444
|
+
);
|
|
445
|
+
if (r.stack.length >= Pe)
|
|
446
|
+
throw new Error(`xi:include nesting exceeds ${Pe} levels`);
|
|
447
|
+
const c = await q(r, a);
|
|
448
|
+
if (c === void 0) {
|
|
449
|
+
const l = Zt(e, t);
|
|
450
|
+
if (l)
|
|
451
|
+
return await X(l, n, t, r), l.children;
|
|
452
|
+
throw new Error(`xi:include target not found: ${o} (in ${i})`);
|
|
453
|
+
}
|
|
454
|
+
if (r.files.includes(a) || r.files.push(a), r.bytes += c.length, e.attributes.parse === "text")
|
|
455
|
+
return [{ type: "text", value: c }];
|
|
456
|
+
let d;
|
|
457
|
+
try {
|
|
458
|
+
d = pe(r, a, c);
|
|
459
|
+
} catch (l) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Could not parse xi:include target ${a} as XML: ${l instanceof Error ? l.message : l}. (Included files must be well-formed, with a single root element.)`
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
r.stack.push(a);
|
|
465
|
+
try {
|
|
466
|
+
await X(d, f.dirname(a), { "": "" }, r);
|
|
467
|
+
} finally {
|
|
468
|
+
r.stack.pop();
|
|
469
|
+
}
|
|
470
|
+
const u = d.children.filter(
|
|
471
|
+
(l) => l.type === "element"
|
|
472
|
+
);
|
|
473
|
+
for (const l of u)
|
|
474
|
+
ze(l, a);
|
|
475
|
+
return u;
|
|
476
|
+
}
|
|
477
|
+
function $e(e) {
|
|
478
|
+
return e.name === "docinfo";
|
|
479
|
+
}
|
|
480
|
+
async function qt(e, n, t, r = {}) {
|
|
481
|
+
try {
|
|
482
|
+
const i = f.resolve(n), s = pe(r, i, e).children.find(
|
|
483
|
+
(u) => u.type === "element"
|
|
484
|
+
);
|
|
485
|
+
if (!s)
|
|
486
|
+
return;
|
|
487
|
+
const a = f.dirname(i), c = {
|
|
488
|
+
...r,
|
|
489
|
+
projectDir: f.resolve(t),
|
|
490
|
+
stack: [i],
|
|
491
|
+
files: [i],
|
|
492
|
+
bytes: e.length
|
|
493
|
+
}, d = J({ "": "" }, s);
|
|
494
|
+
for (const u of s.children) {
|
|
495
|
+
if (u.type !== "element")
|
|
496
|
+
continue;
|
|
497
|
+
const l = J(d, u);
|
|
498
|
+
if ($e(u))
|
|
499
|
+
return await X(u, a, l, c), N(u);
|
|
500
|
+
if (Je(u, l)) {
|
|
501
|
+
const b = (await Ke(
|
|
502
|
+
u,
|
|
503
|
+
a,
|
|
504
|
+
l,
|
|
505
|
+
c
|
|
506
|
+
)).find(
|
|
507
|
+
(y) => y.type === "element" && $e(y)
|
|
508
|
+
);
|
|
509
|
+
if (b)
|
|
510
|
+
return N(b);
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
return;
|
|
516
|
+
} catch {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function Zt(e, n) {
|
|
521
|
+
for (const t of e.children) {
|
|
522
|
+
if (t.type !== "element")
|
|
523
|
+
continue;
|
|
524
|
+
const r = J(n, t), i = t.name.indexOf(":"), o = i === -1 ? "" : t.name.slice(0, i);
|
|
525
|
+
if ((i === -1 ? t.name : t.name.slice(i + 1)) === "fallback" && r[o] === We)
|
|
526
|
+
return t;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
function Ve(e) {
|
|
530
|
+
return typeof e == "object" && e !== null && e.type === "element";
|
|
531
|
+
}
|
|
532
|
+
function Qt(e) {
|
|
533
|
+
return /^(pf|xhtml):/.test(e.name);
|
|
534
|
+
}
|
|
535
|
+
function en(e, n, t) {
|
|
536
|
+
const r = [];
|
|
537
|
+
return Ge(e, n, t, (i, o, s, a) => {
|
|
538
|
+
r.push({
|
|
539
|
+
id: o,
|
|
540
|
+
file: s,
|
|
541
|
+
line: i.position?.start.line ?? 1,
|
|
542
|
+
column: i.position?.start.column ?? 1,
|
|
543
|
+
endLine: i.position?.end.line ?? i.position?.start.line ?? 1,
|
|
544
|
+
parent: a
|
|
545
|
+
});
|
|
546
|
+
}), r;
|
|
547
|
+
}
|
|
548
|
+
function tn(e, n, t) {
|
|
549
|
+
let r;
|
|
550
|
+
return Ge(e, "", t, (i, o) => {
|
|
551
|
+
if (i === n)
|
|
552
|
+
return r = o, !1;
|
|
553
|
+
}), r;
|
|
554
|
+
}
|
|
555
|
+
function Ge(e, n, t, r) {
|
|
556
|
+
const i = e.children.find(Ve);
|
|
557
|
+
if (i) {
|
|
558
|
+
const o = t?.parentId ?? "root";
|
|
559
|
+
Ye(i, o, t?.position ?? 1, n, o, r);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
function Ye(e, n, t, r, i, o) {
|
|
563
|
+
const s = He(e) ?? r;
|
|
564
|
+
let a, c;
|
|
565
|
+
if (Qt(e))
|
|
566
|
+
c = "root";
|
|
567
|
+
else {
|
|
568
|
+
const u = e.attributes.label ?? e.attributes["xml:id"];
|
|
569
|
+
if (a = u ?? `${n}-${t}`, o(e, a, s, i) === !1)
|
|
570
|
+
return !1;
|
|
571
|
+
c = a;
|
|
572
|
+
}
|
|
573
|
+
let d = 0;
|
|
574
|
+
for (const u of e.children)
|
|
575
|
+
if (Ve(u) && (d += 1, !Ye(
|
|
576
|
+
u,
|
|
577
|
+
c,
|
|
578
|
+
d,
|
|
579
|
+
s,
|
|
580
|
+
a ?? i,
|
|
581
|
+
o
|
|
582
|
+
)))
|
|
583
|
+
return !1;
|
|
584
|
+
return !0;
|
|
585
|
+
}
|
|
586
|
+
function tr(e, n) {
|
|
587
|
+
let t;
|
|
588
|
+
for (const r of e)
|
|
589
|
+
r.line <= n && (t = r);
|
|
590
|
+
return t ?? e[0];
|
|
591
|
+
}
|
|
592
|
+
function nn(e) {
|
|
593
|
+
const n = e.replace(/<!--[\s\S]*?-->/g, " ").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, " ");
|
|
594
|
+
return /<\s*slide(?:show)?[\s/>]/.test(n) ? "slides" : "html";
|
|
595
|
+
}
|
|
596
|
+
const qe = /* @__PURE__ */ new Set([
|
|
597
|
+
"colophon",
|
|
598
|
+
"biography",
|
|
599
|
+
"dedication",
|
|
600
|
+
"acknowledgement",
|
|
601
|
+
"preface",
|
|
602
|
+
"chapter",
|
|
603
|
+
"section",
|
|
604
|
+
"subsection",
|
|
605
|
+
"subsubsection",
|
|
606
|
+
"slide",
|
|
607
|
+
"appendix",
|
|
608
|
+
"index",
|
|
609
|
+
"exercises",
|
|
610
|
+
"reading-questions",
|
|
611
|
+
"references",
|
|
612
|
+
"solutions",
|
|
613
|
+
"glossary",
|
|
614
|
+
"worksheet",
|
|
615
|
+
"handout"
|
|
616
|
+
]), Ze = /* @__PURE__ */ new Set([
|
|
617
|
+
"book",
|
|
618
|
+
"article",
|
|
619
|
+
"slideshow",
|
|
620
|
+
"letter",
|
|
621
|
+
"memo"
|
|
622
|
+
]), A = /* @__PURE__ */ new Set([
|
|
623
|
+
...Ze,
|
|
624
|
+
...qe,
|
|
625
|
+
"part",
|
|
626
|
+
"foreword",
|
|
627
|
+
"frontmatter",
|
|
628
|
+
"backmatter"
|
|
629
|
+
]);
|
|
630
|
+
function Z(e) {
|
|
631
|
+
return A.has(e.name);
|
|
632
|
+
}
|
|
633
|
+
const rn = /* @__PURE__ */ new Set(["docinfo"]), Qe = /* @__PURE__ */ new Set([
|
|
634
|
+
"title",
|
|
635
|
+
"shorttitle",
|
|
636
|
+
"plaintitle",
|
|
637
|
+
"subtitle",
|
|
638
|
+
"caption"
|
|
639
|
+
]);
|
|
640
|
+
function g(e) {
|
|
641
|
+
return e.type === "element";
|
|
642
|
+
}
|
|
643
|
+
function et(e) {
|
|
644
|
+
return e.attributes["xml:id"] ?? void 0;
|
|
645
|
+
}
|
|
646
|
+
function K(e, n) {
|
|
647
|
+
for (const t of e.children) {
|
|
648
|
+
if (!g(t)) continue;
|
|
649
|
+
if (et(t) === n) return t;
|
|
650
|
+
const r = K(t, n);
|
|
651
|
+
if (r) return r;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
function R(e, n) {
|
|
655
|
+
for (const t of e.children) {
|
|
656
|
+
if (!g(t)) continue;
|
|
657
|
+
if (t === n) return [t];
|
|
658
|
+
const r = R(t, n);
|
|
659
|
+
if (r) return [t, ...r];
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
function tt(e, n, t, r) {
|
|
663
|
+
return Ze.has(t) ? 0 : t === "frontmatter" || t === "backmatter" || t === "part" ? n === "book" && r ? 1 : 0 : qe.has(t) ? e + 1 : e;
|
|
664
|
+
}
|
|
665
|
+
function V(e, n) {
|
|
666
|
+
let t = 0;
|
|
667
|
+
for (const [r, i] of e.entries()) {
|
|
668
|
+
const o = r === 0 ? void 0 : e[r - 1];
|
|
669
|
+
t = tt(t, o?.name, i.name, n);
|
|
670
|
+
}
|
|
671
|
+
return t;
|
|
672
|
+
}
|
|
673
|
+
function ve(e) {
|
|
674
|
+
return e?.name === "book" && e.children.some(
|
|
675
|
+
(n) => g(n) && n.name === "part"
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
function O(e, n) {
|
|
679
|
+
return e.children.some(
|
|
680
|
+
(t) => g(t) && n.includes(t.name)
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
function on(e) {
|
|
684
|
+
if (!e) return 0;
|
|
685
|
+
const n = e.name;
|
|
686
|
+
if (n === "book") {
|
|
687
|
+
const t = ve(e), r = t ? e.children.some(
|
|
688
|
+
(o) => g(o) && o.name === "part" && O(o, ["chapter"])
|
|
689
|
+
) : O(e, ["chapter"]), i = (t ? e.children.flatMap(
|
|
690
|
+
(o) => g(o) && o.name === "part" ? o.children : []
|
|
691
|
+
) : e.children).some(
|
|
692
|
+
(o) => g(o) && o.name === "chapter" && O(o, ["section"])
|
|
693
|
+
);
|
|
694
|
+
return t && i ? 3 : t && r || i ? 2 : r ? 1 : 0;
|
|
695
|
+
}
|
|
696
|
+
if (n === "article") {
|
|
697
|
+
const t = e.children.filter(
|
|
698
|
+
(r) => g(r) && r.name === "section"
|
|
699
|
+
);
|
|
700
|
+
if (t.some((r) => O(r, ["subsection"])))
|
|
701
|
+
return 2;
|
|
702
|
+
if (t.length > 0 || O(e, ["worksheet", "handout"]))
|
|
703
|
+
return 1;
|
|
704
|
+
}
|
|
705
|
+
return 0;
|
|
706
|
+
}
|
|
707
|
+
function sn(e) {
|
|
708
|
+
return e ? e.name === "book" ? ve(e) ? 3 : 2 : e.name === "article" && O(e, ["section", "worksheet", "handout"]) ? 1 : 0 : 0;
|
|
709
|
+
}
|
|
710
|
+
function be(e) {
|
|
711
|
+
if (!Qe.has(e.name)) {
|
|
712
|
+
e.children = e.children.filter(g);
|
|
713
|
+
for (const n of e.children)
|
|
714
|
+
be(n);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function an(e) {
|
|
718
|
+
for (const n of e.children)
|
|
719
|
+
g(n) && !A.has(n.name) && be(n);
|
|
720
|
+
}
|
|
721
|
+
function cn(e, n = !1) {
|
|
722
|
+
const t = /* @__PURE__ */ new Set(), r = (i) => {
|
|
723
|
+
if (!(n && i !== e && A.has(i.name))) {
|
|
724
|
+
if (i.name === "xref") {
|
|
725
|
+
const o = [
|
|
726
|
+
i.attributes.ref,
|
|
727
|
+
i.attributes.first,
|
|
728
|
+
i.attributes.last
|
|
729
|
+
];
|
|
730
|
+
for (const s of o)
|
|
731
|
+
for (const a of s?.split(/[\s,]+/) ?? [])
|
|
732
|
+
a && t.add(a);
|
|
733
|
+
}
|
|
734
|
+
for (const o of i.children)
|
|
735
|
+
g(o) && r(o);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
return r(e), t;
|
|
739
|
+
}
|
|
740
|
+
function ln(e, n, t) {
|
|
741
|
+
const r = (i) => {
|
|
742
|
+
for (const [o, s] of i.children.entries())
|
|
743
|
+
if (g(s)) {
|
|
744
|
+
if (et(s) === n)
|
|
745
|
+
return i.children[o] = t, !0;
|
|
746
|
+
if (r(s)) return !0;
|
|
747
|
+
}
|
|
748
|
+
return !1;
|
|
749
|
+
};
|
|
750
|
+
return r(e);
|
|
751
|
+
}
|
|
752
|
+
function nt(e, n, t) {
|
|
753
|
+
const r = t.contentKept.has(e), i = t.chain.has(e), o = [];
|
|
754
|
+
for (const s of e.children) {
|
|
755
|
+
if (!g(s)) {
|
|
756
|
+
r && o.push(s);
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
if (t.verbatim.has(s) || rn.has(s.name) || Qe.has(s.name))
|
|
760
|
+
o.push(s);
|
|
761
|
+
else if (A.has(s.name)) {
|
|
762
|
+
const a = tt(
|
|
763
|
+
n,
|
|
764
|
+
e.name,
|
|
765
|
+
s.name,
|
|
766
|
+
t.hasParts
|
|
767
|
+
);
|
|
768
|
+
(t.chain.has(s) || i || a <= t.tocLevel) && (nt(s, a, t), o.push(s));
|
|
769
|
+
} else r && o.push(s);
|
|
770
|
+
}
|
|
771
|
+
e.children = o;
|
|
772
|
+
}
|
|
773
|
+
function un(e, n, t = {}) {
|
|
774
|
+
const r = K(e, n);
|
|
775
|
+
if (!r) return;
|
|
776
|
+
const i = R(e, r);
|
|
777
|
+
if (!i) return;
|
|
778
|
+
const o = (t.collapseChildren ?? !1) && r.children.some(
|
|
779
|
+
(p) => g(p) && A.has(p.name)
|
|
780
|
+
), s = (p) => p.name === "pretext" || p.name === "mathbook", a = i.filter((p) => !s(p)), c = a[0], d = ve(c), u = V(a, d), l = (p) => {
|
|
781
|
+
const T = R(e, p)?.filter((v) => !s(v)) ?? [];
|
|
782
|
+
return V(T, d);
|
|
783
|
+
}, m = t.maxNumberingLevel ?? 1 / 0, b = Math.min(
|
|
784
|
+
t.numberingLevel ?? sn(c),
|
|
785
|
+
m
|
|
786
|
+
), y = t.tocLevel ?? on(c), x = {
|
|
787
|
+
verbatim: /* @__PURE__ */ new Set(),
|
|
788
|
+
chain: new Set(i),
|
|
789
|
+
contentKept: /* @__PURE__ */ new Set(),
|
|
790
|
+
tocLevel: y,
|
|
791
|
+
hasParts: d
|
|
792
|
+
}, j = /* @__PURE__ */ new Set(), $ = /* @__PURE__ */ new Set();
|
|
793
|
+
o ? x.contentKept.add(r) : x.verbatim.add(r);
|
|
794
|
+
const Q = (p) => {
|
|
795
|
+
const T = R(e, p);
|
|
796
|
+
if (!T) return;
|
|
797
|
+
const v = T.filter((S) => A.has(S.name)), I = v[v.length - 1];
|
|
798
|
+
if (!I || I === r) return;
|
|
799
|
+
if (i.includes(I)) {
|
|
800
|
+
x.contentKept.add(I), $.add(I);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
let P = I;
|
|
804
|
+
for (let S = v.length - 1; S >= 0 && !(l(v[S]) <= b || i.includes(v[S - 1])); S--)
|
|
805
|
+
P = v[S - 1] ?? P;
|
|
806
|
+
if (!x.verbatim.has(P)) {
|
|
807
|
+
x.verbatim.add(P), j.add(P);
|
|
808
|
+
for (const S of R(e, P) ?? []) x.chain.add(S);
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
for (const p of cn(r, o)) {
|
|
812
|
+
const T = K(e, p);
|
|
813
|
+
T && T !== r && Q(T);
|
|
814
|
+
}
|
|
815
|
+
for (const p of [...x.chain]) {
|
|
816
|
+
if (!A.has(p.name) || l(p) <= b)
|
|
817
|
+
continue;
|
|
818
|
+
const T = R(e, p)?.at(-2);
|
|
819
|
+
if (T)
|
|
820
|
+
for (const v of T.children) {
|
|
821
|
+
if (v === p) break;
|
|
822
|
+
!g(v) || !A.has(v.name) || x.verbatim.has(v) || x.chain.has(v) || (x.verbatim.add(v), j.add(v));
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
const C = e.children.find(g);
|
|
826
|
+
C && nt(C, 0, x);
|
|
827
|
+
for (const p of j)
|
|
828
|
+
be(p);
|
|
829
|
+
for (const p of $)
|
|
830
|
+
an(p);
|
|
831
|
+
return { content: N(e), divisionId: n, level: u, collapsed: o };
|
|
832
|
+
}
|
|
833
|
+
class dn {
|
|
834
|
+
entries = /* @__PURE__ */ new Map();
|
|
835
|
+
maxEntries;
|
|
836
|
+
/** Cumulative hit/miss counts, for diagnostics and tests. */
|
|
837
|
+
hits = 0;
|
|
838
|
+
misses = 0;
|
|
839
|
+
constructor(n = {}) {
|
|
840
|
+
this.maxEntries = Math.max(1, n.maxEntries ?? 1024);
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* The parse of `content`, as a fresh tree the caller may mutate freely.
|
|
844
|
+
* `key` names the file — a path — so that a changed file replaces its own
|
|
845
|
+
* entry instead of accumulating one per version.
|
|
846
|
+
*
|
|
847
|
+
* Throws what `fromXml` throws for malformed content; nothing is cached
|
|
848
|
+
* then.
|
|
849
|
+
*/
|
|
850
|
+
parse(n, t) {
|
|
851
|
+
const r = this.entries.get(n);
|
|
852
|
+
if (r && r.content === t)
|
|
853
|
+
return this.hits += 1, this.entries.delete(n), this.entries.set(n, r), le(r.tree);
|
|
854
|
+
this.misses += 1;
|
|
855
|
+
const i = B(t);
|
|
856
|
+
for (this.entries.delete(n), this.entries.set(n, { content: t, tree: i }); this.entries.size > this.maxEntries; ) {
|
|
857
|
+
const o = this.entries.keys().next().value;
|
|
858
|
+
if (o === void 0) break;
|
|
859
|
+
this.entries.delete(o);
|
|
860
|
+
}
|
|
861
|
+
return le(i);
|
|
862
|
+
}
|
|
863
|
+
/** Number of files currently held. */
|
|
864
|
+
get size() {
|
|
865
|
+
return this.entries.size;
|
|
866
|
+
}
|
|
867
|
+
/** Drop one file (when the host knows it is gone), or everything. */
|
|
868
|
+
invalidate(n) {
|
|
869
|
+
n === void 0 ? this.entries.clear() : this.entries.delete(n);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
function le(e) {
|
|
873
|
+
const n = { ...e };
|
|
874
|
+
return n.attributes && (n.attributes = { ...n.attributes }), n.children && (n.children = n.children.map((t) => le(t))), n.data && (n.data = { ...n.data }), n;
|
|
875
|
+
}
|
|
876
|
+
function G(e) {
|
|
877
|
+
return typeof e == "object" && e !== null && e.type === "element";
|
|
878
|
+
}
|
|
879
|
+
function fn(e) {
|
|
880
|
+
for (let n = e.length - 1; n >= 0; n--)
|
|
881
|
+
if (Z(e[n])) return e[n];
|
|
882
|
+
}
|
|
883
|
+
function hn(e, n, t) {
|
|
884
|
+
const r = [], i = (s, a, c) => {
|
|
885
|
+
const d = He(s) ?? a, u = [...c, s];
|
|
886
|
+
d === t && Z(s) && r.push({ element: s, chain: u });
|
|
887
|
+
for (const l of s.children)
|
|
888
|
+
G(l) && i(l, d, u);
|
|
889
|
+
}, o = e.children.find(G);
|
|
890
|
+
return o && i(o, n, []), r;
|
|
891
|
+
}
|
|
892
|
+
function pn(e, n, t, r) {
|
|
893
|
+
const i = hn(e, n, t);
|
|
894
|
+
let o, s, a;
|
|
895
|
+
for (const { element: c } of i) {
|
|
896
|
+
const d = c.position?.start.line, u = c.position?.end.line ?? d;
|
|
897
|
+
d === void 0 || u === void 0 || (d <= r && r <= u ? o = c : d > r ? s ??= c : a = c);
|
|
898
|
+
}
|
|
899
|
+
return o ?? s ?? a;
|
|
900
|
+
}
|
|
901
|
+
function mn(e, n, t) {
|
|
902
|
+
let r;
|
|
903
|
+
if (n.id !== void 0) {
|
|
904
|
+
const l = K(e, n.id), m = l && R(e, l);
|
|
905
|
+
r = m && fn(m);
|
|
906
|
+
} else if (n.line !== void 0) {
|
|
907
|
+
const l = f.resolve(t), m = f.resolve(n.file ?? t);
|
|
908
|
+
r = pn(e, l, m, n.line);
|
|
909
|
+
}
|
|
910
|
+
if (!r) return;
|
|
911
|
+
const i = n.level ?? 1 / 0;
|
|
912
|
+
let o = !1;
|
|
913
|
+
const a = (R(e, r) ?? [r]).filter(
|
|
914
|
+
(l) => l.name !== "pretext" && l.name !== "mathbook"
|
|
915
|
+
), c = a[0], d = c?.name === "book" && c.children.some(
|
|
916
|
+
(l) => G(l) && l.name === "part"
|
|
917
|
+
), u = V(a, d);
|
|
918
|
+
if (u > i)
|
|
919
|
+
for (let l = 0; l < a.length; l++) {
|
|
920
|
+
const m = a[l];
|
|
921
|
+
if (Z(m) && V(a.slice(0, l + 1), d) >= i) {
|
|
922
|
+
r = m;
|
|
923
|
+
break;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else u < i && (o = !0);
|
|
927
|
+
return { element: r, id: rt(e, r), collapse: o };
|
|
928
|
+
}
|
|
929
|
+
function rt(e, n) {
|
|
930
|
+
const t = n.attributes["xml:id"];
|
|
931
|
+
if (t) return t;
|
|
932
|
+
const r = tn(e, n) ?? "root-1";
|
|
933
|
+
return n.attributes["xml:id"] = r, r;
|
|
934
|
+
}
|
|
935
|
+
function Y(e) {
|
|
936
|
+
let n = 0;
|
|
937
|
+
for (const t of e.children)
|
|
938
|
+
G(t) && (n += 1 + Y(t));
|
|
939
|
+
return n;
|
|
940
|
+
}
|
|
941
|
+
const vn = "This live preview shows a single division, so links into the rest of the document do not work here.", bn = /<a\b([^>]*)>/g, wn = /\sid="([^"]*)"/g, re = /\shref="([^"]*)"/, gn = /\\href\{([^{}]*)\}/g, Ie = /\stitle="([^"]*)"/;
|
|
942
|
+
function xn(e) {
|
|
943
|
+
const n = /* @__PURE__ */ new Set();
|
|
944
|
+
for (const t of e.matchAll(wn))
|
|
945
|
+
n.add(t[1]);
|
|
946
|
+
return n;
|
|
947
|
+
}
|
|
948
|
+
function ie(e) {
|
|
949
|
+
return e.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
950
|
+
}
|
|
951
|
+
function Le(e, n) {
|
|
952
|
+
if (e.startsWith("#") || e === "") return { kind: "keep" };
|
|
953
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(e) || e.startsWith("//"))
|
|
954
|
+
return { kind: "keep" };
|
|
955
|
+
const t = e.indexOf("#"), i = (t === -1 ? e : e.slice(0, t)).replace(/\.html?$/i, "");
|
|
956
|
+
if (t === -1) return { kind: "off-page", division: i };
|
|
957
|
+
const o = e.slice(t + 1);
|
|
958
|
+
return n.has(o) && o !== "" ? { kind: "same-page", id: o } : { kind: "off-page", division: i, ...o ? { id: o } : {} };
|
|
959
|
+
}
|
|
960
|
+
function yn(e, n = {}) {
|
|
961
|
+
const t = n.offPageMessage ?? vn, r = xn(e);
|
|
962
|
+
return e.replace(bn, (o, s) => {
|
|
963
|
+
const a = re.exec(s);
|
|
964
|
+
if (!a) return o;
|
|
965
|
+
const c = Le(a[1], r);
|
|
966
|
+
if (c.kind === "keep") return o;
|
|
967
|
+
if (c.kind === "same-page")
|
|
968
|
+
return `<a${s.replace(re, ` href="#${c.id}"`)}>`;
|
|
969
|
+
const d = Ie.exec(s), u = ie(t), l = d ? `${d[1]} — ${u}` : u, b = s.replace(re, "").replace(Ie, ""), y = ` data-ptx-division="${ie(c.division)}"` + (c.id ? ` data-ptx-id="${ie(c.id)}"` : "");
|
|
970
|
+
return `<a${b} title="${l}" aria-disabled="true" style="cursor:default"${y}>`;
|
|
971
|
+
}).replace(gn, (o, s) => {
|
|
972
|
+
const a = Le(s, r);
|
|
973
|
+
return a.kind === "same-page" ? `\\href{#${a.id}}` : o;
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
function Tn() {
|
|
977
|
+
return It(ae(), "xsl");
|
|
978
|
+
}
|
|
979
|
+
function Sn() {
|
|
980
|
+
return "Suspending" in WebAssembly;
|
|
981
|
+
}
|
|
982
|
+
function En() {
|
|
983
|
+
if (!Sn())
|
|
984
|
+
throw new Error(
|
|
985
|
+
"WebAssembly JSPI is not enabled. Run Node with --experimental-wasm-jspi (or use the pretext-html CLI, which re-launches itself with the flag)."
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
function U(e) {
|
|
989
|
+
return e.includes("'") ? e.includes('"') ? `concat(${e.split("'").map((t) => `'${t}'`).join(`, "'", `)})` : `"${e}"` : `'${e}'`;
|
|
990
|
+
}
|
|
991
|
+
function kn(e) {
|
|
992
|
+
return e.replace(
|
|
993
|
+
/from '\.\/(https:\/\/[^']+)'/g,
|
|
994
|
+
(n, t) => `from '${t}'`
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
const Pn = `https://cdn.jsdelivr.net/gh/PreTeXtBook/html-static@${_e}/dist/`, $n = {
|
|
998
|
+
"cli.version": _e,
|
|
999
|
+
// Colon-delimited: pretext-runestone.xsl splits them with str:tokenize.
|
|
1000
|
+
"rs-js": Dt.join(":"),
|
|
1001
|
+
"rs-css": Rt.join(":"),
|
|
1002
|
+
"rs-version": Lt
|
|
1003
|
+
};
|
|
1004
|
+
function In(e) {
|
|
1005
|
+
return e.replace(
|
|
1006
|
+
/(<link\b[^>]*\bhref=["'])_static\//gi,
|
|
1007
|
+
`$1${Pn}_static/`
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
function Ln(e) {
|
|
1011
|
+
return e.slice(0, 65536).replace(/<\?[\s\S]*?\?>/g, " ").replace(/<!--[\s\S]*?-->/g, " ").replace(/<!DOCTYPE[^>]*>/gi, " ").match(/<\s*([A-Za-z][\w:-]*)/)?.[1];
|
|
1012
|
+
}
|
|
1013
|
+
let Dn;
|
|
1014
|
+
function Rn() {
|
|
1015
|
+
return Dn ??= new dn();
|
|
1016
|
+
}
|
|
1017
|
+
function it(e) {
|
|
1018
|
+
const n = e.files ? new Map(
|
|
1019
|
+
Object.entries(e.files).map(([o, s]) => [
|
|
1020
|
+
f.resolve(o),
|
|
1021
|
+
s
|
|
1022
|
+
])
|
|
1023
|
+
) : void 0, t = e.readSource, r = n || t ? async (o) => n?.get(o) ?? await t?.(o) : void 0, i = e.cache === !1 ? void 0 : e.cache ?? Rn();
|
|
1024
|
+
return { readSource: r, cache: i };
|
|
1025
|
+
}
|
|
1026
|
+
async function ue(e, n) {
|
|
1027
|
+
const t = await q(e, n);
|
|
1028
|
+
if (t === void 0)
|
|
1029
|
+
throw new Error(
|
|
1030
|
+
`Could not read ${n}. (In the browser build only absolute URLs are readable — pass sourceContent instead of relying on sourcePath.)`
|
|
1031
|
+
);
|
|
1032
|
+
return t;
|
|
1033
|
+
}
|
|
1034
|
+
async function An(e, n, t) {
|
|
1035
|
+
const r = f.resolve(e), i = await q(t, r);
|
|
1036
|
+
if (i !== void 0)
|
|
1037
|
+
return qt(i, r, n, t);
|
|
1038
|
+
}
|
|
1039
|
+
async function nr(e) {
|
|
1040
|
+
const n = it(e), t = f.resolve(e.sourcePath), r = f.resolve(
|
|
1041
|
+
e.projectDir ?? f.dirname(t)
|
|
1042
|
+
), i = e.sourceContent ?? await ue(n, t), o = await me(
|
|
1043
|
+
i,
|
|
1044
|
+
t,
|
|
1045
|
+
r,
|
|
1046
|
+
n
|
|
1047
|
+
);
|
|
1048
|
+
return {
|
|
1049
|
+
bytes: o.bytes,
|
|
1050
|
+
elements: Y(o.tree),
|
|
1051
|
+
files: o.files
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
function jn(e, n, t, r) {
|
|
1055
|
+
const i = e.replace(/^\uFEFF/, "").replace(/<\?xml[\s\S]*?\?>/, "").replace(/<!DOCTYPE[^>]*>/i, ""), o = t === "slides" ? "slideshow" : n === "chapter" || n === "part" ? "book" : "article";
|
|
1056
|
+
return `<pretext>
|
|
1057
|
+
${r?.trim() ? `${r.trim()}
|
|
1058
|
+
` : ""}<${o}>
|
|
1059
|
+
<title/>
|
|
1060
|
+
${i}
|
|
1061
|
+
</${o}>
|
|
1062
|
+
</pretext>
|
|
1063
|
+
`;
|
|
1064
|
+
}
|
|
1065
|
+
async function Cn(e, n, t, r, i, o) {
|
|
1066
|
+
const s = e.attributes["xml:id"];
|
|
1067
|
+
if (!s) return;
|
|
1068
|
+
const a = f.resolve(t), c = i ?? await q(o, a);
|
|
1069
|
+
if (c === void 0) return;
|
|
1070
|
+
let d, u, l;
|
|
1071
|
+
try {
|
|
1072
|
+
({ tree: d, files: u, bytes: l } = await me(
|
|
1073
|
+
c,
|
|
1074
|
+
a,
|
|
1075
|
+
r,
|
|
1076
|
+
o
|
|
1077
|
+
));
|
|
1078
|
+
} catch {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
if (ze(e, n), !!ln(d, s, e))
|
|
1082
|
+
return u.includes(n) || u.push(n), { tree: d, divisionId: s, files: u, bytes: l };
|
|
1083
|
+
}
|
|
1084
|
+
let ot = !1;
|
|
1085
|
+
function Mn(e) {
|
|
1086
|
+
return e instanceof Error && /\bAborted\(/.test(e.message);
|
|
1087
|
+
}
|
|
1088
|
+
function On(e) {
|
|
1089
|
+
return e instanceof Error && /memory access|out of bounds/i.test(e.message);
|
|
1090
|
+
}
|
|
1091
|
+
function _n() {
|
|
1092
|
+
if (ot)
|
|
1093
|
+
throw new Error(
|
|
1094
|
+
"The WebAssembly renderer aborted earlier in this process and cannot be reused. Restart the process (or reload the page) to render again."
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
function De(e) {
|
|
1098
|
+
if (Mn(e))
|
|
1099
|
+
throw ot = !0, new Error(
|
|
1100
|
+
"The WebAssembly renderer aborted and cannot be reused. Restart the process (or reload the page) to render again.",
|
|
1101
|
+
{ cause: e }
|
|
1102
|
+
);
|
|
1103
|
+
if (On(e))
|
|
1104
|
+
throw new Error(
|
|
1105
|
+
"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.",
|
|
1106
|
+
{ cause: e }
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
let oe;
|
|
1110
|
+
async function st() {
|
|
1111
|
+
return oe || (oe = (async () => {
|
|
1112
|
+
const [e, n] = await Promise.all([
|
|
1113
|
+
import("@pretextbook/libxslt-wasm"),
|
|
1114
|
+
import("@pretextbook/libxslt-wasm/exslt")
|
|
1115
|
+
]);
|
|
1116
|
+
return n.registerAll(), e;
|
|
1117
|
+
})()), oe;
|
|
1118
|
+
}
|
|
1119
|
+
const se = /* @__PURE__ */ new Map(), Nn = {
|
|
1120
|
+
html: "preview-html.xsl",
|
|
1121
|
+
slides: "preview-revealjs.xsl"
|
|
1122
|
+
};
|
|
1123
|
+
async function Bn(e, n) {
|
|
1124
|
+
const t = Nn[n], r = `${n}\0${e}`;
|
|
1125
|
+
let i = se.get(r);
|
|
1126
|
+
return i || (i = (async () => {
|
|
1127
|
+
const { XmlDocument: o, XsltStylesheet: s } = await st(), a = Ue(e), c = await Me(ae(), `/${t}`);
|
|
1128
|
+
if (c === void 0)
|
|
1129
|
+
throw new Error(
|
|
1130
|
+
`Could not read ${t} from ${ae()}. Check the assets location (PRETEXT_HTML_ASSETS under Node, setAssetsBase() in the browser).`
|
|
1131
|
+
);
|
|
1132
|
+
const d = new TextDecoder().decode(c), u = await o.fromString(d, {
|
|
1133
|
+
url: `${a}/${t}`,
|
|
1134
|
+
options: { noEnt: !0, dtdLoad: !0, huge: !0 }
|
|
1135
|
+
});
|
|
1136
|
+
return s.fromXmlDocument(u);
|
|
1137
|
+
})(), se.set(r, i), i.catch(() => se.delete(r))), i;
|
|
1138
|
+
}
|
|
1139
|
+
let Re = Promise.resolve();
|
|
1140
|
+
function Fn(e) {
|
|
1141
|
+
const n = Re.then(
|
|
1142
|
+
() => Ae(e),
|
|
1143
|
+
() => Ae(e)
|
|
1144
|
+
);
|
|
1145
|
+
return Re = n.catch(() => {
|
|
1146
|
+
}), n;
|
|
1147
|
+
}
|
|
1148
|
+
async function Ae(e) {
|
|
1149
|
+
En(), _n();
|
|
1150
|
+
const { XmlDocument: n } = await st(), t = it(e), r = f.resolve(e.sourcePath), i = f.resolve(
|
|
1151
|
+
e.projectDir ?? f.dirname(r)
|
|
1152
|
+
), o = e.sourceContent ?? await ue(t, r), s = f.relative(i, r);
|
|
1153
|
+
if (s.startsWith(".."))
|
|
1154
|
+
throw new Error(
|
|
1155
|
+
`sourcePath (${r}) must live inside projectDir (${i})`
|
|
1156
|
+
);
|
|
1157
|
+
const a = f.relative(
|
|
1158
|
+
i,
|
|
1159
|
+
f.resolve(e.mainSourcePath ?? r)
|
|
1160
|
+
), c = a.startsWith("..") ? s : a, d = Ue(i);
|
|
1161
|
+
try {
|
|
1162
|
+
let u, l = `${d}/__pretext-preview-publication.xml`;
|
|
1163
|
+
if (e.publicationPath) {
|
|
1164
|
+
const h = f.resolve(e.publicationPath);
|
|
1165
|
+
u = await ue(t, h);
|
|
1166
|
+
const w = f.relative(i, h);
|
|
1167
|
+
w.startsWith("..") || (l = `${d}/${w.split(f.sep).join("/")}`);
|
|
1168
|
+
}
|
|
1169
|
+
const m = await me(
|
|
1170
|
+
o,
|
|
1171
|
+
r,
|
|
1172
|
+
i,
|
|
1173
|
+
t
|
|
1174
|
+
);
|
|
1175
|
+
let b = m.tree, y = m.content, x = m.files, j = m.bytes;
|
|
1176
|
+
const $ = e.target ?? nn(y), Q = await Bn(e.xslDir ?? Tn(), $), C = Xe(u, {
|
|
1177
|
+
cssTheme: e.cssTheme,
|
|
1178
|
+
revealTheme: e.revealTheme,
|
|
1179
|
+
target: $
|
|
1180
|
+
});
|
|
1181
|
+
Xt(l, C);
|
|
1182
|
+
const p = Ln(y);
|
|
1183
|
+
let T = { parentId: "root", position: 1 }, v, I = r, P, S;
|
|
1184
|
+
const we = (h, w) => {
|
|
1185
|
+
P = { bytes: j, elements: Y(h), files: x };
|
|
1186
|
+
const k = e.subtree ? mn(h, e.subtree, r) : void 0, D = k?.id ?? w;
|
|
1187
|
+
if (!D) return !1;
|
|
1188
|
+
const W = e.subtree?.wholeDocumentUpTo;
|
|
1189
|
+
if (W !== void 0 && P.elements <= W) return !1;
|
|
1190
|
+
const ct = k?.collapse && k.element ? k.element.children.filter(
|
|
1191
|
+
(H) => H.type === "element" && Z(H)
|
|
1192
|
+
).map((H) => rt(h, H)) : [], M = un(h, D, {
|
|
1193
|
+
collapseChildren: k?.collapse,
|
|
1194
|
+
...Gt(C)
|
|
1195
|
+
});
|
|
1196
|
+
return M ? (y = M.content, v = {
|
|
1197
|
+
id: M.divisionId,
|
|
1198
|
+
level: M.level,
|
|
1199
|
+
collapsed: M.collapsed,
|
|
1200
|
+
children: M.collapsed ? ct : []
|
|
1201
|
+
}, !0) : !1;
|
|
1202
|
+
};
|
|
1203
|
+
if (p !== "pretext" && p !== "mathbook") {
|
|
1204
|
+
if (!e.fragment)
|
|
1205
|
+
throw new Error(
|
|
1206
|
+
`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.`
|
|
1207
|
+
);
|
|
1208
|
+
let h = !1;
|
|
1209
|
+
if (e.contextSourcePath || e.contextSourceContent) {
|
|
1210
|
+
const w = e.contextSourcePath ?? f.join(f.dirname(r), "__pretext-preview-context.ptx"), k = b.children.find(
|
|
1211
|
+
(W) => W.type === "element"
|
|
1212
|
+
), D = k ? await Cn(
|
|
1213
|
+
k,
|
|
1214
|
+
r,
|
|
1215
|
+
w,
|
|
1216
|
+
i,
|
|
1217
|
+
e.contextSourceContent,
|
|
1218
|
+
t
|
|
1219
|
+
) : void 0;
|
|
1220
|
+
D && (h = !0, b = D.tree, S = z(b), x = D.files, j = D.bytes, I = f.resolve(w), we(b, D.divisionId) || (y = N(b)));
|
|
1221
|
+
}
|
|
1222
|
+
if (!h) {
|
|
1223
|
+
const w = e.docinfo ?? (e.docinfoSourcePath ? await An(
|
|
1224
|
+
e.docinfoSourcePath,
|
|
1225
|
+
i,
|
|
1226
|
+
t
|
|
1227
|
+
) : void 0);
|
|
1228
|
+
y = jn(
|
|
1229
|
+
y,
|
|
1230
|
+
p,
|
|
1231
|
+
$,
|
|
1232
|
+
w
|
|
1233
|
+
), S = w === void 0 ? void 0 : z(w), T = { parentId: w?.trim() ? "root-1-2" : "root-1-1", position: 2 };
|
|
1234
|
+
}
|
|
1235
|
+
} else
|
|
1236
|
+
S = z(b), e.subtree && we(b);
|
|
1237
|
+
P ??= { bytes: j, elements: Y(b), files: x };
|
|
1238
|
+
const ee = Yt(C, S), ge = f.dirname(f.resolve(i, c)), at = {
|
|
1239
|
+
generated: f.resolve(ge, ee.generated),
|
|
1240
|
+
...ee.external !== void 0 ? { external: f.resolve(ge, ee.external) } : {}
|
|
1241
|
+
}, xe = e.sourceMap ? en(b, I, T) : void 0, ye = await n.fromString(y, {
|
|
1242
|
+
url: `${d}/${c.split(f.sep).join("/")}`,
|
|
1243
|
+
options: { noEnt: !0, dtdLoad: !0, huge: !0 }
|
|
1244
|
+
}), F = {
|
|
1245
|
+
publisher: U(l)
|
|
1246
|
+
};
|
|
1247
|
+
for (const [h, w] of Object.entries($n))
|
|
1248
|
+
F[h] = U(w);
|
|
1249
|
+
v && (F.subtree = U(v.id), F["subtree-level"] = U(
|
|
1250
|
+
String(v.level + (v.collapsed ? 1 : 0))
|
|
1251
|
+
));
|
|
1252
|
+
for (const [h, w] of Object.entries(e.stringParams ?? {}))
|
|
1253
|
+
F[h] = U(w);
|
|
1254
|
+
let te;
|
|
1255
|
+
try {
|
|
1256
|
+
te = await Q.apply(ye, F);
|
|
1257
|
+
} catch (h) {
|
|
1258
|
+
throw De(h), new Error(
|
|
1259
|
+
"PreTeXt XSLT transform failed; see the PTX:ERROR/PTX:FATAL messages on stderr for details.",
|
|
1260
|
+
{ cause: h }
|
|
1261
|
+
);
|
|
1262
|
+
} finally {
|
|
1263
|
+
ye.delete();
|
|
1264
|
+
}
|
|
1265
|
+
try {
|
|
1266
|
+
let h = kn(te.toHtmlString());
|
|
1267
|
+
h = yn(h, {
|
|
1268
|
+
...e.offPageMessage !== void 0 ? { offPageMessage: e.offPageMessage } : {}
|
|
1269
|
+
}), (e.openKnowls ?? !0) && (h = Ot(h)), $ === "slides" ? (h = In(h), h = vt(h, e.revealView ?? "scroll", {
|
|
1270
|
+
zoom: e.revealZoom
|
|
1271
|
+
})) : e.theme && (h = bt(h, e.theme)), e.previewBanner && (h = Pt(h, e.previewBanner));
|
|
1272
|
+
const w = $ === "slides" ? [] : pt(h), k = mt(w, p);
|
|
1273
|
+
return e.printPreview && (h = Ce(h, e.printPreview)), {
|
|
1274
|
+
html: h,
|
|
1275
|
+
target: $,
|
|
1276
|
+
printouts: w,
|
|
1277
|
+
size: P,
|
|
1278
|
+
assetDirs: at,
|
|
1279
|
+
...v ? { subtree: v } : {},
|
|
1280
|
+
...xe ? { sourceMap: xe } : {},
|
|
1281
|
+
...k ? { rootPrintout: k } : {}
|
|
1282
|
+
};
|
|
1283
|
+
} catch (h) {
|
|
1284
|
+
throw De(h), h;
|
|
1285
|
+
} finally {
|
|
1286
|
+
te.delete();
|
|
1287
|
+
}
|
|
1288
|
+
} finally {
|
|
1289
|
+
Ut(d);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
const je = `Usage: pretext-html <source.ptx> [options]
|
|
1293
|
+
|
|
1294
|
+
Render a PreTeXt document to a single standalone HTML page (one page,
|
|
1295
|
+
css/js/MathJax from CDN). No PreTeXt installation required.
|
|
1296
|
+
|
|
1297
|
+
Images, generated ones included, are linked rather than embedded. With
|
|
1298
|
+
--output, their URLs point at the project's own files, relative to the output
|
|
1299
|
+
file, and a missing one shows a placeholder naming what to generate. On stdout
|
|
1300
|
+
they are left as PreTeXt emits them, under external/ and generated/.
|
|
1301
|
+
|
|
1302
|
+
Options:
|
|
1303
|
+
-o, --output <file> Write HTML to a file instead of stdout
|
|
1304
|
+
--publication <file> Publication file (CDN resources, chunk level 0 and
|
|
1305
|
+
cross-references as links are forced on)
|
|
1306
|
+
--css-theme <name> HTML theme to use when the publication file names
|
|
1307
|
+
none of its own: default-modern (PreTeXt's default),
|
|
1308
|
+
denver, tacoma, salem, greeley or boulder
|
|
1309
|
+
--project-dir <dir> Directory served to the transform for xi:includes
|
|
1310
|
+
(default: the source file's directory)
|
|
1311
|
+
--param <name=value> Extra XSLT string parameter (repeatable)
|
|
1312
|
+
--xsl-dir <dir> Use PreTeXt stylesheets from this directory
|
|
1313
|
+
instead of the vendored copy
|
|
1314
|
+
--fragment Allow a non-root source file: wrap the fragment
|
|
1315
|
+
in a minimal <pretext> document (an <article>,
|
|
1316
|
+
or a <book> for <chapter>/<part> fragments)
|
|
1317
|
+
--docinfo <file> File whose contents (a <docinfo> element) are
|
|
1318
|
+
injected into the wrapper in --fragment mode, so
|
|
1319
|
+
the fragment keeps the project's LaTeX macros
|
|
1320
|
+
--docinfo-source <file> Complete source file (e.g. main.ptx) to lift the
|
|
1321
|
+
<docinfo> from for --fragment mode, resolving
|
|
1322
|
+
xi:includes (used when --docinfo is not given)
|
|
1323
|
+
--context <file> Complete document (e.g. main.ptx) the fragment
|
|
1324
|
+
belongs to. Renders it in place, so it is numbered
|
|
1325
|
+
and its cross-references resolve as in the built
|
|
1326
|
+
book. Supersedes --docinfo-source
|
|
1327
|
+
--off-page-message <text> Tooltip on links whose target is not on the
|
|
1328
|
+
previewed page, which cannot navigate in a
|
|
1329
|
+
single-page preview
|
|
1330
|
+
--source-map <file> Also write a JSON source map: HTML id → source
|
|
1331
|
+
file/line for every element (for editor sync)
|
|
1332
|
+
--no-open-knowls Leave solutions, hints and other born-hidden
|
|
1333
|
+
knowls collapsed, as a real PreTeXt build does.
|
|
1334
|
+
They are expanded by default, since these pages
|
|
1335
|
+
are previews of work in progress
|
|
1336
|
+
--print-preview[=id] Open the page in the print-preview layout: the
|
|
1337
|
+
named printout paginated to a paper size, with
|
|
1338
|
+
workspaces at their true height. Without an id, the
|
|
1339
|
+
document's own printout is used (a lone worksheet
|
|
1340
|
+
or handout), or failing that its first. The page's
|
|
1341
|
+
printouts are listed on stderr
|
|
1342
|
+
-h, --help Show this help
|
|
1343
|
+
`;
|
|
1344
|
+
function Un(e) {
|
|
1345
|
+
let n, t, r, i, o;
|
|
1346
|
+
const s = {}, a = {};
|
|
1347
|
+
for (let c = 0; c < e.length; c++) {
|
|
1348
|
+
const d = e[c], u = () => {
|
|
1349
|
+
if (c += 1, c >= e.length)
|
|
1350
|
+
throw new Error(`Missing value for ${d}`);
|
|
1351
|
+
return e[c];
|
|
1352
|
+
};
|
|
1353
|
+
switch (d) {
|
|
1354
|
+
case "-h":
|
|
1355
|
+
case "--help":
|
|
1356
|
+
L.stdout.write(je), L.exit(0);
|
|
1357
|
+
break;
|
|
1358
|
+
case "-o":
|
|
1359
|
+
case "--output":
|
|
1360
|
+
t = u();
|
|
1361
|
+
break;
|
|
1362
|
+
case "--publication":
|
|
1363
|
+
s.publicationPath = u();
|
|
1364
|
+
break;
|
|
1365
|
+
case "--css-theme":
|
|
1366
|
+
s.cssTheme = u();
|
|
1367
|
+
break;
|
|
1368
|
+
case "--project-dir":
|
|
1369
|
+
s.projectDir = u();
|
|
1370
|
+
break;
|
|
1371
|
+
case "--xsl-dir":
|
|
1372
|
+
s.xslDir = u();
|
|
1373
|
+
break;
|
|
1374
|
+
case "--fragment":
|
|
1375
|
+
s.fragment = !0;
|
|
1376
|
+
break;
|
|
1377
|
+
case "--no-open-knowls":
|
|
1378
|
+
s.openKnowls = !1;
|
|
1379
|
+
break;
|
|
1380
|
+
case "--docinfo":
|
|
1381
|
+
r = u();
|
|
1382
|
+
break;
|
|
1383
|
+
case "--docinfo-source":
|
|
1384
|
+
s.docinfoSourcePath = u();
|
|
1385
|
+
break;
|
|
1386
|
+
case "--context":
|
|
1387
|
+
s.contextSourcePath = u();
|
|
1388
|
+
break;
|
|
1389
|
+
case "--off-page-message":
|
|
1390
|
+
s.offPageMessage = u();
|
|
1391
|
+
break;
|
|
1392
|
+
case "--source-map":
|
|
1393
|
+
i = u(), s.sourceMap = !0;
|
|
1394
|
+
break;
|
|
1395
|
+
// Attached form only (--print-preview=<id>), so that a bare
|
|
1396
|
+
// --print-preview cannot swallow the source file as its id.
|
|
1397
|
+
case "--print-preview":
|
|
1398
|
+
o = !0;
|
|
1399
|
+
break;
|
|
1400
|
+
case "--param": {
|
|
1401
|
+
const l = u(), m = l.indexOf("=");
|
|
1402
|
+
if (m === -1)
|
|
1403
|
+
throw new Error(`--param expects name=value, got: ${l}`);
|
|
1404
|
+
a[l.slice(0, m)] = l.slice(m + 1);
|
|
1405
|
+
break;
|
|
1406
|
+
}
|
|
1407
|
+
default:
|
|
1408
|
+
if (d.startsWith("--print-preview=")) {
|
|
1409
|
+
o = d.slice(16);
|
|
1410
|
+
break;
|
|
1411
|
+
}
|
|
1412
|
+
if (d.startsWith("-"))
|
|
1413
|
+
throw new Error(`Unknown option: ${d}`);
|
|
1414
|
+
if (n)
|
|
1415
|
+
throw new Error(`Unexpected extra argument: ${d}`);
|
|
1416
|
+
n = d;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
if (!n)
|
|
1420
|
+
throw new Error(`No source file given.
|
|
1421
|
+
|
|
1422
|
+
` + je);
|
|
1423
|
+
return Object.keys(a).length > 0 && (s.stringParams = a), {
|
|
1424
|
+
options: { ...s, sourcePath: n },
|
|
1425
|
+
output: t,
|
|
1426
|
+
docinfoPath: r,
|
|
1427
|
+
sourceMapPath: i,
|
|
1428
|
+
printPreview: o
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
function Xn(e, n, t) {
|
|
1432
|
+
return ft(e, (r, i) => {
|
|
1433
|
+
const o = n[r], s = o === void 0 ? void 0 : f.resolve(o, i);
|
|
1434
|
+
if (s === void 0 || !lt(s))
|
|
1435
|
+
return ht(r, i);
|
|
1436
|
+
const a = f.relative(t, s);
|
|
1437
|
+
return f.isAbsolute(a) ? dt(s).href : a.split(f.sep).map(encodeURIComponent).join("/");
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
async function rr(e) {
|
|
1441
|
+
const { options: n, output: t, docinfoPath: r, sourceMapPath: i, printPreview: o } = Un(e);
|
|
1442
|
+
r && (n.docinfo = await de(r, "utf8"));
|
|
1443
|
+
const s = Date.now(), a = await Fn(n), { sourceMap: c, printouts: d, rootPrintout: u } = a;
|
|
1444
|
+
let l = a.html;
|
|
1445
|
+
if (L.stderr.write(`pretext-html: rendered in ${Date.now() - s}ms
|
|
1446
|
+
`), o !== void 0) {
|
|
1447
|
+
for (const b of d)
|
|
1448
|
+
L.stderr.write(
|
|
1449
|
+
`pretext-html: printout ${b.id} - ${b.label}
|
|
1450
|
+
`
|
|
1451
|
+
);
|
|
1452
|
+
const m = typeof o == "string" ? o : u ?? d[0]?.id;
|
|
1453
|
+
m ? (L.stderr.write(`pretext-html: print preview of ${m}
|
|
1454
|
+
`), l = Ce(l, m)) : L.stderr.write(
|
|
1455
|
+
`pretext-html: --print-preview: this document has no printouts (worksheet, handout, or project with a workspace); writing the ordinary page.
|
|
1456
|
+
`
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
i && c && (await Te(i, JSON.stringify(c, null, 2)), L.stderr.write(`pretext-html: wrote ${i}
|
|
1460
|
+
`)), t ? (l = Xn(
|
|
1461
|
+
l,
|
|
1462
|
+
a.assetDirs,
|
|
1463
|
+
f.dirname(f.resolve(t))
|
|
1464
|
+
), await Te(t, l), L.stderr.write(`pretext-html: wrote ${t}
|
|
1465
|
+
`)) : L.stdout.write(l);
|
|
1466
|
+
}
|
|
1467
|
+
export {
|
|
1468
|
+
vn as O,
|
|
1469
|
+
wt as P,
|
|
1470
|
+
dn as S,
|
|
1471
|
+
Tn as a,
|
|
1472
|
+
un as b,
|
|
1473
|
+
nn as c,
|
|
1474
|
+
Rn as d,
|
|
1475
|
+
V as e,
|
|
1476
|
+
tr as f,
|
|
1477
|
+
er as g,
|
|
1478
|
+
Xe as h,
|
|
1479
|
+
Pt as i,
|
|
1480
|
+
Sn as j,
|
|
1481
|
+
Fn as k,
|
|
1482
|
+
ln as l,
|
|
1483
|
+
nr as m,
|
|
1484
|
+
yn as n,
|
|
1485
|
+
Ot as o,
|
|
1486
|
+
Tt as p,
|
|
1487
|
+
rr as q,
|
|
1488
|
+
Gt as r,
|
|
1489
|
+
Zn as s,
|
|
1490
|
+
Qn as t,
|
|
1491
|
+
Xn as u,
|
|
1492
|
+
Un as v,
|
|
1493
|
+
U as x
|
|
1494
|
+
};
|