@helloao/tools 0.0.5 → 0.0.6-alpha
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/LICENSE +21 -21
- package/README.md +98 -98
- package/dist/cjs/generation/api.cjs +240 -0
- package/dist/cjs/generation/api.cjs.map +7 -0
- package/dist/cjs/generation/audio.cjs +83 -0
- package/dist/cjs/generation/audio.cjs.map +7 -0
- package/dist/cjs/generation/book-order.cjs +508 -0
- package/dist/cjs/generation/book-order.cjs.map +7 -0
- package/dist/cjs/generation/common-types.cjs +17 -0
- package/dist/cjs/generation/common-types.cjs.map +7 -0
- package/dist/cjs/generation/dataset.cjs +158 -0
- package/dist/cjs/generation/dataset.cjs.map +7 -0
- package/dist/cjs/generation/index.cjs +51 -0
- package/dist/cjs/generation/index.cjs.map +7 -0
- package/dist/cjs/index.cjs +45 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/parser/codex-parser.cjs +176 -0
- package/dist/cjs/parser/codex-parser.cjs.map +7 -0
- package/dist/cjs/parser/index.cjs +48 -0
- package/dist/cjs/parser/index.cjs.map +7 -0
- package/dist/cjs/parser/iterators.cjs +204 -0
- package/dist/cjs/parser/iterators.cjs.map +7 -0
- package/dist/cjs/parser/types.cjs +17 -0
- package/dist/cjs/parser/types.cjs.map +7 -0
- package/dist/cjs/parser/usfm-parser.cjs +791 -0
- package/dist/cjs/parser/usfm-parser.cjs.map +7 -0
- package/dist/cjs/parser/usx-parser.cjs +471 -0
- package/dist/cjs/parser/usx-parser.cjs.map +7 -0
- package/dist/cjs/utils.cjs +85 -0
- package/dist/cjs/utils.cjs.map +7 -0
- package/dist/esm/generation/api.js +198 -0
- package/dist/esm/generation/api.js.map +7 -0
- package/dist/esm/generation/audio.js +53 -0
- package/dist/esm/generation/audio.js.map +7 -0
- package/dist/esm/generation/book-order.js +478 -0
- package/dist/esm/generation/book-order.js.map +7 -0
- package/dist/esm/generation/common-types.js +2 -0
- package/dist/esm/generation/common-types.js.map +7 -0
- package/dist/esm/generation/dataset.js +132 -0
- package/dist/esm/generation/dataset.js.map +7 -0
- package/dist/esm/generation/index.js +8 -0
- package/dist/esm/generation/index.js.map +7 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/parser/codex-parser.js +144 -0
- package/dist/esm/parser/codex-parser.js.map +7 -0
- package/dist/esm/parser/index.js +8 -0
- package/dist/esm/parser/index.js.map +7 -0
- package/dist/esm/parser/iterators.js +152 -0
- package/dist/esm/parser/iterators.js.map +7 -0
- package/dist/esm/parser/types.js +2 -0
- package/dist/esm/parser/types.js.map +7 -0
- package/dist/esm/parser/usfm-parser.js +749 -0
- package/dist/esm/parser/usfm-parser.js.map +7 -0
- package/dist/esm/parser/usx-parser.js +447 -0
- package/dist/esm/parser/usx-parser.js.map +7 -0
- package/dist/esm/utils.js +51 -0
- package/dist/esm/utils.js.map +7 -0
- package/{generation → dist/types/generation}/api.d.ts +14 -2
- package/{generation → dist/types/generation}/audio.d.ts +1 -1
- package/{generation → dist/types/generation}/dataset.d.ts +1 -1
- package/dist/types/generation/index.d.ts +7 -0
- package/dist/types/index.d.ts +5 -0
- package/{parser → dist/types/parser}/codex-parser.d.ts +1 -1
- package/dist/types/parser/index.d.ts +7 -0
- package/{parser → dist/types/parser}/usfm-parser.d.ts +1 -1
- package/{parser → dist/types/parser}/usx-parser.d.ts +2 -2
- package/package.json +25 -4
- package/typings/types.d.ts +13 -13
- package/generation/api.js +0 -179
- package/generation/api.spec.d.ts +0 -2
- package/generation/api.spec.js +0 -656
- package/generation/audio.js +0 -60
- package/generation/audio.spec.d.ts +0 -2
- package/generation/audio.spec.js +0 -36
- package/generation/book-order.js +0 -494
- package/generation/book-order.spec.d.ts +0 -2
- package/generation/book-order.spec.js +0 -8
- package/generation/common-types.js +0 -2
- package/generation/dataset.js +0 -106
- package/generation/index.d.ts +0 -7
- package/generation/index.js +0 -38
- package/index.d.ts +0 -5
- package/index.js +0 -32
- package/parser/codex-parser.js +0 -160
- package/parser/codex-parser.spec.d.ts +0 -2
- package/parser/codex-parser.spec.js +0 -645
- package/parser/index.d.ts +0 -7
- package/parser/index.js +0 -35
- package/parser/iterators.js +0 -222
- package/parser/iterators.spec.d.ts +0 -2
- package/parser/iterators.spec.js +0 -174
- package/parser/types.js +0 -2
- package/parser/usfm-parser.js +0 -840
- package/parser/usfm-parser.spec.d.ts +0 -2
- package/parser/usfm-parser.spec.js +0 -1593
- package/parser/usx-parser.js +0 -425
- package/parser/usx-parser.spec.d.ts +0 -2
- package/parser/usx-parser.spec.js +0 -1260
- package/utils.js +0 -73
- package/utils.spec.d.ts +0 -2
- package/utils.spec.js +0 -42
- /package/{generation → dist/types/generation}/book-order.d.ts +0 -0
- /package/{generation → dist/types/generation}/common-types.d.ts +0 -0
- /package/{parser → dist/types/parser}/iterators.d.ts +0 -0
- /package/{parser → dist/types/parser}/types.d.ts +0 -0
- /package/{utils.d.ts → dist/types/utils.d.ts} +0 -0
package/parser/usx-parser.js
DELETED
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.USXParser = exports.PARSER_VERSION = void 0;
|
|
4
|
-
const iterators_1 = require("./iterators");
|
|
5
|
-
var NodeType;
|
|
6
|
-
(function (NodeType) {
|
|
7
|
-
NodeType[NodeType["Text"] = 3] = "Text";
|
|
8
|
-
})(NodeType || (NodeType = {}));
|
|
9
|
-
/**
|
|
10
|
-
* The version of the parser.
|
|
11
|
-
* Used to determine whether input files need to be re-parsed.
|
|
12
|
-
*/
|
|
13
|
-
exports.PARSER_VERSION = '1';
|
|
14
|
-
/**
|
|
15
|
-
* Defines a class that is able to parse USX content.
|
|
16
|
-
*/
|
|
17
|
-
class USXParser {
|
|
18
|
-
_domParser;
|
|
19
|
-
_noteCounter = 0;
|
|
20
|
-
constructor(domParser) {
|
|
21
|
-
this._domParser = domParser;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Parses the specified USX content.
|
|
25
|
-
*
|
|
26
|
-
* @param usx The USX content to parse.
|
|
27
|
-
* @returns The parse tree that was generated.
|
|
28
|
-
*/
|
|
29
|
-
parse(usx) {
|
|
30
|
-
const parser = this._domParser;
|
|
31
|
-
const doc = parser.parseFromString(usx, 'application/xml');
|
|
32
|
-
const usxElement = doc.documentElement;
|
|
33
|
-
let root = {
|
|
34
|
-
type: 'root',
|
|
35
|
-
content: []
|
|
36
|
-
};
|
|
37
|
-
const bookElement = usxElement.querySelector('book[code]');
|
|
38
|
-
if (!bookElement) {
|
|
39
|
-
throw new Error('The USX content does not contain a book element.');
|
|
40
|
-
}
|
|
41
|
-
const bookCode = bookElement.getAttribute('code') || '';
|
|
42
|
-
if (!bookCode) {
|
|
43
|
-
throw new Error('The book element does not contain a code attribute.');
|
|
44
|
-
}
|
|
45
|
-
root.id = bookCode;
|
|
46
|
-
const header = usxElement.querySelector('para[style="h"]');
|
|
47
|
-
if (header) {
|
|
48
|
-
root.header = header.textContent || '';
|
|
49
|
-
}
|
|
50
|
-
const titles = usxElement.querySelectorAll('para[style="mt1"], para[style="mt2"], para[style="mt3"]');
|
|
51
|
-
// const title2 = usxElement.querySelector('para[style="mt2"]');
|
|
52
|
-
// const title3 = usxElement.querySelector('para[style="mt3"]');
|
|
53
|
-
if (titles.length > 0) {
|
|
54
|
-
root.title = [...titles].map(t => t.textContent).filter(t => t).join(' ');
|
|
55
|
-
}
|
|
56
|
-
for (let content of this.iterateRootContent(usxElement)) {
|
|
57
|
-
root.content.push(content);
|
|
58
|
-
}
|
|
59
|
-
return root;
|
|
60
|
-
}
|
|
61
|
-
*iterateRootContent(usxElement) {
|
|
62
|
-
const iterator = (0, iterators_1.iterateAll)(usxElement);
|
|
63
|
-
while (true) {
|
|
64
|
-
const { done, value: child } = iterator.next();
|
|
65
|
-
if (done) {
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
if (!(child instanceof Element)) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
if (child.nodeName === 'chapter') {
|
|
72
|
-
if (child.hasAttribute('eid')) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
const chapter = {
|
|
76
|
-
type: 'chapter',
|
|
77
|
-
number: parseInt(child.getAttribute('number') || '0', 10),
|
|
78
|
-
content: [],
|
|
79
|
-
footnotes: [],
|
|
80
|
-
};
|
|
81
|
-
for (let content of this.iterateChapterContent(chapter, iterator)) {
|
|
82
|
-
chapter.content.push(content);
|
|
83
|
-
}
|
|
84
|
-
yield chapter;
|
|
85
|
-
}
|
|
86
|
-
else if (child.nodeName === 'para') {
|
|
87
|
-
const style = child.getAttribute('style');
|
|
88
|
-
if (style === 's1' || style === 's2' || style === 's3' || style === 's4') {
|
|
89
|
-
yield {
|
|
90
|
-
type: 'heading',
|
|
91
|
-
content: child.textContent ? [child.textContent] : []
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
*iterateChapterContent(chapter, nodes) {
|
|
98
|
-
while (true) {
|
|
99
|
-
const { done, value: element } = nodes.next();
|
|
100
|
-
if (done) {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
if (!(element instanceof Element)) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
if (element.nodeName === 'chapter') {
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
else if (element.nodeName === 'para') {
|
|
110
|
-
const style = element.getAttribute('style');
|
|
111
|
-
if (style === 's1' || style === 's2' || style === 's3' || style === 's4') {
|
|
112
|
-
yield {
|
|
113
|
-
type: 'heading',
|
|
114
|
-
content: element.textContent ? [element.textContent] : []
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
else if (style === 'b') {
|
|
118
|
-
yield {
|
|
119
|
-
type: 'line_break',
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
else if (style === 'd') {
|
|
123
|
-
yield* this.parseHebrewSubtitle(element, chapter, nodes);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
else if (element.nodeName === 'verse') {
|
|
127
|
-
if (element.hasAttribute('eid')) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
yield this.parseVerse(element, chapter, nodes);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
*iterateVerseContent(chapter, verse, nodes) {
|
|
135
|
-
while (true) {
|
|
136
|
-
const { done, value: node } = nodes.next();
|
|
137
|
-
if (done) {
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
if (node.nodeName === 'verse') {
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
const parent = node.parentElement;
|
|
144
|
-
let poem = null;
|
|
145
|
-
let descriptive = null;
|
|
146
|
-
if (parent.nodeName === 'para') {
|
|
147
|
-
const style = parent.getAttribute('style');
|
|
148
|
-
if (style === 'q1' || style === 'q2' || style === 'q3' || style === 'q4') {
|
|
149
|
-
poem = style === 'q1' ? 1 : style === 'q2' ? 2 : style === 'q3' ? 3 : 4;
|
|
150
|
-
}
|
|
151
|
-
else if (style === 'd') {
|
|
152
|
-
descriptive = true;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
for (let content of this.iterateNodeTextContent(nodes, node, chapter, verse)) {
|
|
156
|
-
if (poem !== null || descriptive !== null) {
|
|
157
|
-
if (typeof content === 'string') {
|
|
158
|
-
let text = {
|
|
159
|
-
text: content
|
|
160
|
-
};
|
|
161
|
-
if (poem !== null) {
|
|
162
|
-
text.poem = poem;
|
|
163
|
-
}
|
|
164
|
-
if (descriptive !== null) {
|
|
165
|
-
text.descriptive = true;
|
|
166
|
-
}
|
|
167
|
-
yield text;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
let text = {
|
|
171
|
-
...content
|
|
172
|
-
};
|
|
173
|
-
if ('text' in text) {
|
|
174
|
-
if (poem !== null) {
|
|
175
|
-
text.poem = poem;
|
|
176
|
-
}
|
|
177
|
-
if (descriptive !== null) {
|
|
178
|
-
text.descriptive = true;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
yield text;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
yield content;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
parseVerse(element, chapter, nodes) {
|
|
191
|
-
const verse = {
|
|
192
|
-
type: 'verse',
|
|
193
|
-
number: parseInt(element.getAttribute('number') || '0', 10),
|
|
194
|
-
content: []
|
|
195
|
-
};
|
|
196
|
-
for (let content of this.iterateVerseContent(chapter, verse, nodes)) {
|
|
197
|
-
addOrJoin(verse.content, content);
|
|
198
|
-
}
|
|
199
|
-
trimContent(verse.content);
|
|
200
|
-
return verse;
|
|
201
|
-
}
|
|
202
|
-
*parseHebrewSubtitle(para, chapter, nodes) {
|
|
203
|
-
const subtitle = {
|
|
204
|
-
type: 'hebrew_subtitle',
|
|
205
|
-
content: []
|
|
206
|
-
};
|
|
207
|
-
for (let content of this.iterateHebrewSubtitleContent(para, chapter, nodes)) {
|
|
208
|
-
if (typeof content === 'object' && 'number' in content) {
|
|
209
|
-
yield content;
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
addOrJoin(subtitle.content, content);
|
|
213
|
-
}
|
|
214
|
-
trimContent(subtitle.content);
|
|
215
|
-
if (subtitle.content.length > 0) {
|
|
216
|
-
yield subtitle;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
*iterateHebrewSubtitleContent(element, chapter, nodes) {
|
|
220
|
-
while (true) {
|
|
221
|
-
const { done, value: node } = nodes.next();
|
|
222
|
-
if (done) {
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
if (!(0, iterators_1.isParent)(node, element)) {
|
|
226
|
-
nodes.rewind(1);
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
if (node instanceof Element && node.nodeName === 'verse') {
|
|
230
|
-
yield this.parseVerse(node, chapter, nodes);
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
yield* this.iterateNodeTextContent(nodes, node, chapter);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
*iterateNodeTextContent(nodes, node, chapter, verse) {
|
|
238
|
-
if (node instanceof Element && node.nodeName === 'note') {
|
|
239
|
-
yield* this.iterateNote(nodes, node, chapter, verse);
|
|
240
|
-
}
|
|
241
|
-
else if (node instanceof Element && node.nodeName === 'char') {
|
|
242
|
-
yield* this.iterateChar(nodes, node);
|
|
243
|
-
}
|
|
244
|
-
else if (node instanceof Element && node.nodeName === 'para' && node.getAttribute('style') === 'b') {
|
|
245
|
-
for (let _ of (0, iterators_1.children)(nodes, node)) {
|
|
246
|
-
// iterate through all the children to prevent iterating over them multiple times
|
|
247
|
-
}
|
|
248
|
-
yield {
|
|
249
|
-
lineBreak: true
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
else if (node.nodeType === NodeType.Text) {
|
|
253
|
-
yield node.textContent || '';
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
*iterateCharContent(char) {
|
|
257
|
-
const style = char.getAttribute('style');
|
|
258
|
-
const text = trimText(char.textContent || '');
|
|
259
|
-
if (style === 'wj') {
|
|
260
|
-
yield {
|
|
261
|
-
text,
|
|
262
|
-
wordsOfJesus: true
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
yield text;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
*iterateNote(nodes, node, chapter, verse) {
|
|
270
|
-
const style = node.getAttribute('style');
|
|
271
|
-
if (style === 'f') {
|
|
272
|
-
const verseReferenceRegex = /^[0-9]{1,3}:[0-9]{1,3}/;
|
|
273
|
-
let text = '';
|
|
274
|
-
for (let child of (0, iterators_1.children)(nodes, node)) {
|
|
275
|
-
if (child.nodeType === NodeType.Text) {
|
|
276
|
-
text += child.textContent || '';
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
text = text.trim();
|
|
280
|
-
if (verseReferenceRegex.test(text)) {
|
|
281
|
-
text = text.replace(verseReferenceRegex, '').trim();
|
|
282
|
-
}
|
|
283
|
-
const note = {
|
|
284
|
-
noteId: this._noteCounter++,
|
|
285
|
-
caller: node.getAttribute('caller') || null,
|
|
286
|
-
text,
|
|
287
|
-
reference: {
|
|
288
|
-
chapter: chapter.number,
|
|
289
|
-
verse: verse?.number ?? 0
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
chapter.footnotes.push(note);
|
|
293
|
-
yield {
|
|
294
|
-
noteId: note.noteId
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
for (let _ of (0, iterators_1.children)(nodes, node)) {
|
|
299
|
-
// iterate through all the children
|
|
300
|
-
// so that we don't end up with duplicates
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
*iterateChar(nodes, node) {
|
|
305
|
-
const style = node.getAttribute('style');
|
|
306
|
-
let text = '';
|
|
307
|
-
for (let char of (0, iterators_1.children)(nodes, node)) {
|
|
308
|
-
if (char.nodeType === NodeType.Text) {
|
|
309
|
-
text += char.textContent || '';
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
if (style === 'wj') {
|
|
313
|
-
yield {
|
|
314
|
-
text,
|
|
315
|
-
wordsOfJesus: true
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
yield text;
|
|
320
|
-
}
|
|
321
|
-
// if (!parentChar(node) && !parentNote(node)) {
|
|
322
|
-
// yield *iterateCharContent(node);
|
|
323
|
-
// }
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
exports.USXParser = USXParser;
|
|
327
|
-
// Taken from https://github.com/gracious-tech/fetch/blob/1576cc4eafb32bf347a09332094cf17c2231c90c/converters/usx-to-json/src/elements.ts#L16
|
|
328
|
-
const ignoredParaStyles = new Set([
|
|
329
|
-
// <para> Identification [exclude all] - Running headings & table of contents
|
|
330
|
-
'ide', // See https://github.com/schierlm/BibleMultiConverter/issues/67
|
|
331
|
-
'rem', // Remarks (valid in schema though missed in docs)
|
|
332
|
-
'h', 'h1', 'h2', 'h3', 'h4',
|
|
333
|
-
'toc1', 'toc2', 'toc3',
|
|
334
|
-
'toca1', 'toca2', 'toca3',
|
|
335
|
-
/* <para> Introductions [exclude all] - Introductionary (non-biblical) content
|
|
336
|
-
Which might be helpful in a printed book, but intro material in apps is usually bad UX,
|
|
337
|
-
and users that really care can research a translations methodology themselves
|
|
338
|
-
*/
|
|
339
|
-
'imt', 'imt1', 'imt2', 'imt3', 'imt4',
|
|
340
|
-
'is', 'is1', 'is2', 'is3', 'is4',
|
|
341
|
-
'ip',
|
|
342
|
-
'ipi',
|
|
343
|
-
'im',
|
|
344
|
-
'imi',
|
|
345
|
-
'ipq',
|
|
346
|
-
'imq',
|
|
347
|
-
'ipr',
|
|
348
|
-
'iq', 'iq1', 'iq2', 'iq3', 'iq4',
|
|
349
|
-
'ib',
|
|
350
|
-
'ili', 'ili1', 'ili2', 'ili3', 'ili4',
|
|
351
|
-
'iot',
|
|
352
|
-
'io', 'io1', 'io2', 'io3', 'io4',
|
|
353
|
-
'iex',
|
|
354
|
-
'imte',
|
|
355
|
-
'ie',
|
|
356
|
-
/* <para> Headings [exclude some] - Exclude book & chapter headings but keep section headings
|
|
357
|
-
Not excluded: ms# | mr | s# | sr | d | sp | sd#
|
|
358
|
-
*/
|
|
359
|
-
'mt', 'mt1', 'mt2', 'mt3', 'mt4',
|
|
360
|
-
'mte', 'mte1', 'mte2', 'mte3', 'mte4',
|
|
361
|
-
'cl',
|
|
362
|
-
'cd', // Non-biblical chapter summary, more than heading
|
|
363
|
-
'r', // Parallels to be provided by external data
|
|
364
|
-
]);
|
|
365
|
-
function* iterateCharContent(char) {
|
|
366
|
-
const style = char.getAttribute('style');
|
|
367
|
-
const text = trimText(char.textContent || '');
|
|
368
|
-
if (style === 'wj') {
|
|
369
|
-
yield {
|
|
370
|
-
text,
|
|
371
|
-
wordsOfJesus: true
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
yield text;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
function trimText(text) {
|
|
379
|
-
return text.replace(/\s+/g, ' ');
|
|
380
|
-
}
|
|
381
|
-
function trimContent(content) {
|
|
382
|
-
for (let i = 0; i < content.length; i++) {
|
|
383
|
-
const value = content[i];
|
|
384
|
-
if (typeof value === 'string') {
|
|
385
|
-
content[i] = trimText(value).trim();
|
|
386
|
-
if (content[i] === '') {
|
|
387
|
-
content.splice(i, 1);
|
|
388
|
-
i--;
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
else if (isVerseText(value)) {
|
|
393
|
-
value.text = trimText(value.text).trim();
|
|
394
|
-
if (value.text === '') {
|
|
395
|
-
content.splice(i, 1);
|
|
396
|
-
i--;
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return content;
|
|
402
|
-
}
|
|
403
|
-
function addOrJoin(array, value) {
|
|
404
|
-
if (array.length === 0) {
|
|
405
|
-
array.push(value);
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
const last = array[array.length - 1];
|
|
409
|
-
if (typeof last === 'string' && typeof value === 'string') {
|
|
410
|
-
array[array.length - 1] = last + value;
|
|
411
|
-
}
|
|
412
|
-
else if (isVerseText(last) && isVerseText(value) && hasSameFormatting(last, value)) {
|
|
413
|
-
last.text += value.text;
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
array.push(value);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
function isVerseText(value) {
|
|
421
|
-
return typeof value === 'object' && value !== null && 'text' in value;
|
|
422
|
-
}
|
|
423
|
-
function hasSameFormatting(a, b) {
|
|
424
|
-
return a.poem === b.poem && a.wordsOfJesus === b.wordsOfJesus;
|
|
425
|
-
}
|