@bendyline/squisq-formats 2.5.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/NOTICE.md +10 -9
  2. package/dist/{chunk-2LT3JL7U.js → chunk-3ITGQRL5.js} +8 -8
  3. package/dist/{chunk-FMQWNPCV.js → chunk-AGGNLRHV.js} +6 -6
  4. package/dist/{chunk-AONELFLA.js → chunk-B7GEAZBI.js} +6 -1
  5. package/dist/chunk-CKSTGNVZ.js +724 -0
  6. package/dist/chunk-DXYWKZ52.js +57 -0
  7. package/dist/{chunk-T4PX33AG.js → chunk-EEDQRZ2M.js} +17 -1
  8. package/dist/chunk-FLR2ARKC.js +240 -0
  9. package/dist/{chunk-5JQ5NDRC.js → chunk-GRKQTQOF.js} +64 -12
  10. package/dist/{chunk-RX55T5HO.js → chunk-OBADJV7C.js} +136 -415
  11. package/dist/{chunk-AD2WT564.js → chunk-Q77KNJIN.js} +45 -0
  12. package/dist/{chunk-TVUX3RUC.js → chunk-VDTGQ4MW.js} +1 -1
  13. package/dist/{chunk-6RQOV3B3.js → chunk-VPWPEMZJ.js} +1 -1
  14. package/dist/{chunk-FIOSE4BO.js → chunk-XJNOZTAY.js} +6 -6
  15. package/dist/csv/index.d.ts +67 -1
  16. package/dist/csv/index.js +10 -3
  17. package/dist/data/index.d.ts +78 -0
  18. package/dist/data/index.js +30 -0
  19. package/dist/docx/index.js +3 -3
  20. package/dist/epub/index.js +4 -4
  21. package/dist/{export-Boq78GMq.d.ts → export-6iQXd-lQ.d.ts} +98 -2
  22. package/dist/html/index.d.ts +2 -8
  23. package/dist/html/index.js +3 -3
  24. package/dist/{images-ESPQKVTW.js → images-JLBFCDD4.js} +1 -1
  25. package/dist/{import-B0gBYUmd.d.ts → import-C7c9tQHK.d.ts} +5 -2
  26. package/dist/index.d.ts +3 -3
  27. package/dist/index.js +29 -26
  28. package/dist/infer/index.js +6 -6
  29. package/dist/materialize-A34OZGEU.js +11 -0
  30. package/dist/outside-in/index.d.ts +3 -3
  31. package/dist/outside-in/index.js +2 -2
  32. package/dist/pdf/index.js +2 -2
  33. package/dist/pptx/index.js +3 -3
  34. package/dist/registry/index.d.ts +4 -4
  35. package/dist/registry/index.js +1 -1
  36. package/dist/{types-bwP9PBSk.d.ts → types-Dzd_5H2A.d.ts} +5 -5
  37. package/dist/xlsx/index.d.ts +85 -4
  38. package/dist/xlsx/index.js +21 -4
  39. package/package.json +17 -2
  40. package/dist/{chunk-KMBBO5H7.js → chunk-7DQP2I57.js} +4 -4
  41. package/dist/{chunk-M7XPXGXW.js → chunk-ROF7SSQP.js} +3 -3
@@ -1,8 +1,19 @@
1
+ import {
2
+ planDataSidecar,
3
+ sidecarReferenceDoc
4
+ } from "./chunk-DXYWKZ52.js";
5
+
1
6
  // src/csv/index.ts
2
7
  import { markdownToDoc } from "@bendyline/squisq/doc";
8
+ import { stringifyMarkdown } from "@bendyline/squisq/markdown";
9
+ import { MemoryContentContainer } from "@bendyline/squisq/storage";
3
10
  var DEFAULT_MAX_CSV_CELLS = 1e5;
4
11
  var DEFAULT_MAX_CSV_ROWS = 1e4;
5
12
  var DEFAULT_MAX_CSV_FIELD_CHARS = 1024 * 1024;
