@pretextbook/import 0.11.0 → 0.12.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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { i as W, P as H, d as U, r as G, a as V, f as C, b as R, w as v, s as k, e as q, c as Z, p as Y, g as $, h as J, j as Q } from "./upload-H_OCZBBn.js";
2
- import { C as Xe, D as ze, L as Be, k as Ke, l as We, M as He, m as Ue, n as Ge, o as Ve, q as qe, t as Ze, u as Ye, v as Je, x as Qe, y as et, z as tt, A as nt, B as rt, E as ot, F as st, G as at, H as it, I as ct, J as lt, K as ut, N as pt, O as dt, Q as mt, R as ft, S as ht, T as gt, U as wt, V as Tt, W as xt, X as Pt, Y as Et, Z as vt, _ as St, $ as bt, a0 as It, a1 as _t, a2 as $t, a3 as At, a4 as Ft, a5 as Lt, a6 as yt, a7 as Ct, a8 as Rt, a9 as kt, aa as Dt, ab as Mt, ac as Ot, ad as Nt, ae as jt, af as Xt, ag as zt, ah as Bt, ai as Kt, aj as Wt, ak as Ht, al as Ut, am as Gt } from "./upload-H_OCZBBn.js";
3
- import { D as qt, a as Zt, d as Yt, b as Jt, c as Qt, f as en, e as tn, g as nn, h as rn, p as on, r as sn } from "./import-mode-DQ8g5P8P.js";
1
+ import { i as W, P as U, d as H, r as G, a as q, f as C, b as k, w as S, s as R, e as V, c as Z, p as Y, g as A, h as J, j as Q } from "./upload-H_OCZBBn.js";
2
+ import { C as Xe, D as ze, L as Be, k as Ke, l as We, M as Ue, m as He, n as Ge, o as qe, q as Ve, t as Ze, u as Ye, v as Je, x as Qe, y as et, z as tt, A as nt, B as rt, E as st, F as ot, G as at, H as it, I as ct, J as lt, K as ut, N as pt, O as dt, Q as mt, R as ft, S as ht, T as gt, U as wt, V as Tt, W as xt, X as Pt, Y as Et, Z as St, _ as vt, $ as bt, a0 as It, a1 as _t, a2 as At, a3 as $t, a4 as Ft, a5 as Lt, a6 as yt, a7 as Ct, a8 as kt, a9 as Rt, aa as Dt, ab as Mt, ac as Ot, ad as Nt, ae as jt, af as Xt, ag as zt, ah as Bt, ai as Kt, aj as Wt, ak as Ut, al as Ht, am as Gt } from "./upload-H_OCZBBn.js";
3
+ import { D as Vt, a as Zt, b as Yt, c as Jt, d as Qt, e as en, f as tn, g as nn, h as rn, i as sn, j as on, k as an, l as cn, m as ln, n as un, o as pn, p as dn, r as mn, q as fn, u as hn } from "./engine-routing-Bu0zM4aw.js";
4
4
  const ee = /\$(?![\s$])([^$\n]{1,200})\$/;
