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.
Files changed (136) hide show
  1. package/.eslintrc.json +79 -0
  2. package/.gitattributes +2 -0
  3. package/docs/_config.yml +1 -0
  4. package/docs/index.md +3 -0
  5. package/docs/pk_edit_0_9.odt +0 -0
  6. package/docs/pk_edit_0_9.pdf +0 -0
  7. package/docs/proskomma_101_slideshow.odp +0 -0
  8. package/docs/proskomma_101_slideshow.pdf +0 -0
  9. package/docs/proskomma_edit_html.png +0 -0
  10. package/docs/proskomma_edit_html.svg +451 -0
  11. package/docs/proskomma_edit_reference.png +0 -0
  12. package/docs/proskomma_edit_reference.svg +349 -0
  13. package/docs/repo_logo.png +0 -0
  14. package/esm/package.json +3 -0
  15. package/esm/wrapper.mjs +5 -0
  16. package/index.cjs +6 -0
  17. package/package.json +18 -15
  18. package/src/graph/index.cjs +201 -0
  19. package/src/graph/lib/do_cv.cjs +249 -0
  20. package/src/graph/lib/dump.cjs +40 -0
  21. package/src/graph/lib/remake_blocks.cjs +57 -0
  22. package/src/graph/lib/sequence_chars.cjs +84 -0
  23. package/src/graph/lib/sort.cjs +39 -0
  24. package/src/graph/lib/tribos.cjs +97 -0
  25. package/src/graph/lib/tribos_expression.cjs +556 -0
  26. package/src/graph/lib/tribos_ohm_UNUSED.cjs +37 -0
  27. package/src/graph/lib/tribos_step.cjs +434 -0
  28. package/src/graph/mutations/add.cjs +91 -0
  29. package/src/graph/mutations/delete.cjs +61 -0
  30. package/src/graph/mutations/index.cjs +54 -0
  31. package/src/graph/mutations/rehash.cjs +17 -0
  32. package/src/graph/mutations/tags.cjs +120 -0
  33. package/src/graph/mutations/update.cjs +210 -0
  34. package/src/graph/mutations/versification.cjs +96 -0
  35. package/src/graph/queries/block.cjs +228 -0
  36. package/src/graph/queries/cIndex.cjs +87 -0
  37. package/src/graph/queries/cell.cjs +42 -0
  38. package/src/graph/queries/cv.cjs +19 -0
  39. package/src/graph/queries/cvBook.cjs +16 -0
  40. package/src/graph/queries/cvChapter.cjs +16 -0
  41. package/src/graph/queries/cvIndex.cjs +47 -0
  42. package/src/graph/queries/cvNavigation.cjs +116 -0
  43. package/src/graph/queries/cvVerseElement.cjs +84 -0
  44. package/src/graph/queries/cvVerses.cjs +14 -0
  45. package/src/graph/queries/doc_set.cjs +220 -0
  46. package/src/graph/queries/document.cjs +555 -0
  47. package/src/graph/queries/idParts.cjs +30 -0
  48. package/src/graph/queries/index.cjs +151 -0
  49. package/src/graph/queries/inputBlockSpec.cjs +17 -0
  50. package/src/graph/queries/inputItemObject.cjs +12 -0
  51. package/src/graph/queries/input_att_spec.cjs +14 -0
  52. package/src/graph/queries/input_key_matches.cjs +11 -0
  53. package/src/graph/queries/input_key_value.cjs +11 -0
  54. package/src/graph/queries/input_key_values.cjs +11 -0
  55. package/src/graph/queries/input_selector_spec.cjs +19 -0
  56. package/src/graph/queries/item.cjs +71 -0
  57. package/src/graph/queries/itemGroup.cjs +75 -0
  58. package/src/graph/queries/key_value.cjs +18 -0
  59. package/src/graph/queries/kv_entry.cjs +21 -0
  60. package/src/graph/queries/kv_sequence.cjs +151 -0
  61. package/src/graph/queries/node.cjs +44 -0
  62. package/src/graph/queries/orig.cjs +11 -0
  63. package/src/graph/queries/regex_index.cjs +18 -0
  64. package/src/graph/queries/row_equals_spec.cjs +11 -0
  65. package/src/graph/queries/row_match_spec.cjs +11 -0
  66. package/src/graph/queries/selector_spec.cjs +29 -0
  67. package/src/graph/queries/sequence.cjs +314 -0
  68. package/src/graph/queries/table_sequence.cjs +192 -0
  69. package/src/graph/queries/tree_sequence.cjs +58 -0
  70. package/src/graph/queries/verseNumber.cjs +44 -0
  71. package/src/graph/queries/verseRange.cjs +11 -0
  72. package/src/graph/queries/versification.cjs +25 -0
  73. package/src/index.cjs +583 -0
  74. package/src/model/doc_set.cjs +389 -0
  75. package/src/model/doc_set_helpers/block.cjs +232 -0
  76. package/src/model/doc_set_helpers/enum.cjs +87 -0
  77. package/src/model/doc_set_helpers/item.cjs +198 -0
  78. package/src/model/doc_set_helpers/rehash.cjs +53 -0
  79. package/src/model/doc_set_helpers/selectors.cjs +58 -0
  80. package/src/model/doc_set_helpers/serialize.cjs +22 -0
  81. package/src/model/doc_set_helpers/unsuccinctify.cjs +288 -0
  82. package/src/model/doc_set_helpers/update.cjs +290 -0
  83. package/src/model/document.cjs +369 -0
  84. package/src/model/document_helpers/blocks.cjs +135 -0
  85. package/src/model/document_helpers/chapter_verse.cjs +291 -0
  86. package/src/model/document_helpers/pre_enums.cjs +67 -0
  87. package/src/model/document_helpers/sequences.cjs +205 -0
  88. package/src/model/document_helpers/serialize_succinct.cjs +55 -0
  89. package/src/model/document_helpers/succinct_filter.cjs +102 -0
  90. package/src/model/versifications/eng_vrs.cjs +455 -0
  91. package/src/model/versifications/index.cjs +38 -0
  92. package/src/model/versifications/lxx_vrs.cjs +950 -0
  93. package/src/model/versifications/org_vrs.cjs +155 -0
  94. package/src/model/versifications/rsc_vrs.cjs +342 -0
  95. package/src/model/versifications/rso_vrs.cjs +541 -0
  96. package/src/model/versifications/vul_vrs.cjs +835 -0
  97. package/src/parser/index.cjs +506 -0
  98. package/src/parser/lexers/index.cjs +11 -0
  99. package/src/parser/lexers/lexingRegexes.cjs +45 -0
  100. package/src/parser/lexers/nodes.cjs +123 -0
  101. package/src/parser/lexers/object_for_fragment.cjs +123 -0
  102. package/src/parser/lexers/tsv.cjs +45 -0
  103. package/src/parser/lexers/usfm.cjs +17 -0
  104. package/src/parser/lexers/usx/index.cjs +7 -0
  105. package/src/parser/lexers/usx/usx_lexer.cjs +321 -0
  106. package/src/parser/lib/tokenize.cjs +37 -0
  107. package/src/parser/model/index.cjs +637 -0
  108. package/src/parser/parser_specs.cjs +781 -0
  109. package/src/pipelines/perf2x/index.cjs +7 -0
  110. package/src/pipelines/perf2x/perf2PkJsonPipeline.json +41 -0
  111. package/src/pipelines/perf2x/perf2usfmPipeline.json +65 -0
  112. package/src/transforms/calculateUsfmChapterPositions.cjs +106 -0
  113. package/src/transforms/index.cjs +9 -0
  114. package/src/transforms/perf2PkJson.cjs +534 -0
  115. package/src/transforms/perf2usfm.cjs +294 -0
  116. package/src/util/byteArray.cjs +251 -0
  117. package/src/util/canons.cjs +117 -0
  118. package/src/util/enums.cjs +41 -0
  119. package/src/util/generateId.cjs +6 -0
  120. package/src/util/graftDefs.cjs +15 -0
  121. package/src/util/index.cjs +29 -0
  122. package/src/util/inspectSuccinct.cjs +59 -0
  123. package/src/util/itemDefs.cjs +33 -0
  124. package/src/util/parserConstantDefs.cjs +30 -0
  125. package/src/util/scopeDefs.cjs +173 -0
  126. package/src/util/scriptlike/blocksSpec.cjs +192 -0
  127. package/src/util/scriptlike/dodson_lexicon.xsl +19 -0
  128. package/src/util/scriptlike/dodson_lexicon_to_entries.cjs +85 -0
  129. package/src/util/scriptlike/open_scriptures_hebrew_lexicon.xsl +28 -0
  130. package/src/util/scriptlike/open_scriptures_hebrew_lexicon_to_entries.cjs +85 -0
  131. package/src/util/succinct.cjs +159 -0
  132. package/src/util/tags.cjs +28 -0
  133. package/src/util/tokenDefs.cjs +27 -0
  134. package/src/util/versification.cjs +364 -0
  135. package/dist/index.js +0 -8
  136. package/dist/index.js.LICENSE.txt +0 -23
