@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.
Files changed (40) hide show
  1. package/README.md +15 -13
  2. package/dist/chunk-4LIFEQKX.js +358 -0
  3. package/dist/{chunk-UXEANVBI.js → chunk-5HUHSLGA.js} +1 -84
  4. package/dist/{chunk-BXWNU4T5.js → chunk-DTJQK7U7.js} +43 -0
  5. package/dist/{chunk-GDUZJ75A.js → chunk-MJTPWLVV.js} +59 -21
  6. package/dist/{chunk-6ALSRHD7.js → chunk-NCDY3EOL.js} +66 -9
  7. package/dist/{chunk-TMOXUUTG.js → chunk-NQNIFIDP.js} +6 -4
  8. package/dist/{chunk-LK4KCVN6.js → chunk-QPJHAMOW.js} +70 -28
  9. package/dist/{chunk-QU4EVC62.js → chunk-S5VXWSRR.js} +1 -1
  10. package/dist/{chunk-KROH7FNT.js → chunk-VKLJUHC2.js} +6 -4
  11. package/dist/chunk-YRFBWYAD.js +128 -0
  12. package/dist/{chunk-SVYTUYZM.js → chunk-ZJERBWTB.js} +6 -4
  13. package/dist/data/index.d.ts +27 -5
  14. package/dist/data/index.js +6 -2
  15. package/dist/diagrams/index.d.ts +19 -8
  16. package/dist/diagrams/index.js +7 -242
  17. package/dist/docx/index.d.ts +1 -1
  18. package/dist/docx/index.js +3 -3
  19. package/dist/epub/index.d.ts +1 -1
  20. package/dist/epub/index.js +3 -3
  21. package/dist/fontAwesome-C6FRDYTY.js +14 -0
  22. package/dist/html/icons.d.ts +29 -0
  23. package/dist/html/icons.js +62 -0
  24. package/dist/html/index.d.ts +3 -130
  25. package/dist/html/index.js +2 -2
  26. package/dist/html/prepare.d.ts +97 -0
  27. package/dist/html/prepare.js +85 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +16 -16
  30. package/dist/{materialize-G4WC5UG3.js → materialize-ICXNO4S4.js} +4 -1
  31. package/dist/outside-in/index.d.ts +12 -0
  32. package/dist/outside-in/index.js +3 -3
  33. package/dist/pdf/index.d.ts +1 -1
  34. package/dist/pdf/index.js +3 -3
  35. package/dist/plainHtml-B6IXcSet.d.ts +148 -0
  36. package/dist/pptx/index.js +2 -2
  37. package/dist/readers-3P5A6A2A.js +17 -0
  38. package/dist/registry/index.js +1 -1
  39. package/package.json +12 -2
  40. /package/dist/{chunk-LBXBRFBZ.js → chunk-DDMPZZJF.js} +0 -0