13
+ var SIDECAR_CSV_LIMITS = Object.freeze({
14
+ maxCells: 2e7,
15
+ maxRows: 2e6
16
+ });
6
17
  async function toText(data) {
7
18
  if (typeof data === "string") return data;
8
19
  if (typeof Blob !== "undefined" && data instanceof Blob) return data.text();
@@ -122,6 +133,37 @@ async function csvToMarkdownDoc(data, options = {}) {
122
133
  async function csvToDoc(data, options = {}) {
123
134
  return markdownToDoc(await csvToMarkdownDoc(data, options));
124
135
  }
136
+ async function csvToContainer(data, options = {}) {
137
+ const plan = planDataSidecar(options.sourceName, "data.csv");
138
+ const mode = options.sidecar ?? "auto";
139
+ const text = (await toText(data)).replace(/^\uFEFF/, "");
140
+ const maxInlineRows = options.maxInlineRows ?? 100;
141
+ const maxInlineBytes = options.maxInlineBytes ?? 256 * 1024;
142
+ const originalBytes = typeof data === "string" ? new TextEncoder().encode(data).buffer : data instanceof Blob ? await data.arrayBuffer() : data;
143
+ let spillNeeded = mode === "always";
144
+ if (!spillNeeded && mode === "auto") {
145
+ const hasHeader = options.hasHeader ?? true;
146
+ const lineCount = (text.match(/\n/g) ?? []).length + (text.endsWith("\n") || !text ? 0 : 1);
147
+ const dataRows = Math.max(lineCount - (hasHeader ? 1 : 0), 0);
148
+ spillNeeded = originalBytes.byteLength > maxInlineBytes || dataRows > maxInlineRows;
149
+ }
150
+ const markdownDoc = spillNeeded ? sidecarReferenceDoc(plan) : await csvToMarkdownDoc(text, options);
151
+ const container = new MemoryContentContainer();
152
+ await container.writeDocument(stringifyMarkdown(markdownDoc), plan.markdownFilename);
153
+ if (spillNeeded) {
154
+ await container.writeFile(plan.sidecarPath, originalBytes, "text/csv");
155
+ }
156
+ return container;
157
+ }
158
+ function serializeCsvRows(rows, options = {}) {
159
+ const delimiter = validateDelimiter(options.delimiter ?? ",");
160
+ const newline = options.newline ?? "\n";
161
+ const handling = options.formulaHandling ?? "preserve";
162
+ const body = rows.map(
163
+ (row) => row.map((cell) => escapeCsvField(neutralizeSpreadsheetFormula(cell, handling), delimiter)).join(delimiter)
164
+ ).join(newline);
165
+ return options.trailingNewline === false ? body : `${body}${newline}`;
166
+ }
125
167
  function escapeCsvField(value, delimiter) {
126
168
  if (value.includes('"') || value.includes(delimiter) || /[\r\n]/.test(value)) {
127
169
  return `"${value.replace(/"/g, '""')}"`;
@@ -166,8 +208,11 @@ function markdownDocToCsv(doc, options = {}) {
166
208
  }
167
209
 
168
210
  export {
211
+ SIDECAR_CSV_LIMITS,
169
212
  parseCsv,
170
213
  csvToMarkdownDoc,
171
214
  csvToDoc,
215
+ csvToContainer,
216
+ serializeCsvRows,
172
217
  markdownDocToCsv
173
218
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  convert,
3
3
  defaultRegistry
4
- } from "./chunk-5JQ5NDRC.js";
4
+ } from "./chunk-GRKQTQOF.js";
5
5
  import {
6
6
  ConversionError
7
7
  } from "./chunk-KXOZMWBS.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  extToMime
3
- } from "./chunk-AONELFLA.js";
3
+ } from "./chunk-B7GEAZBI.js";
4
4
 
5
5
  // src/html/imageUtils.ts
6
6
  function inferMimeType(filename) {
@@ -5,6 +5,9 @@ import {
5
5
  normalizeOoxmlHex,
6
6
  sanitizeOfficeHyperlink
7
7
  } from "./chunk-A6N6IN3I.js";
8
+ import {
9
+ extToMime
10
+ } from "./chunk-B7GEAZBI.js";
8
11
  import {
9
12
  stripHtmlTags
10
13
  } from "./chunk-AVOZAKGP.js";
@@ -47,6 +50,9 @@ import {
47
50
  requireMainPartPath,
48
51
  resolveTarget
49
52
  } from "./chunk-S5PCVMKU.js";
53
+ import {
54
+ renumberFootnotes
55
+ } from "./chunk-BXWNU4T5.js";
50
56
  import {
51
57
  buildContainer
52
58
  } from "./chunk-IIQYS2YH.js";
@@ -56,12 +62,6 @@ import {
56
62
  fontAwesomeGlyph,
57
63
  obfuscateDocxFont
58
64
  } from "./chunk-USU6HTKB.js";
59
- import {
60
- extToMime
61
- } from "./chunk-AONELFLA.js";
62
- import {
63
- renumberFootnotes
64
- } from "./chunk-BXWNU4T5.js";
65
65
 
66
66
  // src/docx/export.ts
67
67
  import { resolveFontFamily } from "@bendyline/squisq/schemas";
@@ -1,5 +1,6 @@
1
1
  import { MarkdownDocument } from '@bendyline/squisq/markdown';
2
2
  import { Doc } from '@bendyline/squisq/schemas';
3
+ import { ContentContainer } from '@bendyline/squisq/storage';
3
4
 
4
5
  /**
5
6
  * @bendyline/squisq-formats CSV Module
@@ -28,6 +29,27 @@ interface CsvImportOptions {
28
29
  maxFieldChars?: number;
29
30
  /** Cancel during parsing checkpoints. */
30
31
  signal?: AbortSignal;
32
+ /**
33
+ * Sidecar spill mode — only honored by `csvToContainer`, which can actually
34
+ * write the sidecar file. `'auto'` (default) spills past the inline
35
+ * thresholds; `'always'` always sidecars (the CSV-open-as-document mode:
36
+ * opening a data file means the FILE is the content); `'never'` keeps the
37
+ * inline table (`csvToMarkdownDoc`'s only behavior).
38
+ */
39
+ sidecar?: 'auto' | 'always' | 'never';
40
+ /** Max data rows kept inline before spilling (container import). Default 100. */
41
+ maxInlineRows?: number;
42
+ /** Max source bytes kept inline before spilling (container import). Default 256 KiB. */
43
+ maxInlineBytes?: number;
44
+ }
45
+ /** Options for {@link csvToContainer}. */
46
+ interface CsvContainerOptions extends CsvImportOptions {
47
+ /**
48
+ * Source file name (e.g. `'Q3 Transactions.csv'`) — names the document
49
+ * (`q3-transactions.md`) and the sidecar path
50
+ * (`q3-transactions_files/data/Q3 Transactions.csv`). Default `'data.csv'`.
51
+ */
52
+ sourceName?: string;
31
53
  }
32
54
  interface CsvExportOptions {
33
55
  /** Field delimiter. Default `,`. */
@@ -56,12 +78,56 @@ interface CsvSafetyLimits {
56
78
  maxFieldChars?: number;
57
79
  signal?: AbortSignal;
58
80
  }
81
+ /**
82
+ * Generous caps for the DATA-SIDECAR tier — the grid ingest and the
83
+ * full-body sidecar readers. The conservative `parseCsv` defaults protect
84
+ * the INLINE pipeline (a 100k-cell markdown table can't reparse anyway),
85
+ * but sidecar data exists precisely because it is big: it renders windowed
86
+ * and virtualized, so the ceiling here is the columnar store's ~20M-cell
87
+ * design wall, not the editor debounce. Every sidecar-path caller passes
88
+ * these; without them a 20 MB upload silently dead-ends at the parser cap.
89
+ */
90
+ declare const SIDECAR_CSV_LIMITS: CsvSafetyLimits;
59
91
  /** Parse CSV text into a grid of string cells (RFC 4180: quotes, escaped quotes). */
60
92
  declare function parseCsv(text: string, delimiter?: string, limits?: CsvSafetyLimits): string[][];
61
93
  /** Convert CSV to a MarkdownDocument containing a single table. */
62
94
  declare function csvToMarkdownDoc(data: ArrayBuffer | Blob | string, options?: CsvImportOptions): Promise<MarkdownDocument>;
63
95
  /** Convert CSV to a squisq Doc. */
64
96
  declare function csvToDoc(data: ArrayBuffer | Blob | string, options?: CsvImportOptions): Promise<Doc>;
97
+ /**
98
+ * Import a CSV into a ContentContainer: the markdown document plus, when the
99
+ * data crosses the inline thresholds (or `sidecar: 'always'`), the ORIGINAL
100
+ * bytes as a `<docbasename>_files/data/<name>` sidecar referenced via
101
+ * `{[dataTable src=…]}` with a body link.
102
+ *
103
+ * Below the thresholds the markdown is byte-identical to `csvToMarkdownDoc`'s
104
+ * output and no sidecar is written.
105
+ */
106
+ declare function csvToContainer(data: ArrayBuffer | Blob | string, options?: CsvContainerOptions): Promise<ContentContainer>;
107
+ /** Options for {@link serializeCsvRows}. */
108
+ interface SerializeCsvRowsOptions {
109
+ /** Field delimiter. Default `,`. */
110
+ delimiter?: string;
111
+ /** Line terminator. Default `\n`. */
112
+ newline?: '\r\n' | '\n';
113
+ /** Emit a terminating newline after the last row. Default true. */
114
+ trailingNewline?: boolean;
115
+ /**
116
+ * Formula neutralization. Default **`'preserve'`** — the OPPOSITE of the
117
+ * export default, deliberately: this API re-serializes EXISTING data (the
118
+ * grid's save path), and `SPREADSHEET_FORMULA_PREFIX` matches a leading
119
+ * `-`/`+`, so blanket escaping would corrupt every negative number in a
120
+ * re-saved file. Callers neutralize specific cells themselves (the grid
121
+ * escapes only journal-edited, non-numeric cells).
122
+ */
123
+ formulaHandling?: 'escape' | 'preserve';
124
+ }
125
+ /**
126
+ * Serialize a plain row matrix to CSV text — the write half of `parseCsv`,
127
+ * used by the grid's sidecar save. RFC-4180 quoting via the same escaper
128
+ * the exporter uses.
129
+ */
130
+ declare function serializeCsvRows(rows: readonly (readonly string[])[], options?: SerializeCsvRowsOptions): string;
65
131
  /**
66
132
  * Serialize one table in a MarkdownDocument to CSV text.
67
133
  *
@@ -72,4 +138,4 @@ declare function csvToDoc(data: ArrayBuffer | Blob | string, options?: CsvImport
72
138
  */
73
139
  declare function markdownDocToCsv(doc: MarkdownDocument, options?: CsvExportOptions): string;
74
140
 
75
- export { type CsvExportOptions, type CsvImportOptions, type CsvSafetyLimits, csvToDoc, csvToMarkdownDoc, markdownDocToCsv, parseCsv };
141
+ export { type CsvContainerOptions, type CsvExportOptions, type CsvImportOptions, type CsvSafetyLimits, SIDECAR_CSV_LIMITS, type SerializeCsvRowsOptions, csvToContainer, csvToDoc, csvToMarkdownDoc, markdownDocToCsv, parseCsv, serializeCsvRows };
package/dist/csv/index.js CHANGED
@@ -1,12 +1,19 @@
1
1
  import {
2
+ SIDECAR_CSV_LIMITS,
3
+ csvToContainer,
2
4
  csvToDoc,
3
5
  csvToMarkdownDoc,
4
6
  markdownDocToCsv,
5
- parseCsv
6
- } from "../chunk-AD2WT564.js";
7
+ parseCsv,
8
+ serializeCsvRows
9
+ } from "../chunk-Q77KNJIN.js";
10
+ import "../chunk-DXYWKZ52.js";
7
11
  export {
12
+ SIDECAR_CSV_LIMITS,
13
+ csvToContainer,
8
14
  csvToDoc,
9
15
  csvToMarkdownDoc,
10
16
  markdownDocToCsv,
11
- parseCsv
17
+ parseCsv,
18
+ serializeCsvRows
12
19
  };
@@ -0,0 +1,78 @@
1
+ import { DataSourceReader } from '@bendyline/squisq/doc';
2
+ import { ContentContainer } from '@bendyline/squisq/storage';
3
+ import { MarkdownDocument } from '@bendyline/squisq/markdown';
4
+
5
+ /**
6
+ * Sidecar data readers — the format implementations behind core's
7
+ * `DataSourceReader` seam (`resolveDataReferences`).
8
+ *
9
+ * Core stays parser-free; these readers decode the actual bytes of a
10
+ * `{[dataTable src=…]}` sidecar into the bounded `DataSourceTable` window the
11
+ * projections render. CSV/TSV wrap the RFC-4180 parser, XLSX reuses the
12
+ * import pipeline's typed region detection (`xlsxToTables`), and parquet
13
+ * loads hyparquet lazily so its bytes never reach consumers that don't
14
+ * reference parquet files.
15
+ */
16
+
17
+ declare const csvDataReader: DataSourceReader;
18
+ declare const xlsxDataReader: DataSourceReader;
19
+ declare const parquetDataReader: DataSourceReader;
20
+ /** The full reader set for `resolveDataReferences({ readers })`. */
21
+ declare function defaultDataReaders(): DataSourceReader[];
22
+
23
+ /**
24
+ * Materialize `{[dataTable src=…]}` sidecar references into inline markdown
25
+ * tables — the FULL data, not the bounded preview. Used by exports that
26
+ * embed values (XLSX: a src-referenced block would otherwise contribute no
27
+ * table and silently vanish from the workbook).
28
+ *
29
+ * Never throws: a missing container, unreadable file, or absent reader
30
+ * degrades to an `onWarning` message and the reference block is left as-is
31
+ * (its body link simply doesn't survive a tables-only export).
32
+ */
33
+
34
+ /**
35
+ * 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.
38
+ */
39
+ declare function materializeDataReferences(markdownDoc: MarkdownDocument, container: ContentContainer | null | undefined, onWarning?: (message: string) => void): Promise<MarkdownDocument>;
40
+
41
+ /**
42
+ * Sidecar naming shared by the spill-capable importers (`xlsxToContainer`,
43
+ * `csvToContainer`): one place decides the document filename and the
44
+ * `<docbasename>_files/data/<file>` path a spilled reference points at, so
45
+ * the markdown `src` param and the container write can never disagree.
46
+ */
47
+
48
+ /** Strip any path components from a user-supplied source file name. */
49
+ declare function sanitizeSourceFileName(name: string | undefined, fallback: string): string;
50
+ /**
51
+ * Doc basename slug for a source file name — the outside-in `slugStem`
52
+ * rules (NFKD, strip marks, lowercase, non-alphanumeric → `-`), applied to
53
+ * the name without its extension. `'Q3 Report.xlsx'` → `'q3-report'`.
54
+ */
55
+ declare function docSlugForFileName(fileName: string): string;
56
+ /** Where a spill-capable import writes its document and sidecar. */
57
+ interface DataSidecarPlan {
58
+ /** Doc basename slug, e.g. `'q3-report'`. */
59
+ slug: string;
60
+ /** Document filename inside the container, e.g. `'q3-report.md'`. */
61
+ markdownFilename: string;
62
+ /** Sidecar file name (source name, path components stripped). */
63
+ fileName: string;
64
+ /** Container path the `src` param references, e.g. `'q3-report_files/data/Q3 Report.xlsx'`. */
65
+ sidecarPath: string;
66
+ }
67
+ declare function planDataSidecar(sourceName: string | undefined, fallbackName: string): DataSidecarPlan;
68
+ /**
69
+ * The reference block a fully-sidecarred data file becomes: an annotated
70
+ * heading (`# <title> {[dataTable src=…]}`) plus the graceful-degradation
71
+ * body link. Built as an AST so annotation quoting and link escaping go
72
+ * through the one stringifier that knows the rules.
73
+ */
74
+ declare function sidecarReferenceDoc(plan: DataSidecarPlan): MarkdownDocument;
75
+ /** {@link sidecarReferenceDoc} as serialized markdown source. */
76
+ declare function sidecarReferenceMarkdown(plan: DataSidecarPlan): string;
77
+
78
+ export { type DataSidecarPlan, csvDataReader, defaultDataReaders, docSlugForFileName, materializeDataReferences, parquetDataReader, planDataSidecar, sanitizeSourceFileName, sidecarReferenceDoc, sidecarReferenceMarkdown, xlsxDataReader };
@@ -0,0 +1,30 @@
1
+ import {
2
+ csvDataReader,
3
+ defaultDataReaders,
4
+ materializeDataReferences,
5
+ parquetDataReader,
6
+ xlsxDataReader
7
+ } from "../chunk-FLR2ARKC.js";
8
+ import "../chunk-OBADJV7C.js";
9
+ import "../chunk-Q77KNJIN.js";
10
+ import {
11
+ docSlugForFileName,
12
+ planDataSidecar,
13
+ sanitizeSourceFileName,
14
+ sidecarReferenceDoc,
15
+ sidecarReferenceMarkdown
16
+ } from "../chunk-DXYWKZ52.js";
17
+ import "../chunk-S5PCVMKU.js";
18
+ import "../chunk-7AWFHP5U.js";
19
+ export {
20
+ csvDataReader,
21
+ defaultDataReaders,
22
+ docSlugForFileName,
23
+ materializeDataReferences,
24
+ parquetDataReader,
25
+ planDataSidecar,
26
+ sanitizeSourceFileName,
27
+ sidecarReferenceDoc,
28
+ sidecarReferenceMarkdown,
29
+ xlsxDataReader
30
+ };
@@ -4,17 +4,17 @@ import {
4
4
  docxToDoc,
5
5
  docxToMarkdownDoc,
6
6
  markdownDocToDocx
7
- } from "../chunk-FIOSE4BO.js";
7
+ } from "../chunk-XJNOZTAY.js";
8
8
  import "../chunk-A6N6IN3I.js";
