@bendyline/squisq-formats 0.1.1 → 1.1.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 (119) hide show
  1. package/dist/__tests__/container.test.d.ts +8 -0
  2. package/dist/__tests__/container.test.d.ts.map +1 -0
  3. package/dist/__tests__/container.test.js +147 -0
  4. package/dist/__tests__/container.test.js.map +1 -0
  5. package/dist/__tests__/docxExport.test.d.ts +8 -0
  6. package/dist/__tests__/docxExport.test.d.ts.map +1 -0
  7. package/dist/__tests__/docxExport.test.js +383 -0
  8. package/dist/__tests__/docxExport.test.js.map +1 -0
  9. package/dist/__tests__/docxImport.test.d.ts +8 -0
  10. package/dist/__tests__/docxImport.test.d.ts.map +1 -0
  11. package/dist/__tests__/docxImport.test.js +309 -0
  12. package/dist/__tests__/docxImport.test.js.map +1 -0
  13. package/dist/__tests__/html.test.d.ts +8 -0
  14. package/dist/__tests__/html.test.d.ts.map +1 -0
  15. package/dist/__tests__/html.test.js +243 -0
  16. package/dist/__tests__/html.test.js.map +1 -0
  17. package/dist/__tests__/ooxml.test.d.ts +5 -0
  18. package/dist/__tests__/ooxml.test.d.ts.map +1 -0
  19. package/dist/__tests__/ooxml.test.js +152 -0
  20. package/dist/__tests__/ooxml.test.js.map +1 -0
  21. package/dist/__tests__/pdfExport.test.d.ts +8 -0
  22. package/dist/__tests__/pdfExport.test.d.ts.map +1 -0
  23. package/dist/__tests__/pdfExport.test.js +275 -0
  24. package/dist/__tests__/pdfExport.test.js.map +1 -0
  25. package/dist/__tests__/pdfImport.test.d.ts +11 -0
  26. package/dist/__tests__/pdfImport.test.d.ts.map +1 -0
  27. package/dist/__tests__/pdfImport.test.js +254 -0
  28. package/dist/__tests__/pdfImport.test.js.map +1 -0
  29. package/dist/__tests__/roundTrip.test.d.ts +7 -0
  30. package/dist/__tests__/roundTrip.test.d.ts.map +1 -0
  31. package/dist/__tests__/roundTrip.test.js +173 -0
  32. package/dist/__tests__/roundTrip.test.js.map +1 -0
  33. package/dist/container/index.d.ts +36 -0
  34. package/dist/container/index.d.ts.map +1 -0
  35. package/dist/container/index.js +74 -0
  36. package/dist/container/index.js.map +1 -0
  37. package/dist/docx/export.d.ts +54 -0
  38. package/dist/docx/export.d.ts.map +1 -0
  39. package/dist/docx/export.js +729 -0
  40. package/dist/docx/export.js.map +1 -0
  41. package/dist/docx/import.d.ts +52 -0
  42. package/dist/docx/import.d.ts.map +1 -0
  43. package/dist/docx/import.js +687 -0
  44. package/dist/docx/import.js.map +1 -0
  45. package/dist/docx/index.d.ts +15 -100
  46. package/dist/docx/index.d.ts.map +1 -0
  47. package/dist/docx/index.js +22 -13
  48. package/dist/docx/index.js.map +1 -1
  49. package/dist/docx/styles.d.ts +68 -0
  50. package/dist/docx/styles.d.ts.map +1 -0
  51. package/dist/docx/styles.js +125 -0
  52. package/dist/docx/styles.js.map +1 -0
  53. package/dist/html/htmlTemplate.d.ts +64 -0
  54. package/dist/html/htmlTemplate.d.ts.map +1 -0
  55. package/dist/html/htmlTemplate.js +235 -0
  56. package/dist/html/htmlTemplate.js.map +1 -0
  57. package/dist/html/imageUtils.d.ts +29 -0
  58. package/dist/html/imageUtils.d.ts.map +1 -0
  59. package/dist/html/imageUtils.js +63 -0
  60. package/dist/html/imageUtils.js.map +1 -0
  61. package/dist/html/index.d.ts +9 -77
  62. package/dist/html/index.d.ts.map +1 -0
  63. package/dist/html/index.js +137 -16
  64. package/dist/html/index.js.map +1 -1
  65. package/dist/index.d.ts +36 -7
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +35 -53
  68. package/dist/index.js.map +1 -1
  69. package/dist/ooxml/index.d.ts +14 -343
  70. package/dist/ooxml/index.d.ts.map +1 -0
  71. package/dist/ooxml/index.js +22 -98
  72. package/dist/ooxml/index.js.map +1 -1
  73. package/dist/ooxml/namespaces.d.ts +67 -0
  74. package/dist/ooxml/namespaces.d.ts.map +1 -0
  75. package/dist/ooxml/namespaces.js +94 -0
  76. package/dist/ooxml/namespaces.js.map +1 -0
  77. package/dist/ooxml/reader.d.ts +52 -0
  78. package/dist/ooxml/reader.d.ts.map +1 -0
  79. package/dist/ooxml/reader.js +190 -0
  80. package/dist/ooxml/reader.js.map +1 -0
  81. package/dist/ooxml/types.d.ts +82 -0
  82. package/dist/ooxml/types.d.ts.map +1 -0
  83. package/dist/ooxml/types.js +9 -0
  84. package/dist/ooxml/types.js.map +1 -0
  85. package/dist/ooxml/writer.d.ts +71 -0
  86. package/dist/ooxml/writer.d.ts.map +1 -0
  87. package/dist/ooxml/writer.js +200 -0
  88. package/dist/ooxml/writer.js.map +1 -0
  89. package/dist/ooxml/xmlUtils.d.ts +76 -0
  90. package/dist/ooxml/xmlUtils.d.ts.map +1 -0
  91. package/dist/ooxml/xmlUtils.js +108 -0
  92. package/dist/ooxml/xmlUtils.js.map +1 -0
  93. package/dist/pdf/export.d.ts +50 -0
  94. package/dist/pdf/export.d.ts.map +1 -0
  95. package/dist/pdf/export.js +740 -0
  96. package/dist/pdf/export.js.map +1 -0
  97. package/dist/pdf/import.d.ts +78 -0
  98. package/dist/pdf/import.d.ts.map +1 -0
  99. package/dist/pdf/import.js +619 -0
  100. package/dist/pdf/import.js.map +1 -0
  101. package/dist/pdf/index.d.ts +17 -121
  102. package/dist/pdf/index.d.ts.map +1 -0
  103. package/dist/pdf/index.js +25 -14
  104. package/dist/pdf/index.js.map +1 -1
  105. package/dist/pdf/styles.d.ts +142 -0
  106. package/dist/pdf/styles.d.ts.map +1 -0
  107. package/dist/pdf/styles.js +145 -0
  108. package/dist/pdf/styles.js.map +1 -0
  109. package/dist/pptx/index.d.ts +9 -12
  110. package/dist/pptx/index.d.ts.map +1 -0
  111. package/dist/pptx/index.js +44 -12
  112. package/dist/pptx/index.js.map +1 -1
  113. package/dist/xlsx/index.d.ts +9 -12
  114. package/dist/xlsx/index.d.ts.map +1 -0
  115. package/dist/xlsx/index.js +44 -12
  116. package/dist/xlsx/index.js.map +1 -1
  117. package/package.json +8 -4
  118. package/src/__tests__/container.test.ts +189 -0
  119. package/src/container/index.ts +89 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Tests for PDF import: pdfToMarkdownDoc, pdfToDoc.
