@bendyline/squisq-formats 2.8.8 → 2.8.10
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 +15 -13
- package/dist/chunk-4LIFEQKX.js +358 -0
- package/dist/{chunk-UXEANVBI.js → chunk-5HUHSLGA.js} +1 -84
- package/dist/{chunk-BXWNU4T5.js → chunk-DTJQK7U7.js} +43 -0
- package/dist/{chunk-GDUZJ75A.js → chunk-MJTPWLVV.js} +59 -21
- package/dist/{chunk-6ALSRHD7.js → chunk-NCDY3EOL.js} +66 -9
- package/dist/{chunk-TMOXUUTG.js → chunk-NQNIFIDP.js} +6 -4
- package/dist/{chunk-LK4KCVN6.js → chunk-QPJHAMOW.js} +70 -28
- package/dist/{chunk-QU4EVC62.js → chunk-S5VXWSRR.js} +1 -1
- package/dist/{chunk-KROH7FNT.js → chunk-VKLJUHC2.js} +6 -4
- package/dist/chunk-YRFBWYAD.js +128 -0
- package/dist/{chunk-SVYTUYZM.js → chunk-ZJERBWTB.js} +6 -4
- package/dist/data/index.d.ts +27 -5
- package/dist/data/index.js +6 -2
- package/dist/diagrams/index.d.ts +19 -8
- package/dist/diagrams/index.js +7 -242
- package/dist/docx/index.d.ts +1 -1
- package/dist/docx/index.js +3 -3
- package/dist/epub/index.d.ts +1 -1
- package/dist/epub/index.js +3 -3
- package/dist/fontAwesome-C6FRDYTY.js +14 -0
- package/dist/html/icons.d.ts +29 -0
- package/dist/html/icons.js +62 -0
- package/dist/html/index.d.ts +3 -130
- package/dist/html/index.js +2 -2
- package/dist/html/prepare.d.ts +97 -0
- package/dist/html/prepare.js +85 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +16 -16
- package/dist/{materialize-G4WC5UG3.js → materialize-ICXNO4S4.js} +4 -1
- package/dist/outside-in/index.d.ts +12 -0
- package/dist/outside-in/index.js +3 -3
- package/dist/pdf/index.d.ts +1 -1
- package/dist/pdf/index.js +3 -3
- package/dist/plainHtml-B6IXcSet.d.ts +148 -0
- package/dist/pptx/index.js +2 -2
- package/dist/readers-3P5A6A2A.js +17 -0
- package/dist/registry/index.js +1 -1
- package/package.json +12 -2
- /package/dist/{chunk-LBXBRFBZ.js → chunk-DDMPZZJF.js} +0 -0
|
@@ -251,7 +251,7 @@ async function collectContainerAssets(container, pattern, signal, flattenBasenam
|
|
|
251
251
|
async function collectContainerImages(container, signal) {
|
|
252
252
|
return collectContainerAssets(container, IMAGE_ASSET_RE, signal);
|
|
253
253
|
}
|
|
254
|
-
function
|
|
254
|
+
function dataReferenceSources(doc) {
|
|
255
255
|
const srcs = /* @__PURE__ */ new Set();
|
|
256
256
|
const visit = (blocks) => {
|
|
257
257
|
for (const block of blocks) {
|
|
@@ -261,10 +261,38 @@ function dataReferenceWarnings(doc, formatLabel) {
|
|
|
261
261
|
}
|
|
262
262
|
};
|
|
263
263
|
visit(doc.blocks);
|
|
264
|
-
return
|
|
265
|
-
|
|
264
|
+
return srcs;
|
|
265
|
+
}
|
|
266
|
+
function dataReferenceWarnings(doc, formatLabel) {
|
|
267
|
+
return [...dataReferenceSources(doc)].map(
|
|
268
|
+
(src) => `${formatLabel} cannot embed the data sidecar "${src}"; the export shows its first rows and the link will not resolve outside the source container.`
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
async function markdownWithDataPreview(input, warnings) {
|
|
272
|
+
const markdownDoc = await markdownOf(input);
|
|
273
|
+
if (dataReferenceSources(input.doc).size === 0) return markdownDoc;
|
|
274
|
+
const { materializeDataReferences, DATA_PREVIEW_ROWS } = await import("./materialize-ICXNO4S4.js");
|
|
275
|
+
return materializeDataReferences(
|
|
276
|
+
markdownDoc,
|
|
277
|
+
input.container,
|
|
278
|
+
(message) => warnings.push(message),
|
|
279
|
+
{ maxRows: DATA_PREVIEW_ROWS }
|
|
266
280
|
);
|
|
267
281
|
}
|
|
282
|
+
async function docWithDataPreview(input, warnings) {
|
|
283
|
+
if (dataReferenceSources(input.doc).size === 0) return input.doc;
|
|
284
|
+
const [{ resolveDataReferences }, { defaultDataReaders }] = await Promise.all([
|
|
285
|
+
import("@bendyline/squisq/doc"),
|
|
286
|
+
import("./readers-3P5A6A2A.js")
|
|
287
|
+
]);
|
|
288
|
+
const { doc, diagnostics } = await resolveDataReferences(input.doc, input.container, {
|
|
289
|
+
readers: defaultDataReaders()
|
|
290
|
+
});
|
|
291
|
+
for (const diagnostic of diagnostics) {
|
|
292
|
+
if (diagnostic.severity !== "info") warnings.push(diagnostic.message);
|
|
293
|
+
}
|
|
294
|
+
return doc;
|
|
295
|
+
}
|
|
268
296
|
async function collectContainerDocxImages(container, signal) {
|
|
269
297
|
const images = await collectContainerImages(container, signal);
|
|
270
298
|
const { extToMime } = await import("./images-PQCYRJJ5.js");
|
|
@@ -351,7 +379,8 @@ function defaultFormats() {
|
|
|
351
379
|
async exportDoc(input, options) {
|
|
352
380
|
const { markdownDocToDocx } = await import("./docx/index.js");
|
|
353
381
|
const raw = optionsFor(options, "docx");
|
|
354
|
-
const
|
|
382
|
+
const warnings = [];
|
|
383
|
+
const markdownDoc = await markdownWithDataPreview(input, warnings);
|
|
355
384
|
const containerImages = await collectContainerDocxImages(input.container, options.signal);
|
|
356
385
|
const images = new Map([...containerImages, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
357
386
|
const buf = await markdownDocToDocx(markdownDoc, {
|
|
@@ -361,7 +390,10 @@ function defaultFormats() {
|
|
|
361
390
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry,
|
|
362
391
|
images
|
|
363
392
|
});
|
|
364
|
-
return ok(await toBytes(buf), MIME.docx,
|
|
393
|
+
return ok(await toBytes(buf), MIME.docx, [
|
|
394
|
+
...markdownFidelityWarnings(markdownDoc, "docx"),
|
|
395
|
+
...warnings
|
|
396
|
+
]);
|
|
365
397
|
}
|
|
366
398
|
};
|
|
367
399
|
const pdf = {
|
|
@@ -381,8 +413,8 @@ function defaultFormats() {
|
|
|
381
413
|
async exportDoc(input, options) {
|
|
382
414
|
const { markdownDocToPdf } = await import("./pdf/index.js");
|
|
383
415
|
const raw = optionsFor(options, "pdf");
|
|
384
|
-
const markdownDoc = await markdownOf(input);
|
|
385
416
|
const pdfWarnings = [];
|
|
417
|
+
const markdownDoc = await markdownWithDataPreview(input, pdfWarnings);
|
|
386
418
|
const containerImages = await collectContainerDocxImages(input.container, options.signal);
|
|
387
419
|
const images = new Map([...containerImages, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
388
420
|
const buf = await markdownDocToPdf(markdownDoc, {
|
|
@@ -420,7 +452,8 @@ function defaultFormats() {
|
|
|
420
452
|
const containerImages = await collectContainerImages(input.container, options.signal);
|
|
421
453
|
const images = new Map([...containerImages, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
422
454
|
const pptxWarnings = [];
|
|
423
|
-
const
|
|
455
|
+
const doc = await docWithDataPreview(input, pptxWarnings);
|
|
456
|
+
const buf = await docToPptx(doc, {
|
|
424
457
|
...raw,
|
|
425
458
|
...options.title !== void 0 ? { title: options.title } : {},
|
|
426
459
|
themeId: resolveThemeId(input, options),
|
|
@@ -456,7 +489,7 @@ function defaultFormats() {
|
|
|
456
489
|
},
|
|
457
490
|
async exportDoc(input, options) {
|
|
458
491
|
const { markdownDocToXlsx } = await import("./xlsx/index.js");
|
|
459
|
-
const { materializeDataReferences } = await import("./materialize-
|
|
492
|
+
const { materializeDataReferences } = await import("./materialize-ICXNO4S4.js");
|
|
460
493
|
const warnings = [];
|
|
461
494
|
const markdownDoc = await materializeDataReferences(
|
|
462
495
|
await markdownOf(input),
|
|
@@ -495,7 +528,7 @@ function defaultFormats() {
|
|
|
495
528
|
},
|
|
496
529
|
async exportDoc(input, options) {
|
|
497
530
|
const { markdownDocToCsv } = await import("./csv/index.js");
|
|
498
|
-
const { materializeDataReferences } = await import("./materialize-
|
|
531
|
+
const { materializeDataReferences } = await import("./materialize-ICXNO4S4.js");
|
|
499
532
|
const warnings = [];
|
|
500
533
|
const markdownDoc = await materializeDataReferences(
|
|
501
534
|
await markdownOf(input),
|
|
@@ -528,9 +561,11 @@ function defaultFormats() {
|
|
|
528
561
|
// so there is nothing to extract into a container this wave.
|
|
529
562
|
async exportDoc(input, options) {
|
|
530
563
|
const raw = optionsFor(options, "html");
|
|
564
|
+
const warnings = [];
|
|
565
|
+
const doc = await docWithDataPreview(input, warnings);
|
|
531
566
|
if (raw.playerScriptPath) {
|
|
532
567
|
const { generateExternalHtml } = await import("./html/index.js");
|
|
533
|
-
const htmlText2 = generateExternalHtml(
|
|
568
|
+
const htmlText2 = generateExternalHtml(doc, {
|
|
534
569
|
...raw,
|
|
535
570
|
playerScriptPath: raw.playerScriptPath,
|
|
536
571
|
title: options.title ?? input.baseName,
|
|
@@ -538,7 +573,7 @@ function defaultFormats() {
|
|
|
538
573
|
themeId: resolveThemeId(input, options),
|
|
539
574
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry
|
|
540
575
|
});
|
|
541
|
-
return ok(new TextEncoder().encode(htmlText2), MIME.html);
|
|
576
|
+
return ok(new TextEncoder().encode(htmlText2), MIME.html, warnings);
|
|
542
577
|
}
|
|
543
578
|
const playerScript = await requirePlayerScript(options, "html");
|
|
544
579
|
const { docToHtml } = await import("./html/index.js");
|
|
@@ -550,7 +585,7 @@ function defaultFormats() {
|
|
|
550
585
|
false
|
|
551
586
|
);
|
|
552
587
|
const images = new Map([...containerImages, ...media, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
553
|
-
const htmlText = docToHtml(
|
|
588
|
+
const htmlText = docToHtml(doc, {
|
|
554
589
|
...raw,
|
|
555
590
|
playerScript,
|
|
556
591
|
images,
|
|
@@ -560,11 +595,10 @@ function defaultFormats() {
|
|
|
560
595
|
themeId: resolveThemeId(input, options),
|
|
561
596
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry
|
|
562
597
|
});
|
|
563
|
-
return ok(
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
);
|
|
598
|
+
return ok(new TextEncoder().encode(htmlText), MIME.html, [
|
|
599
|
+
...dataReferenceWarnings(input.doc, "Single-file HTML"),
|
|
600
|
+
...warnings
|
|
601
|
+
]);
|
|
568
602
|
}
|
|
569
603
|
};
|
|
570
604
|
const htmlzip = {
|
|
@@ -596,7 +630,9 @@ function defaultFormats() {
|
|
|
596
630
|
...media,
|
|
597
631
|
...raw.images ?? /* @__PURE__ */ new Map()
|
|
598
632
|
]);
|
|
599
|
-
const
|
|
633
|
+
const warnings = [];
|
|
634
|
+
const doc = await docWithDataPreview(input, warnings);
|
|
635
|
+
const blob = await docToHtmlZip(doc, {
|
|
600
636
|
...raw,
|
|
601
637
|
playerScript,
|
|
602
638
|
images,
|
|
@@ -606,7 +642,7 @@ function defaultFormats() {
|
|
|
606
642
|
themeId: resolveThemeId(input, options),
|
|
607
643
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry
|
|
608
644
|
});
|
|
609
|
-
return ok(await toBytes(blob), MIME.zip);
|
|
645
|
+
return ok(await toBytes(blob), MIME.zip, warnings);
|
|
610
646
|
}
|
|
611
647
|
};
|
|
612
648
|
const epub = {
|
|
@@ -618,7 +654,8 @@ function defaultFormats() {
|
|
|
618
654
|
async exportDoc(input, options) {
|
|
619
655
|
const { markdownDocToEpub } = await import("./epub/index.js");
|
|
620
656
|
const raw = optionsFor(options, "epub");
|
|
621
|
-
const
|
|
657
|
+
const warnings = [];
|
|
658
|
+
const markdownDoc = await markdownWithDataPreview(input, warnings);
|
|
622
659
|
const containerImages = await collectContainerImages(input.container, options.signal);
|
|
623
660
|
const images = new Map([...containerImages, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
624
661
|
const buf = await markdownDocToEpub(markdownDoc, {
|
|
@@ -630,7 +667,8 @@ function defaultFormats() {
|
|
|
630
667
|
});
|
|
631
668
|
return ok(await toBytes(buf), MIME.epub, [
|
|
632
669
|
...markdownFidelityWarnings(markdownDoc, "epub"),
|
|
633
|
-
...dataReferenceWarnings(input.doc, "EPUB")
|
|
670
|
+
...dataReferenceWarnings(input.doc, "EPUB"),
|
|
671
|
+
...warnings
|
|
634
672
|
]);
|
|
635
673
|
}
|
|
636
674
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OUTSIDE_IN_FORMAT_IDS,
|
|
3
|
+
OUTSIDE_IN_OUTPUT_TEMPLATE_KEY,
|
|
4
|
+
resolveOutsideInLayout
|
|
5
|
+
} from "./chunk-WJTC5OD6.js";
|
|
1
6
|
import {
|
|
2
7
|
convert,
|
|
3
8
|
defaultRegistry
|
|
4
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MJTPWLVV.js";
|
|
5
10
|
import {
|
|
6
11
|
ConversionError
|
|
7
12
|
} from "./chunk-KXOZMWBS.js";
|
|
8
|
-
import {
|
|
9
|
-
OUTSIDE_IN_FORMAT_IDS,
|
|
10
|
-
OUTSIDE_IN_OUTPUT_TEMPLATE_KEY,
|
|
11
|
-
resolveOutsideInLayout
|
|
12
|
-
} from "./chunk-WJTC5OD6.js";
|
|
13
13
|
|
|
14
14
|
// src/outside-in/index.ts
|
|
15
15
|
import {
|
|
@@ -188,7 +188,9 @@ async function renderOutsideInDocument(source, options = {}) {
|
|
|
188
188
|
{ format: "html" }
|
|
189
189
|
);
|
|
190
190
|
}
|
|
191
|
-
const formatOptions = {
|
|
191
|
+
const formatOptions = {
|
|
192
|
+
...options.formatOptions ?? {}
|
|
193
|
+
};
|
|
192
194
|
if (layout.format === "html" && options.html) {
|
|
193
195
|
formatOptions.html = {
|
|
194
196
|
...formatOptions.html ?? {},
|
|
@@ -196,10 +198,19 @@ async function renderOutsideInDocument(source, options = {}) {
|
|
|
196
198
|
basePath: options.html.basePath ?? layout.companionName
|
|
197
199
|
};
|
|
198
200
|
}
|
|
199
|
-
|
|
201
|
+
const warnings = [];
|
|
202
|
+
const markdown = await prepareOutsideInMarkdown(
|
|
203
|
+
source.markdown,
|
|
204
|
+
layout.format,
|
|
205
|
+
source.container,
|
|
206
|
+
options,
|
|
207
|
+
formatOptions,
|
|
208
|
+
warnings
|
|
209
|
+
);
|
|
210
|
+
const result = await convert(
|
|
200
211
|
{
|
|
201
212
|
kind: "markdown",
|
|
202
|
-
markdown
|
|
213
|
+
markdown,
|
|
203
214
|
container: source.container,
|
|
204
215
|
baseName: layout.stem
|
|
205
216
|
},
|
|
@@ -210,6 +221,52 @@ async function renderOutsideInDocument(source, options = {}) {
|
|
|
210
221
|
formatOptions
|
|
211
222
|
}
|
|
212
223
|
);
|
|
224
|
+
return warnings.length > 0 ? { ...result, warnings: [...warnings, ...result.warnings] } : result;
|
|
225
|
+
}
|
|
226
|
+
async function prepareOutsideInMarkdown(markdown, format, container, options, formatOptions, warnings) {
|
|
227
|
+
const render = options.renderDiagram;
|
|
228
|
+
if (!render || format !== "docx" && format !== "pdf" && format !== "pptx") return markdown;
|
|
229
|
+
const onWarning = (message) => {
|
|
230
|
+
warnings.push(message);
|
|
231
|
+
};
|
|
232
|
+
let doc = typeof markdown === "string" ? parseMarkdown(markdown) : markdown;
|
|
233
|
+
const { rasterizeDiagrams, EXPORT_DIAGRAM_KINDS } = await import("./diagrams/index.js");
|
|
234
|
+
const signal = options.signal;
|
|
235
|
+
if (format === "pptx") {
|
|
236
|
+
const { mermaid, svg } = await rasterizeDiagrams(doc, render, {
|
|
237
|
+
kinds: ["mermaid", "svg"],
|
|
238
|
+
signal,
|
|
239
|
+
onWarning
|
|
240
|
+
});
|
|
241
|
+
formatOptions.pptx = {
|
|
242
|
+
...formatOptions.pptx,
|
|
243
|
+
diagramImages: new Map([...mermaid, ...svg, ...formatOptions.pptx?.diagramImages ?? []])
|
|
244
|
+
};
|
|
245
|
+
return doc;
|
|
246
|
+
}
|
|
247
|
+
const { materializeDataReferences, DATA_PREVIEW_ROWS } = await import("./materialize-ICXNO4S4.js");
|
|
248
|
+
doc = await materializeDataReferences(doc, container, onWarning, {
|
|
249
|
+
maxRows: DATA_PREVIEW_ROWS
|
|
250
|
+
});
|
|
251
|
+
const pictured = await rasterizeDiagrams(doc, render, {
|
|
252
|
+
kinds: format === "pdf" ? EXPORT_DIAGRAM_KINDS : void 0,
|
|
253
|
+
signal,
|
|
254
|
+
onWarning
|
|
255
|
+
});
|
|
256
|
+
if (format === "docx") {
|
|
257
|
+
const { svg } = await rasterizeDiagrams(doc, render, { kinds: ["svg"], signal, onWarning });
|
|
258
|
+
formatOptions.docx = {
|
|
259
|
+
...formatOptions.docx,
|
|
260
|
+
images: new Map([...formatOptions.docx?.images ?? [], ...pictured.images]),
|
|
261
|
+
svgIslandFallbacks: new Map([...svg, ...formatOptions.docx?.svgIslandFallbacks ?? []])
|
|
262
|
+
};
|
|
263
|
+
} else {
|
|
264
|
+
formatOptions.pdf = {
|
|
265
|
+
...formatOptions.pdf,
|
|
266
|
+
images: new Map([...formatOptions.pdf?.images ?? [], ...pictured.images])
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return pictured.markdownDoc;
|
|
213
270
|
}
|
|
214
271
|
|
|
215
272
|
export {
|
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
upngEncoder
|
|
3
3
|
} from "./chunk-34KECNZO.js";
|
|
4
4
|
import {
|
|
5
|
-
FootnoteIndex
|
|
6
|
-
|
|
5
|
+
FootnoteIndex,
|
|
6
|
+
withoutBlockTags
|
|
7
|
+
} from "./chunk-DTJQK7U7.js";
|
|
7
8
|
import {
|
|
8
9
|
buildContainer
|
|
9
10
|
} from "./chunk-IIQYS2YH.js";
|
|
@@ -11,7 +12,7 @@ import {
|
|
|
11
12
|
collectInlineIconFamilies,
|
|
12
13
|
fontAwesomeFaces,
|
|
13
14
|
fontAwesomeGlyph
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DDMPZZJF.js";
|
|
15
16
|
import {
|
|
16
17
|
authoredImageSize,
|
|
17
18
|
fitWithin,
|
|
@@ -499,8 +500,9 @@ var IMPORT_TABLE_MIN_ROWS = 2;
|
|
|
499
500
|
var IMPORT_URL_PATTERN = /https?:\/\/[^\s)>\]]+/g;
|
|
500
501
|
|
|
501
502
|
// src/pdf/export.ts
|
|
502
|
-
async function markdownDocToPdf(
|
|
503
|
+
async function markdownDocToPdf(source, options = {}) {
|
|
503
504
|
options.signal?.throwIfAborted();
|
|
505
|
+
const doc = withoutBlockTags(source);
|
|
504
506
|
const pdfDoc = await PDFDocument.create();
|
|
505
507
|
if (options.title) pdfDoc.setTitle(options.title);
|
|
506
508
|
if (options.author) pdfDoc.setAuthor(options.author);
|
|
@@ -8,8 +8,9 @@ import {
|
|
|
8
8
|
} from "./chunk-VCZUXQUL.js";
|
|
9
9
|
import {
|
|
10
10
|
FootnoteIndex,
|
|
11
|
-
footnoteIds
|
|
12
|
-
|
|
11
|
+
footnoteIds,
|
|
12
|
+
withoutBlockTags
|
|
13
|
+
} from "./chunk-DTJQK7U7.js";
|
|
13
14
|
import {
|
|
14
15
|
imageSizeAttributes
|
|
15
16
|
} from "./chunk-JZR32FON.js";
|
|
@@ -294,7 +295,9 @@ function escapeHtml(str) {
|
|
|
294
295
|
import {
|
|
295
296
|
findBlockVideoEmbed,
|
|
296
297
|
isSvgIslandLang,
|
|
298
|
+
mediaKindForUrl,
|
|
297
299
|
parseSvgIsland,
|
|
300
|
+
parseTimeSeconds,
|
|
298
301
|
sanitizeHtmlNodes,
|
|
299
302
|
svgIslandDataUrl,
|
|
300
303
|
svgSourceFromDataUrl,
|
|
@@ -304,7 +307,11 @@ import {
|
|
|
304
307
|
readFrontmatterThemeId as readFrontmatterThemeId2
|
|
305
308
|
} from "@bendyline/squisq/markdown";
|
|
306
309
|
import { resolveFontFamily, buildGoogleFontsUrl } from "@bendyline/squisq/schemas";
|
|
307
|
-
import {
|
|
310
|
+
import {
|
|
311
|
+
isMediaAnnotationName,
|
|
312
|
+
parseStandaloneAnnotation,
|
|
313
|
+
resolveThemeForDoc
|
|
314
|
+
} from "@bendyline/squisq/doc";
|
|
308
315
|
function markdownDocToPlainHtml(doc, options = {}) {
|
|
309
316
|
const { title, body, fontsLink, iconsLink, themedCss, featureCss } = renderPlainHtml(
|
|
310
317
|
doc,
|
|
@@ -347,7 +354,8 @@ function renderPlainHtml(doc, options) {
|
|
|
347
354
|
iconsCss,
|
|
348
355
|
htmlPolicy = "sanitize",
|
|
349
356
|
externalResources = "deny",
|
|
350
|
-
videoEmbeds
|
|
357
|
+
videoEmbeds,
|
|
358
|
+
icons
|
|
351
359
|
} = options;
|
|
352
360
|
const resolveId = themeId ?? readFrontmatterThemeId2(doc.frontmatter);
|
|
353
361
|
const theme = options.theme ?? (resolveId ? resolveThemeForDoc(doc, resolveId, options.themeRegistry) : void 0);
|
|
@@ -358,13 +366,14 @@ function renderPlainHtml(doc, options) {
|
|
|
358
366
|
htmlPolicy,
|
|
359
367
|
footnotes,
|
|
360
368
|
videoEmbeds,
|
|
369
|
+
icons,
|
|
361
370
|
textColor: theme?.colors.text
|
|
362
371
|
};
|
|
363
|
-
const
|
|
372
|
+
const blocks = withoutBlockTags(doc, { keepMedia: true }).children;
|
|
373
|
+
const body = renderTopLevel(blocks, ctx) + renderFootnotesSection(footnotes, ctx);
|
|
364
374
|
const fontsLink = theme && externalResources === "allow" ? renderFontsLink(theme) : "";
|
|
365
|
-
const usesIcons = docUsesIcons(doc);
|
|
366
375
|
let iconsLink = "";
|
|
367
|
-
if (
|
|
376
|
+
if (ctx.usesFontIcons) {
|
|
368
377
|
iconsLink = iconsCss ? `<style data-fa-inline>
|
|
369
378
|
${escapeStyleText(iconsCss)}
|
|
370
379
|
</style>
|
|
@@ -375,13 +384,17 @@ ${escapeStyleText(iconsCss)}
|
|
|
375
384
|
${VIDEO_EMBED_CSS}` : "";
|
|
376
385
|
const svgCss = docUsesSvgIslands(doc) ? `
|
|
377
386
|
${SVG_ISLAND_CSS}` : "";
|
|
387
|
+
const mediaCss = ctx.usesMediaPlayers ? `
|
|
388
|
+
${MEDIA_PLAYER_CSS}` : "";
|
|
389
|
+
const iconCss = ctx.usesSvgIcons ? `
|
|
390
|
+
${SVG_ICON_CSS}` : "";
|
|
378
391
|
return {
|
|
379
392
|
title,
|
|
380
393
|
body,
|
|
381
394
|
fontsLink,
|
|
382
395
|
iconsLink,
|
|
383
396
|
themedCss,
|
|
384
|
-
featureCss: `${FEATURE_CSS}${videoCss}${svgCss}`
|
|
397
|
+
featureCss: `${FEATURE_CSS}${videoCss}${svgCss}${mediaCss}${iconCss}`
|
|
385
398
|
};
|
|
386
399
|
}
|
|
387
400
|
function escapeStyleText(css) {
|
|
@@ -389,18 +402,7 @@ function escapeStyleText(css) {
|
|
|
389
402
|
}
|
|
390
403
|
var FONT_AWESOME_LINK = `<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.3.1/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">
|
|
391
404
|
`;
|
|
392
|
-
|
|
393
|
-
function visit(node) {
|
|
394
|
-
if (!node || typeof node !== "object") return false;
|
|
395
|
-
const n = node;
|
|
396
|
-
if (n.type === "inlineIcon") return true;
|
|
397
|
-
if (Array.isArray(n.children)) {
|
|
398
|
-
for (const child of n.children) if (visit(child)) return true;
|
|
399
|
-
}
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
return visit(doc);
|
|
403
|
-
}
|
|
405
|
+
var SVG_ICON_CSS = ` .squisq-icon { display: inline-block; height: 1em; vertical-align: -0.125em; overflow: visible; }`;
|
|
404
406
|
function docUsesVideoEmbeds(doc, htmlPolicy) {
|
|
405
407
|
const iframeIn = (nodes) => nodes.some(
|
|
406
408
|
(node) => node.type === "htmlElement" && (videoEmbedFromIframe(node) !== null || iframeIn(node.children))
|
|
@@ -441,15 +443,21 @@ function renderTopLevel(children, ctx) {
|
|
|
441
443
|
continue;
|
|
442
444
|
}
|
|
443
445
|
}
|
|
444
|
-
const
|
|
445
|
-
if (
|
|
446
|
-
out.push(videoEmbedToHtml(video.embed, video.title, ctx));
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
out.push(nodeToHtml(node, ctx));
|
|
446
|
+
const html = topLevelBlockToHtml(node, ctx);
|
|
447
|
+
if (html !== null) out.push(html);
|
|
450
448
|
}
|
|
451
449
|
return out.join("\n");
|
|
452
450
|
}
|
|
451
|
+
function topLevelBlockToHtml(node, ctx) {
|
|
452
|
+
if (node?.type !== "paragraph") return nodeToHtml(node, ctx);
|
|
453
|
+
const video = findBlockVideoEmbed(node);
|
|
454
|
+
if (video) return videoEmbedToHtml(video.embed, video.title, ctx);
|
|
455
|
+
const tag = parseStandaloneAnnotation(node);
|
|
456
|
+
if (tag?.template && isMediaAnnotationName(tag.template)) {
|
|
457
|
+
return mediaAnnotationToHtml(tag.template, tag.params, ctx);
|
|
458
|
+
}
|
|
459
|
+
return nodeToHtml(node, ctx);
|
|
460
|
+
}
|
|
453
461
|
function renderFootnotesSection(footnotes, ctx) {
|
|
454
462
|
if (footnotes.isEmpty) return "";
|
|
455
463
|
const items = footnotes.ordered().map((fn) => {
|
|
@@ -484,7 +492,7 @@ function renderFeatureSection(heading, bodyNodes, side, ctx) {
|
|
|
484
492
|
const headingHtml = `<${headingTag}>${childrenToHtml({ children: heading.children }, ctx)}</${headingTag}>`;
|
|
485
493
|
const featured = takeFirstImage(bodyNodes);
|
|
486
494
|
const media = featured.image ? renderFeatureImage(featured.image, ctx) : '<div class="squisq-feature__media squisq-feature__media--empty"></div>';
|
|
487
|
-
const textHtml = [headingHtml, ...featured.remaining.map((n) =>
|
|
495
|
+
const textHtml = [headingHtml, ...featured.remaining.map((n) => topLevelBlockToHtml(n, ctx))].filter((s) => !!s).join("\n");
|
|
488
496
|
const sideClass = side === "leftFeature" ? "squisq-feature--left" : "squisq-feature--right";
|
|
489
497
|
return `<section class="squisq-feature ${sideClass}">
|
|
490
498
|
${media}
|
|
@@ -807,6 +815,11 @@ function nodeToHtml(node, ctx) {
|
|
|
807
815
|
case "image": {
|
|
808
816
|
const original = node.url ?? "";
|
|
809
817
|
const resolved = ctx?.images?.get(original) ?? original;
|
|
818
|
+
const mediaKind = mediaKindForUrl(original);
|
|
819
|
+
if (mediaKind) {
|
|
820
|
+
const label = node.alt || node.title || void 0;
|
|
821
|
+
return mediaPlayerHtml(mediaKind, resolved, label, ctx) ?? escapeHtml2(node.alt ?? "");
|
|
822
|
+
}
|
|
810
823
|
const safeSrc = sanitizeUrl(resolved, "media") ?? svgDataImageToHtmlSrc(resolved);
|
|
811
824
|
if (!safeSrc) return escapeHtml2(node.alt ?? "");
|
|
812
825
|
return `<img src="${escapeAttr(safeSrc)}" alt="${escapeAttr(node.alt ?? "")}"${imageSizeAttributes(node)} />`;
|
|
@@ -816,9 +829,16 @@ function nodeToHtml(node, ctx) {
|
|
|
816
829
|
case "table":
|
|
817
830
|
return tableToHtml(node, ctx);
|
|
818
831
|
case "inlineIcon": {
|
|
832
|
+
const token = escapeAttr(node.token ?? `${node.family}:${node.name}`);
|
|
833
|
+
const svg = ctx?.icons?.get(`${node.family}:${node.name}`);
|
|
834
|
+
if (svg) {
|
|
835
|
+
ctx.usesSvgIcons = true;
|
|
836
|
+
const width = Number((svg.width / svg.height).toFixed(4));
|
|
837
|
+
return `<svg class="squisq-icon" viewBox="0 0 ${svg.width} ${svg.height}" width="${width}em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" data-icon="${token}"><path d="${escapeAttr(svg.path)}"/></svg>`;
|
|
838
|
+
}
|
|
839
|
+
if (ctx) ctx.usesFontIcons = true;
|
|
819
840
|
const family = escapeAttr(node.family ?? "solid");
|
|
820
841
|
const name = escapeAttr(node.name ?? "");
|
|
821
|
-
const token = escapeAttr(node.token ?? `${node.family}:${node.name}`);
|
|
822
842
|
return `<i class="fa-${family} fa-${name}" data-icon="${token}" aria-hidden="true"></i>`;
|
|
823
843
|
}
|
|
824
844
|
case "htmlBlock":
|
|
@@ -955,6 +975,28 @@ var VIDEO_EMBED_CSS = ` .squisq-video-embed { display: block; max-width: 720px;
|
|
|
955
975
|
.squisq-video-embed-play::after { content: ''; position: absolute; left: 26px; top: 12px; border-style: solid; border-width: 10px 0 10px 16px; border-color: transparent transparent transparent #fff; }
|
|
956
976
|
.squisq-video-embed-provider { position: absolute; left: 12px; bottom: 10px; color: #fff; font-size: 0.8em; font-weight: 600; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8); }
|
|
957
977
|
.squisq-video-embed-caption { margin-top: 0.4em; font-size: 0.875em; opacity: 0.8; }`;
|
|
978
|
+
function mediaPlayerHtml(kind, src, label, ctx) {
|
|
979
|
+
const safeSrc = sanitizeUrl(src, "media");
|
|
980
|
+
if (!safeSrc) return null;
|
|
981
|
+
if (ctx) ctx.usesMediaPlayers = true;
|
|
982
|
+
const aria = label ? ` aria-label="${escapeAttr(label)}"` : "";
|
|
983
|
+
return `<${kind} class="squisq-media" src="${escapeAttr(safeSrc)}" controls preload="metadata"${aria}></${kind}>`;
|
|
984
|
+
}
|
|
985
|
+
function mediaAnnotationToHtml(template, params, ctx) {
|
|
986
|
+
if (!params.src) return null;
|
|
987
|
+
const kind = template === "video" ? "video" : "audio";
|
|
988
|
+
let src = ctx?.images?.get(params.src) ?? params.src;
|
|
989
|
+
const start = parseTimeSeconds(params.clipStart ?? "");
|
|
990
|
+
const end = parseTimeSeconds(params.clipEnd ?? "");
|
|
991
|
+
if ((start !== null || end !== null) && !src.includes("#")) {
|
|
992
|
+
src += `#t=${start ?? ""}${end !== null ? `,${end}` : ""}`;
|
|
993
|
+
}
|
|
994
|
+
const player = mediaPlayerHtml(kind, src, void 0, ctx);
|
|
995
|
+
return player ? `<figure class="squisq-media-clip">${player}</figure>` : null;
|
|
996
|
+
}
|
|
997
|
+
var MEDIA_PLAYER_CSS = ` .squisq-media-clip { margin: 1.25em 0; }
|
|
998
|
+
video.squisq-media { display: block; width: 100%; max-width: 720px; height: auto; border-radius: 6px; }
|
|
999
|
+
audio.squisq-media { display: block; width: 100%; max-width: 480px; }`;
|
|
958
1000
|
function svgDataImageToHtmlSrc(url) {
|
|
959
1001
|
const source = svgSourceFromDataUrl(url);
|
|
960
1002
|
const result = source === null ? null : parseSvgIsland(source);
|
|
@@ -55,8 +55,9 @@ import {
|
|
|
55
55
|
resolveTarget
|
|
56
56
|
} from "./chunk-S5PCVMKU.js";
|
|
57
57
|
import {
|
|
58
|
-
renumberFootnotes
|
|
59
|
-
|
|
58
|
+
renumberFootnotes,
|
|
59
|
+
withoutBlockTags
|
|
60
|
+
} from "./chunk-DTJQK7U7.js";
|
|
60
61
|
import {
|
|
61
62
|
buildContainer
|
|
62
63
|
} from "./chunk-IIQYS2YH.js";
|
|
@@ -65,7 +66,7 @@ import {
|
|
|
65
66
|
fontAwesomeFaces,
|
|
66
67
|
fontAwesomeGlyph,
|
|
67
68
|
obfuscateDocxFont
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-DDMPZZJF.js";
|
|
69
70
|
import {
|
|
70
71
|
authoredImageSize,
|
|
71
72
|
extToMime,
|
|
@@ -214,8 +215,9 @@ function pointsToTwips(points) {
|
|
|
214
215
|
}
|
|
215
216
|
|
|
216
217
|
// src/docx/export.ts
|
|
217
|
-
async function markdownDocToDocx(
|
|
218
|
+
async function markdownDocToDocx(source, options = {}) {
|
|
218
219
|
options.signal?.throwIfAborted();
|
|
220
|
+
const doc = withoutBlockTags(source);
|
|
219
221
|
const resolvedOptions = options.themeId !== void 0 ? options : { ...options, themeId: readFrontmatterThemeId(doc.frontmatter) };
|
|
220
222
|
const ctx = new ExportContext(resolvedOptions, doc);
|
|
221
223
|
const stories = partitionDocumentStories(doc.children);
|