9
+ import "../chunk-B7GEAZBI.js";
9
10
  import "../chunk-AVOZAKGP.js";
10
11
  import "../chunk-ILCJ3WFD.js";
11
12
  import "../chunk-JU2RHXUB.js";
12
13
  import "../chunk-S5PCVMKU.js";
13
14
  import "../chunk-7AWFHP5U.js";
15
+ import "../chunk-BXWNU4T5.js";
14
16
  import "../chunk-IIQYS2YH.js";
15
17
  import "../chunk-USU6HTKB.js";
16
- import "../chunk-AONELFLA.js";
17
- import "../chunk-BXWNU4T5.js";
18
18
  export {
19
19
  docToDocx,
20
20
  docxToContainer,
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  docToEpub,
3
3
  markdownDocToEpub
4
- } from "../chunk-2LT3JL7U.js";
4
+ } from "../chunk-3ITGQRL5.js";
5
+ import "../chunk-VPWPEMZJ.js";
6
+ import "../chunk-B7GEAZBI.js";
5
7
  import "../chunk-AVOZAKGP.js";
6
8
  import "../chunk-JU2RHXUB.js";
7
- import "../chunk-USU6HTKB.js";
8
- import "../chunk-6RQOV3B3.js";
9
- import "../chunk-AONELFLA.js";
10
9
  import "../chunk-BXWNU4T5.js";
