@bendyline/squisq-formats 2.8.8 → 2.8.9

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 (35) hide show
  1. package/dist/chunk-4LIFEQKX.js +358 -0
  2. package/dist/{chunk-UXEANVBI.js → chunk-5HUHSLGA.js} +1 -84
  3. package/dist/{chunk-6ALSRHD7.js → chunk-6HUQFEP3.js} +61 -4
  4. package/dist/{chunk-BXWNU4T5.js → chunk-DTJQK7U7.js} +43 -0
  5. package/dist/{chunk-QU4EVC62.js → chunk-GFHUJ7L4.js} +1 -1
  6. package/dist/{chunk-TMOXUUTG.js → chunk-NQNIFIDP.js} +6 -4
  7. package/dist/{chunk-LK4KCVN6.js → chunk-SZ3OIY6G.js} +150 -28
  8. package/dist/{chunk-KROH7FNT.js → chunk-VKLJUHC2.js} +6 -4
  9. package/dist/{chunk-GDUZJ75A.js → chunk-WVDAFJFS.js} +59 -21
  10. package/dist/chunk-YRFBWYAD.js +128 -0
  11. package/dist/{chunk-SVYTUYZM.js → chunk-ZJERBWTB.js} +6 -4
  12. package/dist/data/index.d.ts +27 -5
  13. package/dist/data/index.js +6 -2
  14. package/dist/diagrams/index.d.ts +19 -8
  15. package/dist/diagrams/index.js +7 -242
  16. package/dist/docx/index.d.ts +1 -1
  17. package/dist/docx/index.js +3 -3
  18. package/dist/epub/index.d.ts +1 -1
  19. package/dist/epub/index.js +3 -3
  20. package/dist/fontAwesome-C6FRDYTY.js +14 -0
  21. package/dist/html/index.d.ts +85 -1
  22. package/dist/html/index.js +9 -4
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +10 -9
  25. package/dist/{materialize-G4WC5UG3.js → materialize-ICXNO4S4.js} +4 -1
  26. package/dist/outside-in/index.d.ts +12 -0
  27. package/dist/outside-in/index.js +2 -2
  28. package/dist/pdf/index.d.ts +1 -1
  29. package/dist/pdf/index.js +3 -3
  30. package/dist/plainHtmlIcons-KBSIJ5EN.js +62 -0
  31. package/dist/pptx/index.js +2 -2
  32. package/dist/readers-3P5A6A2A.js +17 -0
  33. package/dist/registry/index.js +1 -1
  34. package/package.json +2 -2
  35. /package/dist/{chunk-LBXBRFBZ.js → chunk-DDMPZZJF.js} +0 -0
