@helloao/tools 0.0.6 → 0.0.9
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 +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 +2 -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 -3
- package/generation/api.js +0 -187
- package/generation/api.spec.d.ts +0 -2
- package/generation/api.spec.js +0 -620
- 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 -486
- 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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { UsfmParser } from "../parser/usfm-parser.js";
|
|
3
|
+
import { USXParser } from "../parser/usx-parser.js";
|
|
4
|
+
import { bookIdMap, bookOrderMap } from "./book-order.js";
|
|
5
|
+
import { omit, sortBy, sortedIndexBy } from "lodash";
|
|
6
|
+
import { getAudioUrlsForChapter } from "./audio.js";
|
|
7
|
+
import { CodexParser } from "../parser/codex-parser.js";
|
|
8
|
+
export function generateDataset(files, parser = new globalThis.DOMParser()) {
|
|
9
|
+
let output = {
|
|
10
|
+
translations: []
|
|
11
|
+
};
|
|
12
|
+
let usfmParser = new UsfmParser();
|
|
13
|
+
let usxParser = new USXParser(parser);
|
|
14
|
+
let codexParser = new CodexParser();
|
|
15
|
+
let parsedTranslations = /* @__PURE__ */ new Map();
|
|
16
|
+
const unknownLanguages = /* @__PURE__ */ new Set();
|
|
17
|
+
for (let file of files) {
|
|
18
|
+
try {
|
|
19
|
+
let parser2;
|
|
20
|
+
if (file.fileType === "usfm") {
|
|
21
|
+
parser2 = usfmParser;
|
|
22
|
+
} else if (file.fileType === "usx") {
|
|
23
|
+
parser2 = usxParser;
|
|
24
|
+
} else if (file.fileType === "json") {
|
|
25
|
+
parser2 = codexParser;
|
|
26
|
+
} else {
|
|
27
|
+
console.warn(
|
|
28
|
+
"[generate] File does not have a valid type!",
|
|
29
|
+
file.name
|
|
30
|
+
);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const parsed = parser2.parse(file.content);
|
|
34
|
+
const id = parsed.id;
|
|
35
|
+
if (!id) {
|
|
36
|
+
console.warn(
|
|
37
|
+
"[generate] File does not have a valid book ID!",
|
|
38
|
+
file.name,
|
|
39
|
+
id
|
|
40
|
+
);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const order = bookOrderMap.get(id);
|
|
44
|
+
if (typeof order !== "number") {
|
|
45
|
+
console.warn("[generate] Book does not have an order!", id);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const bookMap = bookIdMap.get(file.metadata.translation.language);
|
|
49
|
+
if (!bookMap) {
|
|
50
|
+
if (!unknownLanguages.has(file.metadata.translation.language)) {
|
|
51
|
+
console.warn(
|
|
52
|
+
"[generate] File does not have a known language!",
|
|
53
|
+
file.name,
|
|
54
|
+
file.metadata.translation.language
|
|
55
|
+
);
|
|
56
|
+
unknownLanguages.add(file.metadata.translation.language);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const bookName = bookMap?.get(id);
|
|
60
|
+
if (!!bookMap && !bookName) {
|
|
61
|
+
console.warn(
|
|
62
|
+
"[generate] Book name not found for ID!",
|
|
63
|
+
file.name,
|
|
64
|
+
id
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
let translation = parsedTranslations.get(
|
|
68
|
+
file.metadata.translation.id
|
|
69
|
+
);
|
|
70
|
+
if (!translation) {
|
|
71
|
+
translation = {
|
|
72
|
+
...omit(file.metadata.translation, "direction"),
|
|
73
|
+
textDirection: file.metadata.translation.direction,
|
|
74
|
+
books: []
|
|
75
|
+
};
|
|
76
|
+
output.translations.push(translation);
|
|
77
|
+
parsedTranslations.set(
|
|
78
|
+
file.metadata.translation.id,
|
|
79
|
+
translation
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
const name = parsed.header ?? bookName?.commonName ?? parsed.title;
|
|
83
|
+
if (!name) {
|
|
84
|
+
console.warn(
|
|
85
|
+
"[generate] Book does not have a name!",
|
|
86
|
+
file.name,
|
|
87
|
+
id
|
|
88
|
+
);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const commonName = bookName?.commonName ?? parsed.header ?? parsed.title ?? id;
|
|
92
|
+
const book = {
|
|
93
|
+
id,
|
|
94
|
+
name,
|
|
95
|
+
commonName,
|
|
96
|
+
title: parsed.title ?? null,
|
|
97
|
+
order,
|
|
98
|
+
chapters: []
|
|
99
|
+
};
|
|
100
|
+
for (let content of parsed.content) {
|
|
101
|
+
if (content.type === "chapter") {
|
|
102
|
+
book.chapters.push({
|
|
103
|
+
chapter: {
|
|
104
|
+
number: content.number,
|
|
105
|
+
content: content.content,
|
|
106
|
+
footnotes: content.footnotes
|
|
107
|
+
},
|
|
108
|
+
thisChapterAudioLinks: getAudioUrlsForChapter(
|
|
109
|
+
translation.id,
|
|
110
|
+
id,
|
|
111
|
+
content.number
|
|
112
|
+
)
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
book.chapters = sortBy(book.chapters, (c) => c.chapter.number);
|
|
117
|
+
const index = sortedIndexBy(
|
|
118
|
+
translation.books,
|
|
119
|
+
book,
|
|
120
|
+
(b) => b.order
|
|
121
|
+
);
|
|
122
|
+
translation.books.splice(index, 0, book);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.error(
|
|
125
|
+
`[generate] Error occurred while parsing ${file.name}`,
|
|
126
|
+
err
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return output;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=dataset.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../generation/dataset.ts"],
|
|
4
|
+
"sourcesContent": ["import { UsfmParser } from '../parser/usfm-parser.js';\r\nimport { USXParser } from '../parser/usx-parser.js';\r\nimport {\r\n InputFile,\r\n Translation,\r\n TranslationBook,\r\n TranslationBookChapter,\r\n} from './common-types.js';\r\nimport { bookIdMap, bookOrderMap } from './book-order.js';\r\nimport { omit, sortBy, sortedIndexBy } from 'lodash';\r\nimport { getAudioUrlsForChapter } from './audio.js';\r\nimport { CodexParser } from '../parser/codex-parser.js';\r\n\r\n/**\r\n * Defines an interface that contains generated dataset info.\r\n */\r\nexport interface DatasetOutput {\r\n /**\r\n * The list of translations that are available in the dataset.\r\n */\r\n translations: DatasetTranslation[];\r\n}\r\n\r\n/**\r\n * Defines a translation that is used in the dataset.\r\n */\r\nexport interface DatasetTranslation extends Translation {\r\n /**\r\n * The list of books that are available for the translation.\r\n */\r\n books: DatasetTranslationBook[];\r\n}\r\n\r\n/**\r\n * Defines a translation book that is used in the dataset.\r\n */\r\nexport interface DatasetTranslationBook extends TranslationBook {\r\n /**\r\n * The list of chapters that are available for the book.\r\n */\r\n chapters: TranslationBookChapter[];\r\n}\r\n\r\n/**\r\n * Generates a list of output files from the given list of input files.\r\n * @param file The list of files.\r\n */\r\nexport function generateDataset(\r\n files: InputFile[],\r\n parser: DOMParser = new globalThis.DOMParser()\r\n): DatasetOutput {\r\n let output: DatasetOutput = {\r\n translations: [],\r\n };\r\n\r\n let usfmParser = new UsfmParser();\r\n let usxParser = new USXParser(parser);\r\n let codexParser = new CodexParser();\r\n\r\n let parsedTranslations = new Map<string, DatasetTranslation>();\r\n\r\n const unknownLanguages = new Set<string>();\r\n for (let file of files) {\r\n try {\r\n let parser: UsfmParser | USXParser | CodexParser;\r\n if (file.fileType === 'usfm') {\r\n parser = usfmParser;\r\n } else if (file.fileType === 'usx') {\r\n parser = usxParser;\r\n } else if (file.fileType === 'json') {\r\n parser = codexParser;\r\n } else {\r\n console.warn(\r\n '[generate] File does not have a valid type!',\r\n file.name\r\n );\r\n continue;\r\n }\r\n\r\n const parsed = parser.parse(file.content);\r\n const id = parsed.id;\r\n\r\n if (!id) {\r\n console.warn(\r\n '[generate] File does not have a valid book ID!',\r\n file.name,\r\n id\r\n );\r\n continue;\r\n }\r\n\r\n const order = bookOrderMap.get(id);\r\n\r\n if (typeof order !== 'number') {\r\n console.warn('[generate] Book does not have an order!', id);\r\n continue;\r\n }\r\n\r\n const bookMap = bookIdMap.get(file.metadata.translation.language);\r\n\r\n if (!bookMap) {\r\n if (!unknownLanguages.has(file.metadata.translation.language)) {\r\n console.warn(\r\n '[generate] File does not have a known language!',\r\n file.name,\r\n file.metadata.translation.language\r\n );\r\n unknownLanguages.add(file.metadata.translation.language);\r\n }\r\n }\r\n\r\n const bookName = bookMap?.get(id);\r\n\r\n if (!!bookMap && !bookName) {\r\n console.warn(\r\n '[generate] Book name not found for ID!',\r\n file.name,\r\n id\r\n );\r\n }\r\n\r\n let translation = parsedTranslations.get(\r\n file.metadata.translation.id\r\n );\r\n\r\n if (!translation) {\r\n translation = {\r\n ...omit(file.metadata.translation, 'direction'),\r\n textDirection: file.metadata.translation.direction,\r\n books: [],\r\n };\r\n output.translations.push(translation);\r\n parsedTranslations.set(\r\n file.metadata.translation.id,\r\n translation\r\n );\r\n }\r\n\r\n const name = parsed.header ?? bookName?.commonName ?? parsed.title;\r\n\r\n if (!name) {\r\n console.warn(\r\n '[generate] Book does not have a name!',\r\n file.name,\r\n id\r\n );\r\n continue;\r\n }\r\n\r\n const commonName =\r\n bookName?.commonName ?? parsed.header ?? parsed.title ?? id;\r\n\r\n const book: DatasetTranslationBook = {\r\n id: id,\r\n name,\r\n commonName,\r\n title: parsed.title ?? null,\r\n order,\r\n chapters: [],\r\n };\r\n\r\n for (let content of parsed.content) {\r\n if (content.type === 'chapter') {\r\n book.chapters.push({\r\n chapter: {\r\n number: content.number,\r\n content: content.content,\r\n footnotes: content.footnotes,\r\n },\r\n thisChapterAudioLinks: getAudioUrlsForChapter(\r\n translation.id,\r\n id,\r\n content.number\r\n ),\r\n });\r\n }\r\n }\r\n\r\n book.chapters = sortBy(book.chapters, (c) => c.chapter.number);\r\n\r\n const index = sortedIndexBy(\r\n translation.books,\r\n book,\r\n (b) => b.order\r\n );\r\n translation.books.splice(index, 0, book);\r\n } catch (err) {\r\n console.error(\r\n `[generate] Error occurred while parsing ${file.name}`,\r\n err\r\n );\r\n }\r\n }\r\n\r\n return output;\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["parser"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import * as api from "./api.js";
|
|
3
|
+
import * as audio from "./audio.js";
|
|
4
|
+
import * as dataset from "./dataset.js";
|
|
5
|
+
import * as bookOrder from "./book-order.js";
|
|
6
|
+
export * from "./common-types.js";
|
|
7
|
+
export { api, audio, dataset, bookOrder };
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../generation/index.ts"],
|
|
4
|
+
"sourcesContent": ["import * as api from './api.js';\r\nimport * as audio from './audio.js';\r\nimport * as dataset from './dataset.js';\r\nimport * as bookOrder from './book-order.js';\r\nexport * from './common-types.js';\r\n\r\nexport { api, audio, dataset, bookOrder };\r\n"],
|
|
5
|
+
"mappings": ";AAAA,YAAY,SAAS;AACrB,YAAY,WAAW;AACvB,YAAY,aAAa;AACzB,YAAY,eAAe;AAC3B,cAAc;AAEd,SAAS,KAAK,OAAO,SAAS;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../index.ts"],
|
|
4
|
+
"sourcesContent": ["import * as utils from './utils.js';\r\nimport * as generation from './generation/index.js';\r\nimport * as parser from './parser/index.js';\r\n\r\nexport { utils, generation, parser };\r\n"],
|
|
5
|
+
"mappings": ";AAAA,YAAY,WAAW;AACvB,YAAY,gBAAgB;AAC5B,YAAY,YAAY;AAExB,SAAS,OAAO,YAAY;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { parseVerseReference } from "../utils.js";
|
|
4
|
+
export const chapterHeadingSchema = z.object({
|
|
5
|
+
type: z.literal("chapter-heading"),
|
|
6
|
+
data: z.object({
|
|
7
|
+
chapter: z.coerce.number().int()
|
|
8
|
+
})
|
|
9
|
+
});
|
|
10
|
+
export const metadataSchema = z.discriminatedUnion("type", [
|
|
11
|
+
chapterHeadingSchema
|
|
12
|
+
]);
|
|
13
|
+
export const codexSchema = z.object({
|
|
14
|
+
cells: z.array(
|
|
15
|
+
z.object({
|
|
16
|
+
// kind: z.number().int(),
|
|
17
|
+
language: z.string(),
|
|
18
|
+
value: z.string(),
|
|
19
|
+
metadata: z.object({
|
|
20
|
+
type: z.string()
|
|
21
|
+
}).passthrough().nullable().optional()
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
});
|
|
25
|
+
export class CodexParser {
|
|
26
|
+
// TODO:
|
|
27
|
+
// /**
|
|
28
|
+
// * Whether to preserve markdown in the parsed content.
|
|
29
|
+
// */
|
|
30
|
+
// preserveMarkdown: boolean = true;
|
|
31
|
+
_noteCounter = 0;
|
|
32
|
+
/**
|
|
33
|
+
* Parses the specified USX content.
|
|
34
|
+
*
|
|
35
|
+
* @param usx The USX content to parse.
|
|
36
|
+
* @returns The parse tree that was generated.
|
|
37
|
+
*/
|
|
38
|
+
parse(codex) {
|
|
39
|
+
const json = JSON.parse(codex);
|
|
40
|
+
const data = codexSchema.parse(json);
|
|
41
|
+
let root = {
|
|
42
|
+
type: "root",
|
|
43
|
+
content: []
|
|
44
|
+
};
|
|
45
|
+
let chapters = /* @__PURE__ */ new Map();
|
|
46
|
+
let lastChapter = null;
|
|
47
|
+
function addChapterContent(chapterNumber, content) {
|
|
48
|
+
let chapter = chapters.get(chapterNumber);
|
|
49
|
+
if (!chapter) {
|
|
50
|
+
chapter = {
|
|
51
|
+
type: "chapter",
|
|
52
|
+
number: chapterNumber,
|
|
53
|
+
content: [],
|
|
54
|
+
footnotes: []
|
|
55
|
+
};
|
|
56
|
+
lastChapter = chapter;
|
|
57
|
+
chapters.set(chapterNumber, chapter);
|
|
58
|
+
}
|
|
59
|
+
chapter.content.push(...content);
|
|
60
|
+
}
|
|
61
|
+
function addReference(ref, content) {
|
|
62
|
+
addChapterContent(ref.chapter, [
|
|
63
|
+
{
|
|
64
|
+
type: "verse",
|
|
65
|
+
number: ref.verse,
|
|
66
|
+
content
|
|
67
|
+
}
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
for (let cell of data.cells) {
|
|
71
|
+
if (cell.language === "scripture") {
|
|
72
|
+
const lines = cell.value.split("\n");
|
|
73
|
+
const references = lines.map(
|
|
74
|
+
(l) => parseVerseReference(l) ?? l
|
|
75
|
+
);
|
|
76
|
+
let currentRef = null;
|
|
77
|
+
let content = [];
|
|
78
|
+
for (let i = 0; i < references.length; i++) {
|
|
79
|
+
const ref = references[i];
|
|
80
|
+
const nextRef = references[i + 1];
|
|
81
|
+
if (typeof ref === "string") {
|
|
82
|
+
if (ref === "") {
|
|
83
|
+
if (typeof nextRef === "object") {
|
|
84
|
+
if (currentRef && currentRef.chapter === nextRef.chapter) {
|
|
85
|
+
addChapterContent(currentRef.chapter, [
|
|
86
|
+
{
|
|
87
|
+
type: "line_break"
|
|
88
|
+
}
|
|
89
|
+
]);
|
|
90
|
+
} else {
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
content.push({
|
|
94
|
+
lineBreak: true
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
} else if (ref) {
|
|
98
|
+
content.push(ref);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
if (!root.id) {
|
|
102
|
+
root.id = ref.book;
|
|
103
|
+
}
|
|
104
|
+
if (currentRef) {
|
|
105
|
+
currentRef = null;
|
|
106
|
+
content = [];
|
|
107
|
+
}
|
|
108
|
+
currentRef = ref;
|
|
109
|
+
if (ref.content) {
|
|
110
|
+
content.push(ref.content);
|
|
111
|
+
}
|
|
112
|
+
addReference(ref, content);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} else if (cell.language === "markdown") {
|
|
116
|
+
if (cell.metadata) {
|
|
117
|
+
if (cell.metadata.type === "chapter-heading") {
|
|
118
|
+
const metadata = metadataSchema.parse(cell.metadata);
|
|
119
|
+
const chapter = metadata.data.chapter;
|
|
120
|
+
addChapterContent(chapter, [
|
|
121
|
+
{
|
|
122
|
+
type: "heading",
|
|
123
|
+
content: [cell.value]
|
|
124
|
+
}
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
if (lastChapter) {
|
|
129
|
+
lastChapter.footnotes.push({
|
|
130
|
+
noteId: this._noteCounter++,
|
|
131
|
+
text: cell.value,
|
|
132
|
+
caller: null
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (let chapter of chapters.values()) {
|
|
139
|
+
root.content.push(chapter);
|
|
140
|
+
}
|
|
141
|
+
return root;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=codex-parser.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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 { 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 metadataSchema = z.discriminatedUnion('type', [\r\n chapterHeadingSchema,\r\n]);\r\n\r\nexport const codexSchema = z.object({\r\n cells: z.array(\r\n z.object({\r\n // kind: z.number().int(),\r\n language: 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 /**\r\n * Parses the specified USX content.\r\n *\r\n * @param usx The USX 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 addChapterContent(\r\n chapterNumber: number,\r\n content: ChapterContent[]\r\n ) {\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 chapter.content.push(...content);\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 for (let cell of data.cells) {\r\n if (cell.language === 'scripture') {\r\n const lines = cell.value.split('\\n');\r\n const references = lines.map(\r\n (l) => parseVerseReference(l) ?? l\r\n );\r\n let currentRef: VerseRef | null = null;\r\n let content: Verse['content'] = [];\r\n for (let i = 0; i < references.length; i++) {\r\n const ref = references[i];\r\n const nextRef = references[i + 1];\r\n\r\n if (typeof ref === 'string') {\r\n // continuation on existing verse\r\n // or line break between verses\r\n\r\n if (ref === '') {\r\n // line break\r\n\r\n if (typeof nextRef === 'object') {\r\n // between verses\r\n\r\n if (\r\n currentRef &&\r\n currentRef.chapter === nextRef.chapter\r\n ) {\r\n // in same chapter\r\n addChapterContent(currentRef.chapter, [\r\n {\r\n type: 'line_break',\r\n },\r\n ]);\r\n } else {\r\n // do nothing since line breaks between chapters are ignored\r\n }\r\n } else {\r\n // inside verse\r\n content.push({\r\n lineBreak: true,\r\n });\r\n }\r\n } else if (ref) {\r\n content.push(ref);\r\n }\r\n } else {\r\n if (!root.id) {\r\n root.id = ref.book;\r\n }\r\n\r\n // new verse\r\n if (currentRef) {\r\n // finish previous verse\r\n currentRef = null;\r\n content = [];\r\n }\r\n\r\n currentRef = ref;\r\n\r\n if (ref.content) {\r\n content.push(ref.content);\r\n }\r\n\r\n addReference(ref, content);\r\n }\r\n }\r\n } else if (cell.language === 'markdown') {\r\n if (cell.metadata) {\r\n if (cell.metadata.type === 'chapter-heading') {\r\n const metadata = metadataSchema.parse(cell.metadata);\r\n\r\n const chapter = metadata.data.chapter;\r\n addChapterContent(chapter, [\r\n {\r\n type: 'heading',\r\n content: [cell.value],\r\n },\r\n ]);\r\n }\r\n } else {\r\n if (lastChapter) {\r\n (lastChapter as Chapter).footnotes.push({\r\n noteId: this._noteCounter++,\r\n text: cell.value,\r\n caller: null,\r\n });\r\n }\r\n }\r\n }\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,2BAAqC;AAEvC,aAAM,uBAAuB,EAAE,OAAO;AAAA,EACzC,MAAM,EAAE,QAAQ,iBAAiB;AAAA,EACjC,MAAM,EAAE,OAAO;AAAA,IACX,SAAS,EAAE,OAAO,OAAO,EAAE,IAAI;AAAA,EACnC,CAAC;AACL,CAAC;AAEM,aAAM,iBAAiB,EAAE,mBAAmB,QAAQ;AAAA,EACvD;AACJ,CAAC;AAEM,aAAM,cAAc,EAAE,OAAO;AAAA,EAChC,OAAO,EAAE;AAAA,IACL,EAAE,OAAO;AAAA;AAAA,MAEL,UAAU,EAAE,OAAO;AAAA,MACnB,OAAO,EAAE,OAAO;AAAA,MAChB,UAAU,EACL,OAAO;AAAA,QACJ,MAAM,EAAE,OAAO;AAAA,MACnB,CAAC,EACA,YAAY,EACZ,SAAS,EACT,SAAS;AAAA,IAClB,CAAC;AAAA,EACL;AACJ,CAAC;AAKM,aAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOb,eAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxB,MAAM,OAA0B;AACnC,UAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,UAAM,OAAO,YAAY,MAAM,IAAI;AAEnC,QAAI,OAAkB;AAAA,MAClB,MAAM;AAAA,MACN,SAAS,CAAC;AAAA,IACd;AAEA,QAAI,WAAiC,oBAAI,IAAI;AAC7C,QAAI,cAA8B;AAElC,aAAS,kBACL,eACA,SACF;AACE,UAAI,UAAU,SAAS,IAAI,aAAa;AACxC,UAAI,CAAC,SAAS;AACV,kBAAU;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS,CAAC;AAAA,UACV,WAAW,CAAC;AAAA,QAChB;AACA,sBAAc;AACd,iBAAS,IAAI,eAAe,OAAO;AAAA,MACvC;AAEA,cAAQ,QAAQ,KAAK,GAAG,OAAO;AAAA,IACnC;AAEA,aAAS,aAAa,KAAe,SAA2B;AAC5D,wBAAkB,IAAI,SAAS;AAAA,QAC3B;AAAA,UACI,MAAM;AAAA,UACN,QAAQ,IAAI;AAAA,UACZ;AAAA,QACJ;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,aAAS,QAAQ,KAAK,OAAO;AACzB,UAAI,KAAK,aAAa,aAAa;AAC/B,cAAM,QAAQ,KAAK,MAAM,MAAM,IAAI;AACnC,cAAM,aAAa,MAAM;AAAA,UACrB,CAAC,MAAM,oBAAoB,CAAC,KAAK;AAAA,QACrC;AACA,YAAI,aAA8B;AAClC,YAAI,UAA4B,CAAC;AACjC,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AACxC,gBAAM,MAAM,WAAW,CAAC;AACxB,gBAAM,UAAU,WAAW,IAAI,CAAC;AAEhC,cAAI,OAAO,QAAQ,UAAU;AAIzB,gBAAI,QAAQ,IAAI;AAGZ,kBAAI,OAAO,YAAY,UAAU;AAG7B,oBACI,cACA,WAAW,YAAY,QAAQ,SACjC;AAEE,oCAAkB,WAAW,SAAS;AAAA,oBAClC;AAAA,sBACI,MAAM;AAAA,oBACV;AAAA,kBACJ,CAAC;AAAA,gBACL,OAAO;AAAA,gBAEP;AAAA,cACJ,OAAO;AAEH,wBAAQ,KAAK;AAAA,kBACT,WAAW;AAAA,gBACf,CAAC;AAAA,cACL;AAAA,YACJ,WAAW,KAAK;AACZ,sBAAQ,KAAK,GAAG;AAAA,YACpB;AAAA,UACJ,OAAO;AACH,gBAAI,CAAC,KAAK,IAAI;AACV,mBAAK,KAAK,IAAI;AAAA,YAClB;AAGA,gBAAI,YAAY;AAEZ,2BAAa;AACb,wBAAU,CAAC;AAAA,YACf;AAEA,yBAAa;AAEb,gBAAI,IAAI,SAAS;AACb,sBAAQ,KAAK,IAAI,OAAO;AAAA,YAC5B;AAEA,yBAAa,KAAK,OAAO;AAAA,UAC7B;AAAA,QACJ;AAAA,MACJ,WAAW,KAAK,aAAa,YAAY;AACrC,YAAI,KAAK,UAAU;AACf,cAAI,KAAK,SAAS,SAAS,mBAAmB;AAC1C,kBAAM,WAAW,eAAe,MAAM,KAAK,QAAQ;AAEnD,kBAAM,UAAU,SAAS,KAAK;AAC9B,8BAAkB,SAAS;AAAA,cACvB;AAAA,gBACI,MAAM;AAAA,gBACN,SAAS,CAAC,KAAK,KAAK;AAAA,cACxB;AAAA,YACJ,CAAC;AAAA,UACL;AAAA,QACJ,OAAO;AACH,cAAI,aAAa;AACb,YAAC,YAAwB,UAAU,KAAK;AAAA,cACpC,QAAQ,KAAK;AAAA,cACb,MAAM,KAAK;AAAA,cACX,QAAQ;AAAA,YACZ,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,aAAS,WAAW,SAAS,OAAO,GAAG;AACnC,WAAK,QAAQ,KAAK,OAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,EACX;AACJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../parser/index.ts"],
|
|
4
|
+
"sourcesContent": ["export * from './types.js';\r\nexport * from './usfm-parser.js';\r\nexport * from './usx-parser.js';\r\nexport * from './codex-parser.js';\r\nimport * as iterators from './iterators.js';\r\n\r\nexport { iterators };\r\n"],
|
|
5
|
+
"mappings": ";AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,YAAY,eAAe;AAE3B,SAAS;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export class Rewindable {
|
|
3
|
+
buffer = [];
|
|
4
|
+
_bufferSize = 0;
|
|
5
|
+
_position = -1;
|
|
6
|
+
_iterator;
|
|
7
|
+
constructor(iterator, bufferSize = 2) {
|
|
8
|
+
this._iterator = iterator;
|
|
9
|
+
this._bufferSize = bufferSize;
|
|
10
|
+
if (this._iterator.return) {
|
|
11
|
+
this.return = (value) => {
|
|
12
|
+
return this._iterator.return(value);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (this._iterator.throw) {
|
|
16
|
+
this.throw = (value) => {
|
|
17
|
+
return this._iterator.throw(value);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
rewind(number) {
|
|
22
|
+
this._position += number;
|
|
23
|
+
}
|
|
24
|
+
[Symbol.iterator]() {
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
next(...args) {
|
|
28
|
+
if (this._position >= 0) {
|
|
29
|
+
let item = this.buffer[this._position];
|
|
30
|
+
this._position--;
|
|
31
|
+
return {
|
|
32
|
+
value: item,
|
|
33
|
+
done: false
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let result = this._iterator.next(...args);
|
|
37
|
+
this.buffer.unshift(result.value);
|
|
38
|
+
if (this.buffer.length > this._bufferSize) {
|
|
39
|
+
this.buffer.splice(this._bufferSize, this.buffer.length - this._bufferSize);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function* debug(label, iterator) {
|
|
45
|
+
for (let value of uncompletable(iterator)) {
|
|
46
|
+
if (value instanceof Element) {
|
|
47
|
+
console.log(label, value.outerHTML);
|
|
48
|
+
} else if (value instanceof Node) {
|
|
49
|
+
console.log(label, value.textContent);
|
|
50
|
+
} else {
|
|
51
|
+
console.log(label, value);
|
|
52
|
+
}
|
|
53
|
+
yield value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function rewindable(iterator, bufferSize = 2) {
|
|
57
|
+
return new Rewindable(iterator, bufferSize);
|
|
58
|
+
}
|
|
59
|
+
function* iterateNodes(node) {
|
|
60
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
61
|
+
yield node.childNodes[i];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function parentChar(node) {
|
|
65
|
+
return matchingParent(node, (n) => n instanceof Element && n.nodeName === "char");
|
|
66
|
+
}
|
|
67
|
+
export function parentNote(node) {
|
|
68
|
+
return matchingParent(node, (n) => n instanceof Element && n.nodeName === "note");
|
|
69
|
+
}
|
|
70
|
+
export function matchingParent(node, filter) {
|
|
71
|
+
let parent = node.parentNode;
|
|
72
|
+
while (parent) {
|
|
73
|
+
if (filter(parent)) {
|
|
74
|
+
return parent;
|
|
75
|
+
}
|
|
76
|
+
parent = parent.parentNode;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
export function isParent(node, parent) {
|
|
81
|
+
let parentNode = node.parentNode;
|
|
82
|
+
while (parentNode) {
|
|
83
|
+
if (parentNode === parent) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
parentNode = parentNode.parentNode;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
export function iterateAll(node) {
|
|
91
|
+
return rewindable(_iterateAll(node));
|
|
92
|
+
}
|
|
93
|
+
export function* iterateUntil(iterator, predicate) {
|
|
94
|
+
for (let value of iterator) {
|
|
95
|
+
if (predicate(value)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
yield value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function* _iterateAll(node) {
|
|
102
|
+
for (let child of node.childNodes) {
|
|
103
|
+
yield child;
|
|
104
|
+
yield* iterateAll(child);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function* elements(iterator) {
|
|
108
|
+
for (let node of uncompletable(iterator)) {
|
|
109
|
+
if (node instanceof Element) {
|
|
110
|
+
yield node;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function* children(iterator, parent) {
|
|
115
|
+
for (let node of uncompletable(iterator)) {
|
|
116
|
+
if (!isParent(node, parent)) {
|
|
117
|
+
iterator.rewind(1);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
yield node;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export function* uncompletable(iterable) {
|
|
124
|
+
while (true) {
|
|
125
|
+
const { done, value } = iterable.next();
|
|
126
|
+
if (done) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
yield value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export async function* toAsyncIterable(input) {
|
|
133
|
+
for (let item of input) {
|
|
134
|
+
yield item;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export function* batch(input, batchSize) {
|
|
138
|
+
while (true) {
|
|
139
|
+
let batch2 = [];
|
|
140
|
+
for (let item of input) {
|
|
141
|
+
batch2.push(item);
|
|
142
|
+
if (batch2.length >= batchSize) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (batch2.length === 0) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
yield batch2;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=iterators.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../parser/iterators.ts"],
|
|
4
|
+
"sourcesContent": ["\r\n/**\r\n * Defines an interface that represents an iterator that can be rewound.\r\n */\r\nexport interface RewindableIterator<T> extends IterableIterator<T> {\r\n /**\r\n * Rewinds the iterator by the specified number of elements.\r\n * @param number The number of elements to rewind.\r\n */\r\n rewind(number: number): void;\r\n}\r\n\r\n/**\r\n * Defines a class that implements an iterator that can be rewound.\r\n */\r\nexport class Rewindable<T> implements RewindableIterator<T> {\r\n buffer: T[] = [];\r\n\r\n private _bufferSize: number = 0;\r\n private _position: number = -1;\r\n private _iterator: IterableIterator<T>;\r\n\r\n constructor(iterator: IterableIterator<T>, bufferSize: number = 2) {\r\n this._iterator = iterator;\r\n this._bufferSize = bufferSize;\r\n\r\n if(this._iterator.return) {\r\n this.return = (value?: any) => {\r\n return this._iterator.return!(value);\r\n };\r\n }\r\n if(this._iterator.throw) {\r\n this.throw = (value?: any) => {\r\n return this._iterator.throw!(value);\r\n };\r\n }\r\n }\r\n\r\n rewind(number: number): void {\r\n this._position += number;\r\n }\r\n\r\n [Symbol.iterator](): IterableIterator<T> {\r\n return this;\r\n }\r\n\r\n next(...args: [] | [undefined]): IteratorResult<T, any> {\r\n if (this._position >= 0) {\r\n let item = this.buffer[this._position];\r\n this._position--;\r\n return {\r\n value: item,\r\n done: false\r\n };\r\n }\r\n\r\n let result = this._iterator.next(...args);\r\n this.buffer.unshift(result.value);\r\n if (this.buffer.length > this._bufferSize) {\r\n this.buffer.splice(this._bufferSize, this.buffer.length - this._bufferSize);\r\n }\r\n return result;\r\n }\r\n\r\n return?(value?: any): IteratorResult<T, any>;\r\n throw?(e?: any): IteratorResult<T, any>;\r\n}\r\n\r\nexport function *debug(label: string, iterator: IterableIterator<any>) {\r\n for (let value of uncompletable(iterator)) {\r\n if (value instanceof Element) {\r\n console.log(label, value.outerHTML);\r\n } else if(value instanceof Node) {\r\n console.log(label, value.textContent);\r\n } else {\r\n console.log(label, value);\r\n }\r\n yield value;\r\n }\r\n}\r\n\r\n/**\r\n * Creates a new rewindable iterator from the given iterator.\r\n * @param iterator The iterator.\r\n * @param bufferSize The size of the buffer.\r\n */\r\nexport function rewindable<T>(iterator: IterableIterator<T>, bufferSize: number = 2): Rewindable<T> {\r\n return new Rewindable(iterator, bufferSize);\r\n}\r\n\r\n\r\nfunction *iterateNodes(node: Node) {\r\n for(let i = 0; i < node.childNodes.length; i++) {\r\n yield node.childNodes[i];\r\n }\r\n}\r\n\r\n/**\r\n * Gets the char element that is the parent of the given node.\r\n * @param node The node.\r\n */\r\nexport function parentChar(node: Node): Element | null {\r\n return matchingParent(node, n => n instanceof Element && n.nodeName === 'char') as Element | null;\r\n}\r\n\r\n/**\r\n * Gets the note element that is the parent of the given node.\r\n * @param node The node.\r\n */\r\nexport function parentNote(node: Node): Element | null {\r\n return matchingParent(node, n => n instanceof Element && n.nodeName === 'note') as Element | null;\r\n}\r\n\r\n/**\r\n * Gets the parent node that matches the given filter.\r\n * @param node The node to start the search from.\r\n * @param filter The filter that should be used.\r\n */\r\nexport function matchingParent(node: Node, filter: (node: Node) => boolean): Node | null {\r\n let parent = node.parentNode;\r\n while(parent) {\r\n if (filter(parent)) {\r\n return parent;\r\n }\r\n parent = parent.parentNode;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Determines if the given node is a child of the parent node.\r\n * @param node The node to test.\r\n * @param parent The parent.\r\n * @returns \r\n */\r\nexport function isParent(node: Node, parent: Node): boolean {\r\n let parentNode = node.parentNode;\r\n while(parentNode) {\r\n if (parentNode === parent) {\r\n return true;\r\n }\r\n parentNode = parentNode.parentNode;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Iterates through all of the nodes in the tree in a depth-first traversal.\r\n * @param node The node to start the traversal from. \r\n */\r\nexport function iterateAll(node: Node): RewindableIterator<Node> {\r\n return rewindable(_iterateAll(node));\r\n}\r\n\r\nexport function *iterateUntil<T>(iterator: IterableIterator<T>, predicate: (value: T) => boolean): IterableIterator<T> {\r\n for(let value of iterator) {\r\n if (predicate(value)) {\r\n return;\r\n }\r\n yield value;\r\n }\r\n}\r\n\r\nfunction *_iterateAll(node: Node): IterableIterator<Node> {\r\n for(let child of node.childNodes) {\r\n yield child;\r\n yield *iterateAll(child);\r\n }\r\n}\r\n\r\n/**\r\n * Iterates only the elements in the iterator.\r\n * @param iterator The iterator that should be used.\r\n */\r\nexport function *elements(iterator: IterableIterator<Node>): IterableIterator<Element> {\r\n for (let node of uncompletable(iterator)) {\r\n if (node instanceof Element) {\r\n yield node;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Iterates only the children of the given node in the iterator.\r\n * @param iterator The iterator that should be used.\r\n * @param parent The parent node.\r\n */\r\nexport function *children(iterator: RewindableIterator<Node>, parent: Node): IterableIterator<Node> {\r\n for (let node of uncompletable(iterator)) {\r\n if (!isParent(node, parent)) {\r\n iterator.rewind(1);\r\n return;\r\n }\r\n\r\n yield node;\r\n }\r\n}\r\n\r\n/**\r\n * Wraps the given iterable in a generator that will prevent consumers from calling return() on the iterator.\r\n * @param iterable The iterable.\r\n */\r\nexport function *uncompletable<T>(iterable: IterableIterator<T>): IterableIterator<T> {\r\n while(true) {\r\n const { done, value } = iterable.next();\r\n if (done) {\r\n return;\r\n }\r\n yield value;\r\n }\r\n}\r\n\r\n/**\r\n * Converts the given iterable into an async iterable.\r\n * @param input The input iterable.\r\n */\r\nexport async function *toAsyncIterable<T>(input: Iterable<T>): AsyncIterable<T> {\r\n for (let item of input) {\r\n yield item;\r\n }\r\n}\r\n\r\n/**\r\n * Batches items from the given iterator.\r\n * @param input The input iterator.\r\n * @param batchSize The size of each batch.\r\n */\r\nexport function* batch<T>(input: Iterable<T>, batchSize: number): Iterable<T[]> {\r\n while(true) {\r\n let batch = [] as T[];\r\n for (let item of input) {\r\n batch.push(item);\r\n if (batch.length >= batchSize) {\r\n break;\r\n }\r\n }\r\n\r\n if (batch.length === 0) {\r\n return;\r\n }\r\n\r\n yield batch;\r\n }\r\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["batch"]
|
|
7
|
+
}
|