10
+ import "../chunk-USU6HTKB.js";
11
11
  export {
12
12
  docToEpub,
13
13
  markdownDocToEpub
@@ -1,5 +1,6 @@
1
1
  import { MarkdownInlineNode, MarkdownDocument } from '@bendyline/squisq/markdown';
2
- import { O as OoxmlOpenOptions } from './reader-B_m1aKZC.js';
2
+ import { O as OoxmlOpenOptions, a as OoxmlPackage } from './reader-B_m1aKZC.js';
3
+ import { ContentContainer } from '@bendyline/squisq/storage';
3
4
  import { Doc } from '@bendyline/squisq/schemas';
4
5
 
5
6
  /**
@@ -38,6 +39,14 @@ interface XlsxCell {
38
39
  * cell reads this, and only when it is present.
39
40
  */
40
41
  richText?: MarkdownInlineNode[];
42
+ /**
43
+ * Set when the cell participates in a shared (fill-down) formula group:
44
+ * `'master'` holds the group's text, `'follower'` inherits by translation.
45
+ * Consumers that EDIT formulas need this — the in-place patcher refuses
46
+ * to replace a master (its followers' `si` would dangle) while a
47
+ * follower may safely leave its group.
48
+ */
49
+ sharedFormulaRole?: 'master' | 'follower';
41
50
  /**
42
51
  * The cell's value as the sheet stores it, before number formatting.
43
52
  *
@@ -64,6 +73,21 @@ interface CellRect {
64
73
  bottom: number;
65
74
  right: number;
66
75
  }
76
+ /** A parsed cell address. */
77
+ interface ParsedCellRef {
78
+ row: number;
79
+ col: number;
80
+ }
81
+ /**
82
+ * Parse a full cell ref into zero-based coordinates, rejecting anything that
83
+ * is not a plain in-range A1 address. `$` anchors are accepted and ignored —
84
+ * an anchor says how a ref behaves when copied, not where it points.
85
+ *
86
+ * Returns null for a malformed ref, a ref past `XFD1048576`, or a range.
87
+ */
88
+ declare function parseCellRef(ref: string): ParsedCellRef | null;
89
+ /** Format zero-based coordinates as a cell ref (`0, 1` → `"B1"`). */
90
+ declare function formatCellRef(row: number, col: number): string;
67
91
 
68
92
  /**
69
93
  * XLSX → typed tables, for consumers reading a workbook as **data**.
@@ -179,7 +203,38 @@ interface XlsxImportOptions extends OoxmlOpenOptions {
179
203
  maxRegionsPerSheet?: number;
180
204
  /** Smallest island that stays a table of its own. Default 2 — single cells coalesce. */
181
205
  minRegionCells?: number;
206
+ /**
207
+ * Sidecar spill mode — only honored by `xlsxToContainer`, which can actually
208
+ * write the sidecar file the reference points at. `'auto'` (default) spills a
209
+ * region past the inline thresholds to a `{[dataTable src=…]}` reference;
210
+ * `'always'` spills every region; `'never'` keeps everything inline
211
+ * (`xlsxToMarkdownDoc`'s only behavior — a doc-only import has nowhere to
212
+ * put the bytes, and a `src` with no sidecar is a broken reference).
213
+ */
214
+ sidecar?: 'auto' | 'always' | 'never';
215
+ /** Max data rows a region keeps inline before spilling (container import). Default 100. */
216
+ maxInlineRows?: number;
217
+ /** Max cells a region keeps inline before spilling (container import). Default 2000. */
218
+ maxInlineCells?: number;
219
+ }
220
+ /** Options for {@link xlsxToContainer}. */
221
+ interface XlsxContainerOptions extends XlsxImportOptions {
222
+ /**
223
+ * Source file name (e.g. `'Q3 Report.xlsx'`) — names the document
224
+ * (`q3-report.md`) and the sidecar path
225
+ * (`q3-report_files/data/Q3 Report.xlsx`). Default `'workbook.xlsx'`.
226
+ */
227
+ sourceName?: string;
228
+ }
229
+ interface SheetRef {
230
+ name: string;
231
+ path: string;
182
232
  }
