proskomma-core 0.9.10 → 0.9.13
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/.eslintrc.json +79 -0
- package/.gitattributes +2 -0
- package/docs/_config.yml +1 -0
- package/docs/index.md +3 -0
- package/docs/pk_edit_0_9.odt +0 -0
- package/docs/pk_edit_0_9.pdf +0 -0
- package/docs/proskomma_101_slideshow.odp +0 -0
- package/docs/proskomma_101_slideshow.pdf +0 -0
- package/docs/proskomma_edit_html.png +0 -0
- package/docs/proskomma_edit_html.svg +451 -0
- package/docs/proskomma_edit_reference.png +0 -0
- package/docs/proskomma_edit_reference.svg +349 -0
- package/docs/repo_logo.png +0 -0
- package/esm/package.json +3 -0
- package/esm/wrapper.mjs +5 -0
- package/index.cjs +6 -0
- package/package.json +18 -15
- package/src/graph/index.cjs +201 -0
- package/src/graph/lib/do_cv.cjs +249 -0
- package/src/graph/lib/dump.cjs +40 -0
- package/src/graph/lib/remake_blocks.cjs +57 -0
- package/src/graph/lib/sequence_chars.cjs +84 -0
- package/src/graph/lib/sort.cjs +39 -0
- package/src/graph/lib/tribos.cjs +97 -0
- package/src/graph/lib/tribos_expression.cjs +556 -0
- package/src/graph/lib/tribos_ohm_UNUSED.cjs +37 -0
- package/src/graph/lib/tribos_step.cjs +434 -0
- package/src/graph/mutations/add.cjs +91 -0
- package/src/graph/mutations/delete.cjs +61 -0
- package/src/graph/mutations/index.cjs +54 -0
- package/src/graph/mutations/rehash.cjs +17 -0
- package/src/graph/mutations/tags.cjs +120 -0
- package/src/graph/mutations/update.cjs +210 -0
- package/src/graph/mutations/versification.cjs +96 -0
- package/src/graph/queries/block.cjs +228 -0
- package/src/graph/queries/cIndex.cjs +87 -0
- package/src/graph/queries/cell.cjs +42 -0
- package/src/graph/queries/cv.cjs +19 -0
- package/src/graph/queries/cvBook.cjs +16 -0
- package/src/graph/queries/cvChapter.cjs +16 -0
- package/src/graph/queries/cvIndex.cjs +47 -0
- package/src/graph/queries/cvNavigation.cjs +116 -0
- package/src/graph/queries/cvVerseElement.cjs +84 -0
- package/src/graph/queries/cvVerses.cjs +14 -0
- package/src/graph/queries/doc_set.cjs +220 -0
- package/src/graph/queries/document.cjs +555 -0
- package/src/graph/queries/idParts.cjs +30 -0
- package/src/graph/queries/index.cjs +151 -0
- package/src/graph/queries/inputBlockSpec.cjs +17 -0
- package/src/graph/queries/inputItemObject.cjs +12 -0
- package/src/graph/queries/input_att_spec.cjs +14 -0
- package/src/graph/queries/input_key_matches.cjs +11 -0
- package/src/graph/queries/input_key_value.cjs +11 -0
- package/src/graph/queries/input_key_values.cjs +11 -0
- package/src/graph/queries/input_selector_spec.cjs +19 -0
- package/src/graph/queries/item.cjs +71 -0
- package/src/graph/queries/itemGroup.cjs +75 -0
- package/src/graph/queries/key_value.cjs +18 -0
- package/src/graph/queries/kv_entry.cjs +21 -0
- package/src/graph/queries/kv_sequence.cjs +151 -0
- package/src/graph/queries/node.cjs +44 -0
- package/src/graph/queries/orig.cjs +11 -0
- package/src/graph/queries/regex_index.cjs +18 -0
- package/src/graph/queries/row_equals_spec.cjs +11 -0
- package/src/graph/queries/row_match_spec.cjs +11 -0
- package/src/graph/queries/selector_spec.cjs +29 -0
- package/src/graph/queries/sequence.cjs +314 -0
- package/src/graph/queries/table_sequence.cjs +192 -0
- package/src/graph/queries/tree_sequence.cjs +58 -0
- package/src/graph/queries/verseNumber.cjs +44 -0
- package/src/graph/queries/verseRange.cjs +11 -0
- package/src/graph/queries/versification.cjs +25 -0
- package/src/index.cjs +583 -0
- package/src/model/doc_set.cjs +389 -0
- package/src/model/doc_set_helpers/block.cjs +232 -0
- package/src/model/doc_set_helpers/enum.cjs +87 -0
- package/src/model/doc_set_helpers/item.cjs +198 -0
- package/src/model/doc_set_helpers/rehash.cjs +53 -0
- package/src/model/doc_set_helpers/selectors.cjs +58 -0
- package/src/model/doc_set_helpers/serialize.cjs +22 -0
- package/src/model/doc_set_helpers/unsuccinctify.cjs +288 -0
- package/src/model/doc_set_helpers/update.cjs +290 -0
- package/src/model/document.cjs +369 -0
- package/src/model/document_helpers/blocks.cjs +135 -0
- package/src/model/document_helpers/chapter_verse.cjs +291 -0
- package/src/model/document_helpers/pre_enums.cjs +67 -0
- package/src/model/document_helpers/sequences.cjs +205 -0
- package/src/model/document_helpers/serialize_succinct.cjs +55 -0
- package/src/model/document_helpers/succinct_filter.cjs +102 -0
- package/src/model/versifications/eng_vrs.cjs +455 -0
- package/src/model/versifications/index.cjs +38 -0
- package/src/model/versifications/lxx_vrs.cjs +950 -0
- package/src/model/versifications/org_vrs.cjs +155 -0
- package/src/model/versifications/rsc_vrs.cjs +342 -0
- package/src/model/versifications/rso_vrs.cjs +541 -0
- package/src/model/versifications/vul_vrs.cjs +835 -0
- package/src/parser/index.cjs +506 -0
- package/src/parser/lexers/index.cjs +11 -0
- package/src/parser/lexers/lexingRegexes.cjs +45 -0
- package/src/parser/lexers/nodes.cjs +123 -0
- package/src/parser/lexers/object_for_fragment.cjs +123 -0
- package/src/parser/lexers/tsv.cjs +45 -0
- package/src/parser/lexers/usfm.cjs +17 -0
- package/src/parser/lexers/usx/index.cjs +7 -0
- package/src/parser/lexers/usx/usx_lexer.cjs +321 -0
- package/src/parser/lib/tokenize.cjs +37 -0
- package/src/parser/model/index.cjs +637 -0
- package/src/parser/parser_specs.cjs +781 -0
- package/src/pipelines/perf2x/index.cjs +7 -0
- package/src/pipelines/perf2x/perf2PkJsonPipeline.json +41 -0
- package/src/pipelines/perf2x/perf2usfmPipeline.json +65 -0
- package/src/transforms/calculateUsfmChapterPositions.cjs +106 -0
- package/src/transforms/index.cjs +9 -0
- package/src/transforms/perf2PkJson.cjs +534 -0
- package/src/transforms/perf2usfm.cjs +294 -0
- package/src/util/byteArray.cjs +251 -0
- package/src/util/canons.cjs +117 -0
- package/src/util/enums.cjs +41 -0
- package/src/util/generateId.cjs +6 -0
- package/src/util/graftDefs.cjs +15 -0
- package/src/util/index.cjs +29 -0
- package/src/util/inspectSuccinct.cjs +59 -0
- package/src/util/itemDefs.cjs +33 -0
- package/src/util/parserConstantDefs.cjs +30 -0
- package/src/util/scopeDefs.cjs +173 -0
- package/src/util/scriptlike/blocksSpec.cjs +192 -0
- package/src/util/scriptlike/dodson_lexicon.xsl +19 -0
- package/src/util/scriptlike/dodson_lexicon_to_entries.cjs +85 -0
- package/src/util/scriptlike/open_scriptures_hebrew_lexicon.xsl +28 -0
- package/src/util/scriptlike/open_scriptures_hebrew_lexicon_to_entries.cjs +85 -0
- package/src/util/succinct.cjs +159 -0
- package/src/util/tags.cjs +28 -0
- package/src/util/tokenDefs.cjs +27 -0
- package/src/util/versification.cjs +364 -0
- package/dist/index.js +0 -8
- package/dist/index.js.LICENSE.txt +0 -23
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
const utils = require('../../util/index.cjs');
|
|
2
|
+
const ByteArray = utils.ByteArray;
|
|
3
|
+
const {
|
|
4
|
+
pushSuccinctGraftBytes,
|
|
5
|
+
pushSuccinctScopeBytes,
|
|
6
|
+
pushSuccinctTokenBytes,
|
|
7
|
+
} = utils.succinct;
|
|
8
|
+
const { itemEnum } = utils.itemDefs;
|
|
9
|
+
const { scopeEnum } = utils.scopeDefs;
|
|
10
|
+
const { tokenCategory, tokenEnum } = utils.tokenDefs;
|
|
11
|
+
|
|
12
|
+
const updateItems1 = (
|
|
13
|
+
docSet,
|
|
14
|
+
documentId,
|
|
15
|
+
sequenceId,
|
|
16
|
+
blockPosition,
|
|
17
|
+
typedArrayName,
|
|
18
|
+
itemObjects) => {
|
|
19
|
+
const document = docSet.processor.documents[documentId];
|
|
20
|
+
|
|
21
|
+
if (!document) {
|
|
22
|
+
throw new Error(`Document '${documentId}' not found`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let sequence;
|
|
26
|
+
|
|
27
|
+
if (sequenceId) {
|
|
28
|
+
sequence = document.sequences[sequenceId];
|
|
29
|
+
|
|
30
|
+
if (!sequence) {
|
|
31
|
+
throw new Error(`Sequence '${sequenceId}' not found`);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
sequence = document.sequences[document.mainId];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (sequence.blocks.length <= blockPosition) {
|
|
38
|
+
throw new Error(`Could not find block ${blockPosition} (length=${sequence.blocks.length})`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const block = sequence.blocks[blockPosition];
|
|
42
|
+
const newItemsBA = new ByteArray(itemObjects.length);
|
|
43
|
+
docSet.maybeBuildPreEnums();
|
|
44
|
+
|
|
45
|
+
let nextToken = 0;
|
|
46
|
+
|
|
47
|
+
if (blockPosition < 0) {
|
|
48
|
+
nextToken = sequence.blocks[blockPosition - 1].nt.nByte(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let charsEnumIndex, graftTypeEnumIndex, seqEnumIndex, scopeBits, scopeTypeByte, scopeBitBytes = null;
|
|
52
|
+
|
|
53
|
+
for (const item of itemObjects) {
|
|
54
|
+
switch (item.type) {
|
|
55
|
+
case 'token':
|
|
56
|
+
charsEnumIndex = docSet.enumForCategoryValue(tokenCategory[item.subType], item.payload, true);
|
|
57
|
+
pushSuccinctTokenBytes(newItemsBA, tokenEnum[item.subType], charsEnumIndex);
|
|
58
|
+
nextToken++;
|
|
59
|
+
break;
|
|
60
|
+
case 'graft':
|
|
61
|
+
graftTypeEnumIndex = docSet.enumForCategoryValue('graftTypes', item.subType, true);
|
|
62
|
+
seqEnumIndex = docSet.enumForCategoryValue('ids', item.payload, true);
|
|
63
|
+
pushSuccinctGraftBytes(newItemsBA, graftTypeEnumIndex, seqEnumIndex);
|
|
64
|
+
break;
|
|
65
|
+
case 'scope':
|
|
66
|
+
scopeBits = item.payload.split('/');
|
|
67
|
+
scopeTypeByte = scopeEnum[scopeBits[0]];
|
|
68
|
+
|
|
69
|
+
if (!scopeTypeByte && scopeTypeByte !== 0) {
|
|
70
|
+
throw new Error(`"${scopeBits[0]}" is not a scope type`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
scopeBitBytes = scopeBits.slice(1).map(b => docSet.enumForCategoryValue('scopeBits', b, true));
|
|
74
|
+
pushSuccinctScopeBytes(newItemsBA, itemEnum[`${item.subType}Scope`], scopeTypeByte, scopeBitBytes);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
newItemsBA.trim();
|
|
79
|
+
block[typedArrayName] = newItemsBA;
|
|
80
|
+
|
|
81
|
+
if (typedArrayName === 'c') {
|
|
82
|
+
block.nt.clear();
|
|
83
|
+
block.nt.pushNByte(nextToken);
|
|
84
|
+
// document.buildChapterVerseIndex();
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const updateItems = (
|
|
90
|
+
docSet,
|
|
91
|
+
documentId,
|
|
92
|
+
sequenceId,
|
|
93
|
+
blockPosition,
|
|
94
|
+
itemObjects) =>
|
|
95
|
+
updateItems1(
|
|
96
|
+
docSet,
|
|
97
|
+
documentId,
|
|
98
|
+
sequenceId,
|
|
99
|
+
blockPosition,
|
|
100
|
+
'c',
|
|
101
|
+
itemObjects,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const updateBlockGrafts = (
|
|
105
|
+
docSet,
|
|
106
|
+
documentId,
|
|
107
|
+
sequenceId,
|
|
108
|
+
blockPosition,
|
|
109
|
+
itemObjects) =>
|
|
110
|
+
updateItems1(
|
|
111
|
+
docSet,
|
|
112
|
+
documentId,
|
|
113
|
+
sequenceId,
|
|
114
|
+
blockPosition,
|
|
115
|
+
'bg',
|
|
116
|
+
itemObjects,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const updateBlockScope = (
|
|
120
|
+
docSet,
|
|
121
|
+
documentId,
|
|
122
|
+
sequenceId,
|
|
123
|
+
blockPosition,
|
|
124
|
+
bsObject) =>
|
|
125
|
+
updateItems1(
|
|
126
|
+
docSet,
|
|
127
|
+
documentId,
|
|
128
|
+
sequenceId,
|
|
129
|
+
blockPosition,
|
|
130
|
+
'bs',
|
|
131
|
+
[bsObject],
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const updateOpenScopes = (
|
|
135
|
+
docSet,
|
|
136
|
+
documentId,
|
|
137
|
+
sequenceId,
|
|
138
|
+
blockPosition,
|
|
139
|
+
osObjects) =>
|
|
140
|
+
updateItems1(
|
|
141
|
+
docSet,
|
|
142
|
+
documentId,
|
|
143
|
+
sequenceId,
|
|
144
|
+
blockPosition,
|
|
145
|
+
'os',
|
|
146
|
+
osObjects,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const updateIncludedScopes = (
|
|
150
|
+
docSet,
|
|
151
|
+
documentId,
|
|
152
|
+
sequenceId,
|
|
153
|
+
blockPosition,
|
|
154
|
+
isObjects) =>
|
|
155
|
+
updateItems1(
|
|
156
|
+
docSet,
|
|
157
|
+
documentId,
|
|
158
|
+
sequenceId,
|
|
159
|
+
blockPosition,
|
|
160
|
+
'is',
|
|
161
|
+
isObjects,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const updateBlockIndexesAfterEdit = (docSet, sequence, blockPosition) => {
|
|
165
|
+
const labelsMatch = (firstA, secondA) => {
|
|
166
|
+
for (const first of Array.from(firstA)) {
|
|
167
|
+
if (!secondA.has(first)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const second of Array.from(secondA)) {
|
|
173
|
+
if (!firstA.has(second)) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const addSuccinctScope = (docSet, succinct, scopeLabel) => {
|
|
181
|
+
const scopeBits = scopeLabel.split('/');
|
|
182
|
+
const scopeTypeByte = scopeEnum[scopeBits[0]];
|
|
183
|
+
|
|
184
|
+
if (!scopeTypeByte && scopeTypeByte !== 0) {
|
|
185
|
+
throw new Error(`"${scopeBits[0]}" is not a scope type`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const scopeBitBytes = scopeBits.slice(1).map(b => docSet.enumForCategoryValue('scopeBits', b, true));
|
|
189
|
+
pushSuccinctScopeBytes(succinct, itemEnum[`startScope`], scopeTypeByte, scopeBitBytes);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const block = sequence.blocks[blockPosition];
|
|
193
|
+
const includedScopeLabels = new Set();
|
|
194
|
+
const openScopeLabels = new Set();
|
|
195
|
+
|
|
196
|
+
for (const openScope of docSet.unsuccinctifyScopes(block.os)) {
|
|
197
|
+
openScopeLabels.add(openScope[2]);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for (const scope of docSet.unsuccinctifyItems(block.c, { scopes: true }, null)) {
|
|
201
|
+
if (scope[1] === 'start') {
|
|
202
|
+
includedScopeLabels.add(scope[2]);
|
|
203
|
+
openScopeLabels.add(scope[2]);
|
|
204
|
+
} else {
|
|
205
|
+
openScopeLabels.delete(scope[2]);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const isArray = Array.from(includedScopeLabels);
|
|
210
|
+
const isBA = new ByteArray(isArray.length);
|
|
211
|
+
|
|
212
|
+
for (const scopeLabel of isArray) {
|
|
213
|
+
addSuccinctScope(docSet, isBA, scopeLabel);
|
|
214
|
+
}
|
|
215
|
+
isBA.trim();
|
|
216
|
+
block.is = isBA;
|
|
217
|
+
|
|
218
|
+
if (blockPosition < (sequence.blocks.length - 1)) {
|
|
219
|
+
const nextOsBlock = sequence.blocks[blockPosition + 1];
|
|
220
|
+
const nextOsBA = nextOsBlock.os;
|
|
221
|
+
const nextOSLabels = new Set(docSet.unsuccinctifyScopes(nextOsBA).map(s => s[2]));
|
|
222
|
+
|
|
223
|
+
if (!labelsMatch(openScopeLabels, nextOSLabels)) {
|
|
224
|
+
const osBA = new ByteArray(nextOSLabels.length);
|
|
225
|
+
|
|
226
|
+
for (const scopeLabel of Array.from(openScopeLabels)) {
|
|
227
|
+
addSuccinctScope(docSet, osBA, scopeLabel);
|
|
228
|
+
}
|
|
229
|
+
osBA.trim();
|
|
230
|
+
nextOsBlock.os = osBA;
|
|
231
|
+
docSet.updateBlockIndexesAfterEdit(sequence, blockPosition + 1);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const updateBlockIndexesAfterFilter = (docSet, sequence) => {
|
|
237
|
+
const addSuccinctScope = (docSet, succinct, scopeLabel) => {
|
|
238
|
+
const scopeBits = scopeLabel.split('/');
|
|
239
|
+
const scopeTypeByte = scopeEnum[scopeBits[0]];
|
|
240
|
+
|
|
241
|
+
if (!scopeTypeByte && scopeTypeByte !== 0) {
|
|
242
|
+
throw new Error(`"${scopeBits[0]}" is not a scope type`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const scopeBitBytes = scopeBits.slice(1).map(b => docSet.enumForCategoryValue('scopeBits', b, true));
|
|
246
|
+
pushSuccinctScopeBytes(succinct, itemEnum[`startScope`], scopeTypeByte, scopeBitBytes);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const openScopeLabels = new Set();
|
|
250
|
+
|
|
251
|
+
for (const block of sequence.blocks) {
|
|
252
|
+
const osArray = Array.from(openScopeLabels);
|
|
253
|
+
const osBA = new ByteArray(osArray.length);
|
|
254
|
+
|
|
255
|
+
for (const scopeLabel of osArray) {
|
|
256
|
+
addSuccinctScope(docSet, osBA, scopeLabel);
|
|
257
|
+
}
|
|
258
|
+
osBA.trim();
|
|
259
|
+
block.os = osBA;
|
|
260
|
+
const includedScopeLabels = new Set();
|
|
261
|
+
|
|
262
|
+
for (const scope of docSet.unsuccinctifyItems(block.c, { scopes: true }, null)) {
|
|
263
|
+
if (scope[1] === 'start') {
|
|
264
|
+
includedScopeLabels.add(scope[2]);
|
|
265
|
+
openScopeLabels.add(scope[2]);
|
|
266
|
+
} else {
|
|
267
|
+
openScopeLabels.delete(scope[2]);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const isArray = Array.from(includedScopeLabels);
|
|
272
|
+
const isBA = new ByteArray(isArray.length);
|
|
273
|
+
|
|
274
|
+
for (const scopeLabel of isArray) {
|
|
275
|
+
addSuccinctScope(docSet, isBA, scopeLabel);
|
|
276
|
+
}
|
|
277
|
+
isBA.trim();
|
|
278
|
+
block.is = isBA;
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
module.exports = {
|
|
283
|
+
updateItems,
|
|
284
|
+
updateBlockGrafts,
|
|
285
|
+
updateBlockScope,
|
|
286
|
+
updateOpenScopes,
|
|
287
|
+
updateIncludedScopes,
|
|
288
|
+
updateBlockIndexesAfterEdit,
|
|
289
|
+
updateBlockIndexesAfterFilter,
|
|
290
|
+
};
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
const {
|
|
2
|
+
PerfRenderFromProskomma,
|
|
3
|
+
SofriaRenderFromProskomma,
|
|
4
|
+
render,
|
|
5
|
+
PipelineHandler,
|
|
6
|
+
} = require('proskomma-json-tools');
|
|
7
|
+
const utils = require('../util/index.cjs');
|
|
8
|
+
const {
|
|
9
|
+
parseUsfm,
|
|
10
|
+
parseUsx,
|
|
11
|
+
parseTableToDocument,
|
|
12
|
+
parseNodes,
|
|
13
|
+
} = require('../parser/lexers/index.cjs');
|
|
14
|
+
const { Parser } = require('../parser/index.cjs');
|
|
15
|
+
const pipelines = require('../pipelines/perf2x/index.cjs');
|
|
16
|
+
const customTransforms = require('../transforms/index.cjs');
|
|
17
|
+
const {
|
|
18
|
+
buildChapterVerseIndex,
|
|
19
|
+
chapterVerseIndex,
|
|
20
|
+
chapterIndex,
|
|
21
|
+
} = require('./document_helpers/chapter_verse.cjs');
|
|
22
|
+
const {
|
|
23
|
+
modifySequence,
|
|
24
|
+
deleteSequence,
|
|
25
|
+
gcSequences,
|
|
26
|
+
newSequence,
|
|
27
|
+
} = require('./document_helpers/sequences.cjs');
|
|
28
|
+
const {
|
|
29
|
+
deleteBlock,
|
|
30
|
+
newBlock,
|
|
31
|
+
rewriteBlock,
|
|
32
|
+
} = require('./document_helpers/blocks.cjs');
|
|
33
|
+
const { succinctFilter } = require('./document_helpers/succinct_filter.cjs');
|
|
34
|
+
const { serializeSuccinct } = require('./document_helpers/serialize_succinct.cjs');
|
|
35
|
+
const {
|
|
36
|
+
recordPreEnums,
|
|
37
|
+
rerecordPreEnums,
|
|
38
|
+
} = require('./document_helpers/pre_enums.cjs');
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
addTag,
|
|
42
|
+
removeTag,
|
|
43
|
+
validateTags,
|
|
44
|
+
} = utils.tags;
|
|
45
|
+
const parserConstantDef = utils.parserConstants;
|
|
46
|
+
// const maybePrint = str => console.log(str);
|
|
47
|
+
const maybePrint = str => str;
|
|
48
|
+
|
|
49
|
+
class Document {
|
|
50
|
+
constructor(processor, docSetId, contentType, contentString, filterOptions, customTags, emptyBlocks, tags) {
|
|
51
|
+
this.processor = processor;
|
|
52
|
+
this.docSetId = docSetId;
|
|
53
|
+
this.baseSequenceTypes = parserConstantDef.usfm.baseSequenceTypes;
|
|
54
|
+
|
|
55
|
+
if (contentType) {
|
|
56
|
+
this.id = utils.generateId();
|
|
57
|
+
this.filterOptions = filterOptions;
|
|
58
|
+
this.customTags = customTags;
|
|
59
|
+
this.emptyBlocks = emptyBlocks;
|
|
60
|
+
this.tags = new Set(tags || []);
|
|
61
|
+
validateTags(this.tags);
|
|
62
|
+
this.headers = {};
|
|
63
|
+
this.mainId = null;
|
|
64
|
+
this.sequences = {};
|
|
65
|
+
|
|
66
|
+
switch (contentType.toLowerCase()) {
|
|
67
|
+
case 'usfm':
|
|
68
|
+
case 'sfm':
|
|
69
|
+
this.processUsfm(contentString);
|
|
70
|
+
break;
|
|
71
|
+
case 'usx':
|
|
72
|
+
this.processUsx(contentString);
|
|
73
|
+
break;
|
|
74
|
+
case 'tsv':
|
|
75
|
+
this.processTSV(contentString);
|
|
76
|
+
break;
|
|
77
|
+
case 'nodes':
|
|
78
|
+
this.processNodes(contentString);
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`Unknown document contentType '${contentType}'`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
addTag(tag) {
|
|
87
|
+
addTag(this.tags, tag);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
removeTag(tag) {
|
|
91
|
+
removeTag(this.tags, tag);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
makeParser() {
|
|
95
|
+
return new Parser(
|
|
96
|
+
this.filterOptions,
|
|
97
|
+
this.customTags,
|
|
98
|
+
this.emptyBlocks,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
processUsfm(usfmString) {
|
|
103
|
+
const parser = this.makeParser();
|
|
104
|
+
const t = Date.now();
|
|
105
|
+
parseUsfm(usfmString, parser);
|
|
106
|
+
const t2 = Date.now();
|
|
107
|
+
maybePrint(`\nParse USFM in ${t2 - t} msec`);
|
|
108
|
+
this.postParseScripture(parser);
|
|
109
|
+
maybePrint(`Total USFM import time = ${Date.now() - t} msec (parse = ${((t2 - t) * 100) / (Date.now() - t)}%)`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
processUsx(usxString) {
|
|
113
|
+
const parser = this.makeParser();
|
|
114
|
+
const t = Date.now();
|
|
115
|
+
parseUsx(usxString, parser);
|
|
116
|
+
const t2 = Date.now();
|
|
117
|
+
maybePrint(`\nParse USX in ${t2 - t} msec`);
|
|
118
|
+
this.postParseScripture(parser);
|
|
119
|
+
maybePrint(`Total USX import time = ${Date.now() - t} msec (parse = ${((t2 - t) * 100) / (Date.now() - t)}%)`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
processTSV(tsvString) {
|
|
123
|
+
const parser = this.makeParser();
|
|
124
|
+
const bookCode = `T${this.processor.nextTable > 9 ? this.processor.nextTable : '0' + this.processor.nextTable}`;
|
|
125
|
+
this.processor.nextTable++;
|
|
126
|
+
parseTableToDocument(tsvString, parser, bookCode);
|
|
127
|
+
this.headers = parser.headers;
|
|
128
|
+
this.succinctPass1(parser);
|
|
129
|
+
this.succinctPass2(parser);
|
|
130
|
+
buildChapterVerseIndex(this);
|
|
131
|
+
|
|
132
|
+
const tableSequence = Object.values(this.sequences).filter(s => s.type === 'table')[0];
|
|
133
|
+
|
|
134
|
+
for (const [colN, colHead] of JSON.parse(tsvString).headings.entries()) {
|
|
135
|
+
tableSequence.tags.add(`col${colN}:${colHead}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
processNodes(nodesString) {
|
|
140
|
+
const parser = this.makeParser();
|
|
141
|
+
const bookCode = `N${this.processor.nextNodes > 9 ? this.processor.nextNodes : '0' + this.processor.nextNodes}`;
|
|
142
|
+
this.processor.nextNodes++;
|
|
143
|
+
parseNodes(nodesString, parser, bookCode);
|
|
144
|
+
this.headers = parser.headers;
|
|
145
|
+
this.succinctPass1(parser);
|
|
146
|
+
this.succinctPass2(parser);
|
|
147
|
+
buildChapterVerseIndex(this);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
postParseScripture(parser) {
|
|
151
|
+
let t = Date.now();
|
|
152
|
+
parser.tidy();
|
|
153
|
+
maybePrint(`Tidy in ${Date.now() - t} msec`);
|
|
154
|
+
t = Date.now();
|
|
155
|
+
const fo = parser.filterOptions; // CHANGE THIS WHEN REFACTORING PARSER
|
|
156
|
+
this.headers = parser.headers;
|
|
157
|
+
this.succinctPass1(parser);
|
|
158
|
+
maybePrint(`Succinct pass 1 in ${Date.now() - t} msec`);
|
|
159
|
+
t = Date.now();
|
|
160
|
+
this.succinctPass2(parser);
|
|
161
|
+
maybePrint(`Succinct pass 2 in ${Date.now() - t} msec`);
|
|
162
|
+
t = Date.now();
|
|
163
|
+
this.succinctFilter(fo);
|
|
164
|
+
maybePrint(`Filter in ${Date.now() - t} msec`);
|
|
165
|
+
t = Date.now();
|
|
166
|
+
buildChapterVerseIndex(this);
|
|
167
|
+
maybePrint(`CV indexes in ${Date.now() - t} msec`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
succinctFilter(filterOptions) {
|
|
171
|
+
succinctFilter(this, filterOptions);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
succinctPass1(parser) {
|
|
175
|
+
const docSet = this.processor.docSets[this.docSetId];
|
|
176
|
+
|
|
177
|
+
let t = Date.now();
|
|
178
|
+
|
|
179
|
+
for (const seq of parser.allSequences()) {
|
|
180
|
+
docSet.recordPreEnum('ids', seq.id);
|
|
181
|
+
this.recordPreEnums(docSet, seq);
|
|
182
|
+
}
|
|
183
|
+
maybePrint(` recordPreEnums in ${Date.now() - t} msec`);
|
|
184
|
+
t = Date.now();
|
|
185
|
+
|
|
186
|
+
if (docSet.enums.wordLike.length === 0) {
|
|
187
|
+
docSet.sortPreEnums();
|
|
188
|
+
maybePrint(` sortPreEnums in ${Date.now() - t} msec`);
|
|
189
|
+
t = Date.now();
|
|
190
|
+
}
|
|
191
|
+
docSet.buildEnums();
|
|
192
|
+
maybePrint(` buildEnums in ${Date.now() - t} msec`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
recordPreEnums(docSet, seq) {
|
|
196
|
+
recordPreEnums(docSet, seq);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
rerecordPreEnums(docSet, seq) {
|
|
200
|
+
rerecordPreEnums(docSet, seq);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
succinctPass2(parser) {
|
|
204
|
+
const docSet = this.processor.docSets[this.docSetId];
|
|
205
|
+
this.mainId = parser.sequences.main.id;
|
|
206
|
+
|
|
207
|
+
for (const seq of parser.allSequences()) {
|
|
208
|
+
this.sequences[seq.id] = {
|
|
209
|
+
id: seq.id,
|
|
210
|
+
type: seq.type,
|
|
211
|
+
tags: new Set(seq.tags),
|
|
212
|
+
isBaseType: (seq.type in parser.baseSequenceTypes),
|
|
213
|
+
blocks: seq.succinctifyBlocks(docSet),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
this.sequences[this.mainId].verseMapping = {};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
modifySequence(
|
|
220
|
+
seqId,
|
|
221
|
+
sequenceRewriteFunc,
|
|
222
|
+
blockFilterFunc,
|
|
223
|
+
itemFilterFunc,
|
|
224
|
+
blockRewriteFunc,
|
|
225
|
+
itemRewriteFunc,
|
|
226
|
+
) {
|
|
227
|
+
modifySequence(
|
|
228
|
+
this,
|
|
229
|
+
seqId,
|
|
230
|
+
sequenceRewriteFunc,
|
|
231
|
+
blockFilterFunc,
|
|
232
|
+
itemFilterFunc,
|
|
233
|
+
blockRewriteFunc,
|
|
234
|
+
itemRewriteFunc,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
buildChapterVerseIndex() {
|
|
239
|
+
buildChapterVerseIndex(this);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
chapterVerseIndexes() {
|
|
243
|
+
const ret = {};
|
|
244
|
+
|
|
245
|
+
for (const chapN of Object.keys(this.sequences[this.mainId].chapterVerses)) {
|
|
246
|
+
ret[chapN] = chapterVerseIndex(this, chapN);
|
|
247
|
+
}
|
|
248
|
+
return ret;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
chapterVerseIndex(chapN) {
|
|
252
|
+
return chapterVerseIndex(this, chapN);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
chapterIndexes() {
|
|
256
|
+
const ret = {};
|
|
257
|
+
|
|
258
|
+
for (const chapN of Object.keys(this.sequences[this.mainId].chapters)) {
|
|
259
|
+
ret[chapN] = chapterIndex(this, chapN);
|
|
260
|
+
}
|
|
261
|
+
return ret;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
chapterIndex(chapN) {
|
|
265
|
+
return chapterIndex(this, chapN);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
rewriteSequenceBlocks(sequenceId, oldToNew) {
|
|
269
|
+
const sequence = this.sequences[sequenceId];
|
|
270
|
+
|
|
271
|
+
for (const block of sequence.blocks) {
|
|
272
|
+
this.rewriteSequenceBlock(block, oldToNew);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
rewriteSequenceBlock(block, oldToNew) {
|
|
277
|
+
rewriteBlock(block, oldToNew);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
serializeSuccinct() {
|
|
281
|
+
return serializeSuccinct(this);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
gcSequences() {
|
|
285
|
+
return gcSequences(this);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
newSequence(seqType, tags) {
|
|
289
|
+
return newSequence(this, seqType, tags);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
deleteSequence(seqId) {
|
|
293
|
+
return deleteSequence(this, seqId);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
deleteBlock(seqId, blockN, buildCV) {
|
|
297
|
+
return deleteBlock(this, seqId, blockN, buildCV);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
newBlock(seqId, blockN, blockScope, blockGrafts, buildCV) {
|
|
301
|
+
return newBlock(this, seqId, blockN, blockScope, blockGrafts, buildCV);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
perf(indent) {
|
|
305
|
+
const cl = new PerfRenderFromProskomma(
|
|
306
|
+
{
|
|
307
|
+
proskomma: this.processor,
|
|
308
|
+
actions: render.perfToPerf.renderActions.identityActions,
|
|
309
|
+
},
|
|
310
|
+
);
|
|
311
|
+
const output = {};
|
|
312
|
+
|
|
313
|
+
cl.renderDocument(
|
|
314
|
+
{
|
|
315
|
+
docId: this.id,
|
|
316
|
+
config: {},
|
|
317
|
+
output,
|
|
318
|
+
},
|
|
319
|
+
);
|
|
320
|
+
return indent ? JSON.stringify(output.perf, null, indent) : JSON.stringify(output.perf);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async usfm() {
|
|
324
|
+
const perf = JSON.parse(this.perf());
|
|
325
|
+
|
|
326
|
+
try {
|
|
327
|
+
const pipelineHandler = new PipelineHandler({
|
|
328
|
+
pipelines:pipelines,
|
|
329
|
+
transforms:customTransforms,
|
|
330
|
+
proskomma:this.processor,
|
|
331
|
+
});
|
|
332
|
+
const output = await pipelineHandler.runPipeline('perf2usfmPipeline', { perf });
|
|
333
|
+
return output.usfm;
|
|
334
|
+
} catch (err) {
|
|
335
|
+
console.error('pipelineHandler Error :\n', err);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
sofria(indent, chapter) {
|
|
340
|
+
const cl = new SofriaRenderFromProskomma(
|
|
341
|
+
{
|
|
342
|
+
proskomma: this.processor,
|
|
343
|
+
actions: render.sofriaToSofria.renderActions.identityActions,
|
|
344
|
+
},
|
|
345
|
+
);
|
|
346
|
+
const output = {};
|
|
347
|
+
const config = {};
|
|
348
|
+
|
|
349
|
+
if (chapter) {
|
|
350
|
+
config.chapters = [`${chapter}`];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
cl.renderDocument(
|
|
355
|
+
{
|
|
356
|
+
docId: this.id,
|
|
357
|
+
config,
|
|
358
|
+
output,
|
|
359
|
+
},
|
|
360
|
+
);
|
|
361
|
+
} catch (err) {
|
|
362
|
+
console.log(err);
|
|
363
|
+
throw err;
|
|
364
|
+
}
|
|
365
|
+
return indent ? JSON.stringify(output.sofria, null, indent) : JSON.stringify(output.sofria);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
module.exports = { Document };
|