@bendyline/squisq-formats 1.3.1 → 1.4.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.
Files changed (107) hide show
  1. package/README.md +180 -43
  2. package/dist/{chunk-33YRFXZZ.js → chunk-46FMDOWZ.js} +260 -14
  3. package/dist/chunk-46FMDOWZ.js.map +1 -0
  4. package/dist/{chunk-ERZ627GR.js → chunk-5LSSWZPU.js} +12 -27
  5. package/dist/chunk-5LSSWZPU.js.map +1 -0
  6. package/dist/chunk-6M7Z25LA.js +46 -0
  7. package/dist/chunk-6M7Z25LA.js.map +1 -0
  8. package/dist/{chunk-S3Y7H2BK.js → chunk-D7IFPWNZ.js} +95 -50
  9. package/dist/chunk-D7IFPWNZ.js.map +1 -0
  10. package/dist/chunk-DQAZR57U.js +33 -0
  11. package/dist/chunk-DQAZR57U.js.map +1 -0
  12. package/dist/chunk-EHLGMSTE.js +273 -0
  13. package/dist/chunk-EHLGMSTE.js.map +1 -0
  14. package/dist/{chunk-A3FHLTY5.js → chunk-MJGRI6XR.js} +6 -19
  15. package/dist/chunk-MJGRI6XR.js.map +1 -0
  16. package/dist/chunk-PN52A5AA.js +32 -0
  17. package/dist/chunk-PN52A5AA.js.map +1 -0
  18. package/dist/chunk-RFAPOKHJ.js +123 -0
  19. package/dist/chunk-RFAPOKHJ.js.map +1 -0
  20. package/dist/chunk-RTS5XBZ7.js +526 -0
  21. package/dist/chunk-RTS5XBZ7.js.map +1 -0
  22. package/dist/{chunk-7DEUGIOO.js → chunk-SHLPSADL.js} +120 -2
  23. package/dist/chunk-SHLPSADL.js.map +1 -0
  24. package/dist/chunk-SSUPBUF5.js +15 -0
  25. package/dist/chunk-SSUPBUF5.js.map +1 -0
  26. package/dist/{chunk-UDS45KUJ.js → chunk-WWBIKRNP.js} +40 -80
  27. package/dist/chunk-WWBIKRNP.js.map +1 -0
  28. package/dist/{chunk-VN2KEOYB.js → chunk-YESS7VY3.js} +379 -87
  29. package/dist/chunk-YESS7VY3.js.map +1 -0
  30. package/dist/csv/index.d.ts +50 -0
  31. package/dist/csv/index.js +13 -0
  32. package/dist/csv/index.js.map +1 -0
  33. package/dist/docx/index.js +6 -3
  34. package/dist/epub/index.js +4 -2
  35. package/dist/html/index.d.ts +42 -2
  36. package/dist/html/index.js +9 -2
  37. package/dist/index.d.ts +3 -1
  38. package/dist/index.js +47 -14
  39. package/dist/ooxml/index.d.ts +5 -1
  40. package/dist/ooxml/index.js +13 -9
  41. package/dist/pdf/index.js +2 -1
  42. package/dist/pptx/index.d.ts +36 -19
  43. package/dist/pptx/index.js +9 -2
  44. package/dist/registry/index.d.ts +167 -0
  45. package/dist/registry/index.js +17 -0
  46. package/dist/registry/index.js.map +1 -0
  47. package/dist/xlsx/index.d.ts +60 -29
  48. package/dist/xlsx/index.js +4 -1
  49. package/package.json +12 -2
  50. package/src/__tests__/convert.test.ts +186 -0
  51. package/src/__tests__/csvImport.test.ts +84 -0
  52. package/src/__tests__/exportThemeReconciliation.test.ts +87 -0
  53. package/src/__tests__/formatRegistry.test.ts +174 -0
  54. package/src/__tests__/htmlImport.test.ts +57 -0
  55. package/src/__tests__/lossyWarnings.test.ts +105 -0
  56. package/src/__tests__/pdfImport.test.ts +95 -1
  57. package/src/__tests__/plainHtml.test.ts +31 -0
  58. package/src/__tests__/pptxExport.test.ts +138 -0
  59. package/src/__tests__/pptxImport.test.ts +115 -0
  60. package/src/__tests__/roundTripAssets.test.ts +50 -0
  61. package/src/__tests__/roundTripMatrix.fixtures.ts +86 -0
  62. package/src/__tests__/roundTripMatrix.helpers.ts +154 -0
  63. package/src/__tests__/roundTripMatrix.test.ts +142 -0
  64. package/src/__tests__/sharedContainer.test.ts +41 -0
  65. package/src/__tests__/sharedImages.test.ts +61 -0
  66. package/src/__tests__/xlsxExport.test.ts +164 -0
  67. package/src/__tests__/xlsxImport.test.ts +80 -0
  68. package/src/csv/index.ts +188 -0
  69. package/src/docx/export.ts +27 -44
  70. package/src/docx/import.ts +7 -39
  71. package/src/epub/export.ts +10 -27
  72. package/src/html/imageUtils.ts +5 -19
  73. package/src/html/import.ts +297 -0
  74. package/src/html/index.ts +4 -0
  75. package/src/html/plainHtml.ts +66 -16
  76. package/src/index.ts +36 -5
  77. package/src/ooxml/index.ts +3 -0
  78. package/src/ooxml/namespaces.ts +13 -0
  79. package/src/pdf/export.ts +10 -5
  80. package/src/pdf/import.ts +146 -51
  81. package/src/pptx/export.ts +225 -85
  82. package/src/pptx/import.ts +273 -0
  83. package/src/pptx/index.ts +10 -28
  84. package/src/registry/convert.ts +318 -0
  85. package/src/registry/defaultFormats.ts +323 -0
  86. package/src/registry/errors.ts +46 -0
  87. package/src/registry/index.ts +38 -0
  88. package/src/registry/registry.ts +48 -0
  89. package/src/registry/types.ts +107 -0
  90. package/src/shared/container.ts +28 -0
  91. package/src/shared/images.ts +44 -0
  92. package/src/shared/inlineRuns.ts +99 -0
  93. package/src/shared/text.ts +41 -0
  94. package/src/xlsx/export.ts +253 -0
  95. package/src/xlsx/import.ts +159 -0
  96. package/src/xlsx/index.ts +18 -61
  97. package/dist/chunk-33YRFXZZ.js.map +0 -1
  98. package/dist/chunk-67KIJHV2.js +0 -21
  99. package/dist/chunk-67KIJHV2.js.map +0 -1
  100. package/dist/chunk-7DEUGIOO.js.map +0 -1
  101. package/dist/chunk-A3FHLTY5.js.map +0 -1
  102. package/dist/chunk-ERZ627GR.js.map +0 -1
  103. package/dist/chunk-S3Y7H2BK.js.map +0 -1
  104. package/dist/chunk-UDS45KUJ.js.map +0 -1
  105. package/dist/chunk-VN2KEOYB.js.map +0 -1
  106. package/dist/chunk-YN5HFCEW.js +0 -120
  107. package/dist/chunk-YN5HFCEW.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @bendyline/squisq-formats