233
+ /**
234
+ * List the workbook's sheets — name plus resolved worksheet part path, in
235
+ * workbook order. Shared by import and the in-place cell patcher.
236
+ */
237
+ declare function listSheetParts(pkg: OoxmlPackage, mainPart: string): Promise<SheetRef[]>;
183
238
  /**
184
239
  * Read a workbook as typed tables rather than as a document.
185
240
  *
@@ -189,7 +244,48 @@ interface XlsxImportOptions extends OoxmlOpenOptions {
189
244
  * number format.
190
245
  */
191
246
  declare function xlsxToTables(data: ArrayBuffer | Blob, options?: XlsxImportOptions & XlsxTablesOptions): Promise<XlsxTable[]>;
247
+ /** One worksheet's raw cell grid, as parsed (formulas + cached values intact). */
248
+ interface XlsxSheetGrid {
249
+ name: string;
250
+ /** Row-major grid; rows may be ragged. Each cell keeps `formula` AND `value`. */
251
+ cells: XlsxCell[][];
252
+ merges: CellRect[];
253
+ }
254
+ /** A workbook as raw cell grids, plus the workbook-level calc facts. */
255
+ interface XlsxWorkbookGrids {
256
+ sheets: XlsxSheetGrid[];
257
+ date1904: boolean;
258
+ /**
259
+ * `<calcPr fullCalcOnLoad="1"/>`: the producer disowned its cached formula
260
+ * values. A cached-value oracle must skip such workbooks, and a consumer
261
+ * re-hosting the formulas in a calculation engine should recompute rather
262
+ * than trust `value`.
263
+ */
264
+ fullCalcOnLoad: boolean;
265
+ }
266
+ /**
267
+ * Read a workbook as raw cell grids — the lowest-level public view.
268
+ *
269
+ * Unlike {@link xlsxToTables} (typed regions, formulas dropped) and
270
+ * {@link xlsxToMarkdownDoc} (rendered for people), this hands over every
271
+ * parsed cell with its formula and cached value colocated. Two consumers:
272
+ * the corpus cached-value oracle (compare `formula` results against `value`)
273
+ * and calculation-engine feeding (`setUserInput`-style APIs need the raw
274
+ * grid, not a detected region).
275
+ */
276
+ declare function xlsxToCellGrids(data: ArrayBuffer | Blob, options?: XlsxImportOptions): Promise<XlsxWorkbookGrids>;
192
277
  declare function xlsxToMarkdownDoc(data: ArrayBuffer | Blob, options?: XlsxImportOptions): Promise<MarkdownDocument>;