3
+ *
4
+ * Builds PDFs with pdf-lib (adding known text), then imports them
5
+ * via pdfToMarkdownDoc and inspects the resulting MarkdownDocument.
6
+ *
7
+ * NOTE: pdfjs-dist text extraction quality depends on the environment.
8
+ * Standard fonts embedded by pdf-lib should produce readable text items.
9
+ */
10
+ import { describe, it, expect } from 'vitest';
11
+ import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
12
+ import { pdfToMarkdownDoc, pdfToDoc } from '../pdf/import';
13
+ // ============================================
14
+ // Helpers
15
+ // ============================================
16
+ /**
17
+ * Create a simple PDF buffer with text drawn at specified sizes/positions.
18
+ */
19
+ async function buildSimplePdf(lines) {
20
+ const doc = await PDFDocument.create();
21
+ const page = doc.addPage([612, 792]); // Letter
22
+ const regular = await doc.embedFont(StandardFonts.Helvetica);
23
+ const bold = await doc.embedFont(StandardFonts.HelveticaBold);
24
+ const italic = await doc.embedFont(StandardFonts.HelveticaOblique);
25
+ const mono = await doc.embedFont(StandardFonts.Courier);
26
+ for (const line of lines) {
27
+ let font = regular;
28
+ const fName = line.fontName?.toLowerCase() ?? '';
29
+ if (fName.includes('bold'))
30
+ font = bold;
31
+ else if (fName.includes('italic') || fName.includes('oblique'))
32
+ font = italic;
33
+ else if (fName.includes('courier') || fName.includes('mono'))
34
+ font = mono;
35
+ page.drawText(line.text, {
36
+ x: line.x,
37
+ y: line.y,
38
+ size: line.fontSize,
39
+ font,
40
+ color: rgb(0, 0, 0),
41
+ });
42
+ }
43
+ return doc.save();
44
+ }
45
+ function flatText(node) {
46
+ const parts = [];
47
+ function walk(n) {
48
+ if (n.type === 'text' && n.value)
49
+ parts.push(n.value);
50
+ if (n.value && n.type === 'code')
51
+ parts.push(n.value);
52
+ if (n.value && n.type === 'inlineCode')
53
+ parts.push(n.value);
54
+ if (n.children)
55
+ for (const c of n.children)
56
+ walk(c);
57
+ }
58
+ walk(node);
59
+ return parts.join('');
60
+ }
61
+ // ============================================
62
+ // Basic Import
63
+ // ============================================
64
+ describe('pdfToMarkdownDoc', () => {
65
+ it('returns an empty document for a blank PDF', async () => {
66
+ const doc = await PDFDocument.create();
67
+ doc.addPage([612, 792]);
68
+ const buffer = await doc.save();
69
+ const md = await pdfToMarkdownDoc(buffer);
70
+ expect(md.type).toBe('document');
71
+ expect(md.children.length).toBe(0);
72
+ });
73
+ it('imports a single paragraph', async () => {
74
+ const buffer = await buildSimplePdf([{ text: 'Hello World', x: 72, y: 700, fontSize: 11 }]);
75
+ const md = await pdfToMarkdownDoc(buffer);
76
+ expect(md.children.length).toBeGreaterThanOrEqual(1);
77
+ // The first block should contain "Hello World"
78
+ const allText = md.children.map(flatText).join(' ');
79
+ expect(allText).toContain('Hello');
80
+ expect(allText).toContain('World');
81
+ });
82
+ it('detects a heading by font size', async () => {
83
+ const buffer = await buildSimplePdf([
84
+ { text: 'Big Title', x: 72, y: 700, fontSize: 24 },
85
+ { text: 'Body text here.', x: 72, y: 660, fontSize: 11 },
86
+ ]);
87
+ // Provide explicit bodyFontSize — with only 2 lines auto-detection
88
+ // picks the first seen size (24) which masks the heading.
89
+ const md = await pdfToMarkdownDoc(buffer, { bodyFontSize: 11 });
90
+ // Find heading block
91
+ const headings = md.children.filter((c) => c.type === 'heading');
92
+ expect(headings.length).toBeGreaterThanOrEqual(1);
93
+ if (headings.length > 0) {
94
+ const h = headings[0];
95
+ expect(h.depth).toBeLessThanOrEqual(2);
96
+ expect(flatText(h)).toContain('Title');
97
+ }
98
+ });
99
+ it('renders bold text as plain text (standard font limitation)', async () => {
100
+ // pdfjs-dist returns opaque font IDs ("g_d0_f2") for standard PDF fonts,
101
+ // not the actual font name. Bold/italic detection only works with
102
+ // embedded fonts whose names contain "Bold"/"Italic" — a known heuristic
103
+ // limitation. Here we verify the text is still extracted.
104
+ const buffer = await buildSimplePdf([
105
+ { text: 'Bold text', x: 72, y: 700, fontSize: 11, fontName: 'Helvetica-Bold' },
106
+ ]);
107
+ const md = await pdfToMarkdownDoc(buffer);
108
+ expect(md.children.length).toBeGreaterThanOrEqual(1);
109
+ const allText = md.children.map(flatText).join(' ');
110
+ expect(allText).toContain('Bold text');
111
+ });
112
+ it('renders italic text as plain text (standard font limitation)', async () => {
113
+ // Same as bold — standard PDF font names are not exposed by pdfjs-dist.
114
+ const buffer = await buildSimplePdf([
115
+ { text: 'Italic text', x: 72, y: 700, fontSize: 11, fontName: 'Helvetica-Oblique' },
116
+ ]);
117
+ const md = await pdfToMarkdownDoc(buffer);
118
+ expect(md.children.length).toBeGreaterThanOrEqual(1);
119
+ const allText = md.children.map(flatText).join(' ');
120
+ expect(allText).toContain('Italic text');
121
+ });
122
+ it('detects monospace text as inline code', async () => {
123
+ const buffer = await buildSimplePdf([
124
+ { text: 'const x = 1;', x: 72, y: 700, fontSize: 10, fontName: 'Courier' },
125
+ ]);
126
+ const md = await pdfToMarkdownDoc(buffer);
127
+ expect(md.children.length).toBeGreaterThanOrEqual(1);
128
+ // Monospace lines should become code blocks or inline code
129
+ function hasCode(node) {
130
+ if (node.type === 'code' || node.type === 'inlineCode')
131
+ return true;
132
+ if (node.children)
133
+ return node.children.some(hasCode);
134
+ return false;
135
+ }
136
+ expect(md.children.some(hasCode)).toBe(true);
137
+ });
138
+ it('detects consecutive monospace lines as a code block', async () => {
139
+ const buffer = await buildSimplePdf([
140
+ { text: 'function hello() {', x: 72, y: 700, fontSize: 10, fontName: 'Courier' },
141
+ { text: ' return 42;', x: 72, y: 686, fontSize: 10, fontName: 'Courier' },
142
+ { text: '}', x: 72, y: 672, fontSize: 10, fontName: 'Courier' },
143
+ ]);
144
+ const md = await pdfToMarkdownDoc(buffer);
145
+ const codeBlocks = md.children.filter((c) => c.type === 'code');
146
+ expect(codeBlocks.length).toBeGreaterThanOrEqual(1);
147
+ if (codeBlocks.length > 0) {
148
+ const cb = codeBlocks[0];
149
+ expect(cb.value).toContain('function');
150
+ expect(cb.value).toContain('return');
151
+ }
152
+ });
153
+ it('detects bullet list items', async () => {
154
+ const buffer = await buildSimplePdf([
155
+ { text: '\u2022 First item', x: 72, y: 700, fontSize: 11 },
156
+ { text: '\u2022 Second item', x: 72, y: 684, fontSize: 11 },
157
+ ]);
158
+ const md = await pdfToMarkdownDoc(buffer);
159
+ const lists = md.children.filter((c) => c.type === 'list');
160
+ expect(lists.length).toBeGreaterThanOrEqual(1);
161
+ });
162
+ it('detects ordered list items', async () => {
163
+ const buffer = await buildSimplePdf([
164
+ { text: '1. First step', x: 72, y: 700, fontSize: 11 },
165
+ { text: '2. Second step', x: 72, y: 684, fontSize: 11 },
166
+ ]);
167
+ const md = await pdfToMarkdownDoc(buffer);
168
+ const lists = md.children.filter((c) => c.type === 'list');
169
+ expect(lists.length).toBeGreaterThanOrEqual(1);
170
+ });
171
+ it('detects indented text as blockquote', async () => {
172
+ const buffer = await buildSimplePdf([
173
+ { text: 'Normal paragraph.', x: 72, y: 720, fontSize: 11 },
174
+ { text: 'This is a quote.', x: 110, y: 700, fontSize: 11 },
175
+ ]);
176
+ const md = await pdfToMarkdownDoc(buffer, { detectBlockquotes: true });
177
+ const quotes = md.children.filter((c) => c.type === 'blockquote');
178
+ expect(quotes.length).toBeGreaterThanOrEqual(1);
179
+ });
180
+ it('detects URLs in text as links', async () => {
181
+ const buffer = await buildSimplePdf([
182
+ { text: 'Visit https://example.com for more.', x: 72, y: 700, fontSize: 11 },
183
+ ]);
184
+ const md = await pdfToMarkdownDoc(buffer, { detectLinks: true });
185
+ function hasLink(node) {
186
+ if (node.type === 'link')
187
+ return true;
188
+ if (node.children)
189
+ return node.children.some(hasLink);
190
+ return false;
191
+ }
192
+ expect(md.children.some(hasLink)).toBe(true);
193
+ });
194
+ it('handles multi-page documents', async () => {
195
+ const doc = await PDFDocument.create();
196
+ const font = await doc.embedFont(StandardFonts.Helvetica);
197
+ for (let p = 0; p < 3; p++) {
198
+ const page = doc.addPage([612, 792]);
199
+ page.drawText(`Page ${p + 1} content`, {
200
+ x: 72,
201
+ y: 700,
202
+ size: 11,
203
+ font,
204
+ });
205
+ }
206
+ const buffer = await doc.save();
207
+ const md = await pdfToMarkdownDoc(buffer);
208
+ expect(md.children.length).toBeGreaterThanOrEqual(3);
209
+ });
210
+ it('respects bodyFontSize option', async () => {
211
+ // If we say body is 14pt, then a 16pt line should still be heading
212
+ // but borderline 13pt would not be
213
+ const buffer = await buildSimplePdf([
214
+ { text: 'Medium heading', x: 72, y: 700, fontSize: 16 },
215
+ { text: 'Body text at 14pt', x: 72, y: 670, fontSize: 14 },
216
+ ]);
217
+ const md = await pdfToMarkdownDoc(buffer, { bodyFontSize: 14 });
218
+ const headings = md.children.filter((c) => c.type === 'heading');
219
+ expect(headings.length).toBeGreaterThanOrEqual(1);
220
+ });
221
+ it('accepts Uint8Array input', async () => {
222
+ const buffer = await buildSimplePdf([{ text: 'Uint8Array test', x: 72, y: 700, fontSize: 11 }]);
223
+ const uint8 = new Uint8Array(buffer);
224
+ const md = await pdfToMarkdownDoc(uint8);
225
+ expect(md.children.length).toBeGreaterThanOrEqual(1);
226
+ });
227
+ it('can disable table detection', async () => {
228
+ const buffer = await buildSimplePdf([
229
+ { text: 'Col A', x: 72, y: 700, fontSize: 11 },
230
+ { text: 'Col B', x: 250, y: 700, fontSize: 11 },
231
+ { text: 'Val 1', x: 72, y: 684, fontSize: 11 },
232
+ { text: 'Val 2', x: 250, y: 684, fontSize: 11 },
233
+ ]);
234
+ const md = await pdfToMarkdownDoc(buffer, { detectTables: false });
235
+ const tables = md.children.filter((c) => c.type === 'table');
236
+ expect(tables.length).toBe(0);
237
+ });
238
+ });
239
+ // ============================================
240
+ // pdfToDoc convenience wrapper
241
+ // ============================================
242
+ describe('pdfToDoc', () => {
243
+ it('converts PDF to a Doc object', async () => {
244
+ const buffer = await buildSimplePdf([
245
+ { text: 'Test Title', x: 72, y: 700, fontSize: 24 },
246
+ { text: 'Some body text.', x: 72, y: 660, fontSize: 11 },
247
+ ]);
248
+ const doc = await pdfToDoc(buffer);
249
+ expect(doc).toBeDefined();
250
+ expect(doc.blocks).toBeDefined();
251
+ expect(doc.blocks.length).toBeGreaterThan(0);
252
+ });
253
+ });
254
+ //# sourceMappingURL=pdfImport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdfImport.test.js","sourceRoot":"","sources":["../../src/__tests__/pdfImport.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Round-trip tests: MarkdownDocument → DOCX → MarkdownDocument.
3
+ *
4
+ * Verifies that core document structures survive the export → import cycle.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=roundTrip.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roundTrip.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/roundTrip.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Round-trip tests: MarkdownDocument → DOCX → MarkdownDocument.
3
+ *
4
+ * Verifies that core document structures survive the export → import cycle.
5
+ */
6
+ import { describe, it, expect } from 'vitest';
7
+ import { markdownDocToDocx } from '../docx/export';
8
+ import { docxToMarkdownDoc } from '../docx/import';
9
+ // ============================================
10
+ // Helpers
11
+ // ============================================
12
+ async function roundTrip(doc) {
13
+ const buffer = await markdownDocToDocx(doc);
14
+ return docxToMarkdownDoc(buffer);
15
+ }
16
+ /**
17
+ * Extract plain text from an inline node tree.
18
+ */
19
+ function extractText(node) {
20
+ if (node.type === 'text')
21
+ return node.value;
22
+ if ('children' in node)
23
+ return node.children.map(extractText).join('');
24
+ if ('value' in node)
25
+ return node.value;
26
+ return '';
27
+ }
28
+ function extractBlockText(block) {
29
+ if ('children' in block)
30
+ return block.children.map(extractText).join('');
31
+ if ('value' in block)
32
+ return block.value;
33
+ return '';
34
+ }
35
+ // ============================================
36
+ // Round-trip Tests
37
+ // ============================================
38
+ describe('DOCX round-trip', () => {
39
+ it('round-trips headings', async () => {
40
+ const original = {
41
+ type: 'document',
42
+ children: [
43
+ {
44
+ type: 'heading',
45
+ depth: 1,
46
+ children: [{ type: 'text', value: 'Main Title' }],
47
+ },
48
+ {
49
+ type: 'heading',
50
+ depth: 2,
51
+ children: [{ type: 'text', value: 'Section' }],
52
+ },
53
+ ],
54
+ };
55
+ const result = await roundTrip(original);
56
+ expect(result.children.length).toBeGreaterThanOrEqual(2);
57
+ expect(result.children[0].type).toBe('heading');
58
+ expect(result.children[0].depth).toBe(1);
59
+ expect(extractBlockText(result.children[0])).toBe('Main Title');
60
+ expect(result.children[1].type).toBe('heading');
61
+ expect(result.children[1].depth).toBe(2);
62
+ expect(extractBlockText(result.children[1])).toBe('Section');
63
+ });
64
+ it('round-trips paragraphs', async () => {
65
+ const original = {
66
+ type: 'document',
67
+ children: [
68
+ {
69
+ type: 'paragraph',
70
+ children: [{ type: 'text', value: 'Hello world' }],
71
+ },
72
+ {
73
+ type: 'paragraph',
74
+ children: [{ type: 'text', value: 'Second paragraph' }],
75
+ },
76
+ ],
77
+ };
78
+ const result = await roundTrip(original);
79
+ expect(result.children.length).toBe(2);
80
+ expect(extractBlockText(result.children[0])).toBe('Hello world');
81
+ expect(extractBlockText(result.children[1])).toBe('Second paragraph');
82
+ });
83
+ it('round-trips bold text', async () => {
84
+ const original = {
85
+ type: 'document',
86
+ children: [
87
+ {
88
+ type: 'paragraph',
89
+ children: [
90
+ { type: 'text', value: 'Normal ' },
91
+ {
92
+ type: 'strong',
93
+ children: [{ type: 'text', value: 'bold' }],
94
+ },
95
+ { type: 'text', value: ' text' },
96
+ ],
97
+ },
98
+ ],
99
+ };
100
+ const result = await roundTrip(original);
101
+ const para = result.children[0];
102
+ expect(para.type).toBe('paragraph');
103
+ // Find the bold node
104
+ const boldNode = para.children.find((c) => c.type === 'strong');
105
+ expect(boldNode).toBeDefined();
106
+ expect(extractText(boldNode)).toBe('bold');
107
+ });
108
+ it('round-trips italic text', async () => {
109
+ const original = {
110
+ type: 'document',
111
+ children: [
112
+ {
113
+ type: 'paragraph',
114
+ children: [
115
+ {
116
+ type: 'emphasis',
117
+ children: [{ type: 'text', value: 'italic' }],
118
+ },
119
+ ],
120
+ },
121
+ ],
122
+ };
123
+ const result = await roundTrip(original);
124
+ const para = result.children[0];
125
+ const italicNode = para.children.find((c) => c.type === 'emphasis');
126
+ expect(italicNode).toBeDefined();
127
+ expect(extractText(italicNode)).toBe('italic');
128
+ });
129
+ it('round-trips mixed content document', async () => {
130
+ const original = {
131
+ type: 'document',
132
+ children: [
133
+ {
134
+ type: 'heading',
135
+ depth: 1,
136
+ children: [{ type: 'text', value: 'Document Title' }],
137
+ },
138
+ {
139
+ type: 'paragraph',
140
+ children: [
141
+ { type: 'text', value: 'This is ' },
142
+ {
143
+ type: 'strong',
144
+ children: [{ type: 'text', value: 'important' }],
145
+ },
146
+ { type: 'text', value: ' content.' },
147
+ ],
148
+ },
149
+ {
150
+ type: 'heading',
151
+ depth: 2,
152
+ children: [{ type: 'text', value: 'Details' }],
153
+ },
154
+ {
155
+ type: 'paragraph',
156
+ children: [{ type: 'text', value: 'More info here.' }],
157
+ },
158
+ ],
159
+ };
160
+ const result = await roundTrip(original);
161
+ // Should have at least 4 blocks
162
+ expect(result.children.length).toBeGreaterThanOrEqual(4);
163
+ // First should be heading
164
+ expect(result.children[0].type).toBe('heading');
165
+ expect(extractBlockText(result.children[0])).toBe('Document Title');
166
+ // Then paragraph with mixed content
167
+ expect(result.children[1].type).toBe('paragraph');
168
+ const fullText = result.children[1].children.map(extractText).join('');
169
+ expect(fullText).toContain('important');
170
+ expect(fullText).toContain('content');
171
+ });
172
+ });
173
+ //# sourceMappingURL=roundTrip.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roundTrip.test.js","sourceRoot":"","sources":["../../src/__tests__/roundTrip.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Container ZIP serialization — convert between ContentContainer and ZIP archives.
3
+ *
4
+ * Uses JSZip (already a formats dependency) to serialize a ContentContainer to
5
+ * a ZIP blob and to deserialize a ZIP blob into a MemoryContentContainer.
6
+ *
7
+ * ZIP structure mirrors the container's flat path hierarchy directly:
8
+ * index.md
9
+ * images/hero.jpg
10
+ * audio/narration.mp3
11
+ * timing.json
12
+ */
13
+ import type { ContentContainer } from '@bendyline/squisq/storage';
14
+ import { MemoryContentContainer } from '@bendyline/squisq/storage';
15
+ /**
16
+ * Serialize a ContentContainer to a ZIP blob.
17
+ *
18
+ * All files in the container are written to the ZIP archive preserving
19
+ * their path structure. The resulting blob can be saved as a .zip file.
20
+ *
21
+ * @param container — The container to serialize
22
+ * @returns A Blob containing the ZIP archive
23
+ */
24
+ export declare function containerToZip(container: ContentContainer): Promise<Blob>;
25
+ /**
26
+ * Deserialize a ZIP archive into a MemoryContentContainer.
27
+ *
28
+ * Reads all files from the ZIP and writes them into a new MemoryContentContainer.
29
+ * Directory entries are skipped. The resulting container can be used immediately
30
+ * for rendering, editing, or saving to persistent storage.
31
+ *
32
+ * @param zipData — The ZIP archive as ArrayBuffer, Uint8Array, or Blob
33
+ * @returns A MemoryContentContainer populated with the ZIP's contents
34
+ */
35
+ export declare function zipToContainer(zipData: ArrayBuffer | Uint8Array | Blob): Promise<MemoryContentContainer>;
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/container/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/E;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,GACvC,OAAO,CAAC,sBAAsB,CAAC,CAgCjC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Container ZIP serialization — convert between ContentContainer and ZIP archives.
3
+ *
4
+ * Uses JSZip (already a formats dependency) to serialize a ContentContainer to
5
+ * a ZIP blob and to deserialize a ZIP blob into a MemoryContentContainer.
6
+ *
7
+ * ZIP structure mirrors the container's flat path hierarchy directly:
8
+ * index.md
9
+ * images/hero.jpg
10
+ * audio/narration.mp3
11
+ * timing.json
12
+ */
13
+ import JSZip from 'jszip';
14
+ import { MemoryContentContainer } from '@bendyline/squisq/storage';
15
+ /**
16
+ * Serialize a ContentContainer to a ZIP blob.
17
+ *
18
+ * All files in the container are written to the ZIP archive preserving
19
+ * their path structure. The resulting blob can be saved as a .zip file.
20
+ *
21
+ * @param container — The container to serialize
22
+ * @returns A Blob containing the ZIP archive
23
+ */
24
+ export async function containerToZip(container) {
25
+ const zip = new JSZip();
26
+ const entries = await container.listFiles();
27
+ for (const entry of entries) {
28
+ const data = await container.readFile(entry.path);
29
+ if (data) {
30
+ zip.file(entry.path, new Uint8Array(data));
31
+ }
32
+ }
33
+ return zip.generateAsync({
34
+ type: 'blob',
35
+ compression: 'DEFLATE',
36
+ compressionOptions: { level: 6 },
37
+ });
38
+ }
39
+ /**
40
+ * Deserialize a ZIP archive into a MemoryContentContainer.
41
+ *
42
+ * Reads all files from the ZIP and writes them into a new MemoryContentContainer.
43
+ * Directory entries are skipped. The resulting container can be used immediately
44
+ * for rendering, editing, or saving to persistent storage.
45
+ *
46
+ * @param zipData — The ZIP archive as ArrayBuffer, Uint8Array, or Blob
47
+ * @returns A MemoryContentContainer populated with the ZIP's contents
48
+ */
49
+ export async function zipToContainer(zipData) {
50
+ const zip = await JSZip.loadAsync(zipData);
51
+ const container = new MemoryContentContainer();
52
+ const filePromises = [];
53
+ zip.forEach((relativePath, zipEntry) => {
54
+ // Skip directories
55
+ if (zipEntry.dir)
56
+ return;
57
+ // Strip leading slash if present
58
+ const entryPath = relativePath.startsWith('/') ? relativePath.slice(1) : relativePath;
59
+ if (!entryPath)
60
+ return;
61
+ // Path-traversal protection: reject absolute paths, backslashes, and .. segments
62
+ if (entryPath.startsWith('/') ||
63
+ entryPath.includes('\\') ||
64
+ entryPath.split('/').some((seg) => seg === '..')) {
65
+ return;
66
+ }
67
+ filePromises.push(zipEntry.async('arraybuffer').then((data) => {
68
+ return container.writeFile(entryPath, data);
69
+ }));
70
+ });
71
+ await Promise.all(filePromises);
72
+ return container;
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/container/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAA2B;IAC9D,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC,aAAa,CAAC;QACvB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,SAAS;QACtB,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;KACjC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAwC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,sBAAsB,EAAE,CAAC;IAE/C,MAAM,YAAY,GAAoB,EAAE,CAAC;IAEzC,GAAG,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,EAAE;QACrC,mBAAmB;QACnB,IAAI,QAAQ,CAAC,GAAG;YAAE,OAAO;QAEzB,iCAAiC;QACjC,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QACtF,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,iFAAiF;QACjF,IACE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;YACzB,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;YACxB,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,EAChD,CAAC;YACD,OAAO;QACT,CAAC;QAED,YAAY,CAAC,IAAI,CACf,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1C,OAAO,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAChC,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * DOCX Export
3
+ *
4
+ * Converts a squisq MarkdownDocument (or Doc) into a .docx file
5
+ * by generating WordprocessingML XML and assembling the OOXML package.
6
+ *
7
+ * No third-party docx library — all XML is generated directly using
8
+ * the shared ooxml/ infrastructure of this package.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { parseMarkdown } from '@bendyline/squisq/markdown';
13
+ * import { markdownDocToDocx } from '@bendyline/squisq-formats/docx';
14
+ *
15
+ * const md = parseMarkdown('# Hello\n\nWorld **bold** text');
16
+ * const blob = await markdownDocToDocx(md);
17
+ * ```
18
+ */
19
+ import type { Doc } from '@bendyline/squisq/schemas';
20
+ import type { MarkdownDocument } from '@bendyline/squisq/markdown';
21
+ /**
22
+ * Options for DOCX export.
23
+ */
24
+ export interface DocxExportOptions {
25
+ /** Document title (appears in core properties) */
26
+ title?: string;
27
+ /** Document author */
28
+ author?: string;
29
+ /** Document description */
30
+ description?: string;
31
+ /** Default body font family. Default: "Calibri" */
32
+ defaultFont?: string;
33
+ /** Default body font size in points. Default: 11 */
34
+ defaultFontSize?: number;
35
+ }
36
+ /**
37
+ * Convert a MarkdownDocument to a .docx Blob.
38
+ *
39
+ * @param doc - The parsed markdown document
40
+ * @param options - Export options
41
+ * @returns An ArrayBuffer containing the .docx file
42
+ */
43
+ export declare function markdownDocToDocx(doc: MarkdownDocument, options?: DocxExportOptions): Promise<ArrayBuffer>;
44
+ /**
45
+ * Convert a squisq Doc to a .docx Blob.
46
+ *
47
+ * Convenience wrapper that converts Doc → MarkdownDocument → DOCX.
48
+ *
49
+ * @param doc - The squisq Doc
50
+ * @param options - Export options
51
+ * @returns An ArrayBuffer containing the .docx file
52
+ */
53
+ export declare function docToDocx(doc: Doc, options?: DocxExportOptions): Promise<ArrayBuffer>;
54
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/docx/export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,KAAK,EACV,gBAAgB,EAkBjB,MAAM,4BAA4B,CAAC;AAsCpC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,gBAAgB,EACrB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,WAAW,CAAC,CAItB;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAG/F"}