@@ -0,0 +1,434 @@
1
+ const xre = require('xregexp');
2
+
3
+ const predicateRegex = '(\\[(([^\\]\']|\'([^\']|\\\\\')*\')+)\\])*';
4
+
5
+ // Nodes with one of the listed ids
6
+ const doAbsoluteIdStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
7
+ const values = matches[1].split(',').map(v => v.trim());
8
+ return { data: Array.from(values).map(nid => allNodes[nodeLookup.get(nid)]) };
9
+ };
10
+
11
+ // The root Node
12
+ const doAbsoluteRootStep = (docSet, allNodes) => ({ data: [allNodes[0]] });
13
+
14
+ // All the nodes
15
+ const doAbsoluteNodesStep = (docSet, allNodes) => ({ data: allNodes });
16
+
17
+ // Children of the nodes
18
+ const doChildrenStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
19
+ const childNo = matches[2];
20
+ const childNodeIds = new Set([]);
21
+
22
+ for (const parentNode of result.data) {
23
+ const children = docSet.unsuccinctifyScopes(parentNode.is)
24
+ .map(s => s[2].split('/'))
25
+ .filter(s => s[0] === 'tTreeChild')
26
+ .filter(s => !childNo || s[1] === childNo)
27
+ .map(s => s[2]);
28
+
29
+ for (const child of children) {
30
+ childNodeIds.add(child);
31
+ }
32
+ }
33
+ return { data: Array.from(childNodeIds).map(nid => allNodes[nodeLookup.get(nid)]) };
34
+ };
35
+
36
+ // The parent of each node
37
+ const doParentStep = (docSet, allNodes, nodeLookup, result) => {
38
+ const parentNodeIds = new Set([]);
39
+
40
+ for (const childNode of result.data) {
41
+ const parentId = docSet.unsuccinctifyScopes(childNode.is)
42
+ .filter(s => s[2].startsWith('tTreeParent'))
43
+ .map(s => s[2].split('/')[1])[0];
44
+ parentNodeIds.add(parentId);
45
+ }
46
+ return { data: Array.from(parentNodeIds).map(nid => allNodes[nodeLookup.get(nid)]) };
47
+ };
48
+
49
+ // The nth ancestor of each node (where 1 === parent)
50
+ const doAncestorStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
51
+ let ancestorNo = parseInt(matches[2]);
52
+
53
+ if (ancestorNo < 1) {
54
+ return { errors: `Expected a positive integer argument for ancestor, found ${queryStep}` };
55
+ }
56
+
57
+ let nodes = result.data;
58
+
59
+ while (ancestorNo > 0) {
60
+ const parentNodeIds = new Set([]);
61
+
62
+ for (const childNode of nodes) {
63
+ const parentId = docSet.unsuccinctifyScopes(childNode.is)
64
+ .filter(s => s[2].startsWith('tTreeParent'))
65
+ .map(s => s[2].split('/')[1])[0];
66
+ parentNodeIds.add(parentId);
67
+ }
68
+ nodes = Array.from(parentNodeIds).map(nid => allNodes[nodeLookup.get(nid)]);
69
+ ancestorNo--;
70
+ }
71
+ return { data: nodes };
72
+ };
73
+
74
+ // The nth-generation descendants of each node (where 1 === child)
75
+ const doDescendantsStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
76
+ const descendantIds = new Set([]);
77
+
78
+ const getDescendants = (node, depth) => {
79
+ const childIds = docSet.unsuccinctifyScopes(node.is)
80
+ .filter(s => s[2].startsWith('tTreeChild'))
81
+ .map(s => s[2].split('/')[2]);
82
+
83
+ if (depth <= 1 || depth === null) {
84
+ childIds.forEach(n => descendantIds.add(n));
85
+ }
86
+
87
+ if (depth === null || depth > 1) {
88
+ childIds.map(nid => allNodes[nodeLookup.get(nid)]).forEach(n => getDescendants(n, depth - 1));
89
+ }
90
+ };
91
+
92
+ let descendantGen = null;
93
+
94
+ if (matches[3]) {
95
+ descendantGen = parseInt(matches[3]);
96
+ }
97
+
98
+ let descendantNo = -1;
99
+
100
+ if (matches[5]) {
101
+ descendantNo = parseInt(matches[5]);
102
+ }
103
+
104
+ for (const node of result.data) {
105
+ getDescendants(node, descendantGen);
106
+ }
107
+ return {
108
+ data: [...Array.from(descendantIds).entries()]
109
+ .filter(n => descendantNo < 0 || n[0] === descendantNo)
110
+ .map(n => n[1])
111
+ .map(nid => allNodes[nodeLookup.get(nid)]),
112
+ };
113
+ };
114
+
115
+ // The leaves of each node
116
+ const doLeavesStep = (docSet, allNodes, nodeLookup, result) => {
117
+ const leafIds = new Set([]);
118
+
119
+ const getLeaves = node => {
120
+ const childIds = docSet.unsuccinctifyScopes(node.is)
121
+ .filter(s => s[2].startsWith('tTreeChild'))
122
+ .map(s => s[2].split('/')[2]);
123
+
124
+ if (childIds.length === 0) {
125
+ leafIds.add(docSet.unsuccinctifyScopes(node.bs)[0][2].split('/')[1]);
126
+ } else {
127
+ childIds.map(nid => allNodes[nodeLookup.get(nid)]).forEach(n => getLeaves(n));
128
+ }
129
+ };
130
+
131
+ for (const node of result.data) {
132
+ getLeaves(node);
133
+ }
134
+ return { data: Array.from(leafIds).map(nid => allNodes[nodeLookup.get(nid)]) };
135
+ };
136
+
137
+ // The children of the parent of each node
138
+ // - get parent of starting node
139
+ // - get children of parent node
140
+ const doSiblingsStep = (docSet, allNodes, nodeLookup, result) => {
141
+ const parentNodeIds = new Set([]);
142
+
143
+ for (const childNode of result.data) {
144
+ const parentId = docSet.unsuccinctifyScopes(childNode.is)
145
+ .filter(s => s[2].startsWith('tTreeParent'))
146
+ .map(s => s[2].split('/')[1])[0];
147
+ parentNodeIds.add(parentId);
148
+ }
149
+
150
+ const parentNodes = allNodes.filter(n => parentNodeIds.has(docSet.unsuccinctifyScopes(n.bs)[0][2].split('/')[1]));
151
+ const childNodeIds = new Set([]);
152
+
153
+ for (const parentNode of parentNodes) {
154
+ const children = docSet.unsuccinctifyScopes(parentNode.is)
155
+ .filter(s => s[2].startsWith('tTreeChild'))
156
+ .map(s => s[2].split('/')[2]);
157
+
158
+ for (const child of children) {
159
+ childNodeIds.add(child);
160
+ }
161
+ }
162
+ // return { data: allNodes.filter(n => childNodeIds.has(docSet.unsuccinctifyScopes(n.bs)[0][2].split('/')[1])) };
163
+ return { data: Array.from(childNodeIds).map(nid => allNodes[nodeLookup.get(nid)]) };
164
+ };
165
+
166
+ const nodeDetails = (docSet, node, allNodes, nodeLookup, fields, isBranch) => {
167
+ const record = {};
168
+
169
+ if (fields.size === 0 || fields.has('id')) {
170
+ record.id = docSet.unsuccinctifyScopes(node.bs)[0][2].split('/')[1];
171
+ }
172
+
173
+ if (fields.size === 0 || fields.has('parentId')) {
174
+ record.parentId = docSet.unsuccinctifyScopes(node.is)
175
+ .filter(s => s[2].startsWith('tTreeParent'))
176
+ .map(s => s[2].split('/')[1])[0];
177
+ }
178
+
179
+ const content = {};
180
+
181
+ for (const [scopeLabels, items] of docSet.sequenceItemsByScopes([node], ['tTreeContent/'], false)) {
182
+ const key = scopeLabels.filter(s => s.startsWith('tTreeContent'))[0].split('/')[1];
183
+
184
+ if (fields.size === 0 || fields.has('content') || fields.has(`@${key}`)) {
185
+ content[key] = items.filter(i => i[0] === 'token').map(t => t[2]).join('');
186
+ }
187
+ }
188
+
189
+ if (Object.keys(content).length > 0) {
190
+ record.content = content;
191
+ }
192
+
193
+ const children = [];
194
+
195
+ if (fields.has('children')) {
196
+ for (const childScope of docSet.unsuccinctifyScopes(node.is)
197
+ .filter(s => s[2].startsWith('tTreeChild'))
198
+ .map(s => s[2].split('/')[2])) {
199
+ children.push(childScope);
200
+ }
201
+ }
202
+
203
+ if (children.length > 0) {
204
+ if (isBranch) {
205
+ record.children = children
206
+ .map(nid => allNodes[nodeLookup.get(nid)])
207
+ .map(n => nodeDetails(docSet, n, allNodes, nodeLookup, fields, true));
208
+ } else {
209
+ record.children = children;
210
+ }
211
+ }
212
+ return record;
213
+ };
214
+
215
+
216
+ // The node details included children
217
+ // optional fields are id, parentId, content, @<contentName>, children
218
+ const doBranchStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
219
+ const ret = [];
220
+ let fields = new Set([]);
221
+
222
+ if (matches[2]) {
223
+ fields = new Set(
224
+ matches[2]
225
+ .split(',')
226
+ .map(f => f.trim()),
227
+ );
228
+ }
229
+
230
+ for (const node of result.data) {
231
+ ret.push(nodeDetails(docSet, node, allNodes, nodeLookup, fields, true));
232
+ }
233
+ return { data: ret };
234
+ };
235
+
236
+ // All values across nodes for the specified content fields
237
+ const doValuesStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
238
+ const nodeFields = [];
239
+ let fields = new Set([]);
240
+
241
+ if (matches[2]) {
242
+ fields = new Set(
243
+ matches[2]
244
+ .split(',')
245
+ .map(f => f.trim())
246
+ .filter(f => f.startsWith('@')),
247
+ );
248
+ }
249
+
250
+ for (const node of result.data) {
251
+ nodeFields.push(nodeDetails(docSet, node, allNodes, nodeLookup, fields, true));
252
+ }
253
+
254
+ const values = {};
255
+
256
+ for (const field of Array.from(fields).map(f => f.substring(1))) {
257
+ values[field] = Array.from(
258
+ new Set(
259
+ nodeFields
260
+ .filter(nd => nd.content)
261
+ .map(nd => nd.content)
262
+ .filter(nd => field in nd)
263
+ .map(nd => nd[field])
264
+ .sort(),
265
+ ),
266
+ );
267
+ }
268
+ return { data: values };
269
+ };
270
+
271
+ // The node details
272
+ // optional fields are id, parentId, content, @<contentName>, children
273
+ const doNodeStep = (docSet, allNodes, nodeLookup, result, queryStep, matches) => {
274
+ const ret = [];
275
+ let fields = new Set([]);
276
+
277
+ if (matches[2]) {
278
+ fields = new Set(matches[2].split(',').map(f => f.trim()));
279
+ }
280
+
281
+ for (const node of result.data) {
282
+ ret.push(nodeDetails(docSet, node, allNodes, nodeLookup, fields, false));
283
+ }
284
+ return { data: ret };
285
+ };
286
+
287
+ const stepActions = [
288
+ {
289
+ regex: xre(`^#\\{([^}]+)\\}${predicateRegex}$`),
290
+ doc: {
291
+ title: 'Nodes by Id',
292
+ syntax: '#(id, id, ...)',
293
+ description: 'Returns nodes whose id is listed',
294
+ },
295
+ predicateCapture: 3,
296
+ inputType: null,
297
+ outputType: 'nodes',
298
+ function: doAbsoluteIdStep,
299
+ },
300
+ {
301
+ regex: xre(`^root${predicateRegex}$`),
302
+ doc: {
303
+ title: 'Root Node',
304
+ syntax: 'root',
305
+ description: 'Returns the root node',
306
+ },
307
+ predicateCapture: 2,
308
+ inputType: null,
309
+ outputType: 'nodes',
310
+ function: doAbsoluteRootStep,
311
+ },
312
+ {
313
+ regex: xre(`^nodes${predicateRegex}$`),
314
+ doc: {
315
+ title: 'Nodes',
316
+ syntax: 'nodes',
317
+ description: 'Returns all the nodes',
318
+ },
319
+ predicateCapture: 2,
320
+ function: doAbsoluteNodesStep,
321
+ inputType: null,
322
+ outputType: 'nodes',
323
+ },
324
+ {
325
+ regex: xre(`^children(\\((\\d+)\\))?${predicateRegex}$`),
326
+ doc: {
327
+ title: 'Children',
328
+ syntax: 'children; children(pos)',
329
+ description: 'Returns the children of the current node(s), optionally filtered by position within the parent node',
330
+ },
331
+ predicateCapture: 4,
332
+ inputType: 'nodes',
333
+ outputType: 'nodes',
334
+ function: doChildrenStep,
335
+ },
336
+ {
337
+ regex: xre(`^descendants((\\((\\d+)(,\\s*(\\d+))?\\))?)${predicateRegex}$`),
338
+ doc: {
339
+ title: 'Descendants',
340
+ syntax: 'descendants; descendants(depth); descendants(depth, pos)',
341
+ description: 'Returns the descendants of the current node(s), optionally at the specified level, optionally filtered by position',
342
+ },
343
+ predicateCapture: 7,
344
+ inputType: 'nodes',
345
+ outputType: 'nodes',
346
+ function: doDescendantsStep,
347
+ },
348
+ {
349
+ regex: xre(`^leaves${predicateRegex}$`),
350
+ doc: {
351
+ title: 'Leaves',
352
+ syntax: 'leaves',
353
+ description: 'Returns the leaves (ie the nodes with no children) below the current node',
354
+ },
355
+ predicateCapture: 2,
356
+ inputType: 'nodes',
357
+ outputType: 'nodes',
358
+ function: doLeavesStep,
359
+ },
360
+ {
361
+ regex: xre(`^parent${predicateRegex}$`),
362
+ doc: {
363
+ title: 'Parent',
364
+ syntax: 'parent',
365
+ description: 'Returns the parent of the current node',
366
+ },
367
+ predicateCapture: 2,
368
+ inputType: 'nodes',
369
+ outputType: 'nodes',
370
+ function: doParentStep,
371
+ },
372
+ {
373
+ regex: xre(`^ancestor(\\((\\d+)\\))${predicateRegex}$`),
374
+ doc: {
375
+ title: 'Ancestor',
376
+ syntax: 'ancestor(depth)',
377
+ description: 'Returns the nth ancestor of the node',
378
+ },
379
+ predicateCapture: 5,
380
+ inputType: 'nodes',
381
+ outputType: 'nodes',
382
+ function: doAncestorStep,
383
+ },
384
+ {
385
+ regex: xre(`^siblings${predicateRegex}$`),
386
+ doc: {
387
+ title: 'Siblings',
388
+ syntax: 'siblings',
389
+ description: 'Returns the children of the parent of the current node',
390
+ },
391
+ predicateCapture: 2,
392
+ inputType: 'nodes',
393
+ outputType: 'nodes',
394
+ function: doSiblingsStep,
395
+ },
396
+ {
397
+ regex: xre(`^node(\\{([^}]+)\\})?${predicateRegex}$`),
398
+ doc: {
399
+ title: 'Node Details',
400
+ syntax: 'node; node{ id, parentId, content, children, @foo }',
401
+ description: 'Returns an object containing the specified content',
402
+ },
403
+ predicateCapture: 4,
404
+ inputType: 'nodes',
405
+ outputType: 'node',
406
+ function: doNodeStep,
407
+ },
408
+ {
409
+ regex: xre(`^branch(\\{([^}]+)\\})?${predicateRegex}$`),
410
+ doc: {
411
+ title: 'Branch',
412
+ syntax: 'branch; branch{ id, parentId, content, children, @foo }',
413
+ description: 'Returns nested objects containing the specified content',
414
+ },
415
+ predicateCapture: 4,
416
+ inputType: 'nodes',
417
+ outputType: 'node',
418
+ function: doBranchStep,
419
+ },
420
+ {
421
+ regex: xre(`^values(\\{([^}]+)\\})?${predicateRegex}$`),
422
+ doc: {
423
+ title: 'Values',
424
+ syntax: 'values{ @foo ... }',
425
+ description: 'Returns all values across nodes for the specified fields',
426
+ },
427
+ predicateCapture: 4,
428
+ inputType: 'nodes',
429
+ outputType: 'values',
430
+ function: doValuesStep,
431
+ },
432
+ ];
433
+
434
+ module.exports = { stepActions };
@@ -0,0 +1,91 @@
1
+ const utils = require('../../util/index.cjs');
2
+ const { remakeBlocks } = require('../lib/remake_blocks.cjs');
3
+
4
+ const addMutationsSchemaString = `
5
+ """Adds a document which will be assigned to an existing or new docSet on the basis of the specified selectors"""
6
+ addDocument(
7
+ """The selectors for this document, the keys of which must match those of the Proskomma instance"""
8
+ selectors: [InputKeyValue!]!
9
+ """The format of the content (probably usfm or usx)"""
10
+ contentType: String!
11
+ """The document content as a string"""
12
+ content: String!
13
+ """A list of tags to be added"""
14
+ tags: [String!]
15
+ ): Boolean!
16
+ """Creates a new, empty sequence"""
17
+ newSequence(
18
+ """The id of the document to which the sequence will be added"""
19
+ documentId: String!
20
+ """The type of the new sequence (main, heading...)"""
21
+ type: String!
22
+ """The JSON describing blocks, if any, for the new sequence"""
23
+ blocksSpec: [inputBlockSpec!]
24
+ """If true, graft to the first block of the main sequence"""
25
+ graftToMain: Boolean
26
+ """'A list of tags to be added"""
27
+ tags: [String!]
28
+ ): String!
29
+ """Adds a new block to a sequence"""
30
+ newBlock(
31
+ """The id of the document containing the sequence to which the block will be added"""
32
+ documentId: String!
33
+ """The id of the sequence to which the block will be added"""
34
+ sequenceId: String!
35
+ """The zero-indexed position at which to add the block"""
36
+ blockN: Int!
37
+ """The scope to be applied to the block, eg blockScope/p"""
38
+ blockScope: String!
39
+ ): Boolean!
40
+ `;
41
+
42
+ const addMutationsResolvers = {
43
+ addDocument: (root, args) => {
44
+ const selectorsObject = {};
45
+
46
+ args.selectors.forEach(
47
+ s => {
48
+ selectorsObject[s.key] = s.value;
49
+ },
50
+ );
51
+ return !!root.importDocument(selectorsObject, args.contentType, args.content, null, null, null, args.tags || []);
52
+ },
53
+ newSequence: (root, args) => {
54
+ const document = root.documents[args.documentId];
55
+ const docSet = document.processor.docSets[document.docSetId];
56
+
57
+ if (!document) {
58
+ throw new Error(`Document '${args.documentId}' not found`);
59
+ }
60
+
61
+ const newSeqId = document.newSequence(args.type, args.tags);
62
+
63
+ if (args.blocksSpec) {
64
+ remakeBlocks(docSet, document, document.sequences[newSeqId], args.blocksSpec);
65
+ document.buildChapterVerseIndex();
66
+ }
67
+
68
+ if (args.graftToMain) {
69
+ docSet.maybeBuildPreEnums();
70
+ const mainSequenceBG = document.sequences[document.mainId].blocks[0].bg;
71
+ const graftTypeEnumIndex = docSet.enumForCategoryValue('graftTypes', args.type, true);
72
+ const seqEnumIndex = docSet.enumForCategoryValue('ids', newSeqId, true);
73
+ utils.succinct.pushSuccinctGraftBytes(mainSequenceBG, graftTypeEnumIndex, seqEnumIndex);
74
+ }
75
+ return newSeqId;
76
+ },
77
+ newBlock: (root, args) => {
78
+ const document = root.documents[args.documentId];
79
+
80
+ if (!document) {
81
+ throw new Error(`Document '${args.documentId}' not found`);
82
+ }
83
+
84
+ return document.newBlock(args.sequenceId, args.blockN, args.blockScope);
85
+ },
86
+ };
87
+
88
+ module.exports = {
89
+ addMutationsSchemaString,
90
+ addMutationsResolvers,
91
+ };
@@ -0,0 +1,61 @@
1
+ const deleteMutationsSchemaString = `
2
+ """Deletes a docSet"""
3
+ deleteDocSet(
4
+ """The id of the docSet containing the document to be deleted"""
5
+ docSetId: String!
6
+ ): Boolean
7
+ """Deletes a document"""
8
+ deleteDocument(
9
+ """The id of the docSet containing the document to be deleted"""
10
+ docSetId: String!
11
+ """The id of the document to be deleted"""
12
+ documentId: String!
13
+ ): Boolean
14
+ """Deletes a sequence from a document"""
15
+ deleteSequence(
16
+ """The id of the document containing the sequence to be deleted"""
17
+ documentId: String!
18
+ """The id of the sequence to be deleted"""
19
+ sequenceId: String!
20
+ ): Boolean
21
+ """Deletes a block from a sequence"""
22
+ deleteBlock(
23
+ """The id of the document containing the sequence from which the block will be deleted"""
24
+ documentId: String!
25
+ """The id of the sequence from which the block will be deleted"""
26
+ sequenceId: String!
27
+ """The zero-indexed number of the block to be deleted"""
28
+ blockN: Int!
29
+ ): Boolean
30
+ `;
31
+
32
+ const deleteMutationsResolvers = {
33
+ deleteDocSet: (root, args) =>
34
+ root.deleteDocSet(args.docSetId),
35
+ deleteDocument: (root, args) =>
36
+ root.deleteDocument(args.docSetId, args.documentId),
37
+ deleteSequence: (root, args) => {
38
+ const document = root.documents[args.documentId];
39
+
40
+ if (!document) {
41
+ throw new Error(`Document '${args.documentId}' not found`);
42
+ }
43
+
44
+ return document.deleteSequence(args.sequenceId);
45
+ },
46
+ deleteBlock: (root, args) => {
47
+ const document = root.documents[args.documentId];
48
+
49
+ if (!document) {
50
+ throw new Error(`Document '${args.documentId}' not found`);
51
+ }
52
+
53
+ return document.deleteBlock(args.sequenceId, args.blockN);
54
+ },
55
+ };
56
+
57
+
58
+ module.exports = {
59
+ deleteMutationsSchemaString,
60
+ deleteMutationsResolvers,
61
+ };
@@ -0,0 +1,54 @@
1
+ const {
2
+ addMutationsSchemaString,
3
+ addMutationsResolvers,
4
+ } = require('./add.cjs');
5
+
6
+ const {
7
+ deleteMutationsSchemaString,
8
+ deleteMutationsResolvers,
9
+ } = require('./delete.cjs');
10
+
11
+ const {
12
+ rehashMutationsSchemaString,
13
+ rehashMutationsResolvers,
14
+ } = require('./rehash.cjs');
15
+
16
+ const {
17
+ tagMutationsSchemaString,
18
+ tagMutationsResolvers,
19
+ } = require('./tags.cjs');
20
+
21
+ const {
22
+ updateMutationsSchemaString,
23
+ updateMutationsResolvers,
24
+ } = require('./update.cjs');
25
+
26
+ const {
27
+ versificationMutationsSchemaString,
28
+ versificationMutationsResolvers,
29
+ } = require('./versification.cjs');
30
+
31
+ const mutationsSchemaString = `
32
+ type Mutation {
33
+ ${addMutationsSchemaString}
34
+ ${deleteMutationsSchemaString}
35
+ ${rehashMutationsSchemaString}
36
+ ${tagMutationsSchemaString}
37
+ ${updateMutationsSchemaString}
38
+ ${versificationMutationsSchemaString}
39
+ }`;
40
+
41
+ const mutationsResolvers = {
42
+ ...addMutationsResolvers,
43
+ ...deleteMutationsResolvers,
44
+ ...rehashMutationsResolvers,
45
+ ...tagMutationsResolvers,
46
+ ...updateMutationsResolvers,
47
+ ...versificationMutationsResolvers,
48
+ };
49
+
50
+
51
+ module.exports = {
52
+ mutationsSchemaString,
53
+ mutationsResolvers,
54
+ };
@@ -0,0 +1,17 @@
1
+ const rehashMutationsSchemaString = `
2
+ """Explicitly rebuild the text lookup tables for a docSet. (You probably don't need to do this)"""
3
+ rehashDocSet(
4
+ """The id of the docSet"""
5
+ docSetId: String!
6
+ ): Boolean!
7
+ `;
8
+
9
+ const rehashMutationsResolvers = {
10
+ rehashDocSet: (root, args) =>
11
+ root.rehashDocSet(args.docSetId),
12
+ };
13
+
14
+ module.exports = {
15
+ rehashMutationsSchemaString,
16
+ rehashMutationsResolvers,
17
+ };