@@ -0,0 +1,358 @@
1
+ // src/diagrams/index.ts
2
+ import {
3
+ extractPlainText,
4
+ isSvgIslandLang,
5
+ parseSvgIsland,
6
+ stringifyMarkdown
7
+ } from "@bendyline/squisq/markdown";
8
+ import {
9
+ TABLE_FED_TEMPLATES,
10
+ buildChartData,
11
+ detectAsciiDiagram,
12
+ detectAsciiTimeline,
13
+ detectTree,
14
+ isContainerTemplate,
15
+ isEligibleAsciiFenceLang,
16
+ isEligibleAsciiTimelineFenceLang,
17
+ isEligibleTreeFenceLang,
18
+ isExplicitDiagramLang,
19
+ isExplicitTimelineLang,
20
+ isExplicitTreeLang,
21
+ resolveTemplateName
22
+ } from "@bendyline/squisq/doc";
23
+ var DEFAULT_KINDS = [
24
+ "mermaid",
25
+ "diagram",
26
+ "timeline",
27
+ "tree",
28
+ "container",
29
+ "chart"
30
+ ];
31
+ var EXPORT_DIAGRAM_KINDS = [...DEFAULT_KINDS, "svg"];
32
+ var KIND_NAMES = {
33
+ mermaid: "Diagram",
34
+ diagram: "Diagram",
35
+ timeline: "Timeline",
36
+ tree: "Tree",
37
+ container: "Diagram",
38
+ svg: "Illustration",
39
+ chart: "Chart"
40
+ };
41
+ function fenceDiagramKind(node) {
42
+ const lang = node.lang ?? null;
43
+ if ((lang ?? "").trim().toLowerCase() === "mermaid") return "mermaid";
44
+ if (isSvgIslandLang(lang)) return parseSvgIsland(node.value).ok ? "svg" : null;
45
+ if (isEligibleAsciiFenceLang(lang)) {
46
+ const detection = detectAsciiDiagram(node.value, { explicit: isExplicitDiagramLang(lang) });
47
+ if (detection.isDiagram) return "diagram";
48
+ }
49
+ if (isEligibleTreeFenceLang(lang)) {
50
+ if (detectTree(node.value, { explicit: isExplicitTreeLang(lang) }).isTree) return "tree";
51
+ }
52
+ if (isEligibleAsciiTimelineFenceLang(lang)) {
53
+ const detection = detectAsciiTimeline(node.value, { explicit: isExplicitTimelineLang(lang) });
54
+ if (detection.isTimeline) return "timeline";
55
+ }
56
+ return null;
57
+ }
58
+ function containerTemplateOf(node) {
59
+ if (node.type !== "heading") return null;
60
+ const requested = node.templateAnnotation?.template;
61
+ if (!requested || !isContainerTemplate(requested)) return null;
62
+ return resolveTemplateName(requested);
63
+ }
64
+ function mermaidAlt(source) {
65
+ const title = /^\s*accTitle\s*:\s*(.+?)\s*$/mu.exec(source)?.[1] ?? "";
66
+ const description = /^\s*accDescr\s*:\s*(.+?)\s*$/mu.exec(source)?.[1] ?? "";
67
+ return [title, description].filter(Boolean).join(". ");
68
+ }
69
+ function fenceAlt(kind, source) {
70
+ if (kind === "mermaid") return mermaidAlt(source);
71
+ if (kind === "svg") {
72
+ const result = parseSvgIsland(source);
73
+ return result.ok && result.island.title || "";
74
+ }
75
+ return "";
76
+ }
77
+ function fenceMarkdown(node) {
78
+ return stringifyMarkdown({ type: "document", children: [node] }).trim();
79
+ }
80
+ function tableText(table) {
81
+ const [header, ...body] = table.children.map(
82
+ (row) => row.children.map((cell) => extractPlainText(cell).trim())
83
+ );
84
+ return { headers: header ?? [], rows: body };
85
+ }
86
+ function listParam(value) {
87
+ const entries = value?.split(",").map((entry) => entry.trim()).filter(Boolean);
88
+ return entries && entries.length > 0 ? entries : void 0;
89
+ }
90
+ var NON_CHART_PARAMS = /* @__PURE__ */ new Set([
91
+ "showTable",
92
+ "src",
93
+ "sheet",
94
+ "anchor",
95
+ "headerRow",
96
+ "titleAnchor",
97
+ "previewRows",
98
+ "sort",
99
+ "filter"
100
+ ]);
101
+ function isTruthyParam(value) {
102
+ return value !== void 0 && value !== "false" && value !== "0";
103
+ }
104
+ function findChart(children, index) {
105
+ const heading = children[index];
106
+ const requested = heading.templateAnnotation?.template;
107
+ const template = requested ? resolveTemplateName(requested) : "";
108
+ if (!TABLE_FED_TEMPLATES.has(template) || template === "dataTable") return null;
109
+ let tableIndex = -1;
110
+ for (let at = index + 1; at < children.length; at++) {
111
+ const node = children[at];
112
+ if (node.type === "heading") break;
113
+ if (node.type === "table") {
114
+ tableIndex = at;
115
+ break;
116
+ }
117
+ }
118
+ if (tableIndex < 0) return null;
119
+ const table = children[tableIndex];
120
+ const params = heading.templateAnnotation?.params ?? {};
121
+ const data = buildChartData(tableText(table), {
122
+ labelColumn: params.labelColumn,
123
+ valueColumns: listParam(params.valueColumns)
124
+ });
125
+ if (!data) return null;
126
+ const { showTable } = params;
127
+ const chartParams = Object.fromEntries(
128
+ Object.entries(params).filter(([key]) => !NON_CHART_PARAMS.has(key))
129
+ );
130
+ const chartHeading = {
131
+ ...heading,
132
+ templateAnnotation: { template, params: chartParams }
133
+ };
134
+ const title = extractPlainText(heading).trim();
135
+ const plotted = data.series.map((series) => series.name).join(", ");
136
+ const what = `${template.replace(/Chart$/, "")} chart of ${plotted}${data.labelHeader ? ` by ${data.labelHeader}` : ""}`;
137
+ return {
138
+ chart: { headingIndex: index, tableIndex, keepTable: isTruthyParam(showTable) },
139
+ diagram: {
140
+ kind: "chart",
141
+ markdown: stringifyMarkdown({ type: "document", children: [chartHeading, table] }).trim(),
142
+ source: "",
143
+ template,
144
+ alt: title ? `${title}: ${what}` : what.charAt(0).toUpperCase() + what.slice(1)
145
+ }
146
+ };
147
+ }
148
+ function findInDocument(doc) {
149
+ const found = [];
150
+ const children = doc.children;
151
+ const walk = (nodes) => {
152
+ for (const node of nodes) {
153
+ if (node.type === "code") {
154
+ const fence = node;
155
+ const kind = fenceDiagramKind(fence);
156
+ if (kind) {
157
+ found.push({
158
+ fence,
159
+ diagram: {
160
+ kind,
161
+ markdown: fenceMarkdown(fence),
162
+ source: fence.value,
163
+ template: "",
164
+ alt: fenceAlt(kind, fence.value) || KIND_NAMES[kind]
165
+ }
166
+ });
167
+ }
168
+ continue;
169
+ }
170
+ const nested = node.children;
171
+ if (Array.isArray(nested) && node.type !== "heading" && node.type !== "paragraph") {
172
+ walk(nested);
173
+ }
174
+ }
175
+ };
176
+ for (let index = 0; index < children.length; index++) {
177
+ const node = children[index];
178
+ const template = containerTemplateOf(node);
179
+ if (!template) {
180
+ const chart = node.type === "heading" ? findChart(children, index) : null;
181
+ if (chart) found.push(chart);
182
+ walk([node]);
183
+ continue;
184
+ }
185
+ const depth = node.depth;
186
+ let end = index + 1;
187
+ while (end < children.length) {
188
+ const next = children[end];
189
+ if (next.type === "heading" && next.depth <= depth) break;
190
+ end++;
191
+ }
192
+ const heading = extractPlainText(node).trim();
193
+ found.push({
194
+ containerIndex: index,
195
+ containerEnd: end,
196
+ diagram: {
197
+ kind: "container",
198
+ markdown: stringifyMarkdown({
199
+ type: "document",
200
+ children: children.slice(index, end)
201
+ }).trim(),
202
+ source: "",
203
+ template,
204
+ alt: heading || KIND_NAMES.container
205
+ }
206
+ });
207
+ index = end - 1;
208
+ }
209
+ return found;
210
+ }
211
+ function imageUrls(nodes, into) {
212
+ for (const node of nodes) {
213
+ if (node.type === "image") into.add(node.url);
214
+ const nested = node.children;
215
+ if (Array.isArray(nested)) imageUrls(nested, into);
216
+ }
217
+ return into;
218
+ }
219
+ function findDiagrams(doc) {
220
+ return findInDocument(doc).map((entry) => entry.diagram);
221
+ }
222
+ function withoutTemplate(heading) {
223
+ const { templateAnnotation: _template, ...plain } = heading;
224
+ return plain;
225
+ }
226
+ function imageParagraph(url, alt) {
227
+ const image = { type: "image", url, alt, title: null };
228
+ return { type: "paragraph", children: [image] };
229
+ }
230
+ function replaceFences(nodes, replacements) {
231
+ let changed = false;
232
+ const next = nodes.map((node) => {
233
+ const replacement = replacements.get(node);
234
+ if (replacement) {
235
+ changed = true;
236
+ return replacement;
237
+ }
238
+ const nested = node.children;
239
+ if (Array.isArray(nested)) {
240
+ const replaced = replaceFences(nested, replacements);
241
+ if (replaced !== nested) {
242
+ changed = true;
243
+ return { ...node, children: replaced };
244
+ }
245
+ }
246
+ return node;
247
+ });
248
+ return changed ? next : nodes;
249
+ }
250
+ function cachingDiagramRasterizer(render, limit = 64) {
251
+ const drawn = /* @__PURE__ */ new Map();
252
+ return (diagram) => {
253
+ const key = `${diagram.kind}\0${diagram.markdown}\0${diagram.source}`;
254
+ let picture = drawn.get(key);
255
+ if (picture) {
256
+ drawn.delete(key);
257
+ } else {
258
+ picture = render(diagram);
259
+ picture.catch(() => drawn.delete(key));
260
+ }
261
+ drawn.set(key, picture);
262
+ if (drawn.size > limit) drawn.delete(drawn.keys().next().value);
263
+ return picture;
264
+ };
265
+ }
266
+ async function rasterizeDiagrams(doc, render, options = {}) {
267
+ const kinds = new Set(options.kinds ?? DEFAULT_KINDS);
268
+ const prefix = options.urlPrefix ?? "diagram";
269
+ const taken = imageUrls(doc.children, /* @__PURE__ */ new Set());
270
+ let counter = 0;
271
+ const nextUrl = () => {
272
+ let url;
273
+ do
274
+ url = `${prefix}-${String(++counter)}.png`;
275
+ while (taken.has(url));
276
+ taken.add(url);
277
+ return url;
278
+ };
279
+ const images = /* @__PURE__ */ new Map();
280
+ const mermaid = /* @__PURE__ */ new Map();
281
+ const svg = /* @__PURE__ */ new Map();
282
+ const fenceReplacements = /* @__PURE__ */ new Map();
283
+ const blockReplacements = [];
284
+ for (const entry of findInDocument(doc)) {
285
+ options.signal?.throwIfAborted();
286
+ if (!kinds.has(entry.diagram.kind)) continue;
287
+ let picture = null;
288
+ try {
289
+ picture = await render(entry.diagram);
290
+ } catch (error) {
291
+ options.onWarning?.(
292
+ `A ${KIND_NAMES[entry.diagram.kind].toLowerCase()} could not be drawn and was kept as text: ${error instanceof Error ? error.message : String(error)}`
293
+ );
294
+ }
295
+ if (!picture || picture.width <= 0 || picture.height <= 0) continue;
296
+ const data = picture.data instanceof Uint8Array ? picture.data : new Uint8Array(picture.data);
297
+ const url = nextUrl();
298
+ images.set(url, {
299
+ data,
300
+ contentType: "image/png",
301
+ width: picture.width,
302
+ height: picture.height
303
+ });
304
+ if (entry.diagram.kind === "mermaid") mermaid.set(entry.diagram.source.trim(), picture);
305
+ if (entry.diagram.kind === "svg") svg.set(entry.diagram.source.trim(), picture);
306
+ const paragraph = imageParagraph(url, entry.diagram.alt);
307
+ if (entry.fence) {
308
+ fenceReplacements.set(entry.fence, paragraph);
309
+ } else if (entry.containerIndex !== void 0 && entry.containerEnd !== void 0) {
310
+ blockReplacements.push({
311
+ start: entry.containerIndex,
312
+ end: entry.containerEnd,
313
+ nodes: [withoutTemplate(doc.children[entry.containerIndex]), paragraph]
314
+ });
315
+ } else if (entry.chart) {
316
+ const { headingIndex, tableIndex, keepTable } = entry.chart;
317
+ const table = doc.children[tableIndex];
318
+ blockReplacements.push(
319
+ {
320
+ start: headingIndex,
321
+ end: headingIndex + 1,
322
+ nodes: [withoutTemplate(doc.children[headingIndex])]
323
+ },
324
+ {
325
+ start: tableIndex,
326
+ end: tableIndex + 1,
327
+ nodes: keepTable ? [paragraph, table] : [paragraph]
328
+ }
329
+ );
330
+ }
331
+ }
332
+ let children = doc.children;
333
+ if (blockReplacements.length > 0) {
334
+ const rebuilt = [];
335
+ let cursor = 0;
336
+ for (const replacement of blockReplacements) {
337
+ rebuilt.push(...children.slice(cursor, replacement.start), ...replacement.nodes);
338
+ cursor = replacement.end;
339
+ }
340
+ rebuilt.push(...children.slice(cursor));
341
+ children = rebuilt;
342
+ }
343
+ if (fenceReplacements.size > 0) children = replaceFences(children, fenceReplacements);
344
+ return {
345
+ markdownDoc: children === doc.children ? doc : { ...doc, children },
346
+ images,
347
+ mermaid,
348
+ svg
349
+ };
350
+ }
351
+
352
+ export {
353
+ EXPORT_DIAGRAM_KINDS,
354
+ fenceDiagramKind,
355
+ findDiagrams,
356
+ cachingDiagramRasterizer,
357
+ rasterizeDiagrams
358
+ };
@@ -8,9 +8,6 @@ import {
8
8
  parseCsv
9
9
  } from "./chunk-Q77KNJIN.js";
