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,389 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
const checksum = require('checksum');
|
|
3
|
+
const utils = require('../util/index.cjs');
|
|
4
|
+
const ByteArray = utils.ByteArray;
|
|
5
|
+
const {
|
|
6
|
+
addTag, removeTag, validateTags,
|
|
7
|
+
} = utils.tags;
|
|
8
|
+
const {
|
|
9
|
+
succinctGraftName,
|
|
10
|
+
succinctGraftSeqId,
|
|
11
|
+
succinctScopeLabel,
|
|
12
|
+
succinctTokenChars,
|
|
13
|
+
headerBytes,
|
|
14
|
+
enumIndex,
|
|
15
|
+
enumIndexes,
|
|
16
|
+
} = utils.succinct;
|
|
17
|
+
const { itemEnum } = utils.itemDefs;
|
|
18
|
+
const { tokenEnumLabels } = utils.tokenDefs;
|
|
19
|
+
const { validateSelectors } = require('./doc_set_helpers/selectors.cjs');
|
|
20
|
+
const {
|
|
21
|
+
blocksWithScriptureCV,
|
|
22
|
+
allBlockScopes,
|
|
23
|
+
anyScopeInBlock,
|
|
24
|
+
allScopesInBlock,
|
|
25
|
+
blockHasBlockScope,
|
|
26
|
+
blockHasChars,
|
|
27
|
+
blockHasMatchingItem,
|
|
28
|
+
} = require('./doc_set_helpers/block.cjs');
|
|
29
|
+
const {
|
|
30
|
+
unsuccinctifyBlock,
|
|
31
|
+
unsuccinctifyItems,
|
|
32
|
+
unsuccinctifyItem,
|
|
33
|
+
unsuccinctifyPrunedItems,
|
|
34
|
+
unsuccinctifyItemsWithScriptureCV,
|
|
35
|
+
} = require('./doc_set_helpers/unsuccinctify.cjs');
|
|
36
|
+
const {
|
|
37
|
+
buildPreEnum,
|
|
38
|
+
recordPreEnum,
|
|
39
|
+
buildEnum,
|
|
40
|
+
enumForCategoryValue,
|
|
41
|
+
} = require('./doc_set_helpers/enum.cjs');
|
|
42
|
+
const {
|
|
43
|
+
countItems,
|
|
44
|
+
itemsByIndex,
|
|
45
|
+
sequenceItemsByScopes,
|
|
46
|
+
sequenceItemsByMilestones,
|
|
47
|
+
} = require('./doc_set_helpers/item.cjs');
|
|
48
|
+
const {
|
|
49
|
+
rehash,
|
|
50
|
+
makeRehashEnumMap,
|
|
51
|
+
} = require('./doc_set_helpers/rehash.cjs');
|
|
52
|
+
const {
|
|
53
|
+
updateItems,
|
|
54
|
+
updateBlockGrafts,
|
|
55
|
+
updateBlockScope,
|
|
56
|
+
updateOpenScopes,
|
|
57
|
+
updateIncludedScopes,
|
|
58
|
+
updateBlockIndexesAfterEdit,
|
|
59
|
+
updateBlockIndexesAfterFilter,
|
|
60
|
+
} = require('./doc_set_helpers/update.cjs');
|
|
61
|
+
const { serializeSuccinct } = require('./doc_set_helpers/serialize.cjs');
|
|
62
|
+
class DocSet {
|
|
63
|
+
constructor(processor, selectors, tags, succinctJson) {
|
|
64
|
+
this.processor = processor;
|
|
65
|
+
this.preEnums = {};
|
|
66
|
+
this.enumIndexes = {};
|
|
67
|
+
this.docIds = [];
|
|
68
|
+
|
|
69
|
+
if (succinctJson) {
|
|
70
|
+
this.fromSuccinct(processor, succinctJson);
|
|
71
|
+
} else {
|
|
72
|
+
this.fromScratch(processor, selectors, tags);
|
|
73
|
+
}
|
|
74
|
+
validateTags(this.tags);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fromScratch(processor, selectors, tags) {
|
|
78
|
+
const defaultedSelectors = selectors || processor.selectors;
|
|
79
|
+
this.selectors = validateSelectors(this, defaultedSelectors);
|
|
80
|
+
this.id = this.selectorString();
|
|
81
|
+
this.tags = new Set(tags || []);
|
|
82
|
+
this.enums = {
|
|
83
|
+
ids: new ByteArray(512),
|
|
84
|
+
wordLike: new ByteArray(8192),
|
|
85
|
+
notWordLike: new ByteArray(256),
|
|
86
|
+
scopeBits: new ByteArray(256),
|
|
87
|
+
graftTypes: new ByteArray(10),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fromSuccinct(processor, succinctJson) {
|
|
92
|
+
const populatedByteArray = (succinct) => {
|
|
93
|
+
const ret = new ByteArray(256);
|
|
94
|
+
ret.fromBase64(succinct);
|
|
95
|
+
ret.trim();
|
|
96
|
+
return ret;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
this.id = succinctJson.id;
|
|
100
|
+
this.selectors = validateSelectors(this, succinctJson.metadata.selectors);
|
|
101
|
+
this.tags = new Set(succinctJson.tags);
|
|
102
|
+
validateTags(this.tags);
|
|
103
|
+
this.preEnums = {};
|
|
104
|
+
this.enums = {
|
|
105
|
+
ids: populatedByteArray(succinctJson.enums.ids),
|
|
106
|
+
wordLike: populatedByteArray(succinctJson.enums.wordLike),
|
|
107
|
+
notWordLike: populatedByteArray(succinctJson.enums.notWordLike),
|
|
108
|
+
scopeBits: populatedByteArray(succinctJson.enums.scopeBits),
|
|
109
|
+
graftTypes: populatedByteArray(succinctJson.enums.graftTypes),
|
|
110
|
+
};
|
|
111
|
+
this.enumIndexes = {};
|
|
112
|
+
this.docIds = [];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
addTag(tag) {
|
|
116
|
+
addTag(this.tags, tag);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
removeTag(tag) {
|
|
120
|
+
removeTag(this.tags, tag);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
selectorString() {
|
|
124
|
+
return this.processor.selectorString(this.selectors);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
documents() {
|
|
128
|
+
return this.docIds.map(did => this.processor.documents[did]);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
documentWithBook(bookCode) {
|
|
132
|
+
const docsWithBook = Object.values(this.documents()).filter(doc => 'bookCode' in doc.headers && doc.headers['bookCode'] === bookCode);
|
|
133
|
+
return docsWithBook.length === 1 ? docsWithBook[0] : null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
maybeBuildPreEnums() {
|
|
137
|
+
if (Object.keys(this.preEnums).length === 0) {
|
|
138
|
+
this.buildPreEnums();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
buildPreEnums() {
|
|
143
|
+
for (const [category, succinct] of Object.entries(this.enums)) {
|
|
144
|
+
this.preEnums[category] = buildPreEnum(this, succinct);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
recordPreEnum(category, value) {
|
|
149
|
+
recordPreEnum(this, category, value);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
sortPreEnums() {
|
|
153
|
+
for (const catKey of Object.keys(this.preEnums)) {
|
|
154
|
+
this.preEnums[catKey] = new Map([...this.preEnums[catKey].entries()].sort((a, b) => b[1].frequency - a[1].frequency));
|
|
155
|
+
|
|
156
|
+
let count = 0;
|
|
157
|
+
|
|
158
|
+
for (const [k, v] of this.preEnums[catKey]) {
|
|
159
|
+
v.enum = count++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
enumForCategoryValue(category, value, addUnknown) {
|
|
165
|
+
return enumForCategoryValue(this, category, value, addUnknown);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
buildEnums() {
|
|
169
|
+
for (const [category, catOb] of Object.entries(this.preEnums)) {
|
|
170
|
+
this.enums[category].clear();
|
|
171
|
+
this.buildEnum(category, catOb);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
buildEnum(category, preEnumOb) {
|
|
176
|
+
buildEnum(this, category, preEnumOb);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
maybeBuildEnumIndexes() {
|
|
180
|
+
if (Object.keys(this.enumIndexes).length === 0) {
|
|
181
|
+
this.buildEnumIndexes();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
buildEnumIndexes() {
|
|
186
|
+
this.enumIndexes = enumIndexes(this.enums);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
buildEnumIndex(category) {
|
|
190
|
+
this.enumIndexes[category] = enumIndex(category, this.enums[category]);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
unsuccinctifyBlock(block, options) {
|
|
194
|
+
return unsuccinctifyBlock(this, block, options);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
unsuccinctifyItems(succinct, options, nextToken, openScopes) {
|
|
198
|
+
return unsuccinctifyItems(this, succinct, options, nextToken, openScopes);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
unsuccinctifyItem(succinct, pos, options) {
|
|
202
|
+
return unsuccinctifyItem(this, succinct, pos, options);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
unsuccinctifyPrunedItems(block, options) {
|
|
206
|
+
return unsuccinctifyPrunedItems(this, block, options);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
unsuccinctifyScopes(succinct) {
|
|
210
|
+
const ret = [];
|
|
211
|
+
let pos = 0;
|
|
212
|
+
|
|
213
|
+
while (pos < succinct.length) {
|
|
214
|
+
const [itemLength, itemType, itemSubtype] = headerBytes(succinct, pos);
|
|
215
|
+
ret.push(this.unsuccinctifyScope(succinct, itemType, itemSubtype, pos));
|
|
216
|
+
pos += itemLength;
|
|
217
|
+
}
|
|
218
|
+
return ret;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
unsuccinctifyGrafts(succinct) {
|
|
222
|
+
const ret = [];
|
|
223
|
+
let pos = 0;
|
|
224
|
+
|
|
225
|
+
while (pos < succinct.length) {
|
|
226
|
+
const [itemLength, itemType, itemSubtype] = headerBytes(succinct, pos);
|
|
227
|
+
ret.push(this.unsuccinctifyGraft(succinct, itemSubtype, pos));
|
|
228
|
+
pos += itemLength;
|
|
229
|
+
}
|
|
230
|
+
return ret;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
unsuccinctifyToken(succinct, itemSubtype, pos) {
|
|
234
|
+
try {
|
|
235
|
+
return [
|
|
236
|
+
'token',
|
|
237
|
+
tokenEnumLabels[itemSubtype],
|
|
238
|
+
this.succinctTokenChars(succinct, itemSubtype, pos),
|
|
239
|
+
];
|
|
240
|
+
} catch (err) {
|
|
241
|
+
throw new Error(`Error from unsuccinctifyToken: ${err}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
unsuccinctifyScope(succinct, itemType, itemSubtype, pos) {
|
|
246
|
+
try {
|
|
247
|
+
return [
|
|
248
|
+
'scope',
|
|
249
|
+
(itemType === itemEnum.startScope) ? 'start' : 'end',
|
|
250
|
+
this.succinctScopeLabel(succinct, itemSubtype, pos),
|
|
251
|
+
];
|
|
252
|
+
} catch (err) {
|
|
253
|
+
throw new Error(`Error from unsuccinctifyScope: ${err}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
unsuccinctifyGraft(succinct, itemSubtype, pos) {
|
|
258
|
+
try {
|
|
259
|
+
return [
|
|
260
|
+
'graft',
|
|
261
|
+
this.succinctGraftName(itemSubtype),
|
|
262
|
+
this.succinctGraftSeqId(succinct, pos),
|
|
263
|
+
];
|
|
264
|
+
} catch (err) {
|
|
265
|
+
throw new Error(`Error from unsuccinctifyGraft: ${err}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
unsuccinctifyBlockScopeLabelsSet(block) {
|
|
270
|
+
const [itemLength, itemType, itemSubtype] = headerBytes(block.bs, 0);
|
|
271
|
+
const blockScope = this.unsuccinctifyScope(block.bs, itemType, itemSubtype, 0);
|
|
272
|
+
return new Set(
|
|
273
|
+
this.unsuccinctifyScopes(block.os).concat(
|
|
274
|
+
this.unsuccinctifyScopes(block.is),
|
|
275
|
+
).concat([blockScope])
|
|
276
|
+
.map(ri => ri[2]));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
unsuccinctifyItemsWithScriptureCV(block, cv, options) {
|
|
280
|
+
return unsuccinctifyItemsWithScriptureCV(this, block, cv, options);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
succinctTokenChars(succinct, itemSubtype, pos) {
|
|
284
|
+
return succinctTokenChars(this.enums, this.enumIndexes, succinct, itemSubtype, pos);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
succinctScopeLabel(succinct, itemSubtype, pos) {
|
|
288
|
+
return succinctScopeLabel(this.enums, this.enumIndexes, succinct, itemSubtype, pos);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
succinctGraftName(itemSubtype) {
|
|
292
|
+
return succinctGraftName(this.enums, this.enumIndexes, itemSubtype);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
succinctGraftSeqId(succinct, pos) {
|
|
296
|
+
return succinctGraftSeqId(this.enums, this.enumIndexes, succinct, pos);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
countItems(succinct) {
|
|
300
|
+
return countItems(this, succinct);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
itemsByIndex(mainSequence, index, includeContext) {
|
|
304
|
+
return itemsByIndex(this, mainSequence, index, includeContext);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
blocksWithScriptureCV(blocks, cv) {
|
|
308
|
+
return blocksWithScriptureCV(this, blocks, cv);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
allBlockScopes(block) {
|
|
312
|
+
return allBlockScopes(this, block);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
allScopesInBlock(block, scopes) {
|
|
316
|
+
return allScopesInBlock(this, block, scopes);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
anyScopeInBlock(block, scopes) {
|
|
320
|
+
return anyScopeInBlock(this, block, scopes);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
blockHasBlockScope(block, scope) {
|
|
324
|
+
return blockHasBlockScope(this, block, scope);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
blockHasChars(block, charsIndexes) {
|
|
328
|
+
return blockHasChars(this, block, charsIndexes);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
blockHasMatchingItem(block, testFunction, options) {
|
|
332
|
+
return blockHasMatchingItem(this, block, testFunction, options);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
sequenceItemsByScopes(blocks, byScopes) {
|
|
336
|
+
return sequenceItemsByScopes(this, blocks, byScopes);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
sequenceItemsByMilestones(blocks, byMilestones) {
|
|
340
|
+
return sequenceItemsByMilestones(this, blocks, byMilestones);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
rehash() {
|
|
344
|
+
return rehash(this);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
makeRehashEnumMap() {
|
|
348
|
+
return makeRehashEnumMap(this);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
updateItems(documentId, sequenceId, blockPosition, itemObjects) {
|
|
352
|
+
return updateItems(this, documentId, sequenceId, blockPosition, itemObjects);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
updateBlockGrafts(documentId, sequenceId, blockPosition, itemObjects) {
|
|
356
|
+
return updateBlockGrafts(this, documentId, sequenceId, blockPosition, itemObjects);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
updateBlockScope(documentId, sequenceId, blockPosition, bsObject) {
|
|
360
|
+
return updateBlockScope(this, documentId, sequenceId, blockPosition, bsObject);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
updateOpenScopes(documentId, sequenceId, blockPosition, osObjects) {
|
|
364
|
+
return updateOpenScopes(this, documentId, sequenceId, blockPosition, osObjects);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
updateIncludedScopes(documentId, sequenceId, blockPosition, isObjects) {
|
|
368
|
+
return updateIncludedScopes(this, documentId, sequenceId, blockPosition, isObjects);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
updateBlockIndexesAfterEdit(sequence, blockPosition) {
|
|
372
|
+
updateBlockIndexesAfterEdit(this, sequence, blockPosition);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
updateBlockIndexesAfterFilter(sequence) {
|
|
376
|
+
updateBlockIndexesAfterFilter(this, sequence);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
serializeSuccinct() {
|
|
380
|
+
return serializeSuccinct(this);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
checksum() {
|
|
384
|
+
const docIdsString = [...this.docIds].sort().join(' ');
|
|
385
|
+
return checksum(docIdsString);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
module.exports = { DocSet };
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
const xre = require('xregexp');
|
|
2
|
+
const utils = require('../../util/index.cjs');
|
|
3
|
+
|
|
4
|
+
const blocksWithScriptureCV = (docSet, blocks, cv) => {
|
|
5
|
+
const hasMiddleChapter = (b, fromC, toC) => {
|
|
6
|
+
const blockChapterScopes = [
|
|
7
|
+
...docSet.unsuccinctifyScopes(b.os).map(s => s[2]),
|
|
8
|
+
...docSet.unsuccinctifyScopes(b.is).map(s => s[2]),
|
|
9
|
+
].filter(s => s.startsWith('chapter/'));
|
|
10
|
+
return blockChapterScopes.map(s => parseInt(s.split('/')[1])).filter(n => n > fromC && n < toC).length > 0;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const hasFirstChapter = (b, fromC, fromV) => {
|
|
14
|
+
const hasFirstChapterScope = [
|
|
15
|
+
...docSet.unsuccinctifyScopes(b.os).map(s => s[2]),
|
|
16
|
+
...docSet.unsuccinctifyScopes(b.is).map(s => s[2]),
|
|
17
|
+
].includes(`chapter/${fromC}`);
|
|
18
|
+
return hasFirstChapterScope &&
|
|
19
|
+
docSet.blockHasMatchingItem(
|
|
20
|
+
b,
|
|
21
|
+
(item, openScopes) => {
|
|
22
|
+
if (!openScopes.has(`chapter/${fromC}`)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return (
|
|
26
|
+
Array.from(openScopes)
|
|
27
|
+
.filter(s => s.startsWith('verse/'))
|
|
28
|
+
.filter(s => parseInt(s.split('/')[1]) >= fromV).length
|
|
29
|
+
> 0
|
|
30
|
+
||
|
|
31
|
+
(
|
|
32
|
+
fromV === 0 &&
|
|
33
|
+
item[0] === 'token' &&
|
|
34
|
+
item[2] &&
|
|
35
|
+
Array.from(openScopes)
|
|
36
|
+
.filter(s => s.startsWith('verse'))
|
|
37
|
+
.length === 0
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
{},
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const hasLastChapter = (b, toC, toV) => {
|
|
46
|
+
const hasLastChapterScope = [
|
|
47
|
+
...docSet.unsuccinctifyScopes(b.os).map(s => s[2]),
|
|
48
|
+
...docSet.unsuccinctifyScopes(b.is).map(s => s[2]),
|
|
49
|
+
].includes(`chapter/${toC}`);
|
|
50
|
+
return hasLastChapterScope &&
|
|
51
|
+
docSet.blockHasMatchingItem(
|
|
52
|
+
b,
|
|
53
|
+
(item, openScopes) => {
|
|
54
|
+
if (!openScopes.has(`chapter/${toC}`)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return (
|
|
58
|
+
Array.from(openScopes)
|
|
59
|
+
.filter(s => s.startsWith('verse/'))
|
|
60
|
+
.filter(s => parseInt(s.split('/')[1]) <= toV).length
|
|
61
|
+
> 0
|
|
62
|
+
||
|
|
63
|
+
(
|
|
64
|
+
toV === 0 &&
|
|
65
|
+
item[0] === 'token' &&
|
|
66
|
+
item[2] &&
|
|
67
|
+
Array.from(openScopes)
|
|
68
|
+
.filter(s => s.startsWith('verse'))
|
|
69
|
+
.length === 0
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
{},
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if (xre.exec(cv, xre('^[1-9][0-9]*$'))) {
|
|
79
|
+
const scopes = [`chapter/${cv}`];
|
|
80
|
+
return blocks.filter(b => docSet.allScopesInBlock(b, scopes));
|
|
81
|
+
} else if (xre.exec(cv, xre('^[1-9][0-9]*-[1-9][0-9]*$'))) {
|
|
82
|
+
const [fromC, toC] = cv.split('-').map(v => parseInt(v));
|
|
83
|
+
|
|
84
|
+
if (fromC > toC) {
|
|
85
|
+
throw new Error(`Chapter range must be from min to max, not '${cv}'`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const scopes = [...Array((toC - fromC) + 1).keys()].map(n => `chapter/${n + fromC}`);
|
|
89
|
+
return blocks.filter(b => docSet.anyScopeInBlock(b, scopes));
|
|
90
|
+
} else if (xre.exec(cv, xre('^[1-9][0-9]*:[0-9]+$'))) {
|
|
91
|
+
const [fromC, fromV] = cv.split(':').map(v => parseInt(v));
|
|
92
|
+
|
|
93
|
+
if (fromV === 0) {
|
|
94
|
+
const scopes = [`chapter/${fromC}`];
|
|
95
|
+
return blocks
|
|
96
|
+
.filter(b => docSet.allScopesInBlock(b, scopes))
|
|
97
|
+
.filter(
|
|
98
|
+
b =>
|
|
99
|
+
[...docSet.allBlockScopes(b)]
|
|
100
|
+
.filter(s => s.startsWith('verse')).length === 0,
|
|
101
|
+
);
|
|
102
|
+
} else {
|
|
103
|
+
const scopes = [`chapter/${fromC}`, `verse/${fromV}`];
|
|
104
|
+
return blocks.filter(b => docSet.allScopesInBlock(b, scopes));
|
|
105
|
+
}
|
|
106
|
+
} else if (xre.exec(cv, xre('^[1-9][0-9]*:[0-9]+-[1-9][0-9]*$'))) {
|
|
107
|
+
const [fromC, vs] = cv.split(':');
|
|
108
|
+
const [fromV, toV] = vs.split('-').map(v => parseInt(v));
|
|
109
|
+
|
|
110
|
+
if (fromV > toV) {
|
|
111
|
+
throw new Error(`Verse range must be from min to max, not '${vs}'`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const chapterScopes = [`chapter/${fromC}`];
|
|
115
|
+
const verseScopes = [...Array((toV - fromV) + 1).keys()].map(n => `verse/${n + fromV}`);
|
|
116
|
+
return blocks
|
|
117
|
+
.filter(b => docSet.allScopesInBlock(b, chapterScopes))
|
|
118
|
+
.filter(
|
|
119
|
+
b =>
|
|
120
|
+
docSet.anyScopeInBlock(b, verseScopes) ||
|
|
121
|
+
(
|
|
122
|
+
fromV === 0 &&
|
|
123
|
+
[...docSet.allBlockScopes(b)]
|
|
124
|
+
.filter(s => s.startsWith('verse')).length === 0
|
|
125
|
+
),
|
|
126
|
+
);
|
|
127
|
+
} else if (xre.exec(cv, xre('^[1-9][0-9]*:[0-9]+-[1-9][0-9]*:[0-9]+$'))) {
|
|
128
|
+
const [fromCV, toCV] = cv.split('-');
|
|
129
|
+
const [fromC, fromV] = fromCV.split(':').map(c => parseInt(c));
|
|
130
|
+
const [toC, toV] = toCV.split(':').map(v => parseInt(v));
|
|
131
|
+
|
|
132
|
+
if (fromC > toC) {
|
|
133
|
+
throw new Error(`Chapter range must be from min to max, not '${fromC}-${toV}'`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const chapterScopes = [...Array((toC - fromC) + 1).keys()].map(n => `chapter/${n + fromC}`);
|
|
137
|
+
const chapterBlocks = blocks.filter(b => docSet.anyScopeInBlock(b, chapterScopes));
|
|
138
|
+
return chapterBlocks.filter(b => hasMiddleChapter(b, fromC, toC) || hasFirstChapter(b, fromC, fromV) || hasLastChapter(b, toC, toV));
|
|
139
|
+
} else {
|
|
140
|
+
throw new Error(`Bad cv reference '${cv}'`);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const allBlockScopes = (docSet, block) => {
|
|
145
|
+
const [itemLength, itemType, itemSubtype] = utils.succinct.headerBytes(block.bs, 0);
|
|
146
|
+
const blockScope = docSet.unsuccinctifyScope(block.bs, itemType, itemSubtype, 0);
|
|
147
|
+
return new Set([
|
|
148
|
+
...docSet.unsuccinctifyScopes(block.os).map(s => s[2]),
|
|
149
|
+
...docSet.unsuccinctifyScopes(block.is).map(s => s[2]),
|
|
150
|
+
blockScope[2],
|
|
151
|
+
],
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const allScopesInBlock = (docSet, block, scopes) => {
|
|
156
|
+
const allBlockScopes = docSet.allBlockScopes(block);
|
|
157
|
+
|
|
158
|
+
for (const scope of scopes) {
|
|
159
|
+
if (!allBlockScopes.has(scope)) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const anyScopeInBlock = (docSet, block, scopes) => {
|
|
167
|
+
const allBlockScopes = docSet.allBlockScopes(block);
|
|
168
|
+
|
|
169
|
+
for (const scope of scopes) {
|
|
170
|
+
if (allBlockScopes.has(scope)) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const blockHasBlockScope = (docSet, block, scope) => {
|
|
178
|
+
const [itemLength, itemType, itemSubtype] = utils.succinct.headerBytes(block.bs, 0);
|
|
179
|
+
const blockScope = docSet.unsuccinctifyScope(block.bs, itemType, itemSubtype, 0);
|
|
180
|
+
return (blockScope[2] === scope);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const blockHasChars = (docSet, block, charsIndexes) => {
|
|
184
|
+
let ret = false;
|
|
185
|
+
let pos = 0;
|
|
186
|
+
const succinct = block.c;
|
|
187
|
+
|
|
188
|
+
if (charsIndexes.includes(-1)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
while (!ret && (pos < succinct.length)) {
|
|
193
|
+
const [itemLength, itemType] = utils.succinct.headerBytes(succinct, pos);
|
|
194
|
+
|
|
195
|
+
if (itemType === utils.itemDefs.itemEnum['token']) {
|
|
196
|
+
if (charsIndexes.includes(succinct.nByte(pos + 2))) {
|
|
197
|
+
ret = true;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
pos += itemLength;
|
|
201
|
+
}
|
|
202
|
+
return ret;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const blockHasMatchingItem = (docSet, block, testFunction, options) => {
|
|
206
|
+
const openScopes = new Set(docSet.unsuccinctifyScopes(block.os).map(ri => ri[2]));
|
|
207
|
+
|
|
208
|
+
for (const item of docSet.unsuccinctifyItems(block.c, options, 0)) {
|
|
209
|
+
if (item[0] === 'scope' && item[1] === 'start') {
|
|
210
|
+
openScopes.add(item[2]);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (testFunction(item, openScopes)) {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (item[0] === 'scope' && item[1] === 'end') {
|
|
218
|
+
openScopes.delete(item[2]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
module.exports = {
|
|
225
|
+
blocksWithScriptureCV,
|
|
226
|
+
allBlockScopes,
|
|
227
|
+
anyScopeInBlock,
|
|
228
|
+
allScopesInBlock,
|
|
229
|
+
blockHasBlockScope,
|
|
230
|
+
blockHasChars,
|
|
231
|
+
blockHasMatchingItem,
|
|
232
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const buildPreEnum = (docSet, succinct) => {
|
|
2
|
+
const ret = new Map();
|
|
3
|
+
let pos = 0;
|
|
4
|
+
let enumCount = 0;
|
|
5
|
+
|
|
6
|
+
while (pos < succinct.length) {
|
|
7
|
+
ret.set(
|
|
8
|
+
succinct.countedString(pos),
|
|
9
|
+
{
|
|
10
|
+
'enum': enumCount++,
|
|
11
|
+
'frequency': 0,
|
|
12
|
+
},
|
|
13
|
+
);
|
|
14
|
+
pos += succinct.byte(pos) + 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return ret;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const recordPreEnum = (docSet, category, value) => {
|
|
21
|
+
if (!(category in docSet.preEnums)) {
|
|
22
|
+
throw new Error(`Unknown category ${category} in recordPreEnum. Maybe call buildPreEnums()?`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (value.length > 255) {
|
|
26
|
+
console.log('Value length of', value.length, 'in recordPreEnum');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!docSet.preEnums[category].has(value)) {
|
|
30
|
+
docSet.preEnums[category].set(
|
|
31
|
+
value,
|
|
32
|
+
{
|
|
33
|
+
'enum': docSet.preEnums[category].size,
|
|
34
|
+
'frequency': 1,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
docSet.preEnums[category].get(value).frequency++;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const buildEnum = (docSet, category, preEnumOb) => {
|
|
43
|
+
const sortedPreEnums = new Map([...preEnumOb.entries()]);
|
|
44
|
+
|
|
45
|
+
for (const enumText of sortedPreEnums.keys()) {
|
|
46
|
+
if (enumText.length > 255) {
|
|
47
|
+
console.log('enum text for', category, 'has length', enumText.length, 'in buildEnum - truncating');
|
|
48
|
+
}
|
|
49
|
+
docSet.enums[category].pushCountedString(enumText.substring(0, 255));
|
|
50
|
+
}
|
|
51
|
+
docSet.enums[category].trim();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const enumForCategoryValue = (docSet, category, value, addUnknown) => {
|
|
55
|
+
if (!addUnknown) {
|
|
56
|
+
addUnknown = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!(category in docSet.preEnums)) {
|
|
60
|
+
throw new Error(`Unknown category ${category} in preEnums. Maybe call buildPreEnums()?`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (docSet.preEnums[category].has(value)) {
|
|
64
|
+
return docSet.preEnums[category].get(value).enum;
|
|
65
|
+
} else if (addUnknown) {
|
|
66
|
+
docSet.preEnums[category].set(
|
|
67
|
+
value,
|
|
68
|
+
{
|
|
69
|
+
'enum': docSet.preEnums[category].size,
|
|
70
|
+
'frequency': 1,
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
docSet.enums[category].pushCountedString(value);
|
|
74
|
+
docSet.buildEnumIndex(category);
|
|
75
|
+
return docSet.preEnums[category].get(value).enum;
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(`Unknown value '${value}' for category ${category} in enumForCategoryValue. Maybe call buildPreEnums()?`);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
module.exports = {
|
|
83
|
+
buildPreEnum,
|
|
84
|
+
recordPreEnum,
|
|
85
|
+
buildEnum,
|
|
86
|
+
enumForCategoryValue,
|
|
87
|
+
};
|