278
+ /**
279
+ * Import a workbook into a ContentContainer: the markdown document plus, when
280
+ * a region crossed the inline thresholds (or `sidecar: 'always'`), the
281
+ * ORIGINAL workbook bytes as a `<docbasename>_files/data/<name>` sidecar that
282
+ * spilled regions reference via `{[dataTable src=… sheet=… anchor=…]}`.
283
+ *
284
+ * Small regions emit byte-identically to `xlsxToMarkdownDoc` — the historical
285
+ * round-trip contract is untouched below the thresholds, and with
286
+ * `sidecar: 'never'` the container is just the doc-only import in a box.
287
+ */
288
+ declare function xlsxToContainer(data: ArrayBuffer | Blob, options?: XlsxContainerOptions): Promise<ContentContainer>;
193
289
 
194
290
  /**
195
291
  * XLSX export — MarkdownDocument → SpreadsheetML (.xlsx).
@@ -267,4 +363,4 @@ declare function markdownDocToXlsx(doc: MarkdownDocument, options?: XlsxExportOp
267
363
  */
268
364
  declare function docToXlsx(doc: Doc, options?: XlsxExportOptions): Promise<ArrayBuffer>;
269
365
 
270
- export { type XlsxExportOptions as X, type XlsxImportOptions as a, type XlsxTable as b, type XlsxTableColumn as c, type XlsxTablesOptions as d, docToXlsx as e, xlsxToTables as f, gridToTables as g, markdownDocToXlsx as m, xlsxToMarkdownDoc as x };
366
+ export { type CellRect as C, type SheetRef as S, type XlsxExportOptions as X, type XlsxImportOptions as a, type XlsxTable as b, type XlsxTableColumn as c, type XlsxTablesOptions as d, docToXlsx as e, xlsxToTables as f, gridToTables as g, type XlsxCell as h, type XlsxCellKind as i, type XlsxContainerOptions as j, type XlsxSheetGrid as k, type XlsxWorkbookGrids as l, markdownDocToXlsx as m, formatCellRef as n, listSheetParts as o, parseCellRef as p, xlsxToCellGrids as q, xlsxToContainer as r, xlsxToMarkdownDoc as x };
@@ -1,6 +1,6 @@
1
1
  import { Theme, ThemeRegistry, Doc } from '@bendyline/squisq/schemas';