@@ -0,0 +1,128 @@
1
+ import {
2
+ defaultDataReaders
3
+ } from "./chunk-5HUHSLGA.js";
4
+
5
+ // src/data/materialize.ts
6
+ import {
7
+ isDataFilePath
8
+ } from "@bendyline/squisq/doc";
9
+ function tableRow(cells) {
10
+ return {
11
+ type: "tableRow",
12
+ children: cells.map((value) => ({
13
+ type: "tableCell",
14
+ children: value ? [{ type: "text", value }] : []
15
+ }))
16
+ };
17
+ }
18
+ function count(n) {
19
+ return n.toLocaleString("en-US");
20
+ }
21
+ function extensionOf(path) {
22
+ const base = path.split("/").pop() ?? path;
23
+ const dot = base.lastIndexOf(".");
24
+ return dot > 0 ? base.slice(dot + 1).toLowerCase() : "";
25
+ }
26
+ var DATA_PREVIEW_ROWS = 100;
27
+ async function materializeDataReferences(markdownDoc, container, onWarning, options = {}) {
28
+ const readers = defaultDataReaders();
29
+ const children = [];
30
+ let changed = false;
31
+ for (const [index, node] of markdownDoc.children.entries()) {
32
+ children.push(node);
33
+ if (node.type !== "heading") continue;
34
+ const params = node.templateAnnotation?.params;
35
+ const src = params?.src;
36
+ if (!src || !isDataFilePath(src)) continue;
37
+ if (markdownDoc.children[index + 1]?.type === "table") continue;
38
+ const label = params?.sheet && params?.anchor ? `${params.sheet}!${params.anchor}` : src;
39
+ if (!container) {
40
+ onWarning?.(
41
+ `Data reference "${src}" could not be embedded: the export has no source container to read it from.`
42
+ );
43
+ continue;
44
+ }
45
+ const ext = extensionOf(src);
46
+ const reader = readers.find((r) => r.extensions.includes(ext));
47
+ if (!reader) {
48
+ onWarning?.(`Data reference "${src}" could not be embedded: no reader for ".${ext}".`);
49
+ continue;
50
+ }
51
+ const previewRows = Number.parseInt(params?.previewRows ?? "", 10);
52
+ const maxRows = options.maxRows === void 0 ? Number.POSITIVE_INFINITY : previewRows > 0 ? previewRows : options.maxRows;
53
+ const readOptions = {
54
+ maxRows,
55
+ ...params?.sheet ? { sheet: params.sheet } : {},
56
+ ...params?.anchor ? { anchor: params.anchor } : {},
57
+ ...params?.headerRow !== void 0 ? { headerRow: params.headerRow !== "false" } : {},
58
+ // Exports honor the author's curated view: the sort/filter params
59
+ // shape the embedded full table exactly as they shape previews.
60
+ ...params?.sort ? { sort: params.sort } : {},
61
+ ...params?.filter ? { filter: params.filter } : {}
62
+ };
63
+ const cacheKey = [
64
+ src,
65
+ readOptions.sheet ?? "",
66
+ readOptions.anchor ?? "",
67
+ String(readOptions.headerRow ?? ""),
68
+ readOptions.sort ?? "",
69
+ readOptions.filter ?? "",
70
+ String(maxRows)
71
+ ].join("\0");
72
+ let pending = options.tableCache?.get(cacheKey);
73
+ if (!pending) {
74
+ let bytes = null;
75
+ try {
76
+ bytes = await container.readFile(src);
77
+ } catch {
78
+ bytes = null;
79
+ }
80
+ if (!bytes) {
81
+ onWarning?.(`Data reference "${src}" could not be embedded: file not found in container.`);
82
+ continue;
83
+ }
84
+ pending = reader.read(bytes, readOptions);
85
+ options.tableCache?.set(cacheKey, pending);
86
+ }
87
+ try {
88
+ const table = await pending;
89
+ const mdTable = {
90
+ type: "table",
91
+ children: [tableRow(table.headers), ...table.rows.map(tableRow)]
92
+ };
93
+ children.push(mdTable);
94
+ if (table.totalRows > table.rows.length) {
95
+ children.push({
96
+ type: "paragraph",
97
+ children: [
98
+ {
99
+ type: "emphasis",
100
+ children: [
101
+ {
102
+ type: "text",
103
+ value: `Showing ${count(table.rows.length)} of ${count(table.totalRows)} rows.`
104
+ }
105
+ ]
106
+ }
107
+ ]
108
+ });
109
+ }
110
+ changed = true;
111
+ if (ext === "xlsx") {
112
+ onWarning?.(
113
+ `Region ${label} exported as values; formulas in the sidecar workbook were not carried over.`
114
+ );
115
+ }
116
+ } catch (err) {
117
+ onWarning?.(
118
+ `Data reference "${src}" could not be embedded: ${err instanceof Error ? err.message : String(err)}`
119
+ );
120
+ }
121
+ }
122
+ return changed ? { ...markdownDoc, children } : markdownDoc;
123
+ }
124
+
125
+ export {
126
+ DATA_PREVIEW_ROWS,
127
+ materializeDataReferences
128
+ };
@@ -14,13 +14,14 @@ import {
14
14
  } from "./chunk-JU2RHXUB.js";
15
15
  import {
16
16
  FootnoteIndex,
17
- footnoteIds
18
- } from "./chunk-BXWNU4T5.js";
17
+ footnoteIds,
18
+ withoutBlockTags
19
+ } from "./chunk-DTJQK7U7.js";
19
20
  import {
20
21
  collectInlineIconFamilies,
21
22
  fontAwesomeFaces,
22
23
  fontAwesomeGlyph
23
- } from "./chunk-LBXBRFBZ.js";
24
+ } from "./chunk-DDMPZZJF.js";
24
25
  import {
25
26
  imageSizeAttributes
26
27
  } from "./chunk-JZR32FON.js";
