@bendyline/squisq-formats 1.2.0 → 1.2.2
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/README.md +14 -0
- package/dist/__tests__/epub.test.d.ts +8 -0
- package/dist/__tests__/epub.test.d.ts.map +1 -0
- package/dist/__tests__/epub.test.js +472 -0
- package/dist/__tests__/epub.test.js.map +1 -0
- package/dist/{chunk-BHHEDPRB.js → chunk-7DEUGIOO.js} +6 -41
- package/dist/chunk-7DEUGIOO.js.map +1 -0
- package/dist/chunk-A3FHLTY5.js +42 -0
- package/dist/chunk-A3FHLTY5.js.map +1 -0
- package/dist/chunk-EUQQYBZZ.js +647 -0
- package/dist/chunk-EUQQYBZZ.js.map +1 -0
- package/dist/{chunk-CLGUOVYR.js → chunk-MEZF76JA.js} +6 -4
- package/dist/{chunk-CLGUOVYR.js.map → chunk-MEZF76JA.js.map} +1 -1
- package/dist/{chunk-FIFCQN3W.js → chunk-NGWHV77G.js} +5 -3
- package/dist/{chunk-FIFCQN3W.js.map → chunk-NGWHV77G.js.map} +1 -1
- package/dist/chunk-U4MRIFKL.js +43 -0
- package/dist/chunk-U4MRIFKL.js.map +1 -0
- package/dist/{chunk-743COJWQ.js → chunk-UM5V2XZG.js} +7 -40
- package/dist/chunk-UM5V2XZG.js.map +1 -0
- package/dist/{chunk-KJ4NS4DX.js → chunk-YN5HFCEW.js} +2 -2
- package/dist/epub/export.d.ts +72 -0
- package/dist/epub/export.d.ts.map +1 -0
- package/dist/epub/export.js +698 -0
- package/dist/epub/export.js.map +1 -0
- package/dist/epub/index.d.ts +20 -0
- package/dist/epub/index.d.ts.map +1 -0
- package/dist/epub/index.js +19 -0
- package/dist/epub/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
- package/src/__tests__/epub.test.ts +548 -0
- package/src/epub/export.ts +916 -0
- package/src/epub/index.ts +20 -0
- package/src/index.ts +4 -0
- package/dist/chunk-743COJWQ.js.map +0 -1
- package/dist/chunk-BHHEDPRB.js.map +0 -1
- /package/dist/{chunk-KJ4NS4DX.js.map → chunk-YN5HFCEW.js.map} +0 -0
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ npm install @bendyline/squisq-formats @bendyline/squisq
|
|
|
20
20
|
| **DOCX** (Word) | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/docx` |
|
|
21
21
|
| **PDF** | ✅ | ✅ | ✅ | `@bendyline/squisq-formats/pdf` |
|
|
22
22
|
| **HTML** | — | ✅ | ✅ | `@bendyline/squisq-formats/html` |
|
|
23
|
+
| **EPUB** (e-book) | — | ✅ | ✅ | `@bendyline/squisq-formats/epub` |
|
|
23
24
|
| **PPTX** (PowerPoint) | planned | ✅ | ✅ | `@bendyline/squisq-formats/pptx` |
|
|
24
25
|
| **XLSX** (Excel) | planned | planned | — | `@bendyline/squisq-formats/xlsx` |
|
|
25
26
|
|
|
@@ -70,6 +71,18 @@ const html = docToHtml(doc);
|
|
|
70
71
|
const zipBytes = await docToHtmlZip(doc);
|
|
71
72
|
```
|
|
72
73
|
|
|
74
|
+
### EPUB
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { markdownDocToEpub } from '@bendyline/squisq-formats/epub';
|
|
78
|
+
|
|
79
|
+
// Export: MarkdownDocument → EPUB (ArrayBuffer)
|
|
80
|
+
const epubBytes = await markdownDocToEpub(markdownDoc, {
|
|
81
|
+
title: 'My Book',
|
|
82
|
+
author: 'Jane Doe',
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
73
86
|
### PPTX
|
|
74
87
|
|
|
75
88
|
```ts
|
|
@@ -97,6 +110,7 @@ import { docToPptx } from '@bendyline/squisq-formats/pptx';
|
|
|
97
110
|
| `@bendyline/squisq-formats/docx` | DOCX import/export |
|
|
98
111
|
| `@bendyline/squisq-formats/pdf` | PDF import/export + worker config |
|
|
99
112
|
| `@bendyline/squisq-formats/html` | HTML export |
|
|
113
|
+
| `@bendyline/squisq-formats/epub` | EPUB 3 e-book export |
|
|
100
114
|
| `@bendyline/squisq-formats/ooxml` | Shared OOXML infrastructure (ZIP reader/writer, XML utilities) |
|
|
101
115
|
| `@bendyline/squisq-formats/pptx` | PPTX export (import planned) |
|
|
102
116
|
| `@bendyline/squisq-formats/xlsx` | XLSX stubs (not yet implemented) |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epub.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/epub.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for EPUB export: markdownDocToEpub, docToEpub.
|
|
3
|
+
*
|
|
4
|
+
* Verifies EPUB 3 structure, chapter splitting, XHTML content,
|
|
5
|
+
* image embedding, metadata, and stylesheet generation.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import JSZip from 'jszip';
|
|
9
|
+
import { markdownDocToEpub } from '../epub/export';
|
|
10
|
+
// ============================================
|
|
11
|
+
// Helpers
|
|
12
|
+
// ============================================
|
|
13
|
+
function makeDoc(children, frontmatter) {
|
|
14
|
+
return { type: 'document', children, frontmatter };
|
|
15
|
+
}
|
|
16
|
+
function heading(depth, text) {
|
|
17
|
+
return { type: 'heading', depth, children: [{ type: 'text', value: text }] };
|
|
18
|
+
}
|
|
19
|
+
function paragraph(text) {
|
|
20
|
+
return { type: 'paragraph', children: [{ type: 'text', value: text }] };
|
|
21
|
+
}
|
|
22
|
+
function boldParagraph(text) {
|
|
23
|
+
return {
|
|
24
|
+
type: 'paragraph',
|
|
25
|
+
children: [{ type: 'strong', children: [{ type: 'text', value: text }] }],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function linkParagraph(text, url) {
|
|
29
|
+
return {
|
|
30
|
+
type: 'paragraph',
|
|
31
|
+
children: [{ type: 'link', url, children: [{ type: 'text', value: text }] }],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function imageParagraph(alt, url) {
|
|
35
|
+
return {
|
|
36
|
+
type: 'paragraph',
|
|
37
|
+
children: [{ type: 'image', url, alt }],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function codeBlock(code, lang) {
|
|
41
|
+
return { type: 'code', value: code, lang: lang ?? null };
|
|
42
|
+
}
|
|
43
|
+
async function exportAndUnzip(doc, options) {
|
|
44
|
+
const buffer = await markdownDocToEpub(doc, options);
|
|
45
|
+
return JSZip.loadAsync(buffer);
|
|
46
|
+
}
|
|
47
|
+
// ============================================
|
|
48
|
+
// Tests
|
|
49
|
+
// ============================================
|
|
50
|
+
describe('markdownDocToEpub', () => {
|
|
51
|
+
describe('EPUB structure', () => {
|
|
52
|
+
it('produces a valid ZIP with required EPUB files', async () => {
|
|
53
|
+
const doc = makeDoc([heading(1, 'Title'), paragraph('Content')]);
|
|
54
|
+
const zip = await exportAndUnzip(doc);
|
|
55
|
+
expect(zip.file('mimetype')).toBeTruthy();
|
|
56
|
+
expect(zip.file('META-INF/container.xml')).toBeTruthy();
|
|
57
|
+
expect(zip.file('OEBPS/content.opf')).toBeTruthy();
|
|
58
|
+
expect(zip.file('OEBPS/toc.xhtml')).toBeTruthy();
|
|
59
|
+
expect(zip.file('OEBPS/styles.css')).toBeTruthy();
|
|
60
|
+
});
|
|
61
|
+
it('mimetype contains "application/epub+zip"', async () => {
|
|
62
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
63
|
+
const zip = await exportAndUnzip(doc);
|
|
64
|
+
const mimetype = await zip.file('mimetype').async('string');
|
|
65
|
+
expect(mimetype).toBe('application/epub+zip');
|
|
66
|
+
});
|
|
67
|
+
it('container.xml points to content.opf', async () => {
|
|
68
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
69
|
+
const zip = await exportAndUnzip(doc);
|
|
70
|
+
const containerXml = await zip.file('META-INF/container.xml').async('string');
|
|
71
|
+
expect(containerXml).toContain('OEBPS/content.opf');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('chapter splitting', () => {
|
|
75
|
+
it('splits at H1 boundaries', async () => {
|
|
76
|
+
const doc = makeDoc([
|
|
77
|
+
heading(1, 'Chapter One'),
|
|
78
|
+
paragraph('First chapter content'),
|
|
79
|
+
heading(1, 'Chapter Two'),
|
|
80
|
+
paragraph('Second chapter content'),
|
|
81
|
+
]);
|
|
82
|
+
const zip = await exportAndUnzip(doc);
|
|
83
|
+
expect(zip.file('OEBPS/chapters/chapter-001.xhtml')).toBeTruthy();
|
|
84
|
+
expect(zip.file('OEBPS/chapters/chapter-002.xhtml')).toBeTruthy();
|
|
85
|
+
const ch1 = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
86
|
+
const ch2 = await zip.file('OEBPS/chapters/chapter-002.xhtml').async('string');
|
|
87
|
+
expect(ch1).toContain('Chapter One');
|
|
88
|
+
expect(ch1).toContain('First chapter content');
|
|
89
|
+
expect(ch2).toContain('Chapter Two');
|
|
90
|
+
expect(ch2).toContain('Second chapter content');
|
|
91
|
+
});
|
|
92
|
+
it('splits at H2 boundaries', async () => {
|
|
93
|
+
const doc = makeDoc([
|
|
94
|
+
heading(2, 'Section A'),
|
|
95
|
+
paragraph('A content'),
|
|
96
|
+
heading(2, 'Section B'),
|
|
97
|
+
paragraph('B content'),
|
|
98
|
+
]);
|
|
99
|
+
const zip = await exportAndUnzip(doc);
|
|
100
|
+
expect(zip.file('OEBPS/chapters/chapter-001.xhtml')).toBeTruthy();
|
|
101
|
+
expect(zip.file('OEBPS/chapters/chapter-002.xhtml')).toBeTruthy();
|
|
102
|
+
});
|
|
103
|
+
it('keeps content before first heading in a single chapter', async () => {
|
|
104
|
+
const doc = makeDoc([
|
|
105
|
+
paragraph('Intro text'),
|
|
106
|
+
heading(1, 'Chapter One'),
|
|
107
|
+
paragraph('Chapter content'),
|
|
108
|
+
]);
|
|
109
|
+
const zip = await exportAndUnzip(doc);
|
|
110
|
+
// Should have 2 chapters: intro + chapter one
|
|
111
|
+
expect(zip.file('OEBPS/chapters/chapter-001.xhtml')).toBeTruthy();
|
|
112
|
+
expect(zip.file('OEBPS/chapters/chapter-002.xhtml')).toBeTruthy();
|
|
113
|
+
const ch1 = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
114
|
+
expect(ch1).toContain('Intro text');
|
|
115
|
+
});
|
|
116
|
+
it('handles a document with no headings', async () => {
|
|
117
|
+
const doc = makeDoc([paragraph('Just a paragraph')]);
|
|
118
|
+
const zip = await exportAndUnzip(doc);
|
|
119
|
+
expect(zip.file('OEBPS/chapters/chapter-001.xhtml')).toBeTruthy();
|
|
120
|
+
const ch1 = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
121
|
+
expect(ch1).toContain('Just a paragraph');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe('XHTML content', () => {
|
|
125
|
+
it('renders headings with correct tags', async () => {
|
|
126
|
+
const doc = makeDoc([heading(1, 'H1'), heading(3, 'H3'), paragraph('text')]);
|
|
127
|
+
const zip = await exportAndUnzip(doc);
|
|
128
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
129
|
+
expect(ch).toContain('<h1>H1</h1>');
|
|
130
|
+
expect(ch).toContain('<h3>H3</h3>');
|
|
131
|
+
});
|
|
132
|
+
it('renders bold text as <strong>', async () => {
|
|
133
|
+
const doc = makeDoc([heading(1, 'Test'), boldParagraph('important')]);
|
|
134
|
+
const zip = await exportAndUnzip(doc);
|
|
135
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
136
|
+
expect(ch).toContain('<strong>important</strong>');
|
|
137
|
+
});
|
|
138
|
+
it('renders links as <a> elements', async () => {
|
|
139
|
+
const doc = makeDoc([heading(1, 'Test'), linkParagraph('click', 'https://example.com')]);
|
|
140
|
+
const zip = await exportAndUnzip(doc);
|
|
141
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
142
|
+
expect(ch).toContain('<a href="https://example.com">click</a>');
|
|
143
|
+
});
|
|
144
|
+
it('renders code blocks with language class', async () => {
|
|
145
|
+
const doc = makeDoc([heading(1, 'Test'), codeBlock('const x = 1;', 'javascript')]);
|
|
146
|
+
const zip = await exportAndUnzip(doc);
|
|
147
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
148
|
+
expect(ch).toContain('class="language-javascript"');
|
|
149
|
+
expect(ch).toContain('const x = 1;');
|
|
150
|
+
});
|
|
151
|
+
it('escapes special XML characters in text', async () => {
|
|
152
|
+
const doc = makeDoc([heading(1, 'Test'), paragraph('a < b & c > d')]);
|
|
153
|
+
const zip = await exportAndUnzip(doc);
|
|
154
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
155
|
+
expect(ch).toContain('a < b & c > d');
|
|
156
|
+
});
|
|
157
|
+
it('renders tables', async () => {
|
|
158
|
+
const table = {
|
|
159
|
+
type: 'table',
|
|
160
|
+
align: ['left', 'right'],
|
|
161
|
+
children: [
|
|
162
|
+
{
|
|
163
|
+
type: 'tableRow',
|
|
164
|
+
children: [
|
|
165
|
+
{ type: 'tableCell', isHeader: true, children: [{ type: 'text', value: 'Name' }] },
|
|
166
|
+
{ type: 'tableCell', isHeader: true, children: [{ type: 'text', value: 'Age' }] },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'tableRow',
|
|
171
|
+
children: [
|
|
172
|
+
{ type: 'tableCell', children: [{ type: 'text', value: 'Alice' }] },
|
|
173
|
+
{ type: 'tableCell', children: [{ type: 'text', value: '30' }] },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
};
|
|
178
|
+
const doc = makeDoc([heading(1, 'Test'), table]);
|
|
179
|
+
const zip = await exportAndUnzip(doc);
|
|
180
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
181
|
+
expect(ch).toContain('<table>');
|
|
182
|
+
expect(ch).toContain('<th');
|
|
183
|
+
expect(ch).toContain('Name');
|
|
184
|
+
expect(ch).toContain('<td');
|
|
185
|
+
expect(ch).toContain('Alice');
|
|
186
|
+
expect(ch).toContain('text-align: right');
|
|
187
|
+
});
|
|
188
|
+
it('renders thematic breaks as <hr/>', async () => {
|
|
189
|
+
const doc = makeDoc([heading(1, 'Test'), { type: 'thematicBreak' }, paragraph('after')]);
|
|
190
|
+
const zip = await exportAndUnzip(doc);
|
|
191
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
192
|
+
expect(ch).toContain('<hr/>');
|
|
193
|
+
});
|
|
194
|
+
it('renders blockquotes', async () => {
|
|
195
|
+
const doc = makeDoc([
|
|
196
|
+
heading(1, 'Test'),
|
|
197
|
+
{ type: 'blockquote', children: [paragraph('A quote')] },
|
|
198
|
+
]);
|
|
199
|
+
const zip = await exportAndUnzip(doc);
|
|
200
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
201
|
+
expect(ch).toContain('<blockquote>');
|
|
202
|
+
expect(ch).toContain('A quote');
|
|
203
|
+
});
|
|
204
|
+
it('renders ordered and unordered lists', async () => {
|
|
205
|
+
const doc = makeDoc([
|
|
206
|
+
heading(1, 'Test'),
|
|
207
|
+
{
|
|
208
|
+
type: 'list',
|
|
209
|
+
ordered: false,
|
|
210
|
+
children: [{ type: 'listItem', children: [paragraph('Bullet')] }],
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
type: 'list',
|
|
214
|
+
ordered: true,
|
|
215
|
+
children: [{ type: 'listItem', children: [paragraph('Numbered')] }],
|
|
216
|
+
},
|
|
217
|
+
]);
|
|
218
|
+
const zip = await exportAndUnzip(doc);
|
|
219
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
220
|
+
expect(ch).toContain('<ul>');
|
|
221
|
+
expect(ch).toContain('<ol>');
|
|
222
|
+
expect(ch).toContain('Bullet');
|
|
223
|
+
expect(ch).toContain('Numbered');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe('images', () => {
|
|
227
|
+
it('embeds provided images in the ZIP', async () => {
|
|
228
|
+
const imgData = new Uint8Array([0x89, 0x50, 0x4e, 0x47]).buffer;
|
|
229
|
+
const doc = makeDoc([heading(1, 'Test'), imageParagraph('Logo', 'images/logo.png')]);
|
|
230
|
+
const zip = await exportAndUnzip(doc, {
|
|
231
|
+
images: new Map([['images/logo.png', imgData]]),
|
|
232
|
+
});
|
|
233
|
+
expect(zip.file('OEBPS/images/logo.png')).toBeTruthy();
|
|
234
|
+
});
|
|
235
|
+
it('references images with correct relative path in XHTML', async () => {
|
|
236
|
+
const imgData = new Uint8Array([0xff, 0xd8]).buffer;
|
|
237
|
+
const doc = makeDoc([heading(1, 'Test'), imageParagraph('Photo', 'photo.jpg')]);
|
|
238
|
+
const zip = await exportAndUnzip(doc, {
|
|
239
|
+
images: new Map([['photo.jpg', imgData]]),
|
|
240
|
+
});
|
|
241
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
242
|
+
expect(ch).toContain('src="../images/photo.jpg"');
|
|
243
|
+
expect(ch).toContain('alt="Photo"');
|
|
244
|
+
});
|
|
245
|
+
it('lists images in the OPF manifest', async () => {
|
|
246
|
+
const imgData = new Uint8Array([0x89]).buffer;
|
|
247
|
+
const doc = makeDoc([heading(1, 'Test'), imageParagraph('Pic', 'pic.png')]);
|
|
248
|
+
const zip = await exportAndUnzip(doc, {
|
|
249
|
+
images: new Map([['pic.png', imgData]]),
|
|
250
|
+
});
|
|
251
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
252
|
+
expect(opf).toContain('images/pic.png');
|
|
253
|
+
expect(opf).toContain('image/png');
|
|
254
|
+
});
|
|
255
|
+
it('embeds cover image with cover-image property', async () => {
|
|
256
|
+
const coverData = new Uint8Array([0xff, 0xd8]).buffer;
|
|
257
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
258
|
+
const zip = await exportAndUnzip(doc, { coverImage: coverData });
|
|
259
|
+
expect(zip.file('OEBPS/images/cover.jpg')).toBeTruthy();
|
|
260
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
261
|
+
expect(opf).toContain('cover-image');
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
describe('metadata', () => {
|
|
265
|
+
it('includes title in OPF', async () => {
|
|
266
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
267
|
+
const zip = await exportAndUnzip(doc, { title: 'My Book' });
|
|
268
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
269
|
+
expect(opf).toContain('<dc:title>My Book</dc:title>');
|
|
270
|
+
});
|
|
271
|
+
it('includes author in OPF', async () => {
|
|
272
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
273
|
+
const zip = await exportAndUnzip(doc, { author: 'Jane Doe' });
|
|
274
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
275
|
+
expect(opf).toContain('<dc:creator>Jane Doe</dc:creator>');
|
|
276
|
+
});
|
|
277
|
+
it('includes language in OPF', async () => {
|
|
278
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
279
|
+
const zip = await exportAndUnzip(doc, { language: 'fr' });
|
|
280
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
281
|
+
expect(opf).toContain('<dc:language>fr</dc:language>');
|
|
282
|
+
});
|
|
283
|
+
it('defaults language to "en"', async () => {
|
|
284
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
285
|
+
const zip = await exportAndUnzip(doc);
|
|
286
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
287
|
+
expect(opf).toContain('<dc:language>en</dc:language>');
|
|
288
|
+
});
|
|
289
|
+
it('includes description and publisher when provided', async () => {
|
|
290
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
291
|
+
const zip = await exportAndUnzip(doc, {
|
|
292
|
+
description: 'A great book',
|
|
293
|
+
publisher: 'Acme Publishing',
|
|
294
|
+
});
|
|
295
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
296
|
+
expect(opf).toContain('<dc:description>A great book</dc:description>');
|
|
297
|
+
expect(opf).toContain('<dc:publisher>Acme Publishing</dc:publisher>');
|
|
298
|
+
});
|
|
299
|
+
it('includes UUID identifier', async () => {
|
|
300
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
301
|
+
const zip = await exportAndUnzip(doc);
|
|
302
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
303
|
+
expect(opf).toContain('urn:uuid:');
|
|
304
|
+
});
|
|
305
|
+
it('uses frontmatter title as fallback', async () => {
|
|
306
|
+
const doc = makeDoc([heading(1, 'Intro')], { title: 'Frontmatter Title' });
|
|
307
|
+
const zip = await exportAndUnzip(doc);
|
|
308
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
309
|
+
expect(opf).toContain('<dc:title>Frontmatter Title</dc:title>');
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
describe('table of contents', () => {
|
|
313
|
+
it('toc.xhtml lists all chapters', async () => {
|
|
314
|
+
const doc = makeDoc([
|
|
315
|
+
heading(1, 'Introduction'),
|
|
316
|
+
paragraph('Intro content'),
|
|
317
|
+
heading(1, 'Main Body'),
|
|
318
|
+
paragraph('Body content'),
|
|
319
|
+
]);
|
|
320
|
+
const zip = await exportAndUnzip(doc);
|
|
321
|
+
const toc = await zip.file('OEBPS/toc.xhtml').async('string');
|
|
322
|
+
expect(toc).toContain('Introduction');
|
|
323
|
+
expect(toc).toContain('Main Body');
|
|
324
|
+
expect(toc).toContain('epub:type="toc"');
|
|
325
|
+
});
|
|
326
|
+
it('spine references all chapters in order', async () => {
|
|
327
|
+
const doc = makeDoc([heading(1, 'Ch 1'), heading(1, 'Ch 2'), heading(1, 'Ch 3')]);
|
|
328
|
+
const zip = await exportAndUnzip(doc);
|
|
329
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
330
|
+
expect(opf).toContain('idref="chapter-001"');
|
|
331
|
+
expect(opf).toContain('idref="chapter-002"');
|
|
332
|
+
expect(opf).toContain('idref="chapter-003"');
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
describe('stylesheet', () => {
|
|
336
|
+
it('includes base CSS styles', async () => {
|
|
337
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
338
|
+
const zip = await exportAndUnzip(doc);
|
|
339
|
+
const css = await zip.file('OEBPS/styles.css').async('string');
|
|
340
|
+
expect(css).toContain('body');
|
|
341
|
+
expect(css).toContain('font-family');
|
|
342
|
+
expect(css).toContain('blockquote');
|
|
343
|
+
});
|
|
344
|
+
it('chapters reference the stylesheet', async () => {
|
|
345
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
346
|
+
const zip = await exportAndUnzip(doc);
|
|
347
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
348
|
+
expect(ch).toContain('href="../styles.css"');
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
describe('empty document', () => {
|
|
352
|
+
it('handles empty document gracefully', async () => {
|
|
353
|
+
const doc = makeDoc([]);
|
|
354
|
+
const zip = await exportAndUnzip(doc);
|
|
355
|
+
// Should still produce valid EPUB structure
|
|
356
|
+
expect(zip.file('mimetype')).toBeTruthy();
|
|
357
|
+
expect(zip.file('OEBPS/content.opf')).toBeTruthy();
|
|
358
|
+
expect(zip.file('OEBPS/chapters/chapter-001.xhtml')).toBeTruthy();
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
describe('audio narration (Media Overlays)', () => {
|
|
362
|
+
const audioData = new Uint8Array([0xff, 0xfb, 0x90, 0x00]).buffer; // fake MP3 header
|
|
363
|
+
const audioSegments = [
|
|
364
|
+
{ src: 'audio/intro.mp3', name: 'intro', duration: 15, startTime: 0 },
|
|
365
|
+
{ src: 'audio/body.mp3', name: 'body', duration: 20, startTime: 15 },
|
|
366
|
+
];
|
|
367
|
+
it('embeds audio files in the ZIP', async () => {
|
|
368
|
+
const doc = makeDoc([
|
|
369
|
+
heading(1, 'Intro'),
|
|
370
|
+
paragraph('Hello'),
|
|
371
|
+
heading(1, 'Body'),
|
|
372
|
+
paragraph('World'),
|
|
373
|
+
]);
|
|
374
|
+
const zip = await exportAndUnzip(doc, {
|
|
375
|
+
audio: new Map([
|
|
376
|
+
['audio/intro.mp3', audioData],
|
|
377
|
+
['audio/body.mp3', audioData],
|
|
378
|
+
]),
|
|
379
|
+
audioSegments,
|
|
380
|
+
totalDuration: 35,
|
|
381
|
+
});
|
|
382
|
+
expect(zip.file('OEBPS/audio/intro.mp3')).toBeTruthy();
|
|
383
|
+
expect(zip.file('OEBPS/audio/body.mp3')).toBeTruthy();
|
|
384
|
+
});
|
|
385
|
+
it('generates SMIL overlay files for each chapter', async () => {
|
|
386
|
+
const doc = makeDoc([
|
|
387
|
+
heading(1, 'Intro'),
|
|
388
|
+
paragraph('Hello'),
|
|
389
|
+
heading(1, 'Body'),
|
|
390
|
+
paragraph('World'),
|
|
391
|
+
]);
|
|
392
|
+
const zip = await exportAndUnzip(doc, {
|
|
393
|
+
audio: new Map([
|
|
394
|
+
['audio/intro.mp3', audioData],
|
|
395
|
+
['audio/body.mp3', audioData],
|
|
396
|
+
]),
|
|
397
|
+
audioSegments,
|
|
398
|
+
totalDuration: 35,
|
|
399
|
+
});
|
|
400
|
+
expect(zip.file('OEBPS/chapters/chapter-001.smil')).toBeTruthy();
|
|
401
|
+
expect(zip.file('OEBPS/chapters/chapter-002.smil')).toBeTruthy();
|
|
402
|
+
});
|
|
403
|
+
it('SMIL files reference correct chapter and audio', async () => {
|
|
404
|
+
const doc = makeDoc([heading(1, 'Intro'), paragraph('Content')]);
|
|
405
|
+
const zip = await exportAndUnzip(doc, {
|
|
406
|
+
audio: new Map([['audio/intro.mp3', audioData]]),
|
|
407
|
+
audioSegments: [audioSegments[0]],
|
|
408
|
+
totalDuration: 15,
|
|
409
|
+
});
|
|
410
|
+
const smil = await zip.file('OEBPS/chapters/chapter-001.smil').async('string');
|
|
411
|
+
expect(smil).toContain('chapter-001.xhtml');
|
|
412
|
+
expect(smil).toContain('intro.mp3');
|
|
413
|
+
expect(smil).toContain('clipBegin');
|
|
414
|
+
expect(smil).toContain('clipEnd');
|
|
415
|
+
expect(smil).toContain('<par');
|
|
416
|
+
expect(smil).toContain('<text');
|
|
417
|
+
expect(smil).toContain('<audio');
|
|
418
|
+
});
|
|
419
|
+
it('OPF includes media-overlay references', async () => {
|
|
420
|
+
const doc = makeDoc([heading(1, 'Intro'), paragraph('Content')]);
|
|
421
|
+
const zip = await exportAndUnzip(doc, {
|
|
422
|
+
audio: new Map([['audio/intro.mp3', audioData]]),
|
|
423
|
+
audioSegments: [audioSegments[0]],
|
|
424
|
+
totalDuration: 15,
|
|
425
|
+
});
|
|
426
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
427
|
+
expect(opf).toContain('media-overlay=');
|
|
428
|
+
expect(opf).toContain('application/smil+xml');
|
|
429
|
+
expect(opf).toContain('audio/intro.mp3');
|
|
430
|
+
});
|
|
431
|
+
it('OPF includes total duration metadata', async () => {
|
|
432
|
+
const doc = makeDoc([heading(1, 'Intro'), paragraph('Content')]);
|
|
433
|
+
const zip = await exportAndUnzip(doc, {
|
|
434
|
+
audio: new Map([['audio/intro.mp3', audioData]]),
|
|
435
|
+
audioSegments: [audioSegments[0]],
|
|
436
|
+
totalDuration: 35,
|
|
437
|
+
});
|
|
438
|
+
const opf = await zip.file('OEBPS/content.opf').async('string');
|
|
439
|
+
expect(opf).toContain('media:duration');
|
|
440
|
+
expect(opf).toContain('media:active-class');
|
|
441
|
+
});
|
|
442
|
+
it('chapter XHTML has element IDs for SMIL references', async () => {
|
|
443
|
+
const doc = makeDoc([heading(1, 'Title'), paragraph('First'), paragraph('Second')]);
|
|
444
|
+
const zip = await exportAndUnzip(doc, {
|
|
445
|
+
audio: new Map([['audio/intro.mp3', audioData]]),
|
|
446
|
+
audioSegments: [audioSegments[0]],
|
|
447
|
+
totalDuration: 15,
|
|
448
|
+
});
|
|
449
|
+
const ch = await zip.file('OEBPS/chapters/chapter-001.xhtml').async('string');
|
|
450
|
+
expect(ch).toContain('id="p1"');
|
|
451
|
+
expect(ch).toContain('id="p2"');
|
|
452
|
+
expect(ch).toContain('id="p3"');
|
|
453
|
+
});
|
|
454
|
+
it('stylesheet includes media overlay active class', async () => {
|
|
455
|
+
const doc = makeDoc([heading(1, 'Test')]);
|
|
456
|
+
const zip = await exportAndUnzip(doc);
|
|
457
|
+
const css = await zip.file('OEBPS/styles.css').async('string');
|
|
458
|
+
expect(css).toContain('epub-media-overlay-active');
|
|
459
|
+
});
|
|
460
|
+
it('no SMIL files when audio is not provided', async () => {
|
|
461
|
+
const doc = makeDoc([heading(1, 'Test'), paragraph('No audio')]);
|
|
462
|
+
const zip = await exportAndUnzip(doc);
|
|
463
|
+
// No .smil files should exist
|
|
464
|
+
const smilFiles = Object.keys(zip.files).filter((f) => f.endsWith('.smil'));
|
|
465
|
+
expect(smilFiles).toHaveLength(0);
|
|
466
|
+
// No audio directory
|
|
467
|
+
const audioDir = Object.keys(zip.files).filter((f) => f.startsWith('OEBPS/audio/'));
|
|
468
|
+
expect(audioDir).toHaveLength(0);
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
//# sourceMappingURL=epub.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epub.test.js","sourceRoot":"","sources":["../../src/__tests__/epub.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
escapeXml,
|
|
3
|
+
xmlDeclaration
|
|
4
|
+
} from "./chunk-U4MRIFKL.js";
|
|
5
|
+
|
|
1
6
|
// src/ooxml/namespaces.ts
|
|
2
7
|
var NS_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
3
8
|
var NS_CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
@@ -42,40 +47,6 @@ var REL_SLIDE_LAYOUT = "http://schemas.openxmlformats.org/officeDocument/2006/re
|
|
|
42
47
|
var REL_SLIDE_MASTER = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster";
|
|
43
48
|
var CONTENT_TYPE_XLSX_WORKBOOK = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
|
|
44
49
|
|
|
45
|
-
// src/ooxml/xmlUtils.ts
|
|
46
|
-
function xmlDeclaration() {
|
|
47
|
-
return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
|
|
48
|
-
}
|
|
49
|
-
function escapeXml(text) {
|
|
50
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
51
|
-
}
|
|
52
|
-
function attrString(attrs) {
|
|
53
|
-
if (!attrs) return "";
|
|
54
|
-
const parts = [];
|
|
55
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
56
|
-
if (value !== void 0 && value !== "") {
|
|
57
|
-
parts.push(` ${key}="${escapeXml(value)}"`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return parts.join("");
|
|
61
|
-
}
|
|
62
|
-
function selfClosingElement(tag, attrs) {
|
|
63
|
-
return `<${tag}${attrString(attrs)}/>`;
|
|
64
|
-
}
|
|
65
|
-
function xmlElement(tag, attrs, ...children) {
|
|
66
|
-
const content = children.join("");
|
|
67
|
-
if (content === "") {
|
|
68
|
-
return selfClosingElement(tag, attrs);
|
|
69
|
-
}
|
|
70
|
-
return `<${tag}${attrString(attrs)}>${content}</${tag}>`;
|
|
71
|
-
}
|
|
72
|
-
function textElement(tag, attrs, text) {
|
|
73
|
-
if (text === void 0 || text === "") {
|
|
74
|
-
return selfClosingElement(tag, attrs);
|
|
75
|
-
}
|
|
76
|
-
return `<${tag}${attrString(attrs)}>${escapeXml(text)}</${tag}>`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
50
|
// src/ooxml/writer.ts
|
|
80
51
|
import JSZip from "jszip";
|
|
81
52
|
function createPackage() {
|
|
@@ -280,12 +251,6 @@ export {
|
|
|
280
251
|
REL_SLIDE_LAYOUT,
|
|
281
252
|
REL_SLIDE_MASTER,
|
|
282
253
|
CONTENT_TYPE_XLSX_WORKBOOK,
|
|
283
|
-
xmlDeclaration,
|
|
284
|
-
escapeXml,
|
|
285
|
-
attrString,
|
|
286
|
-
selfClosingElement,
|
|
287
|
-
xmlElement,
|
|
288
|
-
textElement,
|
|
289
254
|
createPackage
|
|
290
255
|
};
|
|
291
|
-
//# sourceMappingURL=chunk-
|
|
256
|
+
//# sourceMappingURL=chunk-7DEUGIOO.js.map
|