2
- import { H as HtmlExportOptions } from '../import-B0gBYUmd.js';
3
- export { a as HtmlImportOptions, c as collectImagePaths, g as generateExternalHtml, h as htmlToMarkdown, b as htmlToMarkdownDoc, d as htmlToMarkdownDocSync } from '../import-B0gBYUmd.js';
2
+ import { H as HtmlExportOptions } from '../import-C7c9tQHK.js';
3
+ export { a as HtmlImportOptions, c as collectImagePaths, g as generateExternalHtml, h as htmlToMarkdown, b as htmlToMarkdownDoc, d as htmlToMarkdownDocSync } from '../import-C7c9tQHK.js';
4
4
  import { HtmlPolicy, MarkdownDocument } from '@bendyline/squisq/markdown';
5
5
 
6
6
  /**
@@ -183,12 +183,6 @@ interface PlainHtmlBundleOptions {
183
183
  * references rewritten from `.md` to `.html`.
184
184
  */
185
185
  declare function markdownDocsToPlainHtmlBundle(options: PlainHtmlBundleOptions): Promise<Blob>;
186
- /**
187
- * Collect every `<a>`-style link URL referenced in a document. Markdown
188
- * `link` nodes plus any raw HTML `<a href>` tags. Returns the raw URLs
189
- * as authored, so callers can use them as both the linkMap *key* and
190
- * the basis for resolution.
191
- */
192
186
  declare function collectLinkRefs(doc: MarkdownDocument): Set<string>;
193
187
 
194
188
  /**
@@ -10,13 +10,13 @@ import {
10
10
  markdownDocToPlainHtml,
11
11
  markdownDocsToHtmlBundle,
12
12
  markdownDocsToPlainHtmlBundle
13
- } from "../chunk-T4PX33AG.js";
13
+ } from "../chunk-EEDQRZ2M.js";
14
14
  import {
15
15
  arrayBufferToBase64DataUrl,
16
16
  extractFilename,
17
17
  inferMimeType
18
- } from "../chunk-6RQOV3B3.js";
19
- import "../chunk-AONELFLA.js";
18
+ } from "../chunk-VPWPEMZJ.js";
19
+ import "../chunk-B7GEAZBI.js";
20
20
  import "../chunk-BXWNU4T5.js";
21
21
  export {
22
22
  arrayBufferToBase64DataUrl,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  extToMime
3
- } from "./chunk-AONELFLA.js";
3
+ } from "./chunk-B7GEAZBI.js";
4
4
  export {
5
5
  extToMime
6
6
  };
@@ -41,8 +41,11 @@ interface HtmlExportOptions {
41
41
  * Only used in ZIP exports — single HTML uses timer-based playback.
42
42
  */