@@ -30,8 +31,9 @@ import JSZip from "jszip";
30
31
  import { resolveFontFamily } from "@bendyline/squisq/schemas";
31
32
  import { resolveThemeForDoc } from "@bendyline/squisq/doc";
32
33
  import { isHtmlLineBreak, readFrontmatterThemeId, sanitizeUrl } from "@bendyline/squisq/markdown";
33
- async function markdownDocToEpub(sourceDoc, options = {}) {
34
+ async function markdownDocToEpub(authoredDoc, options = {}) {
34
35
  options.signal?.throwIfAborted();
36
+ const sourceDoc = withoutBlockTags(authoredDoc);
35
37
  const themeId = options.themeId ?? readFrontmatterThemeId(sourceDoc.frontmatter);
36
38
  const islandColor = themeId ? resolveThemeForDoc(sourceDoc, themeId, options.themeRegistry).colors.text : void 0;
37
39
  const { doc, images: islandImages } = svgIslandsAsImages(sourceDoc, { color: islandColor });
@@ -1,4 +1,4 @@
1
- import { DataSourceReader } from '@bendyline/squisq/doc';
1
+ import { DataSourceReader, DataSourceTable } from '@bendyline/squisq/doc';
2
2
  import { ContentContainer } from '@bendyline/squisq/storage';
3
3
  import { MarkdownDocument } from '@bendyline/squisq/markdown';
4
4
 
@@ -31,12 +31,34 @@ declare function defaultDataReaders(): DataSourceReader[];
31
31
  * (its body link simply doesn't survive a tables-only export).
32
32
  */
33
33
 
34
+ /**
35
+ * Rows a data reference shows in a document or page, which cannot carry the
36
+ * file it points at; the reader follows the author's link for the rest.
37
+ */
38
+ declare const DATA_PREVIEW_ROWS = 100;
39
+ interface MaterializeDataReferencesOptions {
40
+ /**
41
+ * Embed at most this many data rows per reference — a block's own
42
+ * `previewRows` param wins — followed by a "Showing N of M rows" note when
43
+ * rows were left out. Default: every row.
44
+ */
45
+ maxRows?: number;
46
+ /**
47
+ * A caller-owned memo of reader results, keyed by file and read options,
48
+ * for a caller that materializes the same document repeatedly (a live
49
+ * preview). The caller clears it when the files may have changed.
50
+ */
51
+ tableCache?: Map<string, Promise<DataSourceTable>>;
52
+ }
34
53
  /**
35
54
  * Returns a copy of `markdownDoc` where every heading annotated with a
36
- * resolvable data `src` is followed by the full source table. The input
37
- * document is returned unchanged (same object) when nothing materialized.
55
+ * resolvable data `src` is followed by the source table (in full unless
56
+ * `options.maxRows` bounds it). A reference whose heading is already followed
57
+ * by a table keeps it — author data wins, as in `resolveDataReferences` — so
58
+ * materializing twice adds nothing. The input document is returned unchanged
59
+ * (same object) when nothing materialized.
38
60
  */
39
- declare function materializeDataReferences(markdownDoc: MarkdownDocument, container: ContentContainer | null | undefined, onWarning?: (message: string) => void): Promise<MarkdownDocument>;
61
+ declare function materializeDataReferences(markdownDoc: MarkdownDocument, container: ContentContainer | null | undefined, onWarning?: (message: string) => void, options?: MaterializeDataReferencesOptions): Promise<MarkdownDocument>;
40
62
 
41
63
  /**
42
64
  * Sidecar naming shared by the spill-capable importers (`xlsxToContainer`,
@@ -75,4 +97,4 @@ declare function sidecarReferenceDoc(plan: DataSidecarPlan): MarkdownDocument;
75
97
  /** {@link sidecarReferenceDoc} as serialized markdown source. */
76
98
  declare function sidecarReferenceMarkdown(plan: DataSidecarPlan): string;
77
99
 
78
- export { type DataSidecarPlan, csvDataReader, defaultDataReaders, docSlugForFileName, materializeDataReferences, parquetDataReader, planDataSidecar, sanitizeSourceFileName, sidecarReferenceDoc, sidecarReferenceMarkdown, xlsxDataReader };
100
+ export { DATA_PREVIEW_ROWS, type DataSidecarPlan, type MaterializeDataReferencesOptions, csvDataReader, defaultDataReaders, docSlugForFileName, materializeDataReferences, parquetDataReader, planDataSidecar, sanitizeSourceFileName, sidecarReferenceDoc, sidecarReferenceMarkdown, xlsxDataReader };
@@ -1,10 +1,13 @@
1
+ import {
2
+ DATA_PREVIEW_ROWS,
3
+ materializeDataReferences
4
+ } from "../chunk-YRFBWYAD.js";
1
5
  import {
2
6
  csvDataReader,
3
7
  defaultDataReaders,
4
- materializeDataReferences,
5
8
  parquetDataReader,
6
9
  xlsxDataReader
7
- } from "../chunk-UXEANVBI.js";
10
+ } from "../chunk-5HUHSLGA.js";
8
11
  import "../chunk-ATWVNF7D.js";
9
12
  import "../chunk-Q77KNJIN.js";
10
13
  import {
@@ -17,6 +20,7 @@ import {
17
20
  import "../chunk-S5PCVMKU.js";
18
21
  import "../chunk-7AWFHP5U.js";
19
22
  export {
23
+ DATA_PREVIEW_ROWS,
20
24
  csvDataReader,
21
25
  defaultDataReaders,
22
26
  docSlugForFileName,
@@ -21,25 +21,28 @@ import { MarkdownDocument, MarkdownCodeBlock } from '@bendyline/squisq/markdown'
21
21
  * and PPTX embed an island natively as vector art, so by default it is
22
22
  * left in place. Ask for it to picture islands for PDF, or to get the
23
23
  * `svg` map of PNG fallbacks the Office exporters place beside the vector.
24
+ * - chart heading blocks (`{[barChart]}`, `{[pieChart]}`, …) whose first
25
+ * table is chartable: the picture replaces the table, as the player shows
26
+ * the chart alone (the table stays beneath it with `showTable`).
24
27
  *
25
- * `docToPptx` keeps drawings, timelines and ASCII diagrams as native shapes;
26
- * for it, use the returned `mermaid` map as its `diagramImages` option.
28
+ * `docToPptx` keeps drawings, timelines, ASCII diagrams and charts as native
29
+ * shapes; for it, use the returned `mermaid` map as its `diagramImages` option.
27
30
  */
28
31
 
29
32
  /** What kind of diagram a picture is wanted for. */
30
- type ExportDiagramKind = 'mermaid' | 'diagram' | 'timeline' | 'tree' | 'container' | 'svg';
33
+ type ExportDiagramKind = 'mermaid' | 'diagram' | 'timeline' | 'tree' | 'container' | 'svg' | 'chart';
31
34
  /** Every kind, `svg` included — for exporters with no vector picture of their own (PDF). */
32
35
  declare const EXPORT_DIAGRAM_KINDS: readonly ExportDiagramKind[];
33
36
  interface ExportDiagram {
34
37
  readonly kind: ExportDiagramKind;
35
38
  /**
36
- * The diagram's own markdown: its fence, or for a container its heading
37
- * and every child heading and body it owns.
39
+ * The diagram's own markdown: its fence, for a container its heading and
40
+ * every child heading and body it owns, for a chart its heading and table.
38
41
  */
39
42
  readonly markdown: string;
40
- /** The fence content for fence kinds; '' for containers. */
43
+ /** The fence content for fence kinds; '' for containers and charts. */
41
44
  readonly source: string;
42
- /** The container's template (`drawing`, `layout`, `diagram`); '' for fences. */
45
+ /** The container's or chart's template (`drawing`, `barChart`, …); '' for fences. */
43
46
  readonly template: string;
44
47
  /** A text alternative for the picture. */
45
48
  readonly alt: string;
@@ -87,6 +90,14 @@ interface RasterizedDiagrams {
87
90
  declare function fenceDiagramKind(node: MarkdownCodeBlock): ExportDiagramKind | null;
88
91
  /** Every diagram in `doc`, in document order. */
89
92
  declare function findDiagrams(doc: MarkdownDocument): ExportDiagram[];
93
+ /**
94
+ * A renderer that remembers what it drew, for a host that renders the same
95
+ * document again and again — a live preview, or a file regenerated on every
96
+ * save — so each pass redraws only the diagrams that changed. A picture is
97
+ * keyed by the diagram itself; the least recently used beyond `limit` are
98
+ * forgotten, and a failure is never remembered.
99
+ */
100
+ declare function cachingDiagramRasterizer(render: DiagramRasterizer, limit?: number): DiagramRasterizer;
90
101
  /**
91
102
  * Picture every diagram in `doc` with `render`, one at a time, and return
92
103
  * the document with each pictured diagram replaced by an image of it. A
@@ -94,4 +105,4 @@ declare function findDiagrams(doc: MarkdownDocument): ExportDiagram[];
94
105
  */
95
106
  declare function rasterizeDiagrams(doc: MarkdownDocument, render: DiagramRasterizer, options?: RasterizeDiagramsOptions): Promise<RasterizedDiagrams>;
96
107
 
97
- export { type DiagramPicture, type DiagramRasterizer, EXPORT_DIAGRAM_KINDS, type ExportDiagram, type ExportDiagramKind, type RasterizeDiagramsOptions, type RasterizedDiagrams, fenceDiagramKind, findDiagrams, rasterizeDiagrams };
108
+ export { type DiagramPicture, type DiagramRasterizer, EXPORT_DIAGRAM_KINDS, type ExportDiagram, type ExportDiagramKind, type RasterizeDiagramsOptions, type RasterizedDiagrams, cachingDiagramRasterizer, fenceDiagramKind, findDiagrams, rasterizeDiagrams };
@@ -1,248 +1,13 @@
1
- // src/diagrams/index.ts
2
1
  import {
3
- extractPlainText,
4
- isSvgIslandLang,
5
- parseSvgIsland,
6
- stringifyMarkdown
7
- } from "@bendyline/squisq/markdown";
8
- import {
9
- detectAsciiDiagram,
10
- detectAsciiTimeline,
11
- detectTree,
12
- isContainerTemplate,
13
- isEligibleAsciiFenceLang,
14
- isEligibleAsciiTimelineFenceLang,
15
- isEligibleTreeFenceLang,
16
- isExplicitDiagramLang,
17
- isExplicitTimelineLang,
18
- isExplicitTreeLang,
19
- resolveTemplateName
20
- } from "@bendyline/squisq/doc";
21
- var DEFAULT_KINDS = [
22
- "mermaid",
23
- "diagram",
24
- "timeline",
25
- "tree",
26
- "container"
27
- ];
28
- var EXPORT_DIAGRAM_KINDS = [...DEFAULT_KINDS, "svg"];
29
- var KIND_NAMES = {
30
- mermaid: "Diagram",
31
- diagram: "Diagram",
32
- timeline: "Timeline",
33
- tree: "Tree",
34
- container: "Diagram",
35
- svg: "Illustration"
36
- };
37
- function fenceDiagramKind(node) {
38
- const lang = node.lang ?? null;
39
- if ((lang ?? "").trim().toLowerCase() === "mermaid") return "mermaid";
40
- if (isSvgIslandLang(lang)) return parseSvgIsland(node.value).ok ? "svg" : null;
41
- if (isEligibleAsciiFenceLang(lang)) {
42
- const detection = detectAsciiDiagram(node.value, { explicit: isExplicitDiagramLang(lang) });
43
- if (detection.isDiagram) return "diagram";
44
- }
45
- if (isEligibleTreeFenceLang(lang)) {
46
- if (detectTree(node.value, { explicit: isExplicitTreeLang(lang) }).isTree) return "tree";
47
- }
48
- if (isEligibleAsciiTimelineFenceLang(lang)) {
49
- const detection = detectAsciiTimeline(node.value, { explicit: isExplicitTimelineLang(lang) });
50
- if (detection.isTimeline) return "timeline";
51
- }
52
- return null;
53
- }
54
- function containerTemplateOf(node) {
55
- if (node.type !== "heading") return null;
56
- const requested = node.templateAnnotation?.template;
57
- if (!requested || !isContainerTemplate(requested)) return null;
58
- return resolveTemplateName(requested);
59
- }
60
- function mermaidAlt(source) {
61
- const title = /^\s*accTitle\s*:\s*(.+?)\s*$/mu.exec(source)?.[1] ?? "";
62
- const description = /^\s*accDescr\s*:\s*(.+?)\s*$/mu.exec(source)?.[1] ?? "";
63
- return [title, description].filter(Boolean).join(". ");
64
- }
65
- function fenceAlt(kind, source) {
66
- if (kind === "mermaid") return mermaidAlt(source);
67
- if (kind === "svg") {
68
- const result = parseSvgIsland(source);
69
- return result.ok && result.island.title || "";
70
- }
71
- return "";
72
- }
73
- function fenceMarkdown(node) {
74
- return stringifyMarkdown({ type: "document", children: [node] }).trim();
75
- }
76
- function findInDocument(doc) {
77
- const found = [];
78
- const children = doc.children;
79
- const walk = (nodes) => {
80
- for (const node of nodes) {
81
- if (node.type === "code") {
82
- const fence = node;
83
- const kind = fenceDiagramKind(fence);
84
- if (kind) {
85
- found.push({
86
- fence,
87
- diagram: {
88
- kind,
89
- markdown: fenceMarkdown(fence),
90
- source: fence.value,
91
- template: "",
92
- alt: fenceAlt(kind, fence.value) || KIND_NAMES[kind]
93
- }
94
- });
95
- }
96
- continue;
97
- }
98
- const nested = node.children;
99
- if (Array.isArray(nested) && node.type !== "heading" && node.type !== "paragraph") {
100
- walk(nested);
101
- }
102
- }
103
- };
104
- for (let index = 0; index < children.length; index++) {
105
- const node = children[index];
106
- const template = containerTemplateOf(node);
107
- if (!template) {
108
- walk([node]);
109
- continue;
110
- }
111
- const depth = node.depth;
112
- let end = index + 1;
113
- while (end < children.length) {
114
- const next = children[end];
115
- if (next.type === "heading" && next.depth <= depth) break;
116
- end++;
117
- }
118
- const heading = extractPlainText(node).trim();
119
- found.push({
120
- containerIndex: index,
121
- containerEnd: end,
122
- diagram: {
123
- kind: "container",
124
- markdown: stringifyMarkdown({
125
- type: "document",
126
- children: children.slice(index, end)
127
- }).trim(),
128
- source: "",
129
- template,
130
- alt: heading || KIND_NAMES.container
131
- }
132
- });
133
- index = end - 1;
134
- }
135
- return found;
136
- }
137
- function imageUrls(nodes, into) {
138
- for (const node of nodes) {
139
- if (node.type === "image") into.add(node.url);
140
- const nested = node.children;
141
- if (Array.isArray(nested)) imageUrls(nested, into);
142
- }
143
- return into;
144
- }
145
- function findDiagrams(doc) {
146
- return findInDocument(doc).map((entry) => entry.diagram);
147
- }
148
- function imageParagraph(url, alt) {
149
- const image = { type: "image", url, alt, title: null };
150
- return { type: "paragraph", children: [image] };
151
- }
152
- function replaceFences(nodes, replacements) {
153
- let changed = false;
154
- const next = nodes.map((node) => {
155
- const replacement = replacements.get(node);
156
- if (replacement) {
157
- changed = true;
158
- return replacement;
159
- }
160
- const nested = node.children;
161
- if (Array.isArray(nested)) {
162
- const replaced = replaceFences(nested, replacements);
163
- if (replaced !== nested) {
164
- changed = true;
165
- return { ...node, children: replaced };
166
- }
167
- }
168
- return node;
169
- });
170
- return changed ? next : nodes;
171
- }
172
- async function rasterizeDiagrams(doc, render, options = {}) {
173
- const kinds = new Set(options.kinds ?? DEFAULT_KINDS);
174
- const prefix = options.urlPrefix ?? "diagram";
175
- const taken = imageUrls(doc.children, /* @__PURE__ */ new Set());
176
- let counter = 0;
177
- const nextUrl = () => {
178
- let url;
179
- do
180
- url = `${prefix}-${String(++counter)}.png`;
181
- while (taken.has(url));
182
- taken.add(url);
183
- return url;
184
- };
185
- const images = /* @__PURE__ */ new Map();
186
- const mermaid = /* @__PURE__ */ new Map();
187
- const svg = /* @__PURE__ */ new Map();
188
- const fenceReplacements = /* @__PURE__ */ new Map();
189
- const containerReplacements = [];
190
- for (const entry of findInDocument(doc)) {
191
- options.signal?.throwIfAborted();
192
- if (!kinds.has(entry.diagram.kind)) continue;
193
- let picture = null;
194
- try {
195
- picture = await render(entry.diagram);
196
- } catch (error) {
197
- options.onWarning?.(
198
- `A ${KIND_NAMES[entry.diagram.kind].toLowerCase()} could not be drawn and was kept as text: ${error instanceof Error ? error.message : String(error)}`
199
- );
200
- }
201
- if (!picture || picture.width <= 0 || picture.height <= 0) continue;
202
- const data = picture.data instanceof Uint8Array ? picture.data : new Uint8Array(picture.data);
203
- const url = nextUrl();
204
- images.set(url, {
205
- data,
206
- contentType: "image/png",
207
- width: picture.width,
208
- height: picture.height
209
- });
210
- if (entry.diagram.kind === "mermaid") mermaid.set(entry.diagram.source.trim(), picture);
211
- if (entry.diagram.kind === "svg") svg.set(entry.diagram.source.trim(), picture);
212
- const paragraph = imageParagraph(url, entry.diagram.alt);
213
- if (entry.fence) {
214
- fenceReplacements.set(entry.fence, paragraph);
215
- } else if (entry.containerIndex !== void 0 && entry.containerEnd !== void 0) {
216
- const heading = doc.children[entry.containerIndex];
217
- const { templateAnnotation: _template, ...plainHeading } = heading;
218
- containerReplacements.push({
219
- start: entry.containerIndex,
220
- end: entry.containerEnd,
221
- nodes: [plainHeading, paragraph]
222
- });
223
- }
224
- }
225
- let children = doc.children;
226
- if (containerReplacements.length > 0) {
227
- const rebuilt = [];
228
- let cursor = 0;
229
- for (const replacement of containerReplacements) {
230
- rebuilt.push(...children.slice(cursor, replacement.start), ...replacement.nodes);
231
- cursor = replacement.end;
232
- }
233
- rebuilt.push(...children.slice(cursor));
234
- children = rebuilt;
235
- }
236
- if (fenceReplacements.size > 0) children = replaceFences(children, fenceReplacements);
237
- return {
238
- markdownDoc: children === doc.children ? doc : { ...doc, children },
239
- images,
240
- mermaid,
241
- svg
242
- };
243
- }
2
+ EXPORT_DIAGRAM_KINDS,
3
+ cachingDiagramRasterizer,
4
+ fenceDiagramKind,
5
+ findDiagrams,
6
+ rasterizeDiagrams
7
+ } from "../chunk-4LIFEQKX.js";
244
8
  export {
245
9
  EXPORT_DIAGRAM_KINDS,
10
+ cachingDiagramRasterizer,
246
11
  fenceDiagramKind,
247
12
  findDiagrams,
248
13
  rasterizeDiagrams
@@ -84,7 +84,7 @@ interface DocxExportOptions {
84
84
  * @param options - Export options
85
85
  * @returns An ArrayBuffer containing the .docx file
86
86
  */
87
- declare function markdownDocToDocx(doc: MarkdownDocument, options?: DocxExportOptions): Promise<ArrayBuffer>;
87
+ declare function markdownDocToDocx(source: MarkdownDocument, options?: DocxExportOptions): Promise<ArrayBuffer>;
88
88
  /**
89
89
  * Convert a squisq Doc to a .docx Blob.
90
90
  *
@@ -4,7 +4,7 @@ import {
4
4
  docxToDoc,
5
5
  docxToMarkdownDoc,
6
6
  markdownDocToDocx
7
- } from "../chunk-KROH7FNT.js";
7
+ } from "../chunk-VKLJUHC2.js";
8
8
  import "../chunk-DHAK4PII.js";
9
9
  import "../chunk-VCZUXQUL.js";
10
10
  import "../chunk-BZ5SHMOY.js";
@@ -12,9 +12,9 @@ import "../chunk-ILCJ3WFD.js";
12
12
  import "../chunk-JU2RHXUB.js";
13
13
  import "../chunk-S5PCVMKU.js";
14
14
  import "../chunk-7AWFHP5U.js";
15
- import "../chunk-BXWNU4T5.js";
15
+ import "../chunk-DTJQK7U7.js";
16
16
  import "../chunk-IIQYS2YH.js";
17
- import "../chunk-LBXBRFBZ.js";
17
+ import "../chunk-DDMPZZJF.js";
18
18
  import "../chunk-JZR32FON.js";
19
19
  export {
20
20
  docToDocx,
@@ -66,7 +66,7 @@ interface EpubExportOptions {
66
66
  * Chapters are split at H1/H2 heading boundaries. All referenced images
67
67
  * (provided via `options.images`) are embedded in the archive.
68
68
  */
69
- declare function markdownDocToEpub(sourceDoc: MarkdownDocument, options?: EpubExportOptions): Promise<ArrayBuffer>;
69
+ declare function markdownDocToEpub(authoredDoc: MarkdownDocument, options?: EpubExportOptions): Promise<ArrayBuffer>;
70
70
  /**
71
71
  * Convert a squisq Doc to an EPUB 3 file.
72
72
  *
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  docToEpub,
3
3
  markdownDocToEpub
4
- } from "../chunk-SVYTUYZM.js";
4
+ } from "../chunk-ZJERBWTB.js";
5
5
  import "../chunk-WMIDXNGR.js";
6
6
  import "../chunk-VCZUXQUL.js";
7
7
  import "../chunk-BZ5SHMOY.js";
8
8
  import "../chunk-JU2RHXUB.js";
9
- import "../chunk-BXWNU4T5.js";
10
- import "../chunk-LBXBRFBZ.js";
9
+ import "../chunk-DTJQK7U7.js";
10
+ import "../chunk-DDMPZZJF.js";
11
11
  import "../chunk-JZR32FON.js";
12
12
  export {
13
13
  docToEpub,
@@ -0,0 +1,14 @@
1
+ import {
2
+ collectInlineIconFamilies,
3
+ fontAwesomeFace,
4
+ fontAwesomeFaces,
5
+ fontAwesomeGlyph,
6
+ obfuscateDocxFont
7
+ } from "./chunk-DDMPZZJF.js";
8
+ export {
9
+ collectInlineIconFamilies,
10
+ fontAwesomeFace,
11
+ fontAwesomeFaces,
12
+ fontAwesomeGlyph,
13
+ obfuscateDocxFont
14
+ };
@@ -0,0 +1,29 @@
1
+ import { MarkdownDocument } from '@bendyline/squisq/markdown';
2
+ import { P as PlainHtmlIcon } from '../plainHtml-B6IXcSet.js';
3
+ import '@bendyline/squisq/schemas';
4
+
5
+ /**
6
+ * Inline icons as SVG, for pages that should not depend on a font.
7
+ *
8
+ * A Font Awesome icon in the plain renderer is `<i class="fa-solid fa-star">`,
9
+ * which draws only where Font Awesome's stylesheet and fonts load — a CDN the
10
+ * page may not be allowed to reach, or a bundle it doesn't ship. Each icon's
11
+ * outline is read here from the same Font Awesome faces the DOCX, PDF and
12
+ * EPUB exporters embed, and drawn as a small inline `<svg>` instead: no font,
13
+ * no network, and it takes the text color like the glyph would.
14
+ *
15
+ * This module is its own entry, `@bendyline/squisq-formats/html-icons`, and
16
+ * nothing under `/html` may import it: the faces and their parser are ~2.5 MB,
17
+ * and a one-file bundle of `/html` would carry them even if it never drew an
18
+ * icon. Hosts pass `plainHtmlIcons` to `prepareMarkdownDocForPlainHtml`
19
+ * (`@bendyline/squisq-formats/html-prepare`) as `outlineIcons`.
20
+ */
21
+
22
+ /**
23
+ * The outline of every icon `doc` uses, keyed `family:name` — the `icons`
24
+ * option of `markdownDocToPlainHtml`. An icon the catalog doesn't know is left
25
+ * out and keeps its Font Awesome markup.
26
+ */
27
+ declare function plainHtmlIcons(doc: MarkdownDocument): Promise<Map<string, PlainHtmlIcon>>;
28
+
29
+ export { plainHtmlIcons };