5
5
  function te(e) {
6
6
  const t = ee.exec(e);
@@ -41,22 +41,22 @@ const ne = [
41
41
  { pattern: /(?:^|\s)_[^_\s][^_\n]*_(?:\s|[.,;:!?]|$)/, weight: 1 },
42
42
  // Inline code span.
43
43
  { pattern: /`[^`\n]+`/, weight: 1 }
44
- ], oe = 2;
45
- function A(e, t) {
44
+ ], se = 2;
45
+ function $(e, t) {
46
46
  return t.reduce(
47
- (n, { pattern: r, weight: o }) => n + (r.test(e) ? o : 0),
47
+ (n, { pattern: r, weight: s }) => n + (r.test(e) ? s : 0),
48
48
  0
49
49
  );
50
50
  }
51
- function se(e) {
52
- return { latex: A(e, ne) + (te(e) ? 2 : 0), markdown: A(e, re) };
51
+ function oe(e) {
52
+ return { latex: $(e, ne) + (te(e) ? 2 : 0), markdown: $(e, re) };
53
53
  }
54
54
  function Fe(e) {
55
55
  const t = e.trim();
56
56
  if (!t || t.startsWith("<"))
57
57
  return;
58
- const { latex: n, markdown: r } = se(t);
59
- if (!(Math.max(n, r) < oe))
58
+ const { latex: n, markdown: r } = oe(t);
59
+ if (!(Math.max(n, r) < se))
60
60
  return n >= r ? "latex" : "markdown";
61
61
  }
62
62
  const ae = {
@@ -81,8 +81,8 @@ const P = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
81
81
  function ce(e) {
82
82
  const t = e.length, n = [];
83
83
  for (let r = 0; r < t; r += 3) {
84
- const o = e[r], a = r + 1 < t, s = r + 2 < t, i = a ? e[r + 1] : 0, c = s ? e[r + 2] : 0;
85
- n.push(P[o >> 2]), n.push(P[(o & 3) << 4 | i >> 4]), n.push(a ? P[(i & 15) << 2 | c >> 6] : "="), n.push(s ? P[c & 63] : "=");
84
+ const s = e[r], a = r + 1 < t, o = r + 2 < t, i = a ? e[r + 1] : 0, c = o ? e[r + 2] : 0;
85
+ n.push(P[s >> 2]), n.push(P[(s & 3) << 4 | i >> 4]), n.push(a ? P[(i & 15) << 2 | c >> 6] : "="), n.push(o ? P[c & 63] : "=");
86
86
  }
87
87
  return n.join("");
88
88
  }
@@ -142,14 +142,14 @@ function Le(e) {
142
142
  return pe(le(e));
143
143
  }
144
144
  function ye(e, t) {
145
- const { root: n, entries: r } = W(e, t), o = new Set(r.map((s) => s.xmlId)), a = e.divisions.filter(
146
- (s) => !o.has(s.xmlId) && !(t.unwrapRoot && s.xmlId === n.xmlId)
145
+ const { root: n, entries: r } = W(e, t), s = new Set(r.map((o) => o.xmlId)), a = e.divisions.filter(
146
+ (o) => !s.has(o.xmlId) && !(t.unwrapRoot && o.xmlId === n.xmlId)
147
147
  );
148
148
  return {
149
149
  divisions: [...r, ...a].map(M),
150
150
  assets: e.assets.map(D),
151
151
  placeholders: r.map(
152
- (s) => `<plus:${s.type} ref="${s.xmlId}"/>`
152
+ (o) => `<plus:${o.type} ref="${o.xmlId}"/>`
153
153
  )
154
154
  };
155
155
  }
@@ -163,7 +163,7 @@ function Ce(e) {
163
163
  return t > 0;
164
164
  }
165
165
  const de = new RegExp(
166
- `<(${H.join("|")})(?=[\\s>/])`
166
+ `<(${U.join("|")})(?=[\\s>/])`
167
167
  );
168
168
  function me(e) {
169
169
  return de.exec(e)?.[1];
@@ -171,15 +171,15 @@ function me(e) {
171
171
  function fe(e, t, n) {
172
172
  return e.split(`
173
173
  `).map(
174
- (r, o) => o === 0 && n ? r : r && t + r
174
+ (r, s) => s === 0 && n ? r : r && t + r
175
175
  ).join(`
176
176
  `);
177
177
  }
178
- function Re(e, t) {
178
+ function ke(e, t) {
179
179
  let n = e.trim(), r;
180
180
  if (t.inline) {
181
- const o = n.replace(/^<p>\s*([\s\S]*?)\s*<\/p>$/, "$1");
182
- n = o !== n ? o : n.replace(/^<p>/, "");
181
+ const s = n.replace(/^<p>\s*([\s\S]*?)\s*<\/p>$/, "$1");
182
+ n = s !== n ? s : n.replace(/^<p>/, "");
183
183
  const a = me(n);
184
184
  a && (r = `Pasted content produced a <${a}>, which cannot sit inside a <p>. It was inserted as-is — move it out of the paragraph to make the document valid.`);
185
185
  }
@@ -197,9 +197,9 @@ ${e}
197
197
  </pretext>`;
198
198
  }
199
199
  function N(e, t, n) {
200
- const r = /* @__PURE__ */ new Map(), o = [], a = `${t}-`;
201
- return e.forEach((s, i) => {
202
- const c = s.attributes["xml:id"];
200
+ const r = /* @__PURE__ */ new Map(), s = [], a = `${t}-`;
201
+ return e.forEach((o, i) => {
202
+ const c = o.attributes["xml:id"];
203
203
  let l;
204
204
  if (c) {
205
205
  const m = Z(c);
@@ -210,33 +210,33 @@ function N(e, t, n) {
210
210
  severity: "info",
211
211
  kind: "structure",
212
212
  category: "missing_xml_id",
213
- macro: s.name,
213
+ macro: o.name,
214
214
  occurrences: 1,
215
- message: `<${s.name}> at position ${i + 1} has no xml:id; using \`${l}\` as filename.`
215
+ message: `<${o.name}> at position ${i + 1} has no xml:id; using \`${l}\` as filename.`
216
216
  });
217
217
  const p = r.get(l) ?? 0;
218
218
  r.set(l, p + 1);
219
219
  const u = p === 0 ? l : `${l}-${p + 1}`;
220
- o.push({
221
- span: s,
220
+ s.push({
221
+ span: o,
222
222
  slug: u,
223
223
  filename: `${u}.ptx`
224
224
  });
225
- }), o;
225
+ }), s;
226
226
  }
227
227
  function he(e, t, n, r) {
228
- const o = R(e, "section");
229
- if (o.length === 0)
228
+ const s = k(e, "section");
229
+ if (s.length === 0)
230
230
  return e;
231
- const s = N(o, "sec", r).map((i) => {
231
+ const o = N(s, "sec", r).map((i) => {
232
232
  const c = `source/${t}/${i.filename}`;
233
- return n[c] = v(i.span.outer), {
233
+ return n[c] = S(i.span.outer), {
234
234
  start: i.span.start,
235
235
  end: i.span.end,
236
236
  replacement: `<xi:include href="${t}/${i.filename}"/>`
237
237
  };
238
238
  });
239
- return k(e, s);
239
+ return R(e, o);
240
240
  }
241
241
  function ge(e, t, n) {
242
242
  const r = C(e, "book");
@@ -250,8 +250,8 @@ function ge(e, t, n) {
250
250
  occurrences: 1,
251
251
  message: "Document was treated as a book but no <book> element found; emitting as a single file."
252
252
  }), j(e, t);
253
- const o = {}, a = R(r.inner, "chapter");
254
- let s = r.inner;
253
+ const s = {}, a = k(r.inner, "chapter");
254
+ let o = r.inner;
255
255
  if (t.splitChapters && a.length > 0) {
256
256
  const p = N(a, "ch", n).map((u) => {
257
257
  let m = u.span.outer;
@@ -259,44 +259,44 @@ function ge(e, t, n) {
259
259
  const d = u.span.inner, f = he(
260
260
  d,
261
261
  u.slug,
262
- o,
262
+ s,
263
263
  n
264
264
  );
265
265
  m = u.span.outer.slice(0, u.span.startTagEnd - u.span.start) + f + u.span.outer.slice(u.span.contentEnd - u.span.start);
266
266
  }
267
267
  const h = `source/${u.filename}`;
268
- return o[h] = v(m), {
268
+ return s[h] = S(m), {
269
269
  start: u.span.start,
270
270
  end: u.span.end,
271
271
  replacement: `<xi:include href="${u.filename}"/>`
272
272
  };
273
273
  });
274
- s = k(r.inner, p);
274
+ o = R(r.inner, p);
275
275
  }
276
- const i = e.slice(r.start, r.startTagEnd) + s + e.slice(r.contentEnd, r.end), c = e.slice(0, r.start) + i + e.slice(r.end);
277
- return o[t.mainSourcePath] = v(
278
- q(O(c.trim()))
279
- ), o;
276
+ const i = e.slice(r.start, r.startTagEnd) + o + e.slice(r.contentEnd, r.end), c = e.slice(0, r.start) + i + e.slice(r.end);
277
+ return s[t.mainSourcePath] = S(
278
+ V(O(c.trim()))
279
+ ), s;
280
280
  }
281
281
  function j(e, t, n) {
282
282
  const r = {};
283
- return r[t.mainSourcePath] = v(
283
+ return r[t.mainSourcePath] = S(
284
284
  O(e.trim())
285
285
  ), r;
286
286
  }
287
- function ke(e, t = {}) {
288
- const n = [], r = t.documentKind ?? U(e), o = {
287
+ function Re(e, t = {}) {
288
+ const n = [], r = t.documentKind ?? H(e), s = {
289
289
  splitChapters: t.splitChapters ?? r === "book",
290
290
  splitSections: t.splitSections ?? !1,
291
291
  mainSourcePath: t.mainSourcePath ?? E.mainSourcePath,
292
292
  publicationPath: t.publicationPath ?? E.publicationPath,
293
293
  projectFilePath: t.projectFilePath ?? E.projectFilePath,
294
294
  docinfoPath: t.docinfoPath ?? E.docinfoPath
295
- }, a = r === "book" ? ge(e, o, n) : j(e, o);
296
- return a[o.projectFilePath] = G({
297
- mainSource: o.mainSourcePath,
298
- publication: o.publicationPath
299
- }), a[o.publicationPath] = V(), { files: a, documentKind: r, warnings: n };
295
+ }, a = r === "book" ? ge(e, s, n) : j(e, s);
296
+ return a[s.projectFilePath] = G({
297
+ mainSource: s.mainSourcePath,
298
+ publication: s.publicationPath
299
+ }), a[s.publicationPath] = q(), { files: a, documentKind: r, warnings: n };
300
300
  }
301
301
  class we extends Error {
302
302
  constructor() {
@@ -305,14 +305,14 @@ class we extends Error {
305
305
  }
306
306
  let Te = 0;
307
307
  function xe(e, t, n = {}) {
308
- const r = `convert-${Te++}`, o = e(), { assets: a = {}, ...s } = n;
308
+ const r = `convert-${Te++}`, s = e(), { assets: a = {}, ...o } = n;
309
309
  let i;
310
310
  const c = new Promise((p, u) => {
311
311
  let m = !1;
312
312
  const h = (d) => {
313
- m || (m = !0, o.terminate(), d());
313
+ m || (m = !0, s.terminate(), d());
314
314
  };
315
- i = () => h(() => u(new we())), o.addEventListener("message", (d) => {
315
+ i = () => h(() => u(new we())), s.addEventListener("message", (d) => {
316
316
  const f = d.data;
317
317
  if (!(!f || f.requestId !== r)) {
318
318
  if (f.type === "result") {
@@ -321,7 +321,7 @@ function xe(e, t, n = {}) {
321
321
  }
322
322
  h(() => u(new Error(f.message)));
323
323
  }
324
- }), o.addEventListener("error", (d) => {
324
+ }), s.addEventListener("error", (d) => {
325
325
  const f = typeof d == "object" && d && "message" in d ? String(d.message) : "The import worker failed to start.";
326
326
  h(() => u(new Error(f)));
327
327
  });
@@ -332,8 +332,8 @@ function xe(e, t, n = {}) {
332
332
  )
333
333
  )
334
334
  ];
335
- return o.postMessage(
336
- { type: "convert", requestId: r, files: t, assets: a, options: s },
335
+ return s.postMessage(
336
+ { type: "convert", requestId: r, files: t, assets: a, options: o },
337
337
  l
338
338
  ), { result: c, cancel: () => i?.() };
339
339
  }
@@ -342,25 +342,25 @@ function De(e) {
342
342
  createWorker: t,
343
343
  id: n = "worker",
344
344
  label: r = "Built-in converter",
345
- description: o = "Create a new project starting with LaTeX, Markdown, or PreTeXt files.",
345
+ description: s = "Create a new project starting with LaTeX, Markdown, or PreTeXt files.",
346
346
  acceptExtensions: a
347
347
  } = e;
348
- let s = null;
348
+ let o = null;
349
349
  const i = async (c, l) => {
350
- s?.cancel(), s = xe(t, c, l);
350
+ o?.cancel(), o = xe(t, c, l);
351
351
  try {
352
- return await s.result;
352
+ return await o.result;
353
353
  } finally {
354
- s = null;
354
+ o = null;
355
355
  }
356
356
  };
357
357
  return {
358
358
  id: n,
359
359
  label: r,
360
- description: o,
360
+ description: s,
361
361
  acceptExtensions: a,
362
362
  prepare: async (c) => {
363
- const { files: l, assets: p } = await $(c);
363
+ const { files: l, assets: p } = await A(c);
364
364
  return {
365
365
  fileName: c.name,
366
366
  files: l,
@@ -370,11 +370,11 @@ function De(e) {
370
370
  },
371
371
  convertPrepared: (c, l) => i(c.files, { ...l, assets: c.assets }),
372
372
  convertFile: async (c, l) => {
373
- const { files: p, assets: u } = await $(c);
373
+ const { files: p, assets: u } = await A(c);
374
374
  return i(p, { ...l, assets: u });
375
375
  },
376
376
  cancel: () => {
377
- s?.cancel(), s = null;
377
+ o?.cancel(), o = null;
378
378
  }
379
379
  };
380
380
  }
@@ -417,24 +417,24 @@ function z(e) {
417
417
  function Ee(e) {
418
418
  return Pe[z(e)];
419
419
  }
420
- function ve(e) {
420
+ function Se(e) {
421
421
  const {
422
422
  convertToPretext: t,
423
423
  id: n = "pandoc",
424
424
  label: r = "Pandoc",
425
- description: o = "Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more.",
425
+ description: s = "Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more.",
426
426
  acceptExtensions: a = X
427
427
  } = e;
428
428
  return {
429
429
  id: n,
430
430
  label: r,
431
- description: o,
431
+ description: s,
432
432
  acceptExtensions: a,
433
- convertFile: async (s, i) => {
434
- const c = await t(s, i);
433
+ convertFile: async (o, i) => {
434
+ const c = await t(o, i);
435
435
  if (!c.trim())
436
436
  throw new Error(
437
- `Pandoc produced no output for ${s.name}. The file may be empty or in an unexpected format.`
437
+ `Pandoc produced no output for ${o.name}. The file may be empty or in an unexpected format.`
438
438
  );
439
439
  const l = Q(
440
440
  { "source.ptx": c },
@@ -445,20 +445,20 @@ function ve(e) {
445
445
  splitLevel: i.splitLevel
446
446
  }
447
447
  );
448
- return "pretextError" in l || (l.sourceName = s.name, l.sourcePath = s.name), l;
448
+ return "pretextError" in l || (l.sourceName = o.name, l.sourcePath = o.name), l;
449
449
  }
450
450
  };
451
451
  }
452
- const Se = 3e4;
452
+ const ve = 3e4;
453
453
  function be(e) {
454
454
  const t = /<pre>([\s\S]*?)<\/pre>/i.exec(e);
455
455
  return (t ? t[1] : e).replace(/<[^>]+>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&").trim();
456
456
  }
457
457
  function Ie(e, t, n) {
458
- const r = _e(be(t)), o = r ? ` (${y(r)})` : "";
458
+ const r = _e(be(t)), s = r ? ` (${y(r)})` : "";
459
459
  switch (e) {
460
460
  case 400:
461
- return `The pandoc server will not convert ${n}${o}.${T(n)}`;
461
+ return `The pandoc server will not convert ${n}${s}.${T(n)}`;
462
462
  case 401:
463
463
  case 403:
464
464
  return `The pandoc server rejected this site's credentials, so ${n} was never converted. Nothing is wrong with your file — this is a configuration problem with the service, and worth reporting.${T(n)}`;
@@ -467,7 +467,7 @@ function Ie(e, t, n) {
467
467
  case 413:
468
468
  return `${n} is too large for the pandoc server to accept. Splitting it into chapters and importing them one at a time should get through.`;
469
469
  case 422:
470
- return `Pandoc could not read ${n}${o}. The file may be damaged, or may use features pandoc does not support.`;
470
+ return `Pandoc could not read ${n}${s}. The file may be damaged, or may use features pandoc does not support.`;
471
471
  case 503:
472
472
  return `The pandoc server is running without its PreTeXt writer, so it cannot convert anything right now. Nothing is wrong with your file — this is a problem with the service, and worth reporting.${T(n)}`;
473
473
  case 504:
@@ -485,38 +485,38 @@ function _e(e) {
485
485
  function y(e) {
486
486
  return e.length <= L ? e : `${e.slice(0, L).trimEnd()}…`;
487
487
  }
488
- const $e = /* @__PURE__ */ new Set([
488
+ const Ae = /* @__PURE__ */ new Set([
489
489
  ".tex",
490
490
  ".ltx",
491
491
  ".md",
492
492
  ".markdown"
493
493
  ]);
494
494
  function T(e) {
495
- return $e.has(z(e)) ? " You can import this file with the built-in converter instead." : "";
495
+ return Ae.has(z(e)) ? " You can import this file with the built-in converter instead." : "";
496
496
  }
497
497
  function Oe(e) {
498
498
  const {
499
499
  url: t,
500
500
  token: n,
501
501
  headers: r,
502
- credentials: o,
502
+ credentials: s,
503
503
  standalone: a = !0,
504
- from: s,
505
- timeoutMs: i = Se,
504
+ from: o,
505
+ timeoutMs: i = ve,
506
506
  fetchImpl: c,
507
507
  id: l = "pandoc-remote",
508
508
  label: p = "Pandoc (server)",
509
509
  description: u = "Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more — no local install needed.",
510
510
  acceptExtensions: m = X
511
511
  } = e;
512
- return ve({
512
+ return Se({
513
513
  convertToPretext: async (d, f) => {
514
- const S = c ?? globalThis.fetch;
515
- if (typeof S != "function")
514
+ const v = c ?? globalThis.fetch;
515
+ if (typeof v != "function")
516
516
  throw new Error(
517
517
  "This environment has no fetch; pass fetchImpl to createRemotePandocEngine."
518
518
  );
519
- const b = s ?? Ee(d.name);
519
+ const b = o ?? Ee(d.name);
520
520
  if (!b)
521
521
  throw new Error(
522
522
  `Pandoc cannot determine a format for ${d.name}. Supported extensions: ${m.join(", ")}.`
@@ -526,11 +526,11 @@ function Oe(e) {
526
526
  const I = new AbortController(), B = setTimeout(() => I.abort(), i);
527
527
  let x;
528
528
  try {
529
- x = await S(t, {
529
+ x = await v(t, {
530
530
  method: "POST",
531
531
  body: g,
532
532
  headers: r,
533
- credentials: o,
533
+ credentials: s,
534
534
  signal: I.signal
535
535
  });
536
536
  } catch (w) {
@@ -559,106 +559,115 @@ function Oe(e) {
559
559
  export {
560
560
  Xe as CLEAN_RULES,
561
561
  we as ConversionCancelledError,
562
- qt as DEFAULT_IMPORT_MODE,
563
- Se as DEFAULT_REMOTE_PANDOC_TIMEOUT_MS,
562
+ Vt as DEFAULT_ACCEPT_EXTENSIONS,
563
+ Zt as DEFAULT_IMPORT_MODE,
564
+ ve as DEFAULT_REMOTE_PANDOC_TIMEOUT_MS,
564
565
  ze as DIVISION_LADDER,
565
566
  Be as LADDER_OVERFLOW_TAG,
566
567
  Ke as LATEX_DIVISION_COMMANDS,
567
568
  We as LATEX_FORMAT_MARKERS,
568
- He as MARKDOWN_FORMAT_MARKERS,
569
- Ue as MAX_SUGGESTED_SPLIT_LEVEL,
569
+ Ue as MARKDOWN_FORMAT_MARKERS,
570
+ He as MAX_SUGGESTED_SPLIT_LEVEL,
570
571
  X as PANDOC_ACCEPT_EXTENSIONS,
571
572
  Me as PANDOC_BINARY_FORMATS,
572
573
  Pe as PANDOC_EXTENSION_FORMATS,
573
- H as PRETEXT_DIVISION_TAGS,
574
+ U as PRETEXT_DIVISION_TAGS,
574
575
  Ge as PRETEXT_ROOT_TAGS,
575
- Ve as PROJECT_DESTINATION,
576
+ qe as PROJECT_DESTINATION,
577
+ Yt as allAcceptExtensions,
578
+ Jt as alternateEngine,
579
+ Qt as alternateFor,
576
580
  J as analyzeImportSources,
577
- qe as applyLatexFixes,
578
- Zt as assetsForImportMode,
581
+ Ve as applyLatexFixes,
582
+ en as assetsForImportMode,
579
583
  Ze as attachLatexRoots,
580
584
  Ye as attachMarkdownRoots,
581
585
  Je as buildDivisionPool,
582
586
  Qe as buildNativeDivisionPool,
583
- ke as buildPretextProjectFiles,
587
+ Re as buildPretextProjectFiles,
584
588
  et as carryOverProjectFiles,
585
589
  tt as cleanLatex,
586
590
  nt as cleanLatexInChunks,
587
591
  rt as cleanLatexText,
588
- ot as convertLatexToPretext,
589
- st as convertMarkdownToPretext,
592
+ st as convertLatexToPretext,
593
+ ot as convertMarkdownToPretext,
590
594
  at as convertSourceToPretext,
591
- ve as createPandocEngine,
595
+ Se as createPandocEngine,
592
596
  Oe as createRemotePandocEngine,
593
597
  De as createWorkerEngine,
594
598
  it as dedupeXmlIds,
595
599
  ct as defaultAttachLevel,
596
600
  lt as defaultManifestTarget,
597
601
  Ie as describeRemotePandocFailure,
598
- U as detectDocumentKind,
602
+ H as detectDocumentKind,
599
603
  Fe as detectSnippetFormat,
600
604
  ut as detectSourceFormat,
601
- Yt as diffHunks,
602
- Jt as diffLines,
603
- Qt as diffStats,
605
+ tn as diffHunks,
606
+ nn as diffLines,
607
+ rn as diffStats,
604
608
  pt as divisionChildRefs,
605
609
  dt as divisionsAtLevel,
610
+ sn as engineAccepts,
611
+ on as engineExtensions,
606
612
  mt as expandPretextIncludes,
607
613
  be as extractPandocErrorDetail,
608
- $ as extractUpload,
609
- en as fileChangesForImport,
614
+ A as extractUpload,
615
+ an as fileChangesForImport,
610
616
  z as fileExtension,
611
617
  ft as filePrefixForDivision,
612
- tn as filesForImportMode,
618
+ cn as filesForImportMode,
613
619
  ht as findLatexFixes,
614
620
  gt as findLatexHeaders,
615
621
  wt as findProjectManifest,
616
622
  me as firstDivisionTag,
617
623
  Tt as fixesToWarnings,
618
- nn as formatWarningLine,
624
+ ln as formatWarningLine,
619
625
  xt as getConversionErrorMessage,
620
626
  Pt as getLatexCleanDiagnostics,
621
627
  Et as handleImportUploadFile,
622
- rn as hasNativeImportMode,
628
+ un as hasNativeImportMode,
623
629
  Q as importProjectFromFiles,
624
- vt as isDivisionTag,
630
+ St as isDivisionTag,
625
631
  Ce as isInlineContext,
626
- St as ladderDepth,
632
+ vt as ladderDepth,
627
633
  bt as latexDivisionHierarchy,
628
634
  It as latexFixesToCodeActions,
635
+ pn as matchesExtension,
629
636
  _t as mergeChunksAtLevel,
630
- $t as normalizePretextSource,
631
- At as outlineDivisions,
637
+ At as normalizePretextSource,
638
+ $t as outlineDivisions,
632
639
  Ee as pandocFormatForFileName,
633
640
  Ft as parseLatexDivisions,
634
641
  Lt as parseProjectManifest,
635
- Re as placeConvertedMarkup,
642
+ ke as placeConvertedMarkup,
636
643
  yt as prepareInsertSource,
637
- on as projectForImportMode,
644
+ dn as projectForImportMode,
638
645
  Ct as pruneDivisions,
639
- Rt as rebuildImport,
646
+ kt as rebuildImport,
640
647
  pe as recordsToPlusPayload,
641
648
  fe as reindentForContext,
642
- kt as relayoutImport,
649
+ Rt as relayoutImport,
643
650
  G as renderProjectPtx,
644
651
  Dt as renderProjectPtxFromManifest,
645
- V as renderPublicationPtx,
652
+ q as renderPublicationPtx,
646
653
  Mt as reselectImport,
647
- sn as resolveImportMode,
654
+ mn as resolveImportMode,
648
655
  Ot as resolveImportSplitLevel,
649
656
  Nt as resolveSplitLevel,
650
657
  jt as retargetFragment,
651
658
  Xt as retargetFragmentToDepth,
652
659
  zt as retargetImport,
660
+ fn as routeEngine,
653
661
  xe as runConversionInWorker,
654
662
  Bt as sanitizeRef,
655
- se as scoreSnippetFormats,
663
+ oe as scoreSnippetFormats,
656
664
  Kt as serializeForDestination,
657
665
  Wt as serializeInsertFiles,
658
666
  ye as serializeInsertToRecords,
659
- Ht as serializeProjectToFiles,
667
+ Ut as serializeProjectToFiles,
660
668
  Le as serializeProjectToPlusPayload,
661
669
  le as serializeProjectToRecords,
662
- Ut as shiftLadderTag,
663
- Gt as suggestSplitLevel
670
+ Ht as shiftLadderTag,
671
+ Gt as suggestSplitLevel,
672
+ hn as unsupportedFileMessage
664
673
  };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Which converter handles which upload.
3
+ *
4
+ * The wizard used to ask the author to pick a converter before picking a file,
5
+ * which made them learn something they have no way of knowing: that Word and
6
+ * EPUB need pandoc while LaTeX and Markdown do not. The file itself already
7
+ * says which converter can read it, so the routing is derived from its
8
+ * extension instead, and nothing is asked up front.
9
+ *
10
+ * Precedence is the order the host lists its engines in: the first engine that
11
+ * accepts an extension owns it. For a format two engines both read, the second
12
+ * one is available as an `alternateFor` that upload — offered only once the
13
+ * file is in hand and there is a converted result to judge it against, since
14
+ * "would the other converter do better?" is not a question anyone can answer
15
+ * before seeing the first one's output.
16
+ */
17
+ /** The part of `ImportEngine` routing cares about. */
18
+ export interface RoutableEngine {
19
+ id: string;
20
+ label: string;
21
+ description?: string;
22
+ /** Extensions this engine accepts, with leading dots. */
23
+ acceptExtensions?: string[];
24
+ }
25
+ /** File extensions accepted by the built-in converter. */
26
+ export declare const DEFAULT_ACCEPT_EXTENSIONS: string[];
27
+ /** What `engine` reads, falling back to the built-in set. */
28
+ export declare function engineExtensions(engine: RoutableEngine): string[];
29
+ /**
30
+ * Does `fileName` end in one of `extensions`?
31
+ *
32
+ * Suffix matching rather than "the text after the last dot", because
33
+ * `.tar.gz` is in the accept list and is not one dot's worth of extension.
34
+ */
35
+ export declare function matchesExtension(fileName: string, extensions: string[]): boolean;
36
+ /** Can `engine` read a file named `fileName`? */
37
+ export declare function engineAccepts(engine: RoutableEngine, fileName: string): boolean;
38
+ /**
39
+ * Every extension any engine reads, in engine order, deduplicated.
40
+ *
41
+ * This is the file picker's whole `accept` list: one picker, every format the
42
+ * host can import, no converter chosen up front.
43
+ */
44
+ export declare function allAcceptExtensions(engines: RoutableEngine[]): string[];
45
+ /**
46
+ * The engine an author may opt into: the first one that duplicates coverage an
47
+ * earlier engine already has. `undefined` when no two engines overlap, in
48
+ * which case routing is fully determined by the file and there is nothing to
49
+ * ask about.
50
+ */
51
+ export declare function alternateEngine(engines: RoutableEngine[]): RoutableEngine | undefined;
52
+ /** Pick the engine for an upload, or `undefined` when nothing reads it. */
53
+ export declare function routeEngine<T extends RoutableEngine>(engines: T[], fileName: string): T | undefined;
54
+ /**
55
+ * The second converter this particular upload could go through, or
56
+ * `undefined` when it has only one.
57
+ *
58
+ * This is what makes the override self-explanatory: it exists for a `.tex`,
59
+ * where both converters have an opinion, and simply is not there for a `.docx`
60
+ * or a `.zip`, where only one converter can read the file at all. Nobody has
61
+ * to be told which is which.
62
+ */
63
+ export declare function alternateFor<T extends RoutableEngine>(engines: T[], fileName: string): T | undefined;
64
+ /** The message shown when no engine can read the file the author chose. */
65
+ export declare function unsupportedFileMessage(fileName: string, engines: RoutableEngine[]): string;
@@ -26,13 +26,19 @@ export interface PreparedUpload {
26
26
  * An engine that implements the optional `prepare`/`convertPrepared` pair also
27
27
  * gets the source-selection step; one that only implements `convertFile` keeps
28
28
  * the original single-shot flow.
29
+ *
30
+ * Engines are never chosen by hand: the wizard routes each upload by its
31
+ * extension, in list order, so list the engine that should own a shared format
32
+ * first (see `lib/engine-routing.ts`). `label` and `description` surface only
33
+ * in the opt-in checkbox for an engine that overlaps an earlier one, and in
34
+ * error messages — so word them for that, not as a menu entry.
29
35
  */
30
36
  export interface ImportEngine {
31
- /** Stable identifier, used as the radio value. */
37
+ /** Stable identifier. */
32
38
  id: string;
33
- /** Short name shown in the engine selector. */
39
+ /** Short name, used in the opt-in checkbox and in error messages. */
34
40
  label: string;
35
- /** Optional one-line explanation shown under the label. */
41
+ /** Optional one-line explanation shown under the opt-in checkbox. */
36
42
  description?: string;
37
43
  /** Extensions this engine accepts (with leading dot). Defaults to the built-in set. */
38
44
  acceptExtensions?: string[];