@storyteller-platform/align 0.1.16 → 0.1.18
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/binding.gyp +26 -0
- package/dist/align/align.cjs +6 -7
- package/dist/align/align.js +6 -7
- package/dist/cli/bin.cjs +1 -1
- package/dist/cli/bin.js +2 -2
- package/dist/common/ffmpeg.cjs +12 -12
- package/dist/common/ffmpeg.js +12 -12
- package/dist/errorAlign/backtraceGraph.cjs +5 -8
- package/dist/errorAlign/backtraceGraph.js +5 -8
- package/dist/errorAlign/beamSearch.cjs +1 -2
- package/dist/errorAlign/beamSearch.js +1 -2
- package/dist/markup/markup.cjs +3 -4
- package/dist/markup/markup.js +3 -4
- package/dist/markup/serializeDom.cjs +1 -1
- package/dist/markup/serializeDom.js +1 -1
- package/dist/process/processAudiobook.cjs +8 -12
- package/dist/process/processAudiobook.js +8 -12
- package/dist/process/ranges.cjs +3 -3
- package/dist/process/ranges.js +3 -3
- package/dist/transcribe/transcribe.cjs +9 -14
- package/dist/transcribe/transcribe.js +9 -14
- package/package.json +3 -1
- package/prebuilds/darwin-arm64/@storyteller-platform+align.node +0 -0
- package/prebuilds/linux-arm64/@storyteller-platform+align.node +0 -0
- package/prebuilds/linux-x64/@storyteller-platform+align.node +0 -0
- package/dist/align/__tests__/align.test.cjs +0 -283
- package/dist/align/__tests__/align.test.d.cts +0 -2
- package/dist/align/__tests__/align.test.d.ts +0 -2
- package/dist/align/__tests__/align.test.js +0 -219
- package/dist/align/__tests__/slugify.test.cjs +0 -64
- package/dist/align/__tests__/slugify.test.d.cts +0 -2
- package/dist/align/__tests__/slugify.test.d.ts +0 -2
- package/dist/align/__tests__/slugify.test.js +0 -41
- package/dist/errorAlign/__tests__/errorAlign.test.cjs +0 -100
- package/dist/errorAlign/__tests__/errorAlign.test.d.cts +0 -2
- package/dist/errorAlign/__tests__/errorAlign.test.d.ts +0 -2
- package/dist/errorAlign/__tests__/errorAlign.test.js +0 -77
- package/dist/errorAlign/__tests__/native.test.cjs +0 -118
- package/dist/errorAlign/__tests__/native.test.d.cts +0 -2
- package/dist/errorAlign/__tests__/native.test.d.ts +0 -2
- package/dist/errorAlign/__tests__/native.test.js +0 -107
- package/dist/markup/__tests__/markup.test.cjs +0 -491
- package/dist/markup/__tests__/markup.test.d.cts +0 -2
- package/dist/markup/__tests__/markup.test.d.ts +0 -2
- package/dist/markup/__tests__/markup.test.js +0 -468
- package/dist/markup/__tests__/parseDom.test.cjs +0 -112
- package/dist/markup/__tests__/parseDom.test.d.cts +0 -2
- package/dist/markup/__tests__/parseDom.test.d.ts +0 -2
- package/dist/markup/__tests__/parseDom.test.js +0 -89
- package/dist/markup/__tests__/serializeDom.test.cjs +0 -120
- package/dist/markup/__tests__/serializeDom.test.d.cts +0 -2
- package/dist/markup/__tests__/serializeDom.test.d.ts +0 -2
- package/dist/markup/__tests__/serializeDom.test.js +0 -97
- package/dist/markup/__tests__/transform.test.cjs +0 -122
- package/dist/markup/__tests__/transform.test.d.cts +0 -2
- package/dist/markup/__tests__/transform.test.d.ts +0 -2
- package/dist/markup/__tests__/transform.test.js +0 -99
- package/dist/process/__tests__/processAudiobook.test.cjs +0 -232
- package/dist/process/__tests__/processAudiobook.test.d.cts +0 -2
- package/dist/process/__tests__/processAudiobook.test.d.ts +0 -2
- package/dist/process/__tests__/processAudiobook.test.js +0 -209
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { describe, it } from "node:test";
|
|
5
|
-
import { Epub } from "@storyteller-platform/epub";
|
|
6
|
-
import { markupChapter } from "../markup.js";
|
|
7
|
-
import { getXhtmlSegmentation } from "../segmentation.js";
|
|
8
|
-
function sanitizeFilename(title) {
|
|
9
|
-
return title.replace(/[/\\:*?"<>|]/g, "-").replace(/\s+/g, " ").trim().replace(/[.]+$/, "");
|
|
10
|
-
}
|
|
11
|
-
function truncate(input, byteLimit, suffix = "") {
|
|
12
|
-
const normalized = input.normalize("NFC");
|
|
13
|
-
const encoder = new TextEncoder();
|
|
14
|
-
let result = "";
|
|
15
|
-
for (const char of normalized) {
|
|
16
|
-
const withSuffix = result + char + suffix;
|
|
17
|
-
const byteLength = encoder.encode(withSuffix).length;
|
|
18
|
-
if (byteLength > byteLimit) break;
|
|
19
|
-
result += char;
|
|
20
|
-
}
|
|
21
|
-
return result + suffix;
|
|
22
|
-
}
|
|
23
|
-
function getSafeFilepathSegment(name, suffix = "") {
|
|
24
|
-
return truncate(sanitizeFilename(name), 150, suffix);
|
|
25
|
-
}
|
|
26
|
-
async function assertMarkupSnapshot(context, output) {
|
|
27
|
-
const snapshotFilename = getSafeFilepathSegment(context.fullName, ".snapshot");
|
|
28
|
-
const snapshotFilepath = join(
|
|
29
|
-
"src",
|
|
30
|
-
"markup",
|
|
31
|
-
"__snapshots__",
|
|
32
|
-
snapshotFilename
|
|
33
|
-
);
|
|
34
|
-
if (process.env["UPDATE_SNAPSHOTS"]) {
|
|
35
|
-
await mkdir(dirname(snapshotFilepath), { recursive: true });
|
|
36
|
-
await writeFile(snapshotFilepath, output, { encoding: "utf-8" });
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
const existingSnapshot = await readFile(snapshotFilepath, {
|
|
41
|
-
encoding: "utf-8"
|
|
42
|
-
});
|
|
43
|
-
const existingLines = existingSnapshot.split("\n");
|
|
44
|
-
const newLines = output.split("\n");
|
|
45
|
-
for (let i = 0; i < existingLines.length; i++) {
|
|
46
|
-
const existingLine = existingLines[i];
|
|
47
|
-
const newLine = newLines[i];
|
|
48
|
-
if (existingLine !== newLine) {
|
|
49
|
-
assert.strictEqual(
|
|
50
|
-
newLines.slice(Math.max(0, i - 5), i + 5),
|
|
51
|
-
existingLines.slice(Math.max(0, i - 5), i + 5)
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
} catch (e) {
|
|
56
|
-
if (e instanceof assert.AssertionError) {
|
|
57
|
-
throw e;
|
|
58
|
-
}
|
|
59
|
-
throw new assert.AssertionError({
|
|
60
|
-
actual: output,
|
|
61
|
-
expected: "",
|
|
62
|
-
diff: "simple"
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
void describe("markupChapter", () => {
|
|
67
|
-
void it("can tag sentences", async (t) => {
|
|
68
|
-
const input = Epub.xhtmlParser.parse(
|
|
69
|
-
/* xml */
|
|
70
|
-
`
|
|
71
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
72
|
-
|
|
73
|
-
<html>
|
|
74
|
-
<head>
|
|
75
|
-
<meta charset="utf-8" />
|
|
76
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
77
|
-
</head>
|
|
78
|
-
<body>
|
|
79
|
-
<p>
|
|
80
|
-
Call me Ishmael. Some years ago\u2014never mind how long precisely\u2014having
|
|
81
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
82
|
-
shore, I thought I would sail about a little and see the watery part of
|
|
83
|
-
the world. It is a way I have of driving off the spleen and regulating the
|
|
84
|
-
circulation. Whenever I find myself growing grim about the mouth; whenever
|
|
85
|
-
it is a damp, drizzly November in my soul; whenever I find myself
|
|
86
|
-
involuntarily pausing before coffin warehouses, and bringing up the rear
|
|
87
|
-
of every funeral I meet; and especially whenever my hypos get such an
|
|
88
|
-
upper hand of me, that it requires a strong moral principle to prevent me
|
|
89
|
-
from deliberately stepping into the street, and methodically knocking
|
|
90
|
-
people\u2019s hats off\u2014then, I account it high time to get to sea as soon
|
|
91
|
-
as I can.
|
|
92
|
-
</p>
|
|
93
|
-
<p>
|
|
94
|
-
This is my substitute for pistol and ball. With a philosophical
|
|
95
|
-
flourish Cato throws himself upon his sword; I quietly take to the ship.
|
|
96
|
-
There is nothing surprising in this. If they but knew it, almost all men
|
|
97
|
-
in their degree, some time or other, cherish very nearly the same feelings
|
|
98
|
-
towards the ocean with me.
|
|
99
|
-
</p>
|
|
100
|
-
</body>
|
|
101
|
-
</html>
|
|
102
|
-
`
|
|
103
|
-
);
|
|
104
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
105
|
-
Epub.getXhtmlBody(input),
|
|
106
|
-
{}
|
|
107
|
-
);
|
|
108
|
-
const { markedUp: output } = markupChapter(
|
|
109
|
-
"chapter_one",
|
|
110
|
-
input,
|
|
111
|
-
segmentation,
|
|
112
|
-
mapping
|
|
113
|
-
);
|
|
114
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
115
|
-
});
|
|
116
|
-
void it("can tag sentences with formatting marks", async (t) => {
|
|
117
|
-
const input = Epub.xhtmlParser.parse(
|
|
118
|
-
/* xml */
|
|
119
|
-
`
|
|
120
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
121
|
-
|
|
122
|
-
<html>
|
|
123
|
-
<head>
|
|
124
|
-
<meta charset="utf-8" />
|
|
125
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
126
|
-
</head>
|
|
127
|
-
<body>
|
|
128
|
-
<p>
|
|
129
|
-
Call me <strong>Ishmael</strong>. Some years ago\u2014never mind how long precisely\u2014having
|
|
130
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
131
|
-
shore, I thought I would sail about a little and see the watery part of
|
|
132
|
-
the world.
|
|
133
|
-
</p>
|
|
134
|
-
</body>
|
|
135
|
-
</html>
|
|
136
|
-
`
|
|
137
|
-
);
|
|
138
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
139
|
-
Epub.getXhtmlBody(input),
|
|
140
|
-
{}
|
|
141
|
-
);
|
|
142
|
-
const { markedUp: output } = markupChapter(
|
|
143
|
-
"chapter_one",
|
|
144
|
-
input,
|
|
145
|
-
segmentation,
|
|
146
|
-
mapping
|
|
147
|
-
);
|
|
148
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
149
|
-
});
|
|
150
|
-
void it("can tag sentences with formatting marks that overlap sentence boundaries", async (t) => {
|
|
151
|
-
const input = Epub.xhtmlParser.parse(
|
|
152
|
-
/* xml */
|
|
153
|
-
`
|
|
154
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
155
|
-
|
|
156
|
-
<html>
|
|
157
|
-
<head>
|
|
158
|
-
<meta charset="utf-8" />
|
|
159
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
160
|
-
</head>
|
|
161
|
-
<body>
|
|
162
|
-
<p>
|
|
163
|
-
Call me <strong>Ishmael. Some years ago</strong>\u2014never mind how long precisely\u2014having
|
|
164
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
165
|
-
shore, I thought I would sail about a little and see the watery part of
|
|
166
|
-
the world.
|
|
167
|
-
</p>
|
|
168
|
-
</body>
|
|
169
|
-
</html>
|
|
170
|
-
`
|
|
171
|
-
);
|
|
172
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
173
|
-
Epub.getXhtmlBody(input),
|
|
174
|
-
{}
|
|
175
|
-
);
|
|
176
|
-
const { markedUp: output } = markupChapter(
|
|
177
|
-
"chapter_one",
|
|
178
|
-
input,
|
|
179
|
-
segmentation,
|
|
180
|
-
mapping
|
|
181
|
-
);
|
|
182
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
183
|
-
});
|
|
184
|
-
void it("can tag sentences with nested formatting marks", async (t) => {
|
|
185
|
-
const input = Epub.xhtmlParser.parse(
|
|
186
|
-
/* xml */
|
|
187
|
-
`
|
|
188
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
189
|
-
|
|
190
|
-
<html>
|
|
191
|
-
<head>
|
|
192
|
-
<meta charset="utf-8" />
|
|
193
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
194
|
-
</head>
|
|
195
|
-
<body>
|
|
196
|
-
<p>
|
|
197
|
-
<em>Call me <strong>Ishmael</strong>.</em> Some years ago\u2014never mind how long precisely\u2014having
|
|
198
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
199
|
-
shore, I thought I would sail about a little and see the watery part of
|
|
200
|
-
the world.
|
|
201
|
-
</p>
|
|
202
|
-
</body>
|
|
203
|
-
</html>
|
|
204
|
-
`
|
|
205
|
-
);
|
|
206
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
207
|
-
Epub.getXhtmlBody(input),
|
|
208
|
-
{}
|
|
209
|
-
);
|
|
210
|
-
const { markedUp: output } = markupChapter(
|
|
211
|
-
"chapter_one",
|
|
212
|
-
input,
|
|
213
|
-
segmentation,
|
|
214
|
-
mapping
|
|
215
|
-
);
|
|
216
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
217
|
-
});
|
|
218
|
-
void it("can tag sentences with atoms", async (t) => {
|
|
219
|
-
const input = Epub.xhtmlParser.parse(
|
|
220
|
-
/* xml */
|
|
221
|
-
`
|
|
222
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
223
|
-
|
|
224
|
-
<html>
|
|
225
|
-
<head>
|
|
226
|
-
<meta charset="utf-8" />
|
|
227
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
228
|
-
</head>
|
|
229
|
-
<body>
|
|
230
|
-
<p>
|
|
231
|
-
Call me Ishmael. Some<img src="#"/> years ago\u2014never mind how long precisely\u2014having
|
|
232
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
233
|
-
shore, I thought I would sail about a little and see the watery part of
|
|
234
|
-
the world.
|
|
235
|
-
</p>
|
|
236
|
-
</body>
|
|
237
|
-
</html>
|
|
238
|
-
`
|
|
239
|
-
);
|
|
240
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
241
|
-
Epub.getXhtmlBody(input),
|
|
242
|
-
{}
|
|
243
|
-
);
|
|
244
|
-
const { markedUp: output } = markupChapter(
|
|
245
|
-
"chapter_one",
|
|
246
|
-
input,
|
|
247
|
-
segmentation,
|
|
248
|
-
mapping
|
|
249
|
-
);
|
|
250
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
251
|
-
});
|
|
252
|
-
void it("can tag sentences in nested textblocks", async (t) => {
|
|
253
|
-
const input = Epub.xhtmlParser.parse(
|
|
254
|
-
/* xml */
|
|
255
|
-
`
|
|
256
|
-
<?xml version='1.0' encoding='utf-8'?>
|
|
257
|
-
<!DOCTYPE html>
|
|
258
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"
|
|
259
|
-
epub:prefix="z3998: http://www.daisy.org/z3998/2012/vocab/structure/#" lang="en" xml:lang="en">
|
|
260
|
-
|
|
261
|
-
<head>
|
|
262
|
-
<link href="../styles/9781534431010.css" rel="stylesheet" type="text/css" />
|
|
263
|
-
<link href="../styles/SS_global.css" rel="stylesheet" type="text/css" />
|
|
264
|
-
<link rel="stylesheet" href="../../Styles/storyteller-readaloud.css" type="text/css" />
|
|
265
|
-
</head>
|
|
266
|
-
|
|
267
|
-
<body>
|
|
268
|
-
<blockquote class="blockquotelet">
|
|
269
|
-
<p class="blockno"><span aria-label="page 7" id="page_7" role="doc-pagebreak" /></p>
|
|
270
|
-
<p class="blockno">Look on my works, ye mighty, and despair!</p>
|
|
271
|
-
<p class="blockno1">A little joke.</p>
|
|
272
|
-
<p class="blockno1"> </p>
|
|
273
|
-
<p class="blockno1">Trust that I have accounted for all variables of irony.</p>
|
|
274
|
-
<p class="blockno1"> </p>
|
|
275
|
-
<p class="blockno1">Though I suppose if you\u2019re unfamiliar with overanthologized works of the early Strand 6
|
|
276
|
-
nineteenth century, the joke\u2019s on me.</p>
|
|
277
|
-
<p class="blockin">I hoped you\u2019d come.</p>
|
|
278
|
-
</blockquote>
|
|
279
|
-
</body>
|
|
280
|
-
|
|
281
|
-
</html>
|
|
282
|
-
`
|
|
283
|
-
);
|
|
284
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
285
|
-
Epub.getXhtmlBody(input),
|
|
286
|
-
{}
|
|
287
|
-
);
|
|
288
|
-
const { markedUp: output } = markupChapter(
|
|
289
|
-
"chapter_one",
|
|
290
|
-
input,
|
|
291
|
-
segmentation,
|
|
292
|
-
mapping
|
|
293
|
-
);
|
|
294
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
295
|
-
});
|
|
296
|
-
void it("can tag sentences that cross textblock boundaries", async (t) => {
|
|
297
|
-
const input = Epub.xhtmlParser.parse(
|
|
298
|
-
/* xml */
|
|
299
|
-
`
|
|
300
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
301
|
-
|
|
302
|
-
<html>
|
|
303
|
-
<head>
|
|
304
|
-
<meta charset="utf-8" />
|
|
305
|
-
<title>The Project Gutenberg eBook of Moby Dick; Or the Whale, by Herman Melville</title>
|
|
306
|
-
</head>
|
|
307
|
-
<body>
|
|
308
|
-
<p>
|
|
309
|
-
Call me Ishmael. Some years ago\u2014never mind how long precisely\u2014having
|
|
310
|
-
little or no money in my purse, and nothing particular to interest me on
|
|
311
|
-
shore,
|
|
312
|
-
</p>
|
|
313
|
-
<p>
|
|
314
|
-
I thought I would sail about a little and see the watery part of
|
|
315
|
-
the world.
|
|
316
|
-
</p>
|
|
317
|
-
</body>
|
|
318
|
-
</html>
|
|
319
|
-
`
|
|
320
|
-
);
|
|
321
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
322
|
-
Epub.getXhtmlBody(input),
|
|
323
|
-
{}
|
|
324
|
-
);
|
|
325
|
-
const { markedUp: output } = markupChapter(
|
|
326
|
-
"chapter_one",
|
|
327
|
-
input,
|
|
328
|
-
segmentation,
|
|
329
|
-
mapping
|
|
330
|
-
);
|
|
331
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
332
|
-
});
|
|
333
|
-
void it.only("can handle soft page breaks", async (t) => {
|
|
334
|
-
const input = Epub.xhtmlParser.parse(
|
|
335
|
-
/* xml */
|
|
336
|
-
`
|
|
337
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="en-US" xml:lang="en-US">
|
|
338
|
-
<head>
|
|
339
|
-
<title>Chapter 1, Black Powder War</title>
|
|
340
|
-
<meta charset="utf-8"/>
|
|
341
|
-
<link href="../css/prh_resets.css" rel="stylesheet" type="text/css"/>
|
|
342
|
-
<link href="../css/rh_static.css" rel="stylesheet" type="text/css"/>
|
|
343
|
-
<link href="../css/9780345493439_style.css" rel="stylesheet" type="text/css"/>
|
|
344
|
-
<meta content="urn:uuid:52698e83-e600-48be-b763-c64bde1e3e0c" name="Adept.expected.resource"/>
|
|
345
|
-
</head>
|
|
346
|
-
<body>
|
|
347
|
-
<a id="d1-d2s6d3s2"/>
|
|
348
|
-
<div class="page_top_padding">
|
|
349
|
-
<span epub:type="pagebreak" id="page_9" role="doc-pagebreak" title="9"/>
|
|
350
|
-
<h1 class="para-cn-chap-pg trajan-pro-3">CHAPTER 1</h1>
|
|
351
|
-
<div class="para-orn">
|
|
352
|
-
<span class="figure figure_dingbat">
|
|
353
|
-
<img alt="" class="height_1em" role="presentation" src="../images/Novi_9780345493439_epub3_001_r1.jpg"/></span></div>
|
|
354
|
-
<p class="para-pf dropcaps3line char-dropcap-DC trajan-pro-3-dc" style="text-indent:0;">The hot wind blowing into Macao was sluggish and unrefreshing, only stirring up the rotting salt smell of the harbor, the fish-corpses and great knots of black-red seaweed, the effluvia of human and dragon wastes. Even so the sailors were sitting crowded along the rails of the <i class="char-i">Allegiance</i> for a breath of the moving air, leaning against one another to get a little room. A little scuffling broke out amongst them from time to time, a dull exchange of shoving back and forth, but these quarrels died almost at once in the punishing heat.</p>
|
|
355
|
-
<p class="para-p">Temeraire lay disconsolately upon the dragondeck, gazing towards the white haze of the open ocean, the aviators on duty lying half-asleep in his great shadow. Laurence himself had sacrificed dignity so far as to take off his coat, as he was sitting in the crook of Temeraire\u2019s foreleg and so concealed from view.</p>
|
|
356
|
-
<p class="para-p">\u201CI am sure I could pull the ship out of the harbor,\u201D Temeraire said, not for the first time in the past week; and sighed when this amiable plan was again refused: in a calm he might indeed have been able to tow even the enormous dragon transport, but against a direct headwind he could only exhaust himself to no purpose.</p>
|
|
357
|
-
<span epub:type="pagebreak" id="page_10" role="doc-pagebreak" title="10"/>
|
|
358
|
-
<p class="para-p">\u201CEven in a calm you could scarcely pull her any great distance,\u201D Laurence added consolingly. \u201CA few miles may be of some use out in the open ocean, but at present we may as well stay in harbor, and be a little more comfortable; we would make very little speed even if we could get her out.\u201D</p>
|
|
359
|
-
<p class="para-p">\u201CIt seems a great pity to me that we must always be waiting on the wind, when everything else is ready and we are also,\u201D Temeraire said. \u201CI would so like to be home <i class="char-i">soon:</i> there is so very much to be done.\u201D His tail thumped hollowly upon the boards, for emphasis.</p>
|
|
360
|
-
<p class="para-p">\u201CI beg you will not raise your hopes too high,\u201D Laurence said, himself a little hopelessly: urging Temeraire to restraint had so far not produced any effect, and he did not expect a different event now. \u201CYou must be prepared to endure some delays; at home as much as here.\u201D</p>
|
|
361
|
-
</div>
|
|
362
|
-
</body>
|
|
363
|
-
</html>`
|
|
364
|
-
);
|
|
365
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
366
|
-
Epub.getXhtmlBody(input),
|
|
367
|
-
{}
|
|
368
|
-
);
|
|
369
|
-
const { markedUp: output } = markupChapter(
|
|
370
|
-
"chapter_one",
|
|
371
|
-
input,
|
|
372
|
-
segmentation,
|
|
373
|
-
mapping
|
|
374
|
-
);
|
|
375
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
376
|
-
});
|
|
377
|
-
void it("can handle boolean-like text values", async (t) => {
|
|
378
|
-
const input = Epub.xhtmlParser.parse(`
|
|
379
|
-
<?xml version="1.0" encoding="UTF-8" standalone="no"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
380
|
-
<head>
|
|
381
|
-
</head>
|
|
382
|
-
<body>
|
|
383
|
-
<p>true</p>
|
|
384
|
-
</body>
|
|
385
|
-
</html>
|
|
386
|
-
`);
|
|
387
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
388
|
-
Epub.getXhtmlBody(input),
|
|
389
|
-
{}
|
|
390
|
-
);
|
|
391
|
-
const { markedUp: output } = markupChapter(
|
|
392
|
-
"chapter_one",
|
|
393
|
-
input,
|
|
394
|
-
segmentation,
|
|
395
|
-
mapping
|
|
396
|
-
);
|
|
397
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
398
|
-
});
|
|
399
|
-
void it("can handle number-like text values", async (t) => {
|
|
400
|
-
const input = Epub.xhtmlParser.parse(`
|
|
401
|
-
<?xml version="1.0" encoding="UTF-8" standalone="no"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
402
|
-
<head>
|
|
403
|
-
</head>
|
|
404
|
-
<body>
|
|
405
|
-
<p>5.000</p>
|
|
406
|
-
</body>
|
|
407
|
-
</html>
|
|
408
|
-
`);
|
|
409
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
410
|
-
Epub.getXhtmlBody(input),
|
|
411
|
-
{}
|
|
412
|
-
);
|
|
413
|
-
const { markedUp: output } = markupChapter(
|
|
414
|
-
"chapter_one",
|
|
415
|
-
input,
|
|
416
|
-
segmentation,
|
|
417
|
-
mapping
|
|
418
|
-
);
|
|
419
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
420
|
-
});
|
|
421
|
-
void it("can handle null-like text values", async (t) => {
|
|
422
|
-
const input = Epub.xhtmlParser.parse(`
|
|
423
|
-
<?xml version="1.0" encoding="UTF-8" standalone="no"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
424
|
-
<head>
|
|
425
|
-
</head>
|
|
426
|
-
<body>
|
|
427
|
-
<p>null</p>
|
|
428
|
-
</body>
|
|
429
|
-
</html>
|
|
430
|
-
`);
|
|
431
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
432
|
-
Epub.getXhtmlBody(input),
|
|
433
|
-
{}
|
|
434
|
-
);
|
|
435
|
-
const { markedUp: output } = markupChapter(
|
|
436
|
-
"chapter_one",
|
|
437
|
-
input,
|
|
438
|
-
segmentation,
|
|
439
|
-
mapping
|
|
440
|
-
);
|
|
441
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
442
|
-
});
|
|
443
|
-
void it("can preserve nbsp entities", async (t) => {
|
|
444
|
-
const input = Epub.xhtmlParser.parse(`
|
|
445
|
-
<?xml version="1.0" encoding="UTF-8"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
446
|
-
<head>
|
|
447
|
-
</head>
|
|
448
|
-
<body>
|
|
449
|
-
<p>First paragraph.</p>
|
|
450
|
-
<p> </p>
|
|
451
|
-
<p> </p>
|
|
452
|
-
<p>Second paragraph.</p>
|
|
453
|
-
</body>
|
|
454
|
-
</html>
|
|
455
|
-
`);
|
|
456
|
-
const { result: segmentation, mapping } = await getXhtmlSegmentation(
|
|
457
|
-
Epub.getXhtmlBody(input),
|
|
458
|
-
{}
|
|
459
|
-
);
|
|
460
|
-
const { markedUp: output } = markupChapter(
|
|
461
|
-
"chapter_one",
|
|
462
|
-
input,
|
|
463
|
-
segmentation,
|
|
464
|
-
mapping
|
|
465
|
-
);
|
|
466
|
-
await assertMarkupSnapshot(t, Epub.xhtmlBuilder.build(output));
|
|
467
|
-
});
|
|
468
|
-
});
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
-
for (let key of __getOwnPropNames(from))
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
-
}
|
|
14
|
-
return to;
|
|
15
|
-
};
|
|
16
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
-
mod
|
|
23
|
-
));
|
|
24
|
-
var import_node_assert = __toESM(require("node:assert"), 1);
|
|
25
|
-
var import_node_test = require("node:test");
|
|
26
|
-
var import_epub = require("@storyteller-platform/epub");
|
|
27
|
-
var import_model = require("../model.cjs");
|
|
28
|
-
var import_parseDom = require("../parseDom.cjs");
|
|
29
|
-
void (0, import_node_test.describe)("parseDom", () => {
|
|
30
|
-
void (0, import_node_test.it)("should parse hierarchical XML", () => {
|
|
31
|
-
const result = (0, import_parseDom.parseDom)([
|
|
32
|
-
import_epub.Epub.createXmlElement("p", {}, [
|
|
33
|
-
import_epub.Epub.createXmlElement("span", {}, [
|
|
34
|
-
import_epub.Epub.createXmlTextNode("Hello, world!")
|
|
35
|
-
])
|
|
36
|
-
])
|
|
37
|
-
]);
|
|
38
|
-
import_node_assert.default.deepStrictEqual(
|
|
39
|
-
result,
|
|
40
|
-
new import_model.Root([
|
|
41
|
-
new import_model.Node("p", {}, [new import_model.TextNode("Hello, world!", [new import_model.Mark("span")])])
|
|
42
|
-
])
|
|
43
|
-
);
|
|
44
|
-
});
|
|
45
|
-
void (0, import_node_test.it)("should parse nested marks", () => {
|
|
46
|
-
const result = (0, import_parseDom.parseDom)([
|
|
47
|
-
import_epub.Epub.createXmlElement("p", {}, [
|
|
48
|
-
import_epub.Epub.createXmlElement("strong", {}, [
|
|
49
|
-
import_epub.Epub.createXmlElement("em", {}, [
|
|
50
|
-
import_epub.Epub.createXmlTextNode("Hello, world!")
|
|
51
|
-
])
|
|
52
|
-
])
|
|
53
|
-
])
|
|
54
|
-
]);
|
|
55
|
-
import_node_assert.default.deepStrictEqual(
|
|
56
|
-
result,
|
|
57
|
-
new import_model.Root([
|
|
58
|
-
new import_model.Node("p", {}, [
|
|
59
|
-
new import_model.TextNode("Hello, world!", [new import_model.Mark("strong"), new import_model.Mark("em")])
|
|
60
|
-
])
|
|
61
|
-
])
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
void (0, import_node_test.it)("should preserve attributes", () => {
|
|
65
|
-
const result = (0, import_parseDom.parseDom)([
|
|
66
|
-
import_epub.Epub.createXmlElement("p", { id: "p1" }, [
|
|
67
|
-
import_epub.Epub.createXmlElement("span", { class: "red" }, [
|
|
68
|
-
import_epub.Epub.createXmlTextNode("Hello, world!")
|
|
69
|
-
])
|
|
70
|
-
])
|
|
71
|
-
]);
|
|
72
|
-
import_node_assert.default.deepStrictEqual(
|
|
73
|
-
result,
|
|
74
|
-
new import_model.Root([
|
|
75
|
-
new import_model.Node("p", { id: "p1" }, [
|
|
76
|
-
new import_model.TextNode("Hello, world!", [new import_model.Mark("span", { class: "red" })])
|
|
77
|
-
])
|
|
78
|
-
])
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
void (0, import_node_test.it)("should preserve leaf nodes", () => {
|
|
82
|
-
const result = (0, import_parseDom.parseDom)([
|
|
83
|
-
import_epub.Epub.createXmlElement("p", {}, [
|
|
84
|
-
import_epub.Epub.createXmlElement("span", {}, [
|
|
85
|
-
import_epub.Epub.createXmlTextNode("Hello,"),
|
|
86
|
-
import_epub.Epub.createXmlElement("span", { class: "x-ebookmaker-pageno" }, [
|
|
87
|
-
import_epub.Epub.createXmlElement("a", { id: "Page_v" })
|
|
88
|
-
]),
|
|
89
|
-
import_epub.Epub.createXmlTextNode(" world!")
|
|
90
|
-
])
|
|
91
|
-
])
|
|
92
|
-
]);
|
|
93
|
-
import_node_assert.default.deepStrictEqual(
|
|
94
|
-
result,
|
|
95
|
-
new import_model.Root([
|
|
96
|
-
new import_model.Node("p", {}, [
|
|
97
|
-
new import_model.TextNode("Hello,", [new import_model.Mark("span")]),
|
|
98
|
-
new import_model.Node(
|
|
99
|
-
"a",
|
|
100
|
-
{ id: "Page_v" },
|
|
101
|
-
[],
|
|
102
|
-
[
|
|
103
|
-
new import_model.Mark("span"),
|
|
104
|
-
new import_model.Mark("span", { class: "x-ebookmaker-pageno" })
|
|
105
|
-
]
|
|
106
|
-
),
|
|
107
|
-
new import_model.TextNode(" world!", [new import_model.Mark("span")])
|
|
108
|
-
])
|
|
109
|
-
])
|
|
110
|
-
);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { Epub } from "@storyteller-platform/epub";
|
|
4
|
-
import { Mark, Node, Root, TextNode } from "../model.js";
|
|
5
|
-
import { parseDom } from "../parseDom.js";
|
|
6
|
-
void describe("parseDom", () => {
|
|
7
|
-
void it("should parse hierarchical XML", () => {
|
|
8
|
-
const result = parseDom([
|
|
9
|
-
Epub.createXmlElement("p", {}, [
|
|
10
|
-
Epub.createXmlElement("span", {}, [
|
|
11
|
-
Epub.createXmlTextNode("Hello, world!")
|
|
12
|
-
])
|
|
13
|
-
])
|
|
14
|
-
]);
|
|
15
|
-
assert.deepStrictEqual(
|
|
16
|
-
result,
|
|
17
|
-
new Root([
|
|
18
|
-
new Node("p", {}, [new TextNode("Hello, world!", [new Mark("span")])])
|
|
19
|
-
])
|
|
20
|
-
);
|
|
21
|
-
});
|
|
22
|
-
void it("should parse nested marks", () => {
|
|
23
|
-
const result = parseDom([
|
|
24
|
-
Epub.createXmlElement("p", {}, [
|
|
25
|
-
Epub.createXmlElement("strong", {}, [
|
|
26
|
-
Epub.createXmlElement("em", {}, [
|
|
27
|
-
Epub.createXmlTextNode("Hello, world!")
|
|
28
|
-
])
|
|
29
|
-
])
|
|
30
|
-
])
|
|
31
|
-
]);
|
|
32
|
-
assert.deepStrictEqual(
|
|
33
|
-
result,
|
|
34
|
-
new Root([
|
|
35
|
-
new Node("p", {}, [
|
|
36
|
-
new TextNode("Hello, world!", [new Mark("strong"), new Mark("em")])
|
|
37
|
-
])
|
|
38
|
-
])
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
void it("should preserve attributes", () => {
|
|
42
|
-
const result = parseDom([
|
|
43
|
-
Epub.createXmlElement("p", { id: "p1" }, [
|
|
44
|
-
Epub.createXmlElement("span", { class: "red" }, [
|
|
45
|
-
Epub.createXmlTextNode("Hello, world!")
|
|
46
|
-
])
|
|
47
|
-
])
|
|
48
|
-
]);
|
|
49
|
-
assert.deepStrictEqual(
|
|
50
|
-
result,
|
|
51
|
-
new Root([
|
|
52
|
-
new Node("p", { id: "p1" }, [
|
|
53
|
-
new TextNode("Hello, world!", [new Mark("span", { class: "red" })])
|
|
54
|
-
])
|
|
55
|
-
])
|
|
56
|
-
);
|
|
57
|
-
});
|
|
58
|
-
void it("should preserve leaf nodes", () => {
|
|
59
|
-
const result = parseDom([
|
|
60
|
-
Epub.createXmlElement("p", {}, [
|
|
61
|
-
Epub.createXmlElement("span", {}, [
|
|
62
|
-
Epub.createXmlTextNode("Hello,"),
|
|
63
|
-
Epub.createXmlElement("span", { class: "x-ebookmaker-pageno" }, [
|
|
64
|
-
Epub.createXmlElement("a", { id: "Page_v" })
|
|
65
|
-
]),
|
|
66
|
-
Epub.createXmlTextNode(" world!")
|
|
67
|
-
])
|
|
68
|
-
])
|
|
69
|
-
]);
|
|
70
|
-
assert.deepStrictEqual(
|
|
71
|
-
result,
|
|
72
|
-
new Root([
|
|
73
|
-
new Node("p", {}, [
|
|
74
|
-
new TextNode("Hello,", [new Mark("span")]),
|
|
75
|
-
new Node(
|
|
76
|
-
"a",
|
|
77
|
-
{ id: "Page_v" },
|
|
78
|
-
[],
|
|
79
|
-
[
|
|
80
|
-
new Mark("span"),
|
|
81
|
-
new Mark("span", { class: "x-ebookmaker-pageno" })
|
|
82
|
-
]
|
|
83
|
-
),
|
|
84
|
-
new TextNode(" world!", [new Mark("span")])
|
|
85
|
-
])
|
|
86
|
-
])
|
|
87
|
-
);
|
|
88
|
-
});
|
|
89
|
-
});
|