43
43
  audio?: Map<string, ArrayBuffer>;
44
- /** Rendering mode: 'slideshow' (interactive, default) or 'static' (scrollable) */
45
- mode?: 'slideshow' | 'static';
44
+ /**
45
+ * Rendering mode: 'slideshow' (interactive, default), 'video' (timed
46
+ * auto-advance movie playback), or 'static' (scrollable).
47
+ */
48
+ mode?: 'slideshow' | 'video' | 'static';
46
49
  /** HTML page title (default: 'Squisq Document') */
47
50
  title?: string;
48
51
  /** Auto-play slideshow on load (default: false) */
package/dist/index.d.ts CHANGED
@@ -6,13 +6,13 @@ export { PdfExportOptions, PdfImportOptions, configurePdfWorker, docToPdf, markd
6
6
  export { HtmlZipExportOptions, docToHtml, docToHtmlZip } from './html/index.js';
7
7
  export { EpubExportOptions, docToEpub, markdownDocToEpub } from './epub/index.js';
8
8
  export { ExtractedFileTheme, InferSourceFormat, InferThemeOptions, InferredFileTheme, compileExtractedTheme, inferThemeFromFile } from './infer/index.js';
9
- export { B as BUILTIN_FORMAT_IDS, a as BuiltinFormatOptions, C as ConversionLimits, b as ConversionResult, c as ConvertOptions, d as ConvertSource, D as DEFAULT_CONVERSION_LIMITS, e as DbkFormatOptions, F as FormatDefinition, f as FormatId, g as FormatRegistry, M as MarkdownFormatOptions, N as NormalizedInput, P as PreparedConversion, h as PreparedExportOptions, r as resolveConversionLimits } from './types-bwP9PBSk.js';
9
+ export { B as BUILTIN_FORMAT_IDS, a as BuiltinFormatOptions, C as ConversionLimits, b as ConversionResult, c as ConvertOptions, d as ConvertSource, D as DEFAULT_CONVERSION_LIMITS, e as DbkFormatOptions, F as FormatDefinition, f as FormatId, g as FormatRegistry, M as MarkdownFormatOptions, N as NormalizedInput, P as PreparedConversion, h as PreparedExportOptions, r as resolveConversionLimits } from './types-Dzd_5H2A.js';
10
10
  export { ConversionError, ConversionErrorCode, ConversionErrorOptions, convert, createRegistry, defaultFormats, defaultRegistry, prepareConversion } from './registry/index.js';
11
11
  export { ImportedOutsideInDocument, OUTSIDE_IN_FORMAT_IDS, OUTSIDE_IN_UPDATE_FROM_MARKDOWN_KEY, OutsideInFormatId, OutsideInLayout, OutsideInMetadata, RenderOutsideInOptions, chooseOutsideInMarkdownPath, importOutsideInDocument, isOutsideInMarkdownEditingEnabled, isOutsideInTargetPath, readOutsideInMetadata, renderOutsideInDocument, resolveOutsideInLayout, withOutsideInMarkdownEditing, withOutsideInMetadata } from './outside-in/index.js';
12
12
  export { Z as ZipSafetyError, a as ZipSafetyErrorCode, b as ZipSafetyErrorOptions, c as ZipSafetyLimits } from './zipLimits-BOKCB7qk.js';
13
- export { H as HtmlExportOptions, a as HtmlImportOptions, c as collectImagePaths, h as htmlToMarkdown, b as htmlToMarkdownDoc, d as htmlToMarkdownDocSync } from './import-B0gBYUmd.js';
13
+ export { H as HtmlExportOptions, a as HtmlImportOptions, c as collectImagePaths, h as htmlToMarkdown, b as htmlToMarkdownDoc, d as htmlToMarkdownDocSync } from './import-C7c9tQHK.js';
14
14
  export { P as PptxExportOptions, a as PptxImportOptions, d as docToPptx, m as markdownDocToPptx, p as pptxToMarkdownDoc } from './import-C16E8Y4X.js';
15
- export { X as XlsxExportOptions, a as XlsxImportOptions, b as XlsxTable, c as XlsxTableColumn, d as XlsxTablesOptions, e as docToXlsx, g as gridToTables, m as markdownDocToXlsx, x as xlsxToMarkdownDoc, f as xlsxToTables } from './export-Boq78GMq.js';
15
+ export { X as XlsxExportOptions, a as XlsxImportOptions, b as XlsxTable, c as XlsxTableColumn, d as XlsxTablesOptions, e as docToXlsx, g as gridToTables, m as markdownDocToXlsx, x as xlsxToMarkdownDoc, f as xlsxToTables } from './export-6iQXd-lQ.js';
16
16
  import '@bendyline/squisq/schemas';
17
17
  import '@bendyline/squisq/markdown';
18
18
  import './reader-B_m1aKZC.js';