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,249 @@
|
|
|
1
|
+
const xre = require('xregexp');
|
|
2
|
+
const utils = require('../../util/index.cjs');
|
|
3
|
+
|
|
4
|
+
const updatedOpenScopes = (openScopes, items) => {
|
|
5
|
+
let ret = openScopes;
|
|
6
|
+
|
|
7
|
+
for (const item of items) {
|
|
8
|
+
if (item[0] === 'scope') {
|
|
9
|
+
if (item[1] === 'start') {
|
|
10
|
+
const existingScopes = ret.filter(s => s === item[2]);
|
|
11
|
+
|
|
12
|
+
if (existingScopes.length === 0) {
|
|
13
|
+
ret.push(item[2]);
|
|
14
|
+
}
|
|
15
|
+
} else {
|
|
16
|
+
ret = ret.filter(s => s !== item[2]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return ret;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const do_chapter_cv = (root, context, mainSequence, chapterN, includeContext) => {
|
|
24
|
+
const ci = root.chapterIndex(chapterN);
|
|
25
|
+
|
|
26
|
+
if (ci) {
|
|
27
|
+
const block = mainSequence.blocks[ci.startBlock];
|
|
28
|
+
return [[
|
|
29
|
+
updatedOpenScopes(
|
|
30
|
+
context.docSet.unsuccinctifyScopes(block.os).map(s => s[2]),
|
|
31
|
+
context.docSet.unsuccinctifyItems(block.c, {}, 0, [])
|
|
32
|
+
.slice(0, ci.startItem + 1)
|
|
33
|
+
.filter(i => i[0] === 'scope'),
|
|
34
|
+
),
|
|
35
|
+
context.docSet.itemsByIndex(mainSequence, ci, includeContext || false)
|
|
36
|
+
.reduce((a, b) => a.concat([['token', 'lineSpace', ' ']].concat(b))),
|
|
37
|
+
]];
|
|
38
|
+
} else {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const do_chapter_verse_array = (root, context, mainSequence, chapterN, verses, includeContext, doMap, mappedDocSetId) => {
|
|
44
|
+
let docSet = context.docSet;
|
|
45
|
+
let book = root.headers.bookCode;
|
|
46
|
+
let chapterVerses = verses.map(v => [parseInt(chapterN), parseInt(v)]);
|
|
47
|
+
|
|
48
|
+
if (doMap) {
|
|
49
|
+
const mappedDocSet = root.processor.docSets[mappedDocSetId];
|
|
50
|
+
|
|
51
|
+
if (mappedDocSet) {
|
|
52
|
+
docSet = mappedDocSet;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if ('forward' in mainSequence.verseMapping && chapterN in mainSequence.verseMapping.forward) {
|
|
56
|
+
let mappings = [];
|
|
57
|
+
|
|
58
|
+
for (const verse of verses) { // May handle multiple verses one day, but, eg, may map to multiple books
|
|
59
|
+
mappings.push(
|
|
60
|
+
utils.versification.mapVerse(
|
|
61
|
+
mainSequence.verseMapping.forward[chapterN],
|
|
62
|
+
root.headers.bookCode,
|
|
63
|
+
chapterN,
|
|
64
|
+
verse,
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const mapping = mappings[0];
|
|
70
|
+
book = mapping[0];
|
|
71
|
+
chapterVerses = mapping[1];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const mappedDocument = docSet.documentWithBook(book);
|
|
75
|
+
|
|
76
|
+
if (mappedDocument) {
|
|
77
|
+
const mappedMainSequence = mappedDocument.sequences[mappedDocument.mainId];
|
|
78
|
+
|
|
79
|
+
if (mappedMainSequence.verseMapping && 'reversed' in mappedMainSequence.verseMapping) {
|
|
80
|
+
const doubleMappings = [];
|
|
81
|
+
|
|
82
|
+
for (const [origC, origV] of chapterVerses) {
|
|
83
|
+
if (`${origC}` in mappedMainSequence.verseMapping.reversed) {
|
|
84
|
+
doubleMappings.push(
|
|
85
|
+
utils.versification.mapVerse(
|
|
86
|
+
mappedMainSequence.verseMapping.reversed[`${origC}`],
|
|
87
|
+
book,
|
|
88
|
+
origC,
|
|
89
|
+
origV,
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
doubleMappings.push([book, [[origC, origV]]]);
|
|
94
|
+
}
|
|
95
|
+
book = doubleMappings[0][0];
|
|
96
|
+
chapterVerses = doubleMappings.map(bcv => bcv[1]).reduce((a, b) => a.concat(b));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const cvis = {};
|
|
103
|
+
|
|
104
|
+
const document = docSet.documentWithBook(book);
|
|
105
|
+
|
|
106
|
+
if (!document) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const documentMainSequence = document.sequences[document.mainId];
|
|
111
|
+
|
|
112
|
+
for (const chapter of chapterVerses.map(cv => cv[0])) {
|
|
113
|
+
if (!(chapter in cvis)) {
|
|
114
|
+
cvis[chapter] = document.chapterVerseIndex(chapter);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const retItemGroups = [];
|
|
119
|
+
|
|
120
|
+
for (const [chapter, verse] of chapterVerses) {
|
|
121
|
+
if (cvis[chapter]) {
|
|
122
|
+
let retItems = [];
|
|
123
|
+
let firstStartBlock;
|
|
124
|
+
let firstStartItem;
|
|
125
|
+
|
|
126
|
+
if (cvis[chapter][verse]) {
|
|
127
|
+
for (const ve of cvis[chapter][verse]) {
|
|
128
|
+
if (!firstStartBlock) {
|
|
129
|
+
firstStartBlock = ve.startBlock;
|
|
130
|
+
firstStartItem = ve.startItem;
|
|
131
|
+
}
|
|
132
|
+
retItems = retItems.concat(docSet.itemsByIndex(documentMainSequence, ve, includeContext || null)
|
|
133
|
+
.reduce((a, b) => a.concat([['token', 'lineSpace', ' ']].concat(b))));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const block = documentMainSequence.blocks[firstStartBlock];
|
|
137
|
+
|
|
138
|
+
retItemGroups.push([
|
|
139
|
+
updatedOpenScopes(
|
|
140
|
+
docSet.unsuccinctifyScopes(block.os).map(s => s[2]),
|
|
141
|
+
docSet.unsuccinctifyItems(block.c, {}, 0, [])
|
|
142
|
+
.slice(0, firstStartItem + 1)
|
|
143
|
+
.filter(i => i[0] === 'scope'),
|
|
144
|
+
),
|
|
145
|
+
retItems,
|
|
146
|
+
]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return retItemGroups;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const scopesMatchAChapterSpec = (scopes, chapterSpecs) => {
|
|
154
|
+
if (chapterSpecs.length === 0) {
|
|
155
|
+
return false;
|
|
156
|
+
} else if (
|
|
157
|
+
scopes.includes(`chapter/${chapterSpecs[0][0]}`) &&
|
|
158
|
+
(!chapterSpecs[0][1] || scopes.filter(s => s.startsWith('verse/') && parseInt(s.split('/')[1]) >= chapterSpecs[0][1]).length > 0) &&
|
|
159
|
+
(!chapterSpecs[0][2] || scopes.filter(s => s.startsWith('verse/') && parseInt(s.split('/')[1]) <= chapterSpecs[0][2]).length > 0)
|
|
160
|
+
) {
|
|
161
|
+
return true;
|
|
162
|
+
} else {
|
|
163
|
+
return scopesMatchAChapterSpec(scopes, chapterSpecs.slice(1));
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const do_chapterVerses = (root, context, mainSequence, fromCV, toCV, includeContext) => {
|
|
168
|
+
const [fromCInt, fromVInt] = fromCV.split(':').map(str => parseInt(str));
|
|
169
|
+
const [toCInt, toVInt] = toCV.split(':').map(str => parseInt(str));
|
|
170
|
+
|
|
171
|
+
if (toCInt < fromCInt) {
|
|
172
|
+
throw new Error(`cv chapterVerses requires fromChapter <= toChapter, not ${fromCInt} to ${toCInt}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const chapterSpecs = []; // [chN, minVN?, maxVN?]
|
|
176
|
+
let ch = fromCInt;
|
|
177
|
+
|
|
178
|
+
while (ch <= toCInt) {
|
|
179
|
+
chapterSpecs.push([
|
|
180
|
+
ch,
|
|
181
|
+
ch === fromCInt ? fromVInt : null,
|
|
182
|
+
ch === toCInt ? toVInt : null,
|
|
183
|
+
]);
|
|
184
|
+
ch++;
|
|
185
|
+
}
|
|
186
|
+
return context.docSet.sequenceItemsByScopes(mainSequence.blocks, ['chapter/', 'verse/'], includeContext)
|
|
187
|
+
.filter(ig => scopesMatchAChapterSpec(ig[0], chapterSpecs));
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const do_cv_separate_args = (root, args, context, mainSequence, doMap, mappedDocSetId) => {
|
|
191
|
+
if (args.chapter && !args.verses) { // whole chapter
|
|
192
|
+
return do_chapter_cv(root, context, mainSequence, args.chapter, args.includeContext);
|
|
193
|
+
} else if (args.verses) { // c:v, c:v-v one day, may be mapped
|
|
194
|
+
return do_chapter_verse_array(root, context, mainSequence, args.chapter, args.verses, args.includeContext, doMap, mappedDocSetId);
|
|
195
|
+
} else {
|
|
196
|
+
throw new Error('Unexpected args to do_cv_separate_args');
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const do_cv_string_arg = (root, args, context, mainSequence) => {
|
|
201
|
+
if (xre.test(args.chapterVerses, xre('^[0-9]+:[0-9]+-[0-9]+:[0-9]+$'))) { // c:v-c:v
|
|
202
|
+
const [fromSpec, toSpec] = args.chapterVerses.split('-');
|
|
203
|
+
return do_chapterVerses(root, context, mainSequence, fromSpec, toSpec, args.includeContext);
|
|
204
|
+
} else if (xre.test(args.chapterVerses, xre('^[0-9]+:[0-9]+-[0-9]+$'))) { // c:v-v
|
|
205
|
+
const [ch, vRange] = args.chapterVerses.split(':');
|
|
206
|
+
const [fromV, toV] = vRange.split('-');
|
|
207
|
+
return do_chapterVerses(root, context, mainSequence, `${ch}:${fromV}`, `${ch}:${toV}`, args.includeContext);
|
|
208
|
+
} else if (xre.test(args.chapterVerses, xre('^[0-9]+:[0-9]+$'))) { // c:v
|
|
209
|
+
const [ch, v] = args.chapterVerses.split(':');
|
|
210
|
+
return do_chapterVerses(root, context, mainSequence, `${ch}:${v}`, `${ch}:${v}`, args.includeContext);
|
|
211
|
+
} else if (xre.test(args.chapterVerses, xre('^[0-9]+$'))) { // c
|
|
212
|
+
const ch = args.chapterVerses;
|
|
213
|
+
const cvi = root.chapterVerseIndex(ch);
|
|
214
|
+
|
|
215
|
+
if (!cvi) {
|
|
216
|
+
throw new Error(`No chapter ${ch} found`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const verseNs = cvi.map((c, n) => [n, c]).filter(nc => nc[1].length > 0).map(nc => nc[0]);
|
|
220
|
+
return do_chapterVerses(root, context, mainSequence, `${ch}:${Math.min(verseNs)}`, `${ch}:${Math.max(verseNs)}`, args.includeContext);
|
|
221
|
+
} else {
|
|
222
|
+
throw new Error(`Could not parse chapterVerses string '${args.chapterVerses}'`);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const do_cv = (root, args, context, doMap, mappedDocSetId) => {
|
|
227
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
228
|
+
const mainSequence = root.sequences[root.mainId];
|
|
229
|
+
|
|
230
|
+
if (!args.chapter && !args.chapterVerses) {
|
|
231
|
+
throw new Error('Must specify either chapter or chapterVerses for cv');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (args.chapter && args.chapterVerses) {
|
|
235
|
+
throw new Error('Must not specify both chapter and chapterVerses for cv');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (args.chapterVerses && args.verses) {
|
|
239
|
+
throw new Error('Must not specify both chapterVerses and verses for cv');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (args.chapter) {
|
|
243
|
+
return do_cv_separate_args(root, args, context, mainSequence, doMap, mappedDocSetId);
|
|
244
|
+
} else {
|
|
245
|
+
return do_cv_string_arg(root, args, context, mainSequence);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
module.exports = { do_cv };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const dumpItem = i => {
|
|
2
|
+
let wrapper;
|
|
3
|
+
|
|
4
|
+
switch (i[0]) {
|
|
5
|
+
case 'token':
|
|
6
|
+
return `|${i[2]}`;
|
|
7
|
+
case 'scope':
|
|
8
|
+
wrapper = i[1] === 'start' ? '+' : '-';
|
|
9
|
+
return `${wrapper}${i[2]}${wrapper}`;
|
|
10
|
+
case 'graft':
|
|
11
|
+
return `>${i[1]}<`;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const dumpItems = il => il.map(bci => dumpItem(bci)).join('');
|
|
16
|
+
|
|
17
|
+
const dumpItemGroup = ig => {
|
|
18
|
+
const ret = ['ItemGroup:'];
|
|
19
|
+
ret.push(` Open Scopes ${ig[0].join(', ')}`);
|
|
20
|
+
ret.push(` ${dumpItems(ig[1])}`);
|
|
21
|
+
return ret.join('\n');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const dumpBlock = b => {
|
|
25
|
+
const ret = ['Block:'];
|
|
26
|
+
|
|
27
|
+
if (b.bg.length > 0) {
|
|
28
|
+
b.bg.forEach(bbg => ret.push(` ${bbg[1]} graft to ${bbg[2]}`));
|
|
29
|
+
}
|
|
30
|
+
ret.push(` Scope ${b.bs[2]}`);
|
|
31
|
+
ret.push(` ${dumpItems(b.c)}`);
|
|
32
|
+
return ret.join('\n');
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
dumpBlock,
|
|
37
|
+
dumpItemGroup,
|
|
38
|
+
dumpItems,
|
|
39
|
+
dumpItem,
|
|
40
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const remakeBlocks = (docSet, document, sequence, blocksSpec) => {
|
|
2
|
+
const nBlocks = sequence.blocks.length;
|
|
3
|
+
|
|
4
|
+
for (let blockN = 0; blockN < nBlocks; blockN++) {
|
|
5
|
+
document.deleteBlock(sequence.id, 0, false);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
for (let blockN = 0; blockN < blocksSpec.length; blockN++) {
|
|
9
|
+
const block = blocksSpec[blockN];
|
|
10
|
+
document.newBlock(sequence.id, blockN, block.bs.payload, null, false);
|
|
11
|
+
const bgResult = docSet.updateBlockGrafts(
|
|
12
|
+
document.id,
|
|
13
|
+
sequence.id,
|
|
14
|
+
blockN,
|
|
15
|
+
block.bg,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
if (!bgResult) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const osResult = docSet.updateOpenScopes(
|
|
23
|
+
document.id,
|
|
24
|
+
sequence.id,
|
|
25
|
+
blockN,
|
|
26
|
+
block.os,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (!osResult) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const isResult = docSet.updateIncludedScopes(
|
|
34
|
+
document.id,
|
|
35
|
+
sequence.id,
|
|
36
|
+
blockN,
|
|
37
|
+
block.is,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (!isResult) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const itemsResult = docSet.updateItems(
|
|
45
|
+
document.id,
|
|
46
|
+
sequence.id,
|
|
47
|
+
blockN,
|
|
48
|
+
block.items,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (!itemsResult) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
module.exports = { remakeBlocks };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const utils = require('../../util/index.cjs');
|
|
2
|
+
|
|
3
|
+
const exactSearchTermIndexes = (docSet, chars, allChars) => {
|
|
4
|
+
let charsIndexesArray = [
|
|
5
|
+
chars
|
|
6
|
+
.map(
|
|
7
|
+
c => [utils.enums.enumStringIndex(docSet.enums.wordLike, c)],
|
|
8
|
+
),
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
if (allChars) {
|
|
12
|
+
charsIndexesArray = charsIndexesArray[0];
|
|
13
|
+
} else {
|
|
14
|
+
charsIndexesArray = charsIndexesArray.map(ci => ci.reduce((a, b) => a.concat(b)));
|
|
15
|
+
}
|
|
16
|
+
return charsIndexesArray;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const regexSearchTermIndexes = (docSet, chars, allChars) => {
|
|
20
|
+
let charsIndexesArray = [
|
|
21
|
+
chars
|
|
22
|
+
.map(
|
|
23
|
+
c =>
|
|
24
|
+
utils.enums.enumRegexIndexTuples(docSet.enums.wordLike, c)
|
|
25
|
+
.map(tup => tup[0]),
|
|
26
|
+
),
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
if (allChars) {
|
|
30
|
+
charsIndexesArray = charsIndexesArray[0];
|
|
31
|
+
} else {
|
|
32
|
+
charsIndexesArray = charsIndexesArray.map(ci => ci.reduce((a, b) => a.concat(b)));
|
|
33
|
+
}
|
|
34
|
+
return charsIndexesArray;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const sequenceMatchesSearchTerms = (seq, charsIndexesArray, allChars) => {
|
|
38
|
+
if (allChars && charsIndexesArray.filter(i => i.length === 0).length > 0) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
charsIndexesArray = charsIndexesArray.filter(i => i.length > 0);
|
|
43
|
+
|
|
44
|
+
if (charsIndexesArray.length === 0) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const charsIndexes of charsIndexesArray) {
|
|
49
|
+
let found = false;
|
|
50
|
+
|
|
51
|
+
for (const charsIndex of charsIndexes) {
|
|
52
|
+
const isPresent = charsIndex >= 0 && seq.tokensPresent.get(charsIndex) > 0;
|
|
53
|
+
|
|
54
|
+
if (isPresent) {
|
|
55
|
+
found = true;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (allChars && !found) {
|
|
61
|
+
return false;
|
|
62
|
+
} else if (!allChars && found) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return allChars;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const sequenceHasChars = (docSet, seq, chars, allChars) => {
|
|
70
|
+
let charsIndexesArray = exactSearchTermIndexes(docSet, chars, allChars);
|
|
71
|
+
return sequenceMatchesSearchTerms(seq, charsIndexesArray, allChars);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const sequenceHasMatchingChars = (docSet, seq, chars, allChars) => {
|
|
75
|
+
let charsIndexesArray = regexSearchTermIndexes(docSet, chars, allChars);
|
|
76
|
+
return sequenceMatchesSearchTerms(seq, charsIndexesArray, allChars);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
sequenceHasChars,
|
|
81
|
+
sequenceHasMatchingChars,
|
|
82
|
+
regexSearchTermIndexes,
|
|
83
|
+
exactSearchTermIndexes,
|
|
84
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const utils = require('../../util/index.cjs');
|
|
2
|
+
|
|
3
|
+
const ptCompare = (a, b) => {
|
|
4
|
+
const bcA = a.headers.bookCode || 'GEN';
|
|
5
|
+
const bcB = b.headers.bookCode || 'GEN';
|
|
6
|
+
const posA = utils.canons.ptBooks[bcA] ? utils.canons.ptBooks[bcA].position : 999;
|
|
7
|
+
const posB = utils.canons.ptBooks[bcB] ? utils.canons.ptBooks[bcB].position : 999;
|
|
8
|
+
return posA - posB;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const alphaCompare = (a, b) => {
|
|
12
|
+
const bcA = a.headers.bookCode || 'GEN';
|
|
13
|
+
const bcB = b.headers.bookCode || 'GEN';
|
|
14
|
+
return bcA.localeCompare(bcB);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const alpha2Compare = (a, b) => {
|
|
18
|
+
const digits = [1, 2, 3, 4, 5, 6];
|
|
19
|
+
let bcA = a.headers.bookCode || 'GEN';
|
|
20
|
+
|
|
21
|
+
if (digits.includes(bcA[0])) {
|
|
22
|
+
bcA = bcA.substring(1) + bcA[0];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let bcB = b.headers.bookCode || 'GEN';
|
|
26
|
+
|
|
27
|
+
if (digits.includes(bcB[0])) {
|
|
28
|
+
bcB = bcB.substring(1) + bcB[0];
|
|
29
|
+
}
|
|
30
|
+
return bcA.localeCompare(bcB);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const bookCodeCompareFunctions = {
|
|
34
|
+
paratext: ptCompare,
|
|
35
|
+
alpha: alphaCompare,
|
|
36
|
+
alpha2: alpha2Compare,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
module.exports = { bookCodeCompareFunctions };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const xre = require('xregexp');
|
|
2
|
+
|
|
3
|
+
const { expressions, doPredicate } = require('./tribos_expression.cjs');
|
|
4
|
+
const { stepActions } = require('./tribos_step.cjs');
|
|
5
|
+
|
|
6
|
+
class Tribos {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.currentStepType = null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
doStep(docSet, allNodes, nodeLookup, result, queryStep) {
|
|
12
|
+
for (const stepAction of stepActions) {
|
|
13
|
+
const matches = xre.exec(queryStep, stepAction.regex);
|
|
14
|
+
|
|
15
|
+
if (matches && stepAction.inputType === this.currentStepType) {
|
|
16
|
+
let ret = stepAction.function(docSet, allNodes, nodeLookup, result, queryStep, matches);
|
|
17
|
+
|
|
18
|
+
if (matches[stepAction.predicateCapture]) {
|
|
19
|
+
ret = doPredicate(docSet, ret, matches[stepAction.predicateCapture]);
|
|
20
|
+
}
|
|
21
|
+
this.currentStepType = stepAction.outputType;
|
|
22
|
+
return ret;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { errors: `Unable to match step ${queryStep}` };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
parse1(docSet, allNodes, nodeLookup, result, queryArray) {
|
|
29
|
+
if (queryArray.length > 0) {
|
|
30
|
+
const stepResult = this.doStep(docSet, allNodes, nodeLookup, result, queryArray[0]);
|
|
31
|
+
|
|
32
|
+
if (stepResult.errors || stepResult.data.length === 0) {
|
|
33
|
+
return stepResult;
|
|
34
|
+
} else {
|
|
35
|
+
return this.parse1(docSet, allNodes, nodeLookup, stepResult, queryArray.slice(1));
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
queryArray(qs) {
|
|
43
|
+
const ret = [];
|
|
44
|
+
|
|
45
|
+
for (const s of qs.split('/')) {
|
|
46
|
+
ret.push(s);
|
|
47
|
+
}
|
|
48
|
+
return ret;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
indexNodes(docSet, nodes) {
|
|
52
|
+
const ret = new Map();
|
|
53
|
+
|
|
54
|
+
for (const [n, node] of nodes.entries()) {
|
|
55
|
+
const nodeId = docSet.unsuccinctifyScopes(node.bs)[0][2].split('/')[1];
|
|
56
|
+
ret.set(nodeId, n);
|
|
57
|
+
}
|
|
58
|
+
return ret;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
doc() {
|
|
62
|
+
return '** Steps **\n\n' +
|
|
63
|
+
stepActions
|
|
64
|
+
.map(sa => sa.doc)
|
|
65
|
+
.map(d => `* ${d.title} *\n${d.syntax}\n${d.description}`)
|
|
66
|
+
.join('\n\n') +
|
|
67
|
+
'** Predicate Operators **\n\n' +
|
|
68
|
+
Object.values(expressions)
|
|
69
|
+
.filter(e => e.doc)
|
|
70
|
+
.map(e => `${e.doc.operator}(${e.doc.args.map(a => '<' + a + '>').join(', ')}) => ${e.doc.result}\n${e.doc.description}`)
|
|
71
|
+
.join('\n\n');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
parse(docSet, nodes, queryString) {
|
|
75
|
+
// console.log(`\n===> ${queryString}\n`);
|
|
76
|
+
const result = this.parse1(
|
|
77
|
+
docSet,
|
|
78
|
+
nodes,
|
|
79
|
+
this.indexNodes(docSet, nodes),
|
|
80
|
+
{ data: nodes },
|
|
81
|
+
this.queryArray(queryString),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (result.data) {
|
|
85
|
+
switch (this.currentStepType) {
|
|
86
|
+
case 'nodes':
|
|
87
|
+
result.data = result.data.map(n => ({ id: docSet.unsuccinctifyScopes(n.bs)[0][2].split('/')[1] }));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const ret = JSON.stringify(result, null, 2);
|
|
92
|
+
// console.log(`${ret}\n`);
|
|
93
|
+
return ret;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = Tribos;
|