@bendyline/squisq-formats 2.5.1 → 2.6.1
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/NOTICE.md +10 -9
- package/dist/{chunk-TVUX3RUC.js → chunk-2OCP46K5.js} +10 -3
- package/dist/{chunk-2LT3JL7U.js → chunk-3ITGQRL5.js} +8 -8
- package/dist/{chunk-FMQWNPCV.js → chunk-AGGNLRHV.js} +6 -6
- package/dist/{chunk-AONELFLA.js → chunk-B7GEAZBI.js} +6 -1
- package/dist/chunk-CKSTGNVZ.js +724 -0
- package/dist/chunk-DXYWKZ52.js +57 -0
- package/dist/chunk-FLR2ARKC.js +240 -0
- package/dist/{chunk-5JQ5NDRC.js → chunk-JPU5GPGG.js} +64 -12
- package/dist/{chunk-RX55T5HO.js → chunk-OBADJV7C.js} +136 -415
- package/dist/{chunk-T4PX33AG.js → chunk-POO3PJFH.js} +23 -3
- package/dist/{chunk-AD2WT564.js → chunk-Q77KNJIN.js} +45 -0
- package/dist/{chunk-6RQOV3B3.js → chunk-VPWPEMZJ.js} +1 -1
- package/dist/{chunk-FIOSE4BO.js → chunk-XJNOZTAY.js} +6 -6
- package/dist/csv/index.d.ts +67 -1
- package/dist/csv/index.js +10 -3
- package/dist/data/index.d.ts +78 -0
- package/dist/data/index.js +30 -0
- package/dist/docx/index.js +3 -3
- package/dist/epub/index.js +4 -4
- package/dist/{export-Boq78GMq.d.ts → export-6iQXd-lQ.d.ts} +98 -2
- package/dist/html/index.d.ts +2 -8
- package/dist/html/index.js +3 -3
- package/dist/{images-ESPQKVTW.js → images-JLBFCDD4.js} +1 -1
- package/dist/{import-B0gBYUmd.d.ts → import-D59rxNTj.d.ts} +11 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +29 -26
- package/dist/infer/index.js +6 -6
- package/dist/materialize-A34OZGEU.js +11 -0
- package/dist/outside-in/index.d.ts +4 -4
- package/dist/outside-in/index.js +2 -2
- package/dist/pdf/index.js +2 -2
- package/dist/pptx/index.js +3 -3
- package/dist/registry/index.d.ts +4 -4
- package/dist/registry/index.js +1 -1
- package/dist/{types-bwP9PBSk.d.ts → types-BD23kHNG.d.ts} +5 -5
- package/dist/xlsx/index.d.ts +85 -4
- package/dist/xlsx/index.js +21 -4
- package/package.json +17 -2
- package/dist/{chunk-KMBBO5H7.js → chunk-7DQP2I57.js} +4 -4
- package/dist/{chunk-M7XPXGXW.js → chunk-ROF7SSQP.js} +3 -3
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/data/sidecar.ts
|
|
2
|
+
import { dataSidecarPrefix } from "@bendyline/squisq/doc";
|
|
3
|
+
import { stringifyMarkdown } from "@bendyline/squisq/markdown";
|
|
4
|
+
function sanitizeSourceFileName(name, fallback) {
|
|
5
|
+
const base = (name ?? "").split(/[\\/]/).pop()?.trim() ?? "";
|
|
6
|
+
return base || fallback;
|
|
7
|
+
}
|
|
8
|
+
function docSlugForFileName(fileName) {
|
|
9
|
+
const stem = fileName.replace(/\.[^.]+$/, "");
|
|
10
|
+
const slug = stem.normalize("NFKD").replace(/\p{Mark}+/gu, "").toLocaleLowerCase("en-US").replace(/[^\p{Letter}\p{Number}]+/gu, "-").replace(/^-+|-+$/g, "");
|
|
11
|
+
return slug || "document";
|
|
12
|
+
}
|
|
13
|
+
function planDataSidecar(sourceName, fallbackName) {
|
|
14
|
+
const fileName = sanitizeSourceFileName(sourceName, fallbackName);
|
|
15
|
+
const slug = docSlugForFileName(fileName);
|
|
16
|
+
return {
|
|
17
|
+
slug,
|
|
18
|
+
markdownFilename: `${slug}.md`,
|
|
19
|
+
fileName,
|
|
20
|
+
sidecarPath: `${dataSidecarPrefix(slug)}${fileName}`
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function sidecarReferenceDoc(plan) {
|
|
24
|
+
const title = plan.fileName.replace(/\.[^.]+$/, "");
|
|
25
|
+
return {
|
|
26
|
+
type: "document",
|
|
27
|
+
children: [
|
|
28
|
+
{
|
|
29
|
+
type: "heading",
|
|
30
|
+
depth: 1,
|
|
31
|
+
children: [{ type: "text", value: title }],
|
|
32
|
+
templateAnnotation: { template: "dataTable", params: { src: plan.sidecarPath } }
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: "paragraph",
|
|
36
|
+
children: [
|
|
37
|
+
{
|
|
38
|
+
type: "link",
|
|
39
|
+
url: plan.sidecarPath,
|
|
40
|
+
children: [{ type: "text", value: plan.fileName }]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function sidecarReferenceMarkdown(plan) {
|
|
48
|
+
return stringifyMarkdown(sidecarReferenceDoc(plan));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
sanitizeSourceFileName,
|
|
53
|
+
docSlugForFileName,
|
|
54
|
+
planDataSidecar,
|
|
55
|
+
sidecarReferenceDoc,
|
|
56
|
+
sidecarReferenceMarkdown
|
|
57
|
+
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import {
|
|
2
|
+
columnLetter2 as columnLetter,
|
|
3
|
+
parseCellRef,
|
|
4
|
+
xlsxToTables
|
|
5
|
+
} from "./chunk-OBADJV7C.js";
|
|
6
|
+
import {
|
|
7
|
+
SIDECAR_CSV_LIMITS,
|
|
8
|
+
parseCsv
|
|
9
|
+
} from "./chunk-Q77KNJIN.js";
|
|
10
|
+
|
|
11
|
+
// src/data/materialize.ts
|
|
12
|
+
import { isDataFilePath } from "@bendyline/squisq/doc";
|
|
13
|
+
|
|
14
|
+
// src/data/readers.ts
|
|
15
|
+
import { applyTableViewState, parseTableViewState } from "@bendyline/squisq/table";
|
|
16
|
+
function applyViewParams(headers, body, opts) {
|
|
17
|
+
if (!opts.sort && !opts.filter) return { body };
|
|
18
|
+
const { view, issues } = parseTableViewState(opts.sort, opts.filter, headers);
|
|
19
|
+
const applied = applyTableViewState(headers, body, view);
|
|
20
|
+
const filtered = applied.rows.length !== applied.unfilteredRowCount;
|
|
21
|
+
return {
|
|
22
|
+
body: applied.rows,
|
|
23
|
+
...filtered ? { unfilteredTotalRows: applied.unfilteredRowCount } : {},
|
|
24
|
+
...issues.length > 0 ? { viewIssues: issues } : {}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function csvToTable(rows, opts) {
|
|
28
|
+
const width = rows.reduce((max, row) => Math.max(max, row.length), 0);
|
|
29
|
+
const pad = (row) => row.length === width ? row : [...row, ...Array(width - row.length).fill("")];
|
|
30
|
+
const headerRow = opts.headerRow !== false;
|
|
31
|
+
const headers = headerRow && rows.length > 0 ? pad(rows[0]) : Array.from({ length: width }, (_, i) => columnLetter(i));
|
|
32
|
+
const rawBody = (headerRow ? rows.slice(1) : rows).map(pad);
|
|
33
|
+
const { body, unfilteredTotalRows, viewIssues } = applyViewParams(headers, rawBody, opts);
|
|
34
|
+
return {
|
|
35
|
+
headers,
|
|
36
|
+
rows: body.slice(0, opts.maxRows),
|
|
37
|
+
totalRows: body.length,
|
|
38
|
+
totalCols: width,
|
|
39
|
+
...unfilteredTotalRows !== void 0 ? { unfilteredTotalRows } : {},
|
|
40
|
+
...viewIssues ? { viewIssues } : {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var csvDataReader = {
|
|
44
|
+
extensions: ["csv", "tsv"],
|
|
45
|
+
async read(data, opts) {
|
|
46
|
+
const text = new TextDecoder().decode(data);
|
|
47
|
+
const firstLine = text.slice(0, text.indexOf("\n") + 1 || text.length);
|
|
48
|
+
const delimiter = firstLine.includes(" ") && !firstLine.includes(",") ? " " : ",";
|
|
49
|
+
return csvToTable(parseCsv(text, delimiter, SIDECAR_CSV_LIMITS), opts);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
function tableRect(table) {
|
|
53
|
+
const ref = parseCellRef(table.anchor);
|
|
54
|
+
if (!ref) return null;
|
|
55
|
+
const height = table.rows.length + (table.hasHeader ? 1 : 0);
|
|
56
|
+
return {
|
|
57
|
+
top: ref.row,
|
|
58
|
+
left: ref.col,
|
|
59
|
+
bottom: ref.row + Math.max(height - 1, 0),
|
|
60
|
+
right: ref.col + Math.max(table.columns.length - 1, 0)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function pickTable(tables, anchor) {
|
|
64
|
+
if (tables.length === 0) return null;
|
|
65
|
+
if (anchor) {
|
|
66
|
+
const exact = tables.find((t) => t.anchor.toUpperCase() === anchor.toUpperCase());
|
|
67
|
+
if (exact) return exact;
|
|
68
|
+
const target = parseCellRef(anchor);
|
|
69
|
+
if (target) {
|
|
70
|
+
const containing = tables.find((t) => {
|
|
71
|
+
const rect = tableRect(t);
|
|
72
|
+
return !!rect && target.row >= rect.top && target.row <= rect.bottom && target.col >= rect.left && target.col <= rect.right;
|
|
73
|
+
});
|
|
74
|
+
if (containing) return containing;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return tables.reduce(
|
|
78
|
+
(best, t) => t.rows.length * t.columns.length > best.rows.length * best.columns.length ? t : best
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
function stringifyCell(value) {
|
|
82
|
+
if (value === null) return "";
|
|
83
|
+
if (typeof value === "string") return value;
|
|
84
|
+
return String(value);
|
|
85
|
+
}
|
|
86
|
+
var xlsxDataReader = {
|
|
87
|
+
extensions: ["xlsx"],
|
|
88
|
+
async read(data, opts) {
|
|
89
|
+
const tables = await xlsxToTables(data, {
|
|
90
|
+
...opts.sheet !== void 0 ? { sheet: opts.sheet } : {}
|
|
91
|
+
});
|
|
92
|
+
if (opts.sheet !== void 0 && tables.length === 0) {
|
|
93
|
+
throw new Error(`worksheet "${opts.sheet}" not found or holds no tabular data`);
|
|
94
|
+
}
|
|
95
|
+
const table = pickTable(tables, opts.anchor);
|
|
96
|
+
if (!table) {
|
|
97
|
+
throw new Error("no tabular data found in workbook");
|
|
98
|
+
}
|
|
99
|
+
const ref = parseCellRef(table.anchor);
|
|
100
|
+
const demoteHeader = opts.headerRow === false && table.hasHeader;
|
|
101
|
+
const headers = demoteHeader ? table.columns.map((_, i) => columnLetter((ref?.col ?? 0) + i)) : table.columns.map((c) => c.name);
|
|
102
|
+
const rawBody = demoteHeader ? [table.columns.map((c) => c.name), ...table.rows.map((row) => row.map(stringifyCell))] : table.rows.map((row) => row.map(stringifyCell));
|
|
103
|
+
const { body, unfilteredTotalRows, viewIssues } = applyViewParams(headers, rawBody, opts);
|
|
104
|
+
return {
|
|
105
|
+
headers,
|
|
106
|
+
rows: body.slice(0, opts.maxRows),
|
|
107
|
+
totalRows: body.length,
|
|
108
|
+
totalCols: table.columns.length,
|
|
109
|
+
...unfilteredTotalRows !== void 0 ? { unfilteredTotalRows } : {},
|
|
110
|
+
...viewIssues ? { viewIssues } : {}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var parquetDataReader = {
|
|
115
|
+
extensions: ["parquet"],
|
|
116
|
+
async read(data, opts) {
|
|
117
|
+
let hyparquet;
|
|
118
|
+
try {
|
|
119
|
+
hyparquet = await import("hyparquet");
|
|
120
|
+
} catch {
|
|
121
|
+
throw new Error('parquet support is not installed (missing optional dependency "hyparquet")');
|
|
122
|
+
}
|
|
123
|
+
const buffer = data instanceof ArrayBuffer ? data : new Uint8Array(data).slice().buffer;
|
|
124
|
+
const metadata = hyparquet.parquetMetadata(buffer);
|
|
125
|
+
const totalRows = Number(metadata.num_rows);
|
|
126
|
+
const columnNames = hyparquet.parquetSchema(metadata).children.map((c) => c.element.name);
|
|
127
|
+
const hasView = Boolean(opts.sort || opts.filter);
|
|
128
|
+
const rows = [];
|
|
129
|
+
await hyparquet.parquetRead({
|
|
130
|
+
file: buffer,
|
|
131
|
+
metadata,
|
|
132
|
+
rowStart: 0,
|
|
133
|
+
rowEnd: hasView ? totalRows : Math.min(opts.maxRows, totalRows),
|
|
134
|
+
onComplete(read) {
|
|
135
|
+
for (const row of read) {
|
|
136
|
+
rows.push(row.map((cell) => cell === null || cell === void 0 ? "" : String(cell)));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
const { body, unfilteredTotalRows, viewIssues } = applyViewParams(columnNames, rows, opts);
|
|
141
|
+
return {
|
|
142
|
+
headers: columnNames,
|
|
143
|
+
rows: body.slice(0, opts.maxRows),
|
|
144
|
+
totalRows: hasView ? body.length : totalRows,
|
|
145
|
+
totalCols: columnNames.length,
|
|
146
|
+
...unfilteredTotalRows !== void 0 ? { unfilteredTotalRows } : {},
|
|
147
|
+
...viewIssues ? { viewIssues } : {}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
function defaultDataReaders() {
|
|
152
|
+
return [csvDataReader, xlsxDataReader, parquetDataReader];
|
|
153
|
+
}
|
|
154
|
+
|
|
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
|
+
export {
|
|
235
|
+
csvDataReader,
|
|
236
|
+
xlsxDataReader,
|
|
237
|
+
parquetDataReader,
|
|
238
|
+
defaultDataReaders,
|
|
239
|
+
materializeDataReferences
|
|
240
|
+
};
|
|
@@ -85,6 +85,9 @@ function assertDocWithinConversionLimits(doc, limits, signal) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// src/registry/defaultFormats.ts
|
|
89
|
+
import { isDataFilePath } from "@bendyline/squisq/doc";
|
|
90
|
+
|
|
88
91
|
// src/shared/fidelity.ts
|
|
89
92
|
var CONTENT_NODE_TYPES = {
|
|
90
93
|
heading: true,
|
|
@@ -221,24 +224,44 @@ async function markdownOf(input) {
|
|
|
221
224
|
const { docToMarkdown } = await import("@bendyline/squisq/doc");
|
|
222
225
|
return docToMarkdown(input.doc);
|
|
223
226
|
}
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
var IMAGE_ASSET_RE = /\.(jpg|jpeg|png|gif|webp|svg|bmp|avif)$/i;
|
|
228
|
+
var DATA_ASSET_RE = /\.(csv|tsv|xlsx|parquet)$/i;
|
|
229
|
+
async function collectContainerAssets(container, pattern, signal, flattenBasenames = true) {
|
|
230
|
+
const assets = /* @__PURE__ */ new Map();
|
|
226
231
|
const files = await container.listFiles();
|
|
227
232
|
for (let index = 0; index < files.length; index++) {
|
|
228
233
|
if ((index & 63) === 0) signal?.throwIfAborted();
|
|
229
234
|
const file = files[index];
|
|
230
|
-
if (
|
|
235
|
+
if (!pattern.test(file.path)) continue;
|
|
231
236
|
const data = await container.readFile(file.path);
|
|
232
237
|
if (!data) continue;
|
|
233
|
-
|
|
238
|
+
assets.set(file.path, data);
|
|
239
|
+
if (!flattenBasenames) continue;
|
|
234
240
|
const slash = file.path.lastIndexOf("/");
|
|
235
|
-
if (slash !== -1)
|
|
241
|
+
if (slash !== -1) assets.set(file.path.slice(slash + 1), data);
|
|
236
242
|
}
|
|
237
|
-
return
|
|
243
|
+
return assets;
|
|
244
|
+
}
|
|
245
|
+
async function collectContainerImages(container, signal) {
|
|
246
|
+
return collectContainerAssets(container, IMAGE_ASSET_RE, signal);
|
|
247
|
+
}
|
|
248
|
+
function dataReferenceWarnings(doc, formatLabel) {
|
|
249
|
+
const srcs = /* @__PURE__ */ new Set();
|
|
250
|
+
const visit = (blocks) => {
|
|
251
|
+
for (const block of blocks) {
|
|
252
|
+
const src = block.templateOverrides?.src;
|
|
253
|
+
if (src && isDataFilePath(src)) srcs.add(src);
|
|
254
|
+
if (block.children) visit(block.children);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
visit(doc.blocks);
|
|
258
|
+
return [...srcs].map(
|
|
259
|
+
(src) => `${formatLabel} cannot embed the data sidecar "${src}"; the export carries its bounded preview and the link will not resolve outside the source container.`
|
|
260
|
+
);
|
|
238
261
|
}
|
|
239
262
|
async function collectContainerDocxImages(container, signal) {
|
|
240
263
|
const images = await collectContainerImages(container, signal);
|
|
241
|
-
const { extToMime } = await import("./images-
|
|
264
|
+
const { extToMime } = await import("./images-JLBFCDD4.js");
|
|
242
265
|
return new Map(
|
|
243
266
|
[...images].map(([path, data]) => [
|
|
244
267
|
path,
|
|
@@ -418,17 +441,29 @@ function defaultFormats() {
|
|
|
418
441
|
label: "Excel (XLSX)",
|
|
419
442
|
mimeType: MIME.xlsx,
|
|
420
443
|
extensions: [".xlsx"],
|
|
444
|
+
async importContainer(data, options) {
|
|
445
|
+
const { xlsxToContainer } = await import("./xlsx/index.js");
|
|
446
|
+
return xlsxToContainer(data, optionsFor(options, "xlsx"));
|
|
447
|
+
},
|
|
421
448
|
async importDoc(data, options) {
|
|
422
449
|
const { xlsxToMarkdownDoc } = await import("./xlsx/index.js");
|
|
423
450
|
return xlsxToMarkdownDoc(data, optionsFor(options, "xlsx"));
|
|
424
451
|
},
|
|
425
452
|
async exportDoc(input, options) {
|
|
426
453
|
const { markdownDocToXlsx } = await import("./xlsx/index.js");
|
|
427
|
-
const
|
|
454
|
+
const { materializeDataReferences } = await import("./materialize-A34OZGEU.js");
|
|
455
|
+
const warnings = [];
|
|
456
|
+
const markdownDoc = await materializeDataReferences(
|
|
457
|
+
await markdownOf(input),
|
|
458
|
+
input.container,
|
|
459
|
+
(message) => warnings.push(message)
|
|
460
|
+
);
|
|
428
461
|
const omitted = markdownDoc.children.filter(
|
|
429
462
|
(n) => n.type !== "table" && n.type !== "heading"
|
|
430
463
|
).length;
|
|
431
|
-
|
|
464
|
+
if (omitted > 0) {
|
|
465
|
+
warnings.push(`XLSX export is tables-only; ${omitted} non-table block(s) were omitted.`);
|
|
466
|
+
}
|
|
432
467
|
const blob = await markdownDocToXlsx(markdownDoc, {
|
|
433
468
|
...optionsFor(options, "xlsx"),
|
|
434
469
|
...options.title !== void 0 ? { title: options.title } : {},
|
|
@@ -445,6 +480,10 @@ function defaultFormats() {
|
|
|
445
480
|
label: "CSV",
|
|
446
481
|
mimeType: MIME.csv,
|
|
447
482
|
extensions: [".csv"],
|
|
483
|
+
async importContainer(data, options) {
|
|
484
|
+
const { csvToContainer } = await import("./csv/index.js");
|
|
485
|
+
return csvToContainer(data, optionsFor(options, "csv"));
|
|
486
|
+
},
|
|
448
487
|
async importDoc(data, options) {
|
|
449
488
|
const { csvToMarkdownDoc } = await import("./csv/index.js");
|
|
450
489
|
return csvToMarkdownDoc(data, optionsFor(options, "csv"));
|
|
@@ -503,7 +542,11 @@ function defaultFormats() {
|
|
|
503
542
|
themeId: resolveThemeId(input, options),
|
|
504
543
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry
|
|
505
544
|
});
|
|
506
|
-
return ok(
|
|
545
|
+
return ok(
|
|
546
|
+
new TextEncoder().encode(htmlText),
|
|
547
|
+
MIME.html,
|
|
548
|
+
dataReferenceWarnings(input.doc, "Single-file HTML")
|
|
549
|
+
);
|
|
507
550
|
}
|
|
508
551
|
};
|
|
509
552
|
const htmlzip = {
|
|
@@ -517,7 +560,13 @@ function defaultFormats() {
|
|
|
517
560
|
const { docToHtmlZip } = await import("./html/index.js");
|
|
518
561
|
const raw = optionsFor(options, "htmlzip");
|
|
519
562
|
const containerImages = await collectContainerImages(input.container, options.signal);
|
|
520
|
-
const
|
|
563
|
+
const containerData = await collectContainerAssets(
|
|
564
|
+
input.container,
|
|
565
|
+
DATA_ASSET_RE,
|
|
566
|
+
options.signal,
|
|
567
|
+
false
|
|
568
|
+
);
|
|
569
|
+
const images = new Map([...containerImages, ...containerData, ...raw.images ?? /* @__PURE__ */ new Map()]);
|
|
521
570
|
const blob = await docToHtmlZip(input.doc, {
|
|
522
571
|
...raw,
|
|
523
572
|
playerScript,
|
|
@@ -549,7 +598,10 @@ function defaultFormats() {
|
|
|
549
598
|
themeRegistry: options.themeRegistry ?? raw.themeRegistry,
|
|
550
599
|
images
|
|
551
600
|
});
|
|
552
|
-
return ok(await toBytes(buf), MIME.epub,
|
|
601
|
+
return ok(await toBytes(buf), MIME.epub, [
|
|
602
|
+
...markdownFidelityWarnings(markdownDoc, "epub"),
|
|
603
|
+
...dataReferenceWarnings(input.doc, "EPUB")
|
|
604
|
+
]);
|
|
553
605
|
}
|
|
554
606
|
};
|
|
555
607
|
const dbk = {
|