2
2
 
3
- Document format converters for Squisq. Import and export between Squisq's Markdown-based document model and common file formats — DOCX, PPTX, PDF, and HTML. All converters run entirely in the browser with no server or native binaries required.
3
+ Document format converters for Squisq. Import and export between Squisq's Markdown-based document model and common file formats — DOCX, PDF, HTML, EPUB, PPTX, XLSX, and CSV. All converters run in the browser or Node with no server or native binaries required.
4
4
 
5
5
  Part of the [Squisq](https://github.com/bendyline/squisq) monorepo.
6
6
 
@@ -13,118 +13,255 @@ Part of the [Squisq](https://github.com/bendyline/squisq) monorepo.
13
13
  npm install @bendyline/squisq-formats @bendyline/squisq
14
14
  ```
15
15
 
16
+ ## How Conversion Works
17
+
18
+ All converters use Squisq's `MarkdownDocument` AST (from `@bendyline/squisq/markdown`) as the pivot format:
19
+
20
+ - **Import** parses a file into a `MarkdownDocument`. The `xxxToContainer` variants (DOCX, PDF, PPTX) also extract embedded images into a `ContentContainer` alongside the markdown.
21
+ - **Export** serializes a `MarkdownDocument` out to the target format. Each format also has a `docToXxx` / `xxxToDoc` wrapper that converts through `MarkdownDocument` internally.
22
+
23
+ Conversions preserve document structure and most of the flavor of the source — headings, text formatting, lists, tables, links, images — but they are **not lossless round-trips**. Per-format fidelity limits are listed below.
24
+
25
+ All exports that accept a `themeId` (DOCX, PDF, EPUB, PPTX, plain HTML) apply Squisq theme colors/typography, and fall back to the doc's frontmatter theme (`squisq-theme` / `themeId` / `theme` keys) when the option is omitted.
26
+
27
+ For a uniform, format-agnostic entry point over every converter, use the **format registry** and `convert()` (`@bendyline/squisq-formats/registry`, also re-exported from the root) — see [Programmatic `convert()`](#programmatic-convert) below.
28
+
16
29
  ## Supported Formats
17
30
 
18
- | Format | Import | Export | Theme | Subpath |
19
- | --------------------- | ------- | ------- | ----- | -------------------------------- |
20
- | **DOCX** (Word) | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/docx` |
21
- | **PDF** | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/pdf` |
22
- | **HTML** | | ✅ | ✅ | `@bendyline/squisq-formats/html` |
23
- | **EPUB** (e-book) | — | ✅ | ✅ | `@bendyline/squisq-formats/epub` |
24
- | **PPTX** (PowerPoint) | planned | ✅ | ✅ | `@bendyline/squisq-formats/pptx` |
25
- | **XLSX** (Excel) | planned | planned | — | `@bendyline/squisq-formats/xlsx` |
31
+ | Format | Import | Export | Theme | Subpath |
32
+ | --------------------- | ------ | ------ | ----- | ------------------------------------- |
33
+ | **DOCX** (Word) | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/docx` |
34
+ | **PDF** | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/pdf` |
35
+ | **HTML** | | ✅ | ✅ | `@bendyline/squisq-formats/html` |
36
+ | **EPUB** (e-book) | — | ✅ | ✅ | `@bendyline/squisq-formats/epub` |
37
+ | **PPTX** (PowerPoint) | | ✅ | ✅ | `@bendyline/squisq-formats/pptx` |
38
+ | **XLSX** (Excel) | | ✅¹ | — | `@bendyline/squisq-formats/xlsx` |
39
+ | **CSV** | ✅ | ✅ | — | `@bendyline/squisq-formats/csv` |
40
+ | **Container ZIP** | ✅ | ✅ | — | `@bendyline/squisq-formats/container` |
26
41
 
27
- All export formats accept an optional `themeId` to apply Squisq theme colors and typography.
42
+ ¹ XLSX export is **tables-only** (v1.5) see the [XLSX](#xlsx) section.
28
43
 
29
44
  ## Quick Examples
30
45
 
31
46
  ### DOCX
32
47
 
33
48
  ```ts
34
- import { markdownDocToDocx, docxToMarkdownDoc } from '@bendyline/squisq-formats/docx';
49
+ import {
50
+ markdownDocToDocx,
51
+ docxToMarkdownDoc,
52
+ docxToContainer,
53
+ } from '@bendyline/squisq-formats/docx';
35
54
 
36
- // Export: MarkdownDocument → DOCX (Uint8Array)
37
- const docxBytes = await markdownDocToDocx(markdownDoc);
55
+ // Export: MarkdownDocument → DOCX (ArrayBuffer)
56
+ const docxBytes = await markdownDocToDocx(markdownDoc, { title: 'Report', themeId: 'documentary' });
38
57
 
39
- // Import: DOCX (ArrayBuffer) → MarkdownDocument
40
- const markdownDoc = await docxToMarkdownDoc(docxBuffer);
58
+ // Import: DOCX (ArrayBuffer | Blob) → MarkdownDocument
59
+ const imported = await docxToMarkdownDoc(docxBuffer, { extractImages: true });
60
+
61
+ // Import with assets: DOCX → ContentContainer (markdown + images/ files)
62
+ const container = await docxToContainer(docxBuffer);
41
63
  ```
42
64
 
65
+ **Fidelity:** import covers headings, paragraphs, inline formatting (bold, italic, strikethrough, inline code), hyperlinks, lists, tables, blockquotes, code blocks, footnotes, and embedded images (opt-in via `extractImages`; always on for `docxToContainer`). Export embeds images only when provided via `options.images`; otherwise they appear as placeholder text.
66
+
43
67
  ### PDF
44
68
 
45
69
  ```ts
46
70
  import {
47
71
  markdownDocToPdf,
48
72
  pdfToMarkdownDoc,
73
+ pdfToContainer,
49
74
  configurePdfWorker,
50
75
  } from '@bendyline/squisq-formats/pdf';
51
76
 
52
- // Configure the PDF.js worker (required for import)
77
+ // Configure the PDF.js worker (needed for import in some environments)
53
78
  configurePdfWorker('/pdf.worker.min.mjs');
54
79
 
55
- // Export: MarkdownDocument → PDF (Uint8Array)
56
- const pdfBytes = await markdownDocToPdf(markdownDoc);
80
+ // Export: MarkdownDocument → PDF (ArrayBuffer)
81
+ const pdfBytes = await markdownDocToPdf(markdownDoc, { pageSize: 'a4' });
57
82
 
58
- // Import: PDF (ArrayBuffer) MarkdownDocument
59
- const markdownDoc = await pdfToMarkdownDoc(pdfBuffer);
83
+ // Import: PDF → MarkdownDocument (heuristic structure detection)
84
+ const imported = await pdfToMarkdownDoc(pdfBuffer);
85
+
86
+ // Import with assets: PDF → ContentContainer (markdown + extracted images)
87
+ const container = await pdfToContainer(pdfBuffer);
60
88
  ```
61
89
 
90
+ **Fidelity:** export uses pdf-lib's standard 14 fonts (`themeId` affects colors only). PDF has no semantic structure, so import is heuristic and best-effort: headings are detected by font size, and tables / code blocks / blockquotes / links via the `detectTables` / `detectCodeBlocks` / `detectBlockquotes` / `detectLinks` options (all default true). `pdfToMarkdownDoc` is text-only; `pdfToContainer` also extracts embedded images, placed **by page** — each image is inserted after the last content block from its page (image-only pages fall back to the nearest preceding page with content, else the document end). Placement is page-level only. Image extraction needs a browser canvas to encode PNG — **under Node it is skipped** (with a `console.warn`) and no images are emitted.
91
+
62
92
  ### HTML
63
93
 
64
94
  ```ts
65
- import { docToHtml, docToHtmlZip } from '@bendyline/squisq-formats/html';
95
+ import { PLAYER_BUNDLE } from '@bendyline/squisq-react/standalone-source';
96
+ import {
97
+ docToHtml,
98
+ docToHtmlZip,
99
+ markdownDocToPlainHtml,
100
+ htmlToMarkdownDoc,
101
+ } from '@bendyline/squisq-formats/html';
102
+
103
+ // Interactive player export: Doc → single self-contained HTML string
104
+ // (player inlined, images as data URIs, timer-based playback — no audio)
105
+ const html = docToHtml(doc, { playerScript: PLAYER_BUNDLE, images });
106
+
107
+ // Interactive player export: Doc → ZIP Blob (external assets + optional audio)
108
+ const zipBlob = await docToHtmlZip(doc, { playerScript: PLAYER_BUNDLE, images, audio });
66
109
 
67
- // Export: Docstandalone HTML string
68
- const html = docToHtml(doc);
110
+ // Static export: MarkdownDocumentsemantic HTML page (no player)
111
+ const page = markdownDocToPlainHtml(markdownDoc, { themeId: 'warm-earth' });
69
112
 
70
- // Export: DocZIP with HTML + images
71
- const zipBytes = await docToHtmlZip(doc);
113
+ // Import: HTMLMarkdownDocument (sanitized by default)
114
+ const imported = await htmlToMarkdownDoc(htmlString);
72
115
  ```
73
116
 
117
+ The subpath also exports `markdownDocsToPlainHtmlBundle` / `markdownDocsToHtmlBundle` (recursive multi-doc ZIP bundles with `.md` links rewritten to `.html`), `htmlToMarkdownDocSync` / `htmlToMarkdown`, and helpers (`collectImagePaths`, `collectLinkRefs`, `inferMimeType`).
118
+
74
119
  ### EPUB
75
120
 
76
121
  ```ts
77
122
  import { markdownDocToEpub } from '@bendyline/squisq-formats/epub';
78
123
 
79
- // Export: MarkdownDocument → EPUB (ArrayBuffer)
124
+ // Export: MarkdownDocument → EPUB 3 (ArrayBuffer). No import path.
80
125
  const epubBytes = await markdownDocToEpub(markdownDoc, {
81
126
  title: 'My Book',
82
127
  author: 'Jane Doe',
128
+ images, // Map<string, ArrayBuffer> — embedded when provided
129
+ coverImage, // optional JPEG/PNG
83
130
  });
84
131
  ```
85
132
 
133
+ Chapters split at H1/H2 boundaries. Providing `audio` + `audioSegments` generates EPUB 3 Media Overlays (SMIL) for synchronized narration.
134
+
86
135
  ### PPTX
87
136
 
88
137
  ```ts
89
- import { markdownDocToPptx } from '@bendyline/squisq-formats/pptx';
138
+ import {
139
+ markdownDocToPptx,
140
+ pptxToMarkdownDoc,
141
+ pptxToContainer,
142
+ } from '@bendyline/squisq-formats/pptx';
90
143
 
91
144
  // Export: MarkdownDocument → PPTX (ArrayBuffer)
92
- // Each H1/H2 heading starts a new slide
93
- const pptxBytes = await markdownDocToPptx(markdownDoc);
145
+ // slideBreak: 'h1' | 'h2' (default — H1 and H2 both break) | 'heading'
146
+ const pptxBytes = await markdownDocToPptx(markdownDoc, { slideBreak: 'h2', images });
147
+
148
+ // Import: PPTX → MarkdownDocument (add { extractImages: true } to reference slide images)
149
+ const imported = await pptxToMarkdownDoc(pptxBuffer);
150
+
151
+ // Import with assets: PPTX → ContentContainer (markdown + extracted slide images)
152
+ const container = await pptxToContainer(pptxBuffer);
153
+ ```
154
+
155
+ **Fidelity:** export preserves inline formatting as DrawingML runs and embeds images when provided via `options.images`. Import reads slide order from `ppt/presentation.xml` and converts each slide's title (→ H2), body text (→ bullet list), and tables. **Slide-image extraction (v1.5):** import can now extract slide-level `<p:pic>` bitmaps into `images/` — `pptxToContainer` returns a container with those files and forces `extractImages: true`, while `pptxToMarkdownDoc` leaves it off by default. Honest limit: only slide-level `<p:pic>` bitmaps are extracted — layout/master images, charts, SmartArt, and picture-fills are **not**.
156
+
157
+ ### CSV
158
+
159
+ ```ts
160
+ import { csvToMarkdownDoc, markdownDocToCsv, parseCsv } from '@bendyline/squisq-formats/csv';
161
+
162
+ // Import: CSV (string | ArrayBuffer | Blob) → single-table MarkdownDocument
163
+ const tableDoc = await csvToMarkdownDoc(csvText, { delimiter: ',', hasHeader: true });
164
+
165
+ // Export: serializes one table node to CSV text (the first by default)
166
+ const csv = markdownDocToCsv(markdownDoc);
167
+ // Pick another table in a multi-table document:
168
+ const second = markdownDocToCsv(markdownDoc, { tableIndex: 1 });
169
+ ```
170
+
171
+ Self-contained RFC-4180 parser/serializer (not OOXML). Cell formatting is flattened to plain text on export. Export emits a single table — the first, or `tableIndex` (zero-based). An out-of-range `tableIndex` throws; a table-less document exports to an empty string.
172
+
173
+ ### XLSX
174
+
175
+ ```ts
176
+ import { xlsxToMarkdownDoc, markdownDocToXlsx } from '@bendyline/squisq-formats/xlsx';
177
+
178
+ // Import: XLSX → MarkdownDocument (one table per sheet; or pick one via `sheet`)
179
+ const imported = await xlsxToMarkdownDoc(xlsxBuffer, { sheet: 0 });
180
+
181
+ // Export: MarkdownDocument → XLSX (ArrayBuffer) — one worksheet per markdown table
182
+ const xlsxBytes = await markdownDocToXlsx(markdownDoc);
183
+ ```
184
+
185
+ **Export is implemented (v1.5) with tables-only fidelity:** every markdown `table` becomes one worksheet, named after the nearest preceding heading (auto-named `Sheet1`, `Sheet2`, … otherwise). All non-table content is dropped. Numeric-looking cells are written as numbers; everything else as inline strings. A document with no tables yields a single empty (but valid) sheet — export never throws. `markdownDocToXlsx` / `docToXlsx` now return `Promise<ArrayBuffer>` (previously threw / returned `Blob`).
186
+
187
+ ### Container ZIP
188
+
189
+ ```ts
190
+ import { containerToZip, zipToContainer } from '@bendyline/squisq-formats/container';
191
+
192
+ // ContentContainer → ZIP Blob (paths preserved)
193
+ const zipBlob = await containerToZip(container);
194
+
195
+ // ZIP → MemoryContentContainer (directories skipped, path traversal rejected)
196
+ const container2 = await zipToContainer(zipData);
94
197
  ```
95
198
 
96
199
  ### Doc-level Convenience Functions
97
200
 
98
- Each format also exports `Doc`-level wrappers that handle the Markdown↔Doc conversion internally:
201
+ Each format also exports `Doc`-level wrappers that handle the Markdown Doc conversion internally:
99
202
 
100
203
  ```ts
101
204
  import { docToDocx, docxToDoc } from '@bendyline/squisq-formats/docx';
102
205
  import { docToPdf, pdfToDoc } from '@bendyline/squisq-formats/pdf';
103
- import { docToPptx } from '@bendyline/squisq-formats/pptx';
206
+ import { docToPptx, pptxToDoc } from '@bendyline/squisq-formats/pptx';
207
+ import { docToEpub } from '@bendyline/squisq-formats/epub';
208
+ import { csvToDoc } from '@bendyline/squisq-formats/csv';
209
+ import { xlsxToDoc, docToXlsx } from '@bendyline/squisq-formats/xlsx';
104
210
  ```
105
211
 
212
+ ## Programmatic `convert()`
213
+
214
+ `@bendyline/squisq-formats/registry` (also re-exported from the package root) is a uniform, format-agnostic front door over every converter. Each format is a `FormatDefinition` that knows how to import raw bytes into the `MarkdownDocument` pivot and/or export back out; `convert()` normalizes any source into a `Doc`, optionally applies a theme/transform, and hands off to the target exporter. Every result comes back as the same `ConversionResult` (`bytes` + `mimeType` + `suggestedFilename` + `warnings`). Converter modules load lazily, so importing the registry never eagerly bundles a heavy converter.
215
+
216
+ ```ts
217
+ import { convert } from '@bendyline/squisq-formats/registry';
218
+
219
+ const result = await convert(
220
+ { kind: 'markdown', markdown: '# Hello', baseName: 'greeting' },
221
+ 'docx',
222
+ );
223
+ // result.bytes, result.mimeType, result.suggestedFilename === 'greeting.docx'
224
+ ```
225
+
226
+ Sources are `{ kind: 'bytes' | 'markdown' | 'doc', … }`; byte sources are format-sniffed by magic bytes + extension (pass `from` to skip). Failures throw a structured `ConversionError` with a stable `code` (`unknown-format`, `unsupported-input`, `unsupported-output`, `invalid-input`, `missing-dependency`, `conversion-failed`) plus a `hint`.
227
+
228
+ **Player-embedding HTML export (`html` / `htmlzip`)** needs the standalone player bundle. Pass `resolvePlayerScript`, or you'll get a `missing-dependency` error:
229
+
230
+ ```ts
231
+ const html = await convert({ kind: 'markdown', markdown: src }, 'html', {
232
+ resolvePlayerScript: () =>
233
+ import('@bendyline/squisq-react/standalone-source').then((m) => m.PLAYER_BUNDLE),
234
+ });
235
+ ```
236
+
237
+ Also exported: `createRegistry` / `defaultRegistry` / `defaultFormats`, `BUILTIN_FORMAT_IDS`, `ConversionError`, and the `ConvertSource` / `ConvertOptions` / `ConversionResult` / `FormatDefinition` / `FormatRegistry` types.
238
+
106
239
  ## Subpath Exports
107
240
 
108
- | Subpath | Contents |
109
- | --------------------------------- | -------------------------------------------------------------- |
110
- | `@bendyline/squisq-formats/docx` | DOCX import/export |
111
- | `@bendyline/squisq-formats/pdf` | PDF import/export + worker config |
112
- | `@bendyline/squisq-formats/html` | HTML export |
113
- | `@bendyline/squisq-formats/epub` | EPUB 3 e-book export |
114
- | `@bendyline/squisq-formats/ooxml` | Shared OOXML infrastructure (ZIP reader/writer, XML utilities) |
115
- | `@bendyline/squisq-formats/pptx` | PPTX export (import planned) |
116
- | `@bendyline/squisq-formats/xlsx` | XLSX stubs (not yet implemented) |
241
+ | Subpath | Contents |
242
+ | ------------------------------------- | ------------------------------------------------------------------------------ |
243
+ | `@bendyline/squisq-formats/docx` | DOCX import/export (+ `docxToContainer`) |
244
+ | `@bendyline/squisq-formats/pdf` | PDF import/export (+ `pdfToContainer`, `configurePdfWorker`) |
245
+ | `@bendyline/squisq-formats/html` | Player HTML export, static plain-HTML export + bundles, HTML import |
246
+ | `@bendyline/squisq-formats/epub` | EPUB 3 e-book export (with optional Media Overlays) |
247
+ | `@bendyline/squisq-formats/pptx` | PPTX export + import (text/lists/tables + slide images) |
248
+ | `@bendyline/squisq-formats/xlsx` | XLSX import + tables-only export |
249
+ | `@bendyline/squisq-formats/csv` | CSV import/export (RFC 4180) |
250
+ | `@bendyline/squisq-formats/ooxml` | Shared OOXML infrastructure (package reader/writer, XML utilities, namespaces) |
251
+ | `@bendyline/squisq-formats/container` | `ContentContainer` ↔ ZIP serialization |
252
+ | `@bendyline/squisq-formats/registry` | Format registry + programmatic `convert()` (also re-exported from the root) |
117
253
 
118
- ## Architecture
254
+ The package root re-exports the common converters; `./container`, the plain-HTML/bundle functions, `docxToContainer`, `pdfToContainer`, `PdfPageSize`, and the image utilities are subpath-only.
119
255
 
120
- All converters use Squisq's `MarkdownDocument` AST as the pivot format. Importing a file parses it into a `MarkdownDocument`; exporting serializes from one. The OOXML subpath provides shared infrastructure for reading and writing Office Open XML packages (used by DOCX and PPTX, and eventually XLSX).
256
+ See the full [API Reference](../../docs/API.md#bendylinesquisq-formats) for every signature and options interface.
121
257
 
122
258
  ## Related Packages
123
259
 
124
260
  | Package | Description |
125
261
  | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
126
262
  | [@bendyline/squisq](https://www.npmjs.com/package/@bendyline/squisq) | Headless core — schemas, templates, spatial, markdown, storage |
127
- | [@bendyline/squisq-react](https://www.npmjs.com/package/@bendyline/squisq-react) | React components for rendering docs |
263
+ | [@bendyline/squisq-react](https://www.npmjs.com/package/@bendyline/squisq-react) | React components for rendering docs (+ `PLAYER_BUNDLE`) |
264
+ | [@bendyline/squisq-cli](https://www.npmjs.com/package/@bendyline/squisq-cli) | `squisq` CLI — batch conversion + MP4 rendering |
128
265
  | [@bendyline/squisq-editor-react](https://www.npmjs.com/package/@bendyline/squisq-editor-react) | React editor with raw/WYSIWYG/preview modes |
129
266
 
130
267
  ## License