@helloao/tools 0.2.0 → 0.3.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.
- package/dist/cjs/generation/api.cjs +856 -36
- package/dist/cjs/generation/api.cjs.map +3 -3
- package/dist/cjs/generation/audio.cjs +5 -5
- package/dist/cjs/generation/audio.cjs.map +1 -1
- package/dist/cjs/generation/book-order.cjs.map +1 -1
- package/dist/cjs/generation/common-types.cjs +359 -14
- package/dist/cjs/generation/common-types.cjs.map +2 -2
- package/dist/cjs/generation/dataset.cjs +13 -9
- package/dist/cjs/generation/dataset.cjs.map +2 -2
- package/dist/cjs/generation/index.cjs +8 -5
- package/dist/cjs/generation/index.cjs.map +2 -2
- package/dist/cjs/generation/simple.cjs +294 -0
- package/dist/cjs/generation/simple.cjs.map +7 -0
- package/dist/cjs/index.cjs +4 -4
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/log.cjs.map +1 -1
- package/dist/cjs/parser/codex-parser.cjs +3 -3
- package/dist/cjs/parser/codex-parser.cjs.map +3 -3
- package/dist/cjs/parser/commentary-csv-parser.cjs +14 -3
- package/dist/cjs/parser/commentary-csv-parser.cjs.map +3 -3
- package/dist/cjs/parser/index.cjs +1 -1
- package/dist/cjs/parser/iterators.cjs.map +1 -1
- package/dist/cjs/parser/lockman-parser.cjs +1 -1
- package/dist/cjs/parser/lockman-parser.cjs.map +1 -1
- package/dist/cjs/parser/tyndale-xml-parser.cjs +1 -1
- package/dist/cjs/parser/tyndale-xml-parser.cjs.map +1 -1
- package/dist/cjs/parser/types.cjs.map +1 -1
- package/dist/cjs/parser/usfm-parser.cjs +2 -2
- package/dist/cjs/parser/usfm-parser.cjs.map +1 -1
- package/dist/cjs/parser/usx-parser.cjs +122 -26
- package/dist/cjs/parser/usx-parser.cjs.map +2 -2
- package/dist/cjs/parser/words.cjs +187 -0
- package/dist/cjs/parser/words.cjs.map +7 -0
- package/dist/cjs/utils.cjs +1 -1
- package/dist/esm/generation/api.js +835 -37
- package/dist/esm/generation/api.js.map +3 -3
- package/dist/esm/generation/audio.js +1 -1
- package/dist/esm/generation/audio.js.map +1 -1
- package/dist/esm/generation/book-order.js.map +1 -1
- package/dist/esm/generation/common-types.js +327 -14
- package/dist/esm/generation/common-types.js.map +2 -2
- package/dist/esm/generation/dataset.js +6 -2
- package/dist/esm/generation/dataset.js.map +2 -2
- package/dist/esm/generation/index.js +2 -1
- package/dist/esm/generation/index.js.map +2 -2
- package/dist/esm/generation/simple.js +260 -0
- package/dist/esm/generation/simple.js.map +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/log.js.map +1 -1
- package/dist/esm/parser/codex-parser.js +3 -3
- package/dist/esm/parser/codex-parser.js.map +3 -3
- package/dist/esm/parser/commentary-csv-parser.js +3 -2
- package/dist/esm/parser/commentary-csv-parser.js.map +2 -2
- package/dist/esm/parser/iterators.js.map +1 -1
- package/dist/esm/parser/lockman-parser.js +1 -1
- package/dist/esm/parser/lockman-parser.js.map +1 -1
- package/dist/esm/parser/tyndale-xml-parser.js +1 -1
- package/dist/esm/parser/tyndale-xml-parser.js.map +1 -1
- package/dist/esm/parser/usfm-parser.js +1 -1
- package/dist/esm/parser/usfm-parser.js.map +1 -1
- package/dist/esm/parser/usx-parser.js +130 -26
- package/dist/esm/parser/usx-parser.js.map +2 -2
- package/dist/esm/parser/words.js +149 -0
- package/dist/esm/parser/words.js.map +7 -0
- package/dist/types/generation/api.d.ts +6879 -918
- package/dist/types/generation/common-types.d.ts +432 -2
- package/dist/types/generation/index.d.ts +2 -1
- package/dist/types/generation/simple.d.ts +110 -0
- package/dist/types/parser/commentary-csv-parser.d.ts +1 -1
- package/dist/types/parser/lockman-parser.d.ts +1 -1
- package/dist/types/parser/tyndale-xml-parser.d.ts +1 -1
- package/dist/types/parser/types.d.ts +63 -0
- package/dist/types/parser/usx-parser.d.ts +6 -5
- package/dist/types/parser/words.d.ts +104 -0
- package/package.json +3 -2
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export function simplifyVerseContent(content, footnotes = /* @__PURE__ */ new Map(), usedFootnotes = /* @__PURE__ */ new Set(), words = []) {
|
|
3
|
+
let text = "";
|
|
4
|
+
const verseFootnotes = [];
|
|
5
|
+
const headings = [];
|
|
6
|
+
const wordsOfJesus = [];
|
|
7
|
+
const poem = [];
|
|
8
|
+
const verseWords = [];
|
|
9
|
+
const wordsByContentIndex = /* @__PURE__ */ new Map();
|
|
10
|
+
for (let word of words) {
|
|
11
|
+
let arr = wordsByContentIndex.get(word.contentIndex);
|
|
12
|
+
if (!arr) {
|
|
13
|
+
arr = [];
|
|
14
|
+
wordsByContentIndex.set(word.contentIndex, arr);
|
|
15
|
+
}
|
|
16
|
+
arr.push(word);
|
|
17
|
+
}
|
|
18
|
+
const truncateTo = (length) => {
|
|
19
|
+
if (length >= text.length) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
text = text.slice(0, length);
|
|
23
|
+
for (let footnote of verseFootnotes) {
|
|
24
|
+
footnote.offset = Math.min(footnote.offset, length);
|
|
25
|
+
}
|
|
26
|
+
for (let heading of headings) {
|
|
27
|
+
heading.offset = Math.min(heading.offset, length);
|
|
28
|
+
}
|
|
29
|
+
for (let range of [...wordsOfJesus, ...poem, ...verseWords]) {
|
|
30
|
+
range.start = Math.min(range.start, length);
|
|
31
|
+
range.end = Math.min(range.end, length);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const addWordsForContent = (contentIndex, contentStart, contentLength) => {
|
|
35
|
+
const contentWords = wordsByContentIndex.get(contentIndex);
|
|
36
|
+
if (!contentWords) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (let { contentIndex: _index, ...word } of contentWords) {
|
|
40
|
+
verseWords.push({
|
|
41
|
+
...word,
|
|
42
|
+
start: contentStart + Math.min(word.start, contentLength),
|
|
43
|
+
end: contentStart + Math.min(word.end, contentLength)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const startNewLine = () => {
|
|
48
|
+
truncateTo(text.replace(/[^\S\n]+$/, "").length);
|
|
49
|
+
text += "\n";
|
|
50
|
+
};
|
|
51
|
+
const needsSeparator = (next) => {
|
|
52
|
+
if (text.length <= 0 || /\s$/.test(text) || !next) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (typeof next === "string") {
|
|
56
|
+
return next.length > 0 && !/^\s/.test(next);
|
|
57
|
+
}
|
|
58
|
+
if ("text" in next) {
|
|
59
|
+
return typeof next.poem !== "number" && next.text.length > 0 && !/^\s/.test(next.text);
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
};
|
|
63
|
+
for (let i = 0; i < content.length; i++) {
|
|
64
|
+
const part = content[i];
|
|
65
|
+
if (typeof part === "string") {
|
|
66
|
+
addWordsForContent(i, text.length, part.length);
|
|
67
|
+
text += part;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if ("text" in part) {
|
|
71
|
+
if (typeof part.poem === "number" && text.length > 0 && !text.endsWith("\n")) {
|
|
72
|
+
startNewLine();
|
|
73
|
+
}
|
|
74
|
+
const start = text.length;
|
|
75
|
+
addWordsForContent(i, start, part.text.length);
|
|
76
|
+
text += part.text;
|
|
77
|
+
const end = text.length;
|
|
78
|
+
if (end > start) {
|
|
79
|
+
if (part.wordsOfJesus) {
|
|
80
|
+
wordsOfJesus.push({ start, end });
|
|
81
|
+
}
|
|
82
|
+
if (typeof part.poem === "number") {
|
|
83
|
+
poem.push({ start, end, level: part.poem });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
} else if ("lineBreak" in part) {
|
|
87
|
+
if (text.length > 0 && !text.endsWith("\n")) {
|
|
88
|
+
startNewLine();
|
|
89
|
+
}
|
|
90
|
+
} else if ("noteId" in part) {
|
|
91
|
+
const footnote = footnotes.get(part.noteId);
|
|
92
|
+
if (footnote) {
|
|
93
|
+
usedFootnotes.add(part.noteId);
|
|
94
|
+
verseFootnotes.push({
|
|
95
|
+
noteId: footnote.noteId,
|
|
96
|
+
offset: text.length,
|
|
97
|
+
text: footnote.text,
|
|
98
|
+
caller: footnote.caller
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (needsSeparator(content[i + 1])) {
|
|
102
|
+
text += " ";
|
|
103
|
+
}
|
|
104
|
+
} else if ("heading" in part) {
|
|
105
|
+
headings.push({
|
|
106
|
+
offset: text.length,
|
|
107
|
+
text: part.heading
|
|
108
|
+
});
|
|
109
|
+
if (needsSeparator(content[i + 1])) {
|
|
110
|
+
text += " ";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
truncateTo(text.replace(/\s+$/, "").length);
|
|
115
|
+
const leading = text.length - text.replace(/^\s+/, "").length;
|
|
116
|
+
if (leading > 0) {
|
|
117
|
+
text = text.slice(leading);
|
|
118
|
+
for (let footnote of verseFootnotes) {
|
|
119
|
+
footnote.offset = Math.max(0, footnote.offset - leading);
|
|
120
|
+
}
|
|
121
|
+
for (let heading of headings) {
|
|
122
|
+
heading.offset = Math.max(0, heading.offset - leading);
|
|
123
|
+
}
|
|
124
|
+
for (let range of [...wordsOfJesus, ...poem, ...verseWords]) {
|
|
125
|
+
range.start = Math.max(0, range.start - leading);
|
|
126
|
+
range.end = Math.max(0, range.end - leading);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
text,
|
|
131
|
+
footnotes: verseFootnotes,
|
|
132
|
+
headings,
|
|
133
|
+
wordsOfJesus: mergeAdjacentRanges(wordsOfJesus, text),
|
|
134
|
+
poem: poem.filter((range) => range.start < range.end),
|
|
135
|
+
words: verseWords.filter((word) => word.start < word.end)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function mergeAdjacentRanges(ranges, text) {
|
|
139
|
+
const merged = [];
|
|
140
|
+
for (let range of ranges) {
|
|
141
|
+
if (range.start >= range.end) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const previous = merged[merged.length - 1];
|
|
145
|
+
if (previous && range.start >= previous.end && !/\S/.test(text.slice(previous.end, range.start))) {
|
|
146
|
+
previous.end = range.end;
|
|
147
|
+
} else {
|
|
148
|
+
merged.push(range);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return merged;
|
|
152
|
+
}
|
|
153
|
+
export function simplifyVerse(verse, footnotes, usedFootnotes, words, remappedWords) {
|
|
154
|
+
const simplified = simplifyVerseContent(
|
|
155
|
+
verse.content,
|
|
156
|
+
footnotes,
|
|
157
|
+
usedFootnotes,
|
|
158
|
+
words
|
|
159
|
+
);
|
|
160
|
+
if (remappedWords) {
|
|
161
|
+
remappedWords.push(...simplified.words);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
type: "verse",
|
|
165
|
+
number: verse.number,
|
|
166
|
+
...omitEmptyProperties(simplified)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function simplifyHebrewSubtitle(subtitle, footnotes, usedFootnotes) {
|
|
170
|
+
const simplified = simplifyVerseContent(
|
|
171
|
+
subtitle.content,
|
|
172
|
+
footnotes,
|
|
173
|
+
usedFootnotes
|
|
174
|
+
);
|
|
175
|
+
return {
|
|
176
|
+
type: "hebrew_subtitle",
|
|
177
|
+
...omitEmptyProperties(simplified)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function omitEmptyProperties(content) {
|
|
181
|
+
return {
|
|
182
|
+
text: content.text,
|
|
183
|
+
footnotes: content.footnotes,
|
|
184
|
+
...content.headings.length > 0 ? { headings: content.headings } : {},
|
|
185
|
+
...content.wordsOfJesus.length > 0 ? { wordsOfJesus: content.wordsOfJesus } : {},
|
|
186
|
+
...content.poem.length > 0 ? { poem: content.poem } : {}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export function simplifyChapter(chapter, words) {
|
|
190
|
+
const footnotes = /* @__PURE__ */ new Map();
|
|
191
|
+
for (let footnote of chapter.footnotes) {
|
|
192
|
+
footnotes.set(footnote.noteId, footnote);
|
|
193
|
+
}
|
|
194
|
+
const usedFootnotes = /* @__PURE__ */ new Set();
|
|
195
|
+
const content = [];
|
|
196
|
+
const versesByNumber = /* @__PURE__ */ new Map();
|
|
197
|
+
const simpleWords = {};
|
|
198
|
+
for (let c of chapter.content) {
|
|
199
|
+
if (c.type === "verse") {
|
|
200
|
+
const verseWords = words?.[String(c.number)];
|
|
201
|
+
const remappedWords = [];
|
|
202
|
+
const verse = simplifyVerse(
|
|
203
|
+
c,
|
|
204
|
+
footnotes,
|
|
205
|
+
usedFootnotes,
|
|
206
|
+
verseWords,
|
|
207
|
+
remappedWords
|
|
208
|
+
);
|
|
209
|
+
if (remappedWords.length > 0) {
|
|
210
|
+
simpleWords[String(c.number)] = remappedWords;
|
|
211
|
+
}
|
|
212
|
+
versesByNumber.set(verse.number, verse);
|
|
213
|
+
content.push(verse);
|
|
214
|
+
} else if (c.type === "hebrew_subtitle") {
|
|
215
|
+
content.push(simplifyHebrewSubtitle(c, footnotes, usedFootnotes));
|
|
216
|
+
} else if (c.type === "heading") {
|
|
217
|
+
content.push({
|
|
218
|
+
type: "heading",
|
|
219
|
+
text: c.content.join(" ")
|
|
220
|
+
});
|
|
221
|
+
} else if (c.type === "line_break") {
|
|
222
|
+
content.push({
|
|
223
|
+
type: "line_break"
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const unreferencedFootnotes = [];
|
|
228
|
+
for (let footnote of chapter.footnotes) {
|
|
229
|
+
if (usedFootnotes.has(footnote.noteId)) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const verse = footnote.reference ? versesByNumber.get(footnote.reference.verse) : void 0;
|
|
233
|
+
if (verse) {
|
|
234
|
+
verse.footnotes.push({
|
|
235
|
+
noteId: footnote.noteId,
|
|
236
|
+
offset: verse.text.length,
|
|
237
|
+
text: footnote.text,
|
|
238
|
+
caller: footnote.caller
|
|
239
|
+
});
|
|
240
|
+
} else {
|
|
241
|
+
unreferencedFootnotes.push(footnote);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
chapter: {
|
|
246
|
+
number: chapter.number,
|
|
247
|
+
content,
|
|
248
|
+
footnotes: unreferencedFootnotes
|
|
249
|
+
},
|
|
250
|
+
words: simpleWords
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
export function simplifyCommentaryChapter(chapter) {
|
|
254
|
+
return {
|
|
255
|
+
number: chapter.number,
|
|
256
|
+
...chapter.introduction !== void 0 ? { introduction: chapter.introduction } : {},
|
|
257
|
+
content: chapter.content.map((verse) => simplifyVerse(verse))
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=simple.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../generation/simple.ts"],
|
|
4
|
+
"sourcesContent": ["import {\r\n ChapterData,\r\n ChapterFootnote,\r\n ChapterHebrewSubtitle,\r\n ChapterVerse,\r\n ChapterWord,\r\n CommentaryChapterData,\r\n SimpleChapterContent,\r\n SimpleChapterData,\r\n SimpleChapterHebrewSubtitle,\r\n SimpleChapterVerse,\r\n SimpleChapterWord,\r\n SimpleCommentaryChapterData,\r\n SimpleInlineHeading,\r\n SimplePoemRange,\r\n SimpleTextRange,\r\n SimpleVerseFootnote,\r\n TranslationBookChapterWords,\r\n SimpleTranslationBookChapterWords,\r\n} from './common-types.js';\r\n\r\n/**\r\n * The types of content that can be contained in a verse or Hebrew Subtitle.\r\n */\r\ntype VerseContent =\r\n | ChapterVerse['content'][number]\r\n | ChapterHebrewSubtitle['content'][number];\r\n\r\n/**\r\n * The result of flattening the content of a verse into a single string.\r\n */\r\nexport interface SimplifiedVerseContent {\r\n /**\r\n * The text of the verse.\r\n */\r\n text: string;\r\n\r\n /**\r\n * The footnotes that occur in the verse.\r\n */\r\n footnotes: SimpleVerseFootnote[];\r\n\r\n /**\r\n * The headings that occur in the middle of the verse.\r\n */\r\n headings: SimpleInlineHeading[];\r\n\r\n /**\r\n * The ranges of text that represent the Words of Jesus.\r\n */\r\n wordsOfJesus: SimpleTextRange[];\r\n\r\n /**\r\n * The ranges of text that represent lines of poetry.\r\n */\r\n poem: SimplePoemRange[];\r\n\r\n /**\r\n * The word-level annotations for the verse, with their offsets remapped onto the text.\r\n */\r\n words: SimpleChapterWord[];\r\n}\r\n\r\n/**\r\n * Flattens the content of a verse into a single string, recording the positions of the\r\n * footnotes, headings, and formatting that occur in it.\r\n *\r\n * The rules used to build the text are:\r\n * - Strings and formatted text are appended as-is. The source data already contains the\r\n * spacing that is needed between them.\r\n * - Lines of poetry and line breaks start a new line.\r\n * - Footnote and heading markers are replaced with a single space when one is needed to\r\n * keep the surrounding words apart.\r\n *\r\n * All of the recorded offsets are measured in UTF-16 code units, which is what\r\n * `String.prototype.slice()` and `String.prototype.length` use.\r\n *\r\n * Word-level annotations are anchored to a range of characters in a single item of the\r\n * content array. Since the simplified format replaces that array with a single string,\r\n * their offsets are remapped onto the text that is built here.\r\n *\r\n * @param content The content of the verse.\r\n * @param footnotes The footnotes for the chapter, keyed by note ID.\r\n * @param usedFootnotes A set that the IDs of the referenced footnotes are added to.\r\n * @param words The word-level annotations for the verse.\r\n */\r\nexport function simplifyVerseContent(\r\n content: readonly VerseContent[],\r\n footnotes: Map<number, ChapterFootnote> = new Map(),\r\n usedFootnotes: Set<number> = new Set(),\r\n words: readonly ChapterWord[] = []\r\n): SimplifiedVerseContent {\r\n let text = '';\r\n const verseFootnotes: SimpleVerseFootnote[] = [];\r\n const headings: SimpleInlineHeading[] = [];\r\n const wordsOfJesus: SimpleTextRange[] = [];\r\n const poem: SimplePoemRange[] = [];\r\n const verseWords: SimpleChapterWord[] = [];\r\n\r\n const wordsByContentIndex = new Map<number, ChapterWord[]>();\r\n for (let word of words) {\r\n let arr = wordsByContentIndex.get(word.contentIndex);\r\n if (!arr) {\r\n arr = [];\r\n wordsByContentIndex.set(word.contentIndex, arr);\r\n }\r\n arr.push(word);\r\n }\r\n\r\n /**\r\n * Removes the given number of characters from the end of the text and moves any\r\n * offsets that pointed into the removed region back to the new end of the text.\r\n */\r\n const truncateTo = (length: number) => {\r\n if (length >= text.length) {\r\n return;\r\n }\r\n text = text.slice(0, length);\r\n for (let footnote of verseFootnotes) {\r\n footnote.offset = Math.min(footnote.offset, length);\r\n }\r\n for (let heading of headings) {\r\n heading.offset = Math.min(heading.offset, length);\r\n }\r\n for (let range of [...wordsOfJesus, ...poem, ...verseWords]) {\r\n range.start = Math.min(range.start, length);\r\n range.end = Math.min(range.end, length);\r\n }\r\n };\r\n\r\n /**\r\n * Moves the annotations for the content item at the given index onto the text that\r\n * the item was appended to.\r\n */\r\n const addWordsForContent = (\r\n contentIndex: number,\r\n contentStart: number,\r\n contentLength: number\r\n ) => {\r\n const contentWords = wordsByContentIndex.get(contentIndex);\r\n if (!contentWords) {\r\n return;\r\n }\r\n\r\n for (let { contentIndex: _index, ...word } of contentWords) {\r\n verseWords.push({\r\n ...word,\r\n start: contentStart + Math.min(word.start, contentLength),\r\n end: contentStart + Math.min(word.end, contentLength),\r\n });\r\n }\r\n };\r\n\r\n /**\r\n * Starts a new line, first removing any spaces that were left at the end of the\r\n * current one.\r\n */\r\n const startNewLine = () => {\r\n truncateTo(text.replace(/[^\\S\\n]+$/, '').length);\r\n text += '\\n';\r\n };\r\n\r\n /**\r\n * Determines whether a space needs to be inserted in place of a marker in order to\r\n * keep the text that surrounds it apart.\r\n */\r\n const needsSeparator = (next: VerseContent | undefined) => {\r\n if (text.length <= 0 || /\\s$/.test(text) || !next) {\r\n return false;\r\n }\r\n if (typeof next === 'string') {\r\n return next.length > 0 && !/^\\s/.test(next);\r\n }\r\n if ('text' in next) {\r\n // Poem lines always start a new line, so they never need a separator.\r\n return (\r\n typeof next.poem !== 'number' &&\r\n next.text.length > 0 &&\r\n !/^\\s/.test(next.text)\r\n );\r\n }\r\n // Line breaks start their own line, and consecutive markers only ever need\r\n // a single separator between them.\r\n return false;\r\n };\r\n\r\n for (let i = 0; i < content.length; i++) {\r\n const part = content[i];\r\n\r\n if (typeof part === 'string') {\r\n addWordsForContent(i, text.length, part.length);\r\n text += part;\r\n continue;\r\n }\r\n\r\n if ('text' in part) {\r\n if (\r\n typeof part.poem === 'number' &&\r\n text.length > 0 &&\r\n !text.endsWith('\\n')\r\n ) {\r\n startNewLine();\r\n }\r\n\r\n const start = text.length;\r\n addWordsForContent(i, start, part.text.length);\r\n text += part.text;\r\n const end = text.length;\r\n\r\n if (end > start) {\r\n if (part.wordsOfJesus) {\r\n wordsOfJesus.push({ start, end });\r\n }\r\n if (typeof part.poem === 'number') {\r\n poem.push({ start, end, level: part.poem });\r\n }\r\n }\r\n } else if ('lineBreak' in part) {\r\n if (text.length > 0 && !text.endsWith('\\n')) {\r\n startNewLine();\r\n }\r\n } else if ('noteId' in part) {\r\n const footnote = footnotes.get(part.noteId);\r\n if (footnote) {\r\n usedFootnotes.add(part.noteId);\r\n verseFootnotes.push({\r\n noteId: footnote.noteId,\r\n offset: text.length,\r\n text: footnote.text,\r\n caller: footnote.caller,\r\n });\r\n }\r\n if (needsSeparator(content[i + 1])) {\r\n text += ' ';\r\n }\r\n } else if ('heading' in part) {\r\n headings.push({\r\n offset: text.length,\r\n text: part.heading,\r\n });\r\n if (needsSeparator(content[i + 1])) {\r\n text += ' ';\r\n }\r\n }\r\n }\r\n\r\n // Trim the whitespace that line breaks and separators can leave behind.\r\n truncateTo(text.replace(/\\s+$/, '').length);\r\n\r\n const leading = text.length - text.replace(/^\\s+/, '').length;\r\n if (leading > 0) {\r\n text = text.slice(leading);\r\n for (let footnote of verseFootnotes) {\r\n footnote.offset = Math.max(0, footnote.offset - leading);\r\n }\r\n for (let heading of headings) {\r\n heading.offset = Math.max(0, heading.offset - leading);\r\n }\r\n for (let range of [...wordsOfJesus, ...poem, ...verseWords]) {\r\n range.start = Math.max(0, range.start - leading);\r\n range.end = Math.max(0, range.end - leading);\r\n }\r\n }\r\n\r\n return {\r\n text,\r\n footnotes: verseFootnotes,\r\n headings,\r\n wordsOfJesus: mergeAdjacentRanges(wordsOfJesus, text),\r\n poem: poem.filter((range) => range.start < range.end),\r\n words: verseWords.filter((word) => word.start < word.end),\r\n };\r\n}\r\n\r\n/**\r\n * Merges the ranges that are only separated by whitespace into single ranges.\r\n * @param ranges The ranges to merge. Must be sorted by their start offset.\r\n * @param text The text that the ranges point into.\r\n */\r\nfunction mergeAdjacentRanges(\r\n ranges: SimpleTextRange[],\r\n text: string\r\n): SimpleTextRange[] {\r\n const merged: SimpleTextRange[] = [];\r\n for (let range of ranges) {\r\n if (range.start >= range.end) {\r\n continue;\r\n }\r\n const previous = merged[merged.length - 1];\r\n if (\r\n previous &&\r\n range.start >= previous.end &&\r\n !/\\S/.test(text.slice(previous.end, range.start))\r\n ) {\r\n previous.end = range.end;\r\n } else {\r\n merged.push(range);\r\n }\r\n }\r\n return merged;\r\n}\r\n\r\n/**\r\n * Converts the given verse into its simplified representation.\r\n * @param verse The verse to convert.\r\n * @param footnotes The footnotes for the chapter, keyed by note ID.\r\n * @param usedFootnotes A set that the IDs of the referenced footnotes are added to.\r\n * @param words The word-level annotations for the verse.\r\n * @param remappedWords An array that the remapped word-level annotations are added to.\r\n */\r\nexport function simplifyVerse(\r\n verse: ChapterVerse,\r\n footnotes?: Map<number, ChapterFootnote>,\r\n usedFootnotes?: Set<number>,\r\n words?: readonly ChapterWord[],\r\n remappedWords?: SimpleChapterWord[]\r\n): SimpleChapterVerse {\r\n const simplified = simplifyVerseContent(\r\n verse.content,\r\n footnotes,\r\n usedFootnotes,\r\n words\r\n );\r\n\r\n if (remappedWords) {\r\n remappedWords.push(...simplified.words);\r\n }\r\n\r\n return {\r\n type: 'verse',\r\n number: verse.number,\r\n ...omitEmptyProperties(simplified),\r\n };\r\n}\r\n\r\n/**\r\n * Converts the given Hebrew Subtitle into its simplified representation.\r\n * @param subtitle The subtitle to convert.\r\n * @param footnotes The footnotes for the chapter, keyed by note ID.\r\n * @param usedFootnotes A set that the IDs of the referenced footnotes are added to.\r\n */\r\nexport function simplifyHebrewSubtitle(\r\n subtitle: ChapterHebrewSubtitle,\r\n footnotes?: Map<number, ChapterFootnote>,\r\n usedFootnotes?: Set<number>\r\n): SimpleChapterHebrewSubtitle {\r\n const simplified = simplifyVerseContent(\r\n subtitle.content,\r\n footnotes,\r\n usedFootnotes\r\n );\r\n\r\n return {\r\n type: 'hebrew_subtitle',\r\n ...omitEmptyProperties(simplified),\r\n };\r\n}\r\n\r\n/**\r\n * Omits the optional properties of the given simplified content when they are empty.\r\n * @param content The content to omit the empty properties from.\r\n */\r\nfunction omitEmptyProperties(content: SimplifiedVerseContent) {\r\n return {\r\n text: content.text,\r\n footnotes: content.footnotes,\r\n ...(content.headings.length > 0 ? { headings: content.headings } : {}),\r\n ...(content.wordsOfJesus.length > 0\r\n ? { wordsOfJesus: content.wordsOfJesus }\r\n : {}),\r\n ...(content.poem.length > 0 ? { poem: content.poem } : {}),\r\n };\r\n}\r\n\r\n/**\r\n * The result of converting a chapter into the simplified chapter format.\r\n */\r\nexport interface SimplifiedChapter {\r\n /**\r\n * The simplified chapter.\r\n */\r\n chapter: SimpleChapterData;\r\n\r\n /**\r\n * The word-level annotations for the chapter, with their offsets remapped onto the\r\n * text of each simplified verse. Empty if the chapter has no annotations.\r\n */\r\n words: SimpleTranslationBookChapterWords;\r\n}\r\n\r\n/**\r\n * Converts the given chapter into the simplified chapter format.\r\n *\r\n * In the simplified format, the content of each verse is a single string instead of a list\r\n * of formatted content, and the footnotes are available on the verse that they occur in,\r\n * along with the offset that they occur at.\r\n *\r\n * The word-level annotations are returned separately, since they are published in their\r\n * own file. They are converted here because their offsets have to be remapped onto the\r\n * text that is built for each verse.\r\n *\r\n * @param chapter The chapter to convert.\r\n * @param words The word-level annotations for the chapter, keyed by verse number.\r\n */\r\nexport function simplifyChapter(\r\n chapter: ChapterData,\r\n words?: TranslationBookChapterWords\r\n): SimplifiedChapter {\r\n const footnotes = new Map<number, ChapterFootnote>();\r\n for (let footnote of chapter.footnotes) {\r\n footnotes.set(footnote.noteId, footnote);\r\n }\r\n\r\n const usedFootnotes = new Set<number>();\r\n const content: SimpleChapterContent[] = [];\r\n const versesByNumber = new Map<number, SimpleChapterVerse>();\r\n const simpleWords: SimpleTranslationBookChapterWords = {};\r\n\r\n for (let c of chapter.content) {\r\n if (c.type === 'verse') {\r\n const verseWords = words?.[String(c.number)];\r\n const remappedWords: SimpleChapterWord[] = [];\r\n const verse = simplifyVerse(\r\n c,\r\n footnotes,\r\n usedFootnotes,\r\n verseWords,\r\n remappedWords\r\n );\r\n if (remappedWords.length > 0) {\r\n simpleWords[String(c.number)] = remappedWords;\r\n }\r\n versesByNumber.set(verse.number, verse);\r\n content.push(verse);\r\n } else if (c.type === 'hebrew_subtitle') {\r\n content.push(simplifyHebrewSubtitle(c, footnotes, usedFootnotes));\r\n } else if (c.type === 'heading') {\r\n content.push({\r\n type: 'heading',\r\n text: c.content.join(' '),\r\n });\r\n } else if (c.type === 'line_break') {\r\n content.push({\r\n type: 'line_break',\r\n });\r\n }\r\n }\r\n\r\n // Footnotes that aren't referenced by any verse content, but that do reference a\r\n // verse, get attached to the end of that verse.\r\n const unreferencedFootnotes: ChapterFootnote[] = [];\r\n for (let footnote of chapter.footnotes) {\r\n if (usedFootnotes.has(footnote.noteId)) {\r\n continue;\r\n }\r\n\r\n const verse = footnote.reference\r\n ? versesByNumber.get(footnote.reference.verse)\r\n : undefined;\r\n\r\n if (verse) {\r\n verse.footnotes.push({\r\n noteId: footnote.noteId,\r\n offset: verse.text.length,\r\n text: footnote.text,\r\n caller: footnote.caller,\r\n });\r\n } else {\r\n unreferencedFootnotes.push(footnote);\r\n }\r\n }\r\n\r\n return {\r\n chapter: {\r\n number: chapter.number,\r\n content,\r\n footnotes: unreferencedFootnotes,\r\n },\r\n words: simpleWords,\r\n };\r\n}\r\n\r\n/**\r\n * Converts the given commentary chapter into the simplified chapter format.\r\n * @param chapter The chapter to convert.\r\n */\r\nexport function simplifyCommentaryChapter(\r\n chapter: CommentaryChapterData\r\n): SimpleCommentaryChapterData {\r\n return {\r\n number: chapter.number,\r\n ...(chapter.introduction !== undefined\r\n ? { introduction: chapter.introduction }\r\n : {}),\r\n content: chapter.content.map((verse) => simplifyVerse(verse)),\r\n };\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../index.ts"],
|
|
4
|
-
"sourcesContent": ["import * as utils from './utils.js';\
|
|
4
|
+
"sourcesContent": ["import * as utils from './utils.js';\nimport * as generation from './generation/index.js';\nimport * as parser from './parser/index.js';\nimport * as log from './log.js';\n\nexport { utils, generation, parser, log };\n"],
|
|
5
5
|
"mappings": ";AAAA,YAAY,WAAW;AACvB,YAAY,gBAAgB;AAC5B,YAAY,YAAY;AACxB,YAAY,SAAS;AAErB,SAAS,OAAO,YAAY,QAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/log.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../log.ts"],
|
|
4
|
-
"sourcesContent": ["/**\
|
|
4
|
+
"sourcesContent": ["/**\n * A simple logging interface that can be used to log messages.\n */\nexport interface Logger {\n log: (message: any, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, ...args: any[]) => void;\n}\n\n/**\n * A logger that logs messages to the console.\n */\nexport const consoleLogger: Logger = {\n log: (message: string, ...args) => {\n console.log(message, ...args);\n },\n warn: (message: string, ...args) => {\n console.warn(message, ...args);\n },\n error: (message: string, ...args) => {\n console.error(message, ...args);\n },\n};\n\n/**\n * The logger that should be used for logging messages.\n */\nlet logger: Logger = consoleLogger;\n\n/**\n * Gets the logger that is currently being used for logging messages.\n * @returns The logger that is currently being used.\n */\nexport function getLogger(): Logger {\n return logger;\n}\n\n/**\n * Sets the logger to use for logging messages.\n * @param newLogger The new logger to use.\n */\nexport function setLogger(newLogger: Logger) {\n logger = newLogger;\n}\n"],
|
|
5
5
|
"mappings": ";AAYO,aAAM,gBAAwB;AAAA,EACjC,KAAK,CAAC,YAAoB,SAAS;AAC/B,YAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,EAChC;AAAA,EACA,MAAM,CAAC,YAAoB,SAAS;AAChC,YAAQ,KAAK,SAAS,GAAG,IAAI;AAAA,EACjC;AAAA,EACA,OAAO,CAAC,YAAoB,SAAS;AACjC,YAAQ,MAAM,SAAS,GAAG,IAAI;AAAA,EAClC;AACJ;AAKA,IAAI,SAAiB;AAMd,gBAAS,YAAoB;AAChC,SAAO;AACX;AAMO,gBAAS,UAAU,WAAmB;AACzC,WAAS;AACb;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -93,11 +93,11 @@ export class CodexParser {
|
|
|
93
93
|
const chapter = ensureChapter(chapterNumber);
|
|
94
94
|
chapter.footnotes.push(footnote);
|
|
95
95
|
}
|
|
96
|
-
function addReference(
|
|
97
|
-
addChapterContent(
|
|
96
|
+
function addReference(ref, content) {
|
|
97
|
+
addChapterContent(ref.chapter, [
|
|
98
98
|
{
|
|
99
99
|
type: "verse",
|
|
100
|
-
number:
|
|
100
|
+
number: ref.verse,
|
|
101
101
|
content
|
|
102
102
|
}
|
|
103
103
|
]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../parser/codex-parser.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod';\r\nimport {\r\n Chapter,\r\n ChapterContent,\r\n ParseTree,\r\n Verse,\r\n VerseContent,\r\n} from './types.js';\r\nimport { getBookId, parseVerseReference, VerseRef } from '../utils.js';\r\nimport { ref } from 'process';\r\n\r\nexport const chapterHeadingSchema = z.object({\r\n type: z.literal('chapter-heading'),\r\n data: z.object({\r\n chapter: z.coerce.number().int(),\r\n }),\r\n});\r\n\r\nexport const verseSchema = z.object({\r\n type: z.literal('text'),\r\n id: z.string(),\r\n bookCode: z.string().optional(),\r\n chapter: z.number().optional(),\r\n verse: z.number().optional(),\r\n data: z\r\n .object({\r\n globalReferences: z.array(z.string()).optional(),\r\n })\r\n .optional(),\r\n});\r\n\r\nexport const paratextSchema = z.object({\r\n type: z.literal('paratext'),\r\n id: z.string(),\r\n});\r\n\r\nexport const metadataSchema = z.discriminatedUnion('type', [\r\n chapterHeadingSchema,\r\n verseSchema,\r\n paratextSchema,\r\n]);\r\n\r\nexport const codexSchema = z.object({\r\n cells: z.array(\r\n z.object({\r\n kind: z.number(),\r\n languageId: z.string(),\r\n value: z.string(),\r\n metadata: z\r\n .object({\r\n type: z.string(),\r\n })\r\n .passthrough()\r\n .nullable()\r\n .optional(),\r\n })\r\n ),\r\n});\r\n\r\n/**\r\n * Defines a parser for codex files.\r\n */\r\nexport class CodexParser {\r\n // TODO:\r\n // /**\r\n // * Whether to preserve markdown in the parsed content.\r\n // */\r\n // preserveMarkdown: boolean = true;\r\n\r\n private _noteCounter: number = 0;\r\n\r\n private _parser: DOMParser;\r\n\r\n constructor(parser: DOMParser) {\r\n this._parser = parser;\r\n }\r\n\r\n /**\r\n * Parses the specified codex content.\r\n *\r\n * @param codex The codex content to parse.\r\n * @returns The parse tree that was generated.\r\n */\r\n public parse(codex: string): ParseTree {\r\n const json = JSON.parse(codex);\r\n const data = codexSchema.parse(json);\r\n\r\n let root: ParseTree = {\r\n type: 'root',\r\n content: [],\r\n };\r\n\r\n let chapters: Map<number, Chapter> = new Map();\r\n let lastChapter: Chapter | null = null;\r\n\r\n function ensureChapter(chapterNumber: number) {\r\n let chapter = chapters.get(chapterNumber);\r\n if (!chapter) {\r\n chapter = {\r\n type: 'chapter',\r\n number: chapterNumber,\r\n content: [],\r\n footnotes: [],\r\n };\r\n lastChapter = chapter;\r\n chapters.set(chapterNumber, chapter);\r\n }\r\n\r\n return chapter;\r\n }\r\n\r\n function getDocumentContent(doc: Document): string {\r\n let content = '';\r\n for (let element of doc.childNodes) {\r\n content += element.textContent;\r\n }\r\n return content;\r\n }\r\n\r\n function addChapterContent(\r\n chapterNumber: number,\r\n content: ChapterContent[]\r\n ) {\r\n const chapter = ensureChapter(chapterNumber);\r\n chapter.content.push(...content);\r\n }\r\n\r\n function addChapterFootnote(\r\n chapterNumber: number,\r\n footnote: Chapter['footnotes'][0]\r\n ) {\r\n const chapter = ensureChapter(chapterNumber);\r\n chapter.footnotes.push(footnote);\r\n }\r\n\r\n function addReference(ref: VerseRef, content: Verse['content']) {\r\n addChapterContent(ref.chapter, [\r\n {\r\n type: 'verse',\r\n number: ref.verse,\r\n content: content,\r\n },\r\n ]);\r\n }\r\n\r\n function stripHTML(value: string) {\r\n return value.replace(/<[^>]*>/g, '');\r\n }\r\n\r\n function toHeading(content: string) {\r\n return {\r\n type: 'heading',\r\n content: [content],\r\n } satisfies ChapterContent;\r\n }\r\n\r\n function addLineBreaks(lines: Verse['content']) {\r\n return lines.reduce(\r\n (prev, current) => {\r\n if (typeof current === 'string' && current.trim() === '') {\r\n return prev; // skip empty lines\r\n }\r\n if (prev.length === 0) {\r\n return [current];\r\n } else {\r\n return [\r\n ...prev,\r\n {\r\n lineBreak: true,\r\n },\r\n current,\r\n ] satisfies Verse['content'];\r\n }\r\n },\r\n [] as Verse['content']\r\n );\r\n }\r\n\r\n let previousReference: VerseRef | null = null;\r\n let lines: Verse['content'] = [];\r\n\r\n for (let cell of data.cells) {\r\n if (cell.languageId === 'html' && cell.value) {\r\n if (!cell.metadata) continue; // ignore html cells without metadata\r\n\r\n const metadataResult = metadataSchema.safeParse(cell.metadata);\r\n\r\n if (!metadataResult.success) continue; // ignore cells with invalid/unknown metadata\r\n const metadata = metadataResult.data;\r\n if (metadata.type === 'text') {\r\n let reference = parseVerseReference(metadata.id);\r\n if (!reference) {\r\n if (metadata.bookCode && metadata.chapter) {\r\n const bookId = getBookId(metadata.bookCode);\r\n if (!bookId) {\r\n throw new Error(\r\n 'Could not find book ID for code: ' +\r\n metadata.bookCode\r\n );\r\n }\r\n\r\n if (metadata.verse) {\r\n reference = {\r\n book: bookId,\r\n chapter: metadata.chapter,\r\n verse: metadata.verse,\r\n };\r\n } else if (previousReference?.verse) {\r\n if (\r\n previousReference.chapter !==\r\n metadata.chapter ||\r\n previousReference.book !== bookId\r\n ) {\r\n throw new Error(\r\n 'Cannot infer verse number for non-consecutive verse reference.'\r\n );\r\n }\r\n\r\n // Sometimes codex doesn't include verse numbers for every cell, so we infer it from the previous reference\r\n reference = {\r\n book: bookId,\r\n chapter: metadata.chapter,\r\n verse: previousReference.verse,\r\n };\r\n } else {\r\n throw new Error(\r\n 'Could not find verse reference in metadata.'\r\n );\r\n }\r\n } else if (metadata.data?.globalReferences?.length) {\r\n reference = parseVerseReference(\r\n metadata.data.globalReferences[0]\r\n );\r\n if (!reference) {\r\n throw new Error(\r\n 'Could not find verse reference in globalReferences metadata.'\r\n );\r\n }\r\n } else {\r\n throw new Error(\r\n 'Could not find verse reference in metadata.'\r\n );\r\n }\r\n }\r\n\r\n if (\r\n previousReference &&\r\n (reference.book !== previousReference.book ||\r\n reference.chapter !== previousReference.chapter ||\r\n reference.verse !== previousReference.verse)\r\n ) {\r\n addReference(previousReference, addLineBreaks(lines));\r\n lines = [];\r\n }\r\n\r\n previousReference = reference;\r\n\r\n if (!root.id) root.id = reference.book; // set book id if not already set\r\n\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n\r\n for (let element of doc.children) {\r\n const allFootnotes = element.querySelectorAll(\r\n 'sup.footnote-marker[data-footnote]'\r\n );\r\n for (const footnote of allFootnotes) {\r\n const footnoteData =\r\n footnote.getAttribute('data-footnote');\r\n if (footnoteData) {\r\n const footnoteDoc =\r\n this._parser.parseFromString(\r\n footnoteData,\r\n 'text/html'\r\n );\r\n const footnoteText =\r\n getDocumentContent(footnoteDoc);\r\n if (footnoteText) {\r\n addChapterFootnote(reference.chapter, {\r\n noteId: this._noteCounter++,\r\n text: footnoteText,\r\n caller: null,\r\n });\r\n }\r\n }\r\n footnote.remove();\r\n }\r\n }\r\n\r\n const content = getDocumentContent(doc);\r\n\r\n if (content) {\r\n // add line breaks in heading if there are multiple lines\r\n const newLines = content.split('\\n');\r\n\r\n lines.push(...newLines);\r\n }\r\n } else if (metadata.type === 'paratext') {\r\n const reference = parseVerseReference(`${metadata.id}:1`); // chapter headings do not have a verse reference always default to 1\r\n if (reference) {\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n const content = getDocumentContent(doc);\r\n\r\n if (!content) {\r\n continue;\r\n }\r\n\r\n // add line breaks in heading if there are multiple lines\r\n const lines = content\r\n .split('\\n')\r\n .reduce<ChapterContent[]>((prev, current) => {\r\n if (prev.length === 0)\r\n return [toHeading(current)];\r\n else\r\n return [\r\n ...prev,\r\n {\r\n type: 'line_break',\r\n },\r\n toHeading(current),\r\n ] satisfies ChapterContent[];\r\n }, []);\r\n\r\n lines.forEach((line) =>\r\n addChapterContent(reference.chapter, [line])\r\n );\r\n } else {\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n const content = getDocumentContent(doc);\r\n // parse paratext that isn't a chapter reference as footnote\r\n // const content = stripHTML(cell.value);\r\n if (content && !cell.metadata) {\r\n if (lastChapter) {\r\n (lastChapter as Chapter).footnotes.push({\r\n noteId: this._noteCounter++,\r\n text: content,\r\n caller: null,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (previousReference) {\r\n addReference(previousReference, addLineBreaks(lines));\r\n }\r\n\r\n for (let chapter of chapters.values()) {\r\n root.content.push(chapter);\r\n }\r\n\r\n return root;\r\n }\r\n}\r\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,SAAS;AAQlB,SAAS,WAAW,2BAAqC;
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod';\r\nimport {\r\n Chapter,\r\n ChapterContent,\r\n ParseTree,\r\n Verse,\r\n VerseContent,\r\n} from './types.js';\r\nimport { getBookId, parseVerseReference, VerseRef } from '../utils.js';\r\n\r\nexport const chapterHeadingSchema = z.object({\r\n type: z.literal('chapter-heading'),\r\n data: z.object({\r\n chapter: z.coerce.number().int(),\r\n }),\r\n});\r\n\r\nexport const verseSchema = z.object({\r\n type: z.literal('text'),\r\n id: z.string(),\r\n bookCode: z.string().optional(),\r\n chapter: z.number().optional(),\r\n verse: z.number().optional(),\r\n data: z\r\n .object({\r\n globalReferences: z.array(z.string()).optional(),\r\n })\r\n .optional(),\r\n});\r\n\r\nexport const paratextSchema = z.object({\r\n type: z.literal('paratext'),\r\n id: z.string(),\r\n});\r\n\r\nexport const metadataSchema = z.discriminatedUnion('type', [\r\n chapterHeadingSchema,\r\n verseSchema,\r\n paratextSchema,\r\n]);\r\n\r\nexport const codexSchema = z.object({\r\n cells: z.array(\r\n z.object({\r\n kind: z.number(),\r\n languageId: z.string(),\r\n value: z.string(),\r\n metadata: z\r\n .object({\r\n type: z.string(),\r\n })\r\n .passthrough()\r\n .nullable()\r\n .optional(),\r\n })\r\n ),\r\n});\r\n\r\n/**\r\n * Defines a parser for codex files.\r\n */\r\nexport class CodexParser {\r\n // TODO:\r\n // /**\r\n // * Whether to preserve markdown in the parsed content.\r\n // */\r\n // preserveMarkdown: boolean = true;\r\n\r\n private _noteCounter: number = 0;\r\n\r\n private _parser: DOMParser;\r\n\r\n constructor(parser: DOMParser) {\r\n this._parser = parser;\r\n }\r\n\r\n /**\r\n * Parses the specified codex content.\r\n *\r\n * @param codex The codex content to parse.\r\n * @returns The parse tree that was generated.\r\n */\r\n public parse(codex: string): ParseTree {\r\n const json = JSON.parse(codex);\r\n const data = codexSchema.parse(json);\r\n\r\n let root: ParseTree = {\r\n type: 'root',\r\n content: [],\r\n };\r\n\r\n let chapters: Map<number, Chapter> = new Map();\r\n let lastChapter: Chapter | null = null;\r\n\r\n function ensureChapter(chapterNumber: number) {\r\n let chapter = chapters.get(chapterNumber);\r\n if (!chapter) {\r\n chapter = {\r\n type: 'chapter',\r\n number: chapterNumber,\r\n content: [],\r\n footnotes: [],\r\n };\r\n lastChapter = chapter;\r\n chapters.set(chapterNumber, chapter);\r\n }\r\n\r\n return chapter;\r\n }\r\n\r\n function getDocumentContent(doc: Document): string {\r\n let content = '';\r\n for (let element of doc.childNodes) {\r\n content += element.textContent;\r\n }\r\n return content;\r\n }\r\n\r\n function addChapterContent(\r\n chapterNumber: number,\r\n content: ChapterContent[]\r\n ) {\r\n const chapter = ensureChapter(chapterNumber);\r\n chapter.content.push(...content);\r\n }\r\n\r\n function addChapterFootnote(\r\n chapterNumber: number,\r\n footnote: Chapter['footnotes'][0]\r\n ) {\r\n const chapter = ensureChapter(chapterNumber);\r\n chapter.footnotes.push(footnote);\r\n }\r\n\r\n function addReference(ref: VerseRef, content: Verse['content']) {\r\n addChapterContent(ref.chapter, [\r\n {\r\n type: 'verse',\r\n number: ref.verse,\r\n content: content,\r\n },\r\n ]);\r\n }\r\n\r\n function stripHTML(value: string) {\r\n return value.replace(/<[^>]*>/g, '');\r\n }\r\n\r\n function toHeading(content: string) {\r\n return {\r\n type: 'heading',\r\n content: [content],\r\n } satisfies ChapterContent;\r\n }\r\n\r\n function addLineBreaks(lines: Verse['content']) {\r\n return lines.reduce(\r\n (prev, current) => {\r\n if (typeof current === 'string' && current.trim() === '') {\r\n return prev; // skip empty lines\r\n }\r\n if (prev.length === 0) {\r\n return [current];\r\n } else {\r\n return [\r\n ...prev,\r\n {\r\n lineBreak: true,\r\n },\r\n current,\r\n ] satisfies Verse['content'];\r\n }\r\n },\r\n [] as Verse['content']\r\n );\r\n }\r\n\r\n let previousReference: VerseRef | null = null;\r\n let lines: Verse['content'] = [];\r\n\r\n for (let cell of data.cells) {\r\n if (cell.languageId === 'html' && cell.value) {\r\n if (!cell.metadata) continue; // ignore html cells without metadata\r\n\r\n const metadataResult = metadataSchema.safeParse(cell.metadata);\r\n\r\n if (!metadataResult.success) continue; // ignore cells with invalid/unknown metadata\r\n const metadata = metadataResult.data;\r\n if (metadata.type === 'text') {\r\n let reference = parseVerseReference(metadata.id);\r\n if (!reference) {\r\n if (metadata.bookCode && metadata.chapter) {\r\n const bookId = getBookId(metadata.bookCode);\r\n if (!bookId) {\r\n throw new Error(\r\n 'Could not find book ID for code: ' +\r\n metadata.bookCode\r\n );\r\n }\r\n\r\n if (metadata.verse) {\r\n reference = {\r\n book: bookId,\r\n chapter: metadata.chapter,\r\n verse: metadata.verse,\r\n };\r\n } else if (previousReference?.verse) {\r\n if (\r\n previousReference.chapter !==\r\n metadata.chapter ||\r\n previousReference.book !== bookId\r\n ) {\r\n throw new Error(\r\n 'Cannot infer verse number for non-consecutive verse reference.'\r\n );\r\n }\r\n\r\n // Sometimes codex doesn't include verse numbers for every cell, so we infer it from the previous reference\r\n reference = {\r\n book: bookId,\r\n chapter: metadata.chapter,\r\n verse: previousReference.verse,\r\n };\r\n } else {\r\n throw new Error(\r\n 'Could not find verse reference in metadata.'\r\n );\r\n }\r\n } else if (metadata.data?.globalReferences?.length) {\r\n reference = parseVerseReference(\r\n metadata.data.globalReferences[0]\r\n );\r\n if (!reference) {\r\n throw new Error(\r\n 'Could not find verse reference in globalReferences metadata.'\r\n );\r\n }\r\n } else {\r\n throw new Error(\r\n 'Could not find verse reference in metadata.'\r\n );\r\n }\r\n }\r\n\r\n if (\r\n previousReference &&\r\n (reference.book !== previousReference.book ||\r\n reference.chapter !== previousReference.chapter ||\r\n reference.verse !== previousReference.verse)\r\n ) {\r\n addReference(previousReference, addLineBreaks(lines));\r\n lines = [];\r\n }\r\n\r\n previousReference = reference;\r\n\r\n if (!root.id) root.id = reference.book; // set book id if not already set\r\n\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n\r\n for (let element of doc.children) {\r\n const allFootnotes = element.querySelectorAll(\r\n 'sup.footnote-marker[data-footnote]'\r\n );\r\n for (const footnote of allFootnotes) {\r\n const footnoteData =\r\n footnote.getAttribute('data-footnote');\r\n if (footnoteData) {\r\n const footnoteDoc =\r\n this._parser.parseFromString(\r\n footnoteData,\r\n 'text/html'\r\n );\r\n const footnoteText =\r\n getDocumentContent(footnoteDoc);\r\n if (footnoteText) {\r\n addChapterFootnote(reference.chapter, {\r\n noteId: this._noteCounter++,\r\n text: footnoteText,\r\n caller: null,\r\n });\r\n }\r\n }\r\n footnote.remove();\r\n }\r\n }\r\n\r\n const content = getDocumentContent(doc);\r\n\r\n if (content) {\r\n // add line breaks in heading if there are multiple lines\r\n const newLines = content.split('\\n');\r\n\r\n lines.push(...newLines);\r\n }\r\n } else if (metadata.type === 'paratext') {\r\n const reference = parseVerseReference(`${metadata.id}:1`); // chapter headings do not have a verse reference always default to 1\r\n if (reference) {\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n const content = getDocumentContent(doc);\r\n\r\n if (!content) {\r\n continue;\r\n }\r\n\r\n // add line breaks in heading if there are multiple lines\r\n const lines = content\r\n .split('\\n')\r\n .reduce<ChapterContent[]>((prev, current) => {\r\n if (prev.length === 0)\r\n return [toHeading(current)];\r\n else\r\n return [\r\n ...prev,\r\n {\r\n type: 'line_break',\r\n },\r\n toHeading(current),\r\n ] satisfies ChapterContent[];\r\n }, []);\r\n\r\n lines.forEach((line) =>\r\n addChapterContent(reference.chapter, [line])\r\n );\r\n } else {\r\n const doc = this._parser.parseFromString(\r\n cell.value,\r\n 'text/html'\r\n );\r\n const content = getDocumentContent(doc);\r\n // parse paratext that isn't a chapter reference as footnote\r\n // const content = stripHTML(cell.value);\r\n if (content && !cell.metadata) {\r\n if (lastChapter) {\r\n (lastChapter as Chapter).footnotes.push({\r\n noteId: this._noteCounter++,\r\n text: content,\r\n caller: null,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (previousReference) {\r\n addReference(previousReference, addLineBreaks(lines));\r\n }\r\n\r\n for (let chapter of chapters.values()) {\r\n root.content.push(chapter);\r\n }\r\n\r\n return root;\r\n }\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["lines"]
|
|
7
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import { getBookId, parseVerseReference } from "../utils";
|
|
3
|
-
import
|
|
2
|
+
import { getBookId, parseVerseReference } from "../utils.js";
|
|
3
|
+
import papaparse from "papaparse";
|
|
4
|
+
const { parse } = papaparse;
|
|
4
5
|
export class CommentaryCsvParser {
|
|
5
6
|
parse(data) {
|
|
6
7
|
const firstLine = data.indexOf("\n");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../parser/commentary-csv-parser.ts"],
|
|
4
|
-
"sourcesContent": ["import {\r\n CommentaryBookNode,\r\n CommentaryChapterNode,\r\n CommentaryParseTree,\r\n} from './types';\r\nimport { getBookId, parseVerseReference } from '../utils';\r\nimport { parse }
|
|
5
|
-
"mappings": ";AAKA,SAAS,WAAW,2BAA2B;AAC/C,
|
|
4
|
+
"sourcesContent": ["import {\r\n CommentaryBookNode,\r\n CommentaryChapterNode,\r\n CommentaryParseTree,\r\n} from './types.js';\r\nimport { getBookId, parseVerseReference } from '../utils.js';\r\nimport papaparse from 'papaparse';\r\n\r\nconst { parse } = papaparse;\r\n\r\nexport interface CsvLine {\r\n book: string;\r\n chapter: string;\r\n verse: string;\r\n commentaries: string;\r\n}\r\n\r\nexport class CommentaryCsvParser {\r\n parse(data: string): CommentaryParseTree {\r\n // remove header automatically\r\n const firstLine = data.indexOf('\\n');\r\n data = data.substring(firstLine + 1);\r\n\r\n const lines = parse<string[]>(data, {\r\n header: false,\r\n // transformHeader: (_, index) => {\r\n // const headers = ['book', 'chapter', 'verse', 'commentaries'];\r\n // if (index < headers.length) {\r\n // return headers[index];\r\n // } else {\r\n // return '';\r\n // }\r\n // },\r\n delimiter: ',',\r\n escapeChar: '\"',\r\n quoteChar: '\"',\r\n });\r\n return this.parseLines(\r\n lines.data.map((line: string[]) => ({\r\n book: line[0],\r\n chapter: line[1],\r\n verse: line[2],\r\n commentaries: line[3],\r\n }))\r\n );\r\n }\r\n\r\n parseLines(data: CsvLine[]): CommentaryParseTree {\r\n let tree: CommentaryParseTree = {\r\n type: 'commentary/root',\r\n books: [],\r\n };\r\n\r\n let book: CommentaryBookNode | null = null;\r\n let chapter: CommentaryChapterNode | null = null;\r\n for (let line of data) {\r\n if (hasValue(line.book)) {\r\n const id = getBookId(line.book);\r\n if (!id) {\r\n throw new Error('Invalid book: ' + line.book);\r\n }\r\n\r\n book = tree.books.find((b) => b.book === id) ?? null;\r\n if (!book) {\r\n book = {\r\n type: 'book',\r\n book: id,\r\n introduction: null,\r\n chapters: [],\r\n };\r\n tree.books.push(book);\r\n }\r\n\r\n if (!book.introduction) {\r\n book.introduction = hasValue(line.commentaries)\r\n ? line.commentaries\r\n : null;\r\n }\r\n } else if (hasValue(line.chapter)) {\r\n const number = parseInt(line.chapter);\r\n if (isNaN(number)) {\r\n throw new Error('Invalid chapter number: ' + line.chapter);\r\n }\r\n\r\n if (!book) {\r\n throw new Error('Chapter without book');\r\n }\r\n\r\n chapter = {\r\n type: 'chapter',\r\n number,\r\n introduction: hasValue(line.commentaries)\r\n ? line.commentaries\r\n : null,\r\n verses: [],\r\n };\r\n book.chapters.push(chapter);\r\n } else if (hasValue(line.verse)) {\r\n const ref = parseVerseReference(line.verse);\r\n if (ref) {\r\n if (ref.book === book?.book) {\r\n // @ts-ignore\r\n if (ref.chapter === chapter?.number) {\r\n chapter.verses.push({\r\n type: 'verse',\r\n number: ref.verse,\r\n content: [line.commentaries],\r\n });\r\n } else {\r\n chapter = {\r\n type: 'chapter',\r\n number: ref.chapter,\r\n introduction: null,\r\n verses: [\r\n {\r\n type: 'verse',\r\n number: ref.verse,\r\n content: [line.commentaries],\r\n },\r\n ],\r\n };\r\n\r\n book.chapters.push(chapter);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return tree;\r\n }\r\n}\r\n\r\nfunction hasValue(value: string | null): boolean {\r\n return (\r\n value !== null &&\r\n value !== undefined &&\r\n value !== '' &&\r\n value.trim() !== ''\r\n );\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../parser/iterators.ts"],
|
|
4
|
-
"sourcesContent": ["import { getLogger } from '../log.js';\
|
|
4
|
+
"sourcesContent": ["import { getLogger } from '../log.js';\n\n/**\n * Defines an interface that represents an iterator that can be rewound.\n */\nexport interface RewindableIterator<T> extends IterableIterator<T> {\n /**\n * Rewinds the iterator by the specified number of elements.\n * @param number The number of elements to rewind.\n */\n rewind(number: number): void;\n}\n\n/**\n * Defines a class that implements an iterator that can be rewound.\n */\nexport class Rewindable<T> implements RewindableIterator<T> {\n buffer: T[] = [];\n\n private _bufferSize: number = 0;\n private _position: number = -1;\n private _iterator: IterableIterator<T>;\n\n constructor(iterator: IterableIterator<T>, bufferSize: number = 2) {\n this._iterator = iterator;\n this._bufferSize = bufferSize;\n\n if (this._iterator.return) {\n this.return = (value?: any) => {\n return this._iterator.return!(value);\n };\n }\n if (this._iterator.throw) {\n this.throw = (value?: any) => {\n return this._iterator.throw!(value);\n };\n }\n }\n\n rewind(number: number): void {\n this._position += number;\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this;\n }\n\n next(...args: [] | [undefined]): IteratorResult<T, any> {\n if (this._position >= 0) {\n let item = this.buffer[this._position];\n this._position--;\n return {\n value: item,\n done: false,\n };\n }\n\n let result = this._iterator.next(...args);\n this.buffer.unshift(result.value);\n if (this.buffer.length > this._bufferSize) {\n this.buffer.splice(\n this._bufferSize,\n this.buffer.length - this._bufferSize\n );\n }\n return result;\n }\n\n return?(value?: any): IteratorResult<T, any>;\n throw?(e?: any): IteratorResult<T, any>;\n}\n\nexport function* debug(label: string, iterator: IterableIterator<any>) {\n const logger = getLogger();\n for (let value of uncompletable(iterator)) {\n if (value instanceof Element) {\n logger.log(label, value.outerHTML);\n } else if (value instanceof Node) {\n logger.log(label, value.textContent);\n } else {\n logger.log(label, value);\n }\n yield value;\n }\n}\n\n/**\n * Creates a new rewindable iterator from the given iterator.\n * @param iterator The iterator.\n * @param bufferSize The size of the buffer.\n */\nexport function rewindable<T>(\n iterator: IterableIterator<T>,\n bufferSize: number = 2\n): Rewindable<T> {\n return new Rewindable(iterator, bufferSize);\n}\n\nfunction* iterateNodes(node: Node) {\n for (let i = 0; i < node.childNodes.length; i++) {\n yield node.childNodes[i];\n }\n}\n\n/**\n * Gets the char element that is the parent of the given node.\n * @param node The node.\n */\nexport function parentChar(node: Node): Element | null {\n return matchingParent(\n node,\n (n) => n instanceof Element && n.nodeName === 'char'\n ) as Element | null;\n}\n\n/**\n * Gets the note element that is the parent of the given node.\n * @param node The node.\n */\nexport function parentNote(node: Node): Element | null {\n return matchingParent(\n node,\n (n) => n instanceof Element && n.nodeName === 'note'\n ) as Element | null;\n}\n\n/**\n * Gets the parent node that matches the given filter.\n * @param node The node to start the search from.\n * @param filter The filter that should be used.\n */\nexport function matchingParent(\n node: Node,\n filter: (node: Node) => boolean\n): Node | null {\n let parent = node.parentNode;\n while (parent) {\n if (filter(parent)) {\n return parent;\n }\n parent = parent.parentNode;\n }\n return null;\n}\n\n/**\n * Determines if the given node is a child of the parent node.\n * @param node The node to test.\n * @param parent The parent.\n * @returns\n */\nexport function isParent(node: Node, parent: Node): boolean {\n let parentNode = node.parentNode;\n while (parentNode) {\n if (parentNode === parent) {\n return true;\n }\n parentNode = parentNode.parentNode;\n }\n return false;\n}\n\n/**\n * Iterates through all of the nodes in the tree in a depth-first traversal.\n * @param node The node to start the traversal from.\n */\nexport function iterateAll(node: Node): RewindableIterator<Node> {\n return rewindable(_iterateAll(node));\n}\n\nexport function* iterateUntil<T>(\n iterator: IterableIterator<T>,\n predicate: (value: T) => boolean\n): IterableIterator<T> {\n for (let value of iterator) {\n if (predicate(value)) {\n return;\n }\n yield value;\n }\n}\n\nfunction* _iterateAll(node: Node): IterableIterator<Node> {\n for (let child of node.childNodes) {\n yield child;\n yield* iterateAll(child);\n }\n}\n\n/**\n * Iterates only the elements in the iterator.\n * @param iterator The iterator that should be used.\n */\nexport function* elements(\n iterator: IterableIterator<Node>\n): IterableIterator<Element> {\n for (let node of uncompletable(iterator)) {\n if (node instanceof Element) {\n yield node;\n }\n }\n}\n\n/**\n * Iterates only the children of the given node in the iterator.\n * @param iterator The iterator that should be used.\n * @param parent The parent node.\n */\nexport function* children(\n iterator: RewindableIterator<Node>,\n parent: Node\n): IterableIterator<Node> {\n for (let node of uncompletable(iterator)) {\n if (!isParent(node, parent)) {\n iterator.rewind(1);\n return;\n }\n\n yield node;\n }\n}\n\n/**\n * Wraps the given iterable in a generator that will prevent consumers from calling return() on the iterator.\n * @param iterable The iterable.\n */\nexport function* uncompletable<T>(\n iterable: IterableIterator<T>\n): IterableIterator<T> {\n while (true) {\n const { done, value } = iterable.next();\n if (done) {\n return;\n }\n yield value;\n }\n}\n\n/**\n * Converts the given iterable into an async iterable.\n * @param input The input iterable.\n */\nexport async function* toAsyncIterable<T>(\n input: Iterable<T>\n): AsyncIterable<T> {\n for (let item of input) {\n yield item;\n }\n}\n\n/**\n * Batches items from the given iterator.\n * @param input The input iterator.\n * @param batchSize The size of each batch.\n */\nexport function* batch<T>(\n input: Iterable<T>,\n batchSize: number\n): Iterable<T[]> {\n while (true) {\n let batch = [] as T[];\n for (let item of input) {\n batch.push(item);\n if (batch.length >= batchSize) {\n break;\n }\n }\n\n if (batch.length === 0) {\n return;\n }\n\n yield batch;\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["batch"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import { bookOrderMap } from "../generation/book-order";
|
|
2
|
+
import { bookOrderMap } from "../generation/book-order.js";
|
|
3
3
|
export const LOCKMAN_PARSER_VERSION = 3;
|
|
4
4
|
const bookNumberIdMap = /* @__PURE__ */ new Map();
|
|
5
5
|
for (const [id, order] of bookOrderMap) {
|