10
10
 
11
- // src/data/materialize.ts
12
- import { isDataFilePath } from "@bendyline/squisq/doc";
13
-
14
11
  // src/data/readers.ts
15
12
  import { applyTableViewState, parseTableViewState } from "@bendyline/squisq/table";
16
13
  function applyViewParams(headers, body, opts) {
@@ -152,89 +149,9 @@ function defaultDataReaders() {
152
149
  return [csvDataReader, xlsxDataReader, parquetDataReader];
153
150
  }
154
151
 
155
- // src/data/materialize.ts
156
- function tableRow(cells) {
157
- return {
158
- type: "tableRow",
159
- children: cells.map((value) => ({
160
- type: "tableCell",
161
- children: value ? [{ type: "text", value }] : []
162
- }))
163
- };
164
- }
165
- function extensionOf(path) {
166
- const base = path.split("/").pop() ?? path;
167
- const dot = base.lastIndexOf(".");
168
- return dot > 0 ? base.slice(dot + 1).toLowerCase() : "";
169
- }
170
- async function materializeDataReferences(markdownDoc, container, onWarning) {
171
- const readers = defaultDataReaders();
172
- const children = [];
173
- let changed = false;
174
- for (const node of markdownDoc.children) {
175
- children.push(node);
176
- if (node.type !== "heading") continue;
177
- const params = node.templateAnnotation?.params;
178
- const src = params?.src;
179
- if (!src || !isDataFilePath(src)) continue;
180
- const label = params?.sheet && params?.anchor ? `${params.sheet}!${params.anchor}` : src;
181
- if (!container) {
182
- onWarning?.(
183
- `Data reference "${src}" could not be embedded: the export has no source container to read it from.`
184
- );
185
- continue;
186
- }
187
- const ext = extensionOf(src);
188
- const reader = readers.find((r) => r.extensions.includes(ext));
189
- if (!reader) {
190
- onWarning?.(`Data reference "${src}" could not be embedded: no reader for ".${ext}".`);
191
- continue;
192
- }
193
- let bytes = null;
194
- try {
195
- bytes = await container.readFile(src);
196
- } catch {
197
- bytes = null;
198
- }
199
- if (!bytes) {
200
- onWarning?.(`Data reference "${src}" could not be embedded: file not found in container.`);
201
- continue;
202
- }
203
- try {
204
- const table = await reader.read(bytes, {
205
- maxRows: Number.POSITIVE_INFINITY,
206
- ...params?.sheet ? { sheet: params.sheet } : {},
207
- ...params?.anchor ? { anchor: params.anchor } : {},
208
- ...params?.headerRow !== void 0 ? { headerRow: params.headerRow !== "false" } : {},
209
- // Exports honor the author's curated view: the sort/filter params
210
- // shape the embedded full table exactly as they shape previews.
211
- ...params?.sort ? { sort: params.sort } : {},
212
- ...params?.filter ? { filter: params.filter } : {}
213
- });
214
- const mdTable = {
215
- type: "table",
216
- children: [tableRow(table.headers), ...table.rows.map(tableRow)]
217
- };
218
- children.push(mdTable);
219
- changed = true;
220
- if (ext === "xlsx") {
221
- onWarning?.(
222
- `Region ${label} exported as values; formulas in the sidecar workbook were not carried over.`
223
- );
224
- }
225
- } catch (err) {
226
- onWarning?.(
227
- `Data reference "${src}" could not be embedded: ${err instanceof Error ? err.message : String(err)}`
228
- );
229
- }
230
- }
231
- return changed ? { ...markdownDoc, children } : markdownDoc;
232
- }
233
-
234
152
  export {
235
153
  csvDataReader,
236
154
  xlsxDataReader,
237
155
  parquetDataReader,
238
- defaultDataReaders,
239
- materializeDataReferences
156
+ defaultDataReaders
240
157
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  convert,
3
3
  defaultRegistry
4
- } from "./chunk-GDUZJ75A.js";
4
+ } from "./chunk-WVDAFJFS.js";
5
5
  import {
6
6
  ConversionError
7
7
  } from "./chunk-KXOZMWBS.js";
@@ -188,7 +188,9 @@ async function renderOutsideInDocument(source, options = {}) {
188
188
  { format: "html" }
189
189
  );
190
190
  }
191
- const formatOptions = { ...options.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
- return convert(
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: source.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 {
@@ -1,3 +1,45 @@
1
+ // src/shared/blockTags.ts
2
+ import {
3
+ detectPromotableBodyAnnotation,
4
+ hasTemplate,
5
+ isMediaAnnotationName,
6
+ parseStandaloneAnnotation
7
+ } from "@bendyline/squisq/doc";
8
+ function withoutBlockTags(doc, options = {}) {
9
+ const children = withoutPromotedTags(doc.children);
10
+ const kept = children.filter((node) => !isRemovedTag(node, options));
11
+ return kept.length === doc.children.length && children === doc.children ? doc : { ...doc, children: kept };
12
+ }
13
+ function isRemovedTag(node, options) {
14
+ const tag = parseStandaloneAnnotation(node)?.template;
15
+ if (!tag) return false;
16
+ if (isMediaAnnotationName(tag)) return !options.keepMedia;
17
+ return hasTemplate(tag);
18
+ }
19
+ function withoutPromotedTags(children) {
20
+ const out = [];
21
+ let changed = false;
22
+ let index = 0;
23
+ while (index < children.length) {
24
+ const node = children[index++];
25
+ out.push(node);
26
+ if (node.type !== "heading" || node.templateAnnotation?.template) continue;
27
+ let end = index;
28
+ while (end < children.length && children[end].type !== "heading") end++;
29
+ const body = children.slice(index, end);
30
+ const found = detectPromotableBodyAnnotation(body);
31
+ const tag = found?.data.template;
32
+ if (found && tag && !isMediaAnnotationName(tag) && hasTemplate(tag)) {
33
+ out.push(...found.strippedContents);
34
+ changed = true;
35
+ } else {
36
+ out.push(...body);
37
+ }
38
+ index = end;
39
+ }
40
+ return changed ? out : children;
41
+ }
42
+
1
43
  // src/shared/footnotes.ts
2
44
  var FootnoteIndex = class {
3
45
  constructor(doc) {
@@ -102,6 +144,7 @@ function renumberFootnotes(doc) {
102
144
  }
103
145
 
104
146
  export {
147
+ withoutBlockTags,
105
148
  FootnoteIndex,
106
149
  footnoteIds,
107
150
  renumberFootnotes
@@ -60,7 +60,7 @@ import {
60
60
  fontAwesomeFace,
61
61
  fontAwesomeFaces,
62
62
  fontAwesomeGlyph
63
- } from "./chunk-LBXBRFBZ.js";
63
+ } from "./chunk-DDMPZZJF.js";
64
64
  import {
65
65
  extToMime,
66
66
  readImageDimensions
@@ -2,8 +2,9 @@ import {
2
2
  upngEncoder
3
3
  } from "./chunk-34KECNZO.js";
4
4
  import {
5
- FootnoteIndex
6
- } from "./chunk-BXWNU4T5.js";
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-LBXBRFBZ.js";
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(doc, options = {}) {
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);