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,555 @@
|
|
|
1
|
+
const xre = require('xregexp');
|
|
2
|
+
|
|
3
|
+
const { do_cv } = require('../lib/do_cv.cjs');
|
|
4
|
+
|
|
5
|
+
const headerById = (root, id) =>
|
|
6
|
+
(id in root.headers) ? root.headers[id] : null;
|
|
7
|
+
|
|
8
|
+
const documentSchemaString = `
|
|
9
|
+
"""A document, typically corresponding to USFM for one book"""
|
|
10
|
+
type Document {
|
|
11
|
+
"""The id of the document"""
|
|
12
|
+
id: String!
|
|
13
|
+
"""A parsed version of the id header"""
|
|
14
|
+
idParts: idParts!
|
|
15
|
+
"""The id of the docSet to which this document belongs"""
|
|
16
|
+
docSetId: String!
|
|
17
|
+
"""USFM header information such as TOC"""
|
|
18
|
+
headers: [KeyValue!]!
|
|
19
|
+
"""One USFM header"""
|
|
20
|
+
header(
|
|
21
|
+
"""The header id, corresponding to the tag name minus any trailing '1'"""
|
|
22
|
+
id: String!
|
|
23
|
+
): String
|
|
24
|
+
"""The main sequence"""
|
|
25
|
+
mainSequence: Sequence!
|
|
26
|
+
"""The number of sequences"""
|
|
27
|
+
nSequences: Int!
|
|
28
|
+
"""A list of sequences for this document"""
|
|
29
|
+
sequences(
|
|
30
|
+
"""ids of sequences to include, if found"""
|
|
31
|
+
ids: [String!]
|
|
32
|
+
"""types of sequences to include, if found"""
|
|
33
|
+
types: [String!]
|
|
34
|
+
"""Only return sequences with all the specified tags"""
|
|
35
|
+
withTags: [String!]
|
|
36
|
+
"""Only return sequences with none of the specified tags"""
|
|
37
|
+
withoutTags: [String!]
|
|
38
|
+
): [Sequence!]!
|
|
39
|
+
"""A list of table sequences for this document"""
|
|
40
|
+
tableSequences(
|
|
41
|
+
"""ids of sequences to include, if found"""
|
|
42
|
+
ids: [String!]
|
|
43
|
+
"""Only return sequences with all the specified tags"""
|
|
44
|
+
withTags: [String!]
|
|
45
|
+
"""Only return sequences with none of the specified tags"""
|
|
46
|
+
withoutTags: [String!]
|
|
47
|
+
): [tableSequence!]!
|
|
48
|
+
"""A list of tree sequences for this document"""
|
|
49
|
+
treeSequences(
|
|
50
|
+
"""ids of sequences to include, if found"""
|
|
51
|
+
ids: [String!]
|
|
52
|
+
"""Only return sequences with all the specified tags"""
|
|
53
|
+
withTags: [String!]
|
|
54
|
+
"""Only return sequences with none of the specified tags"""
|
|
55
|
+
withoutTags: [String!]
|
|
56
|
+
): [treeSequence!]!
|
|
57
|
+
"""A list of key-value sequences for this document"""
|
|
58
|
+
kvSequences(
|
|
59
|
+
"""ids of sequences to include, if found"""
|
|
60
|
+
ids: [String!]
|
|
61
|
+
"""Only return sequences with all the specified tags"""
|
|
62
|
+
withTags: [String!]
|
|
63
|
+
"""Only return sequences with none of the specified tags"""
|
|
64
|
+
withoutTags: [String!]
|
|
65
|
+
): [kvSequence!]!
|
|
66
|
+
"""A list of text (ie non-table, non-tree, non-kv) sequences for this document"""
|
|
67
|
+
textSequences(
|
|
68
|
+
"""ids of sequences to include, if found"""
|
|
69
|
+
ids: [String!]
|
|
70
|
+
"""Only return sequences with all the specified tags"""
|
|
71
|
+
withTags: [String!]
|
|
72
|
+
"""Only return sequences with none of the specified tags"""
|
|
73
|
+
withoutTags: [String!]
|
|
74
|
+
): [Sequence!]!
|
|
75
|
+
"""The sequence with the specified id"""
|
|
76
|
+
sequence(
|
|
77
|
+
"""id of the sequence"""
|
|
78
|
+
id: String!
|
|
79
|
+
): Sequence
|
|
80
|
+
"""The table sequence with the specified id"""
|
|
81
|
+
tableSequence(
|
|
82
|
+
"""id of the sequence"""
|
|
83
|
+
id: String!
|
|
84
|
+
): tableSequence
|
|
85
|
+
"""The tree sequence with the specified id"""
|
|
86
|
+
treeSequence(
|
|
87
|
+
"""id of the sequence"""
|
|
88
|
+
id: String!
|
|
89
|
+
): treeSequence
|
|
90
|
+
"""The key-value sequence with the specified id"""
|
|
91
|
+
kvSequence(
|
|
92
|
+
"""id of the sequence"""
|
|
93
|
+
id: String!
|
|
94
|
+
): kvSequence
|
|
95
|
+
"""The blocks of the main sequence"""
|
|
96
|
+
mainBlocks: [Block!]!
|
|
97
|
+
"""The items for each block of the main sequence"""
|
|
98
|
+
mainBlocksItems: [[Item!]!]!
|
|
99
|
+
"""The tokens for each block of the main sequence"""
|
|
100
|
+
mainBlocksTokens: [[Item!]!]!
|
|
101
|
+
"""The text for each block of the main sequence"""
|
|
102
|
+
mainBlocksText(
|
|
103
|
+
"""If true, converts each whitespace character to a single space"""
|
|
104
|
+
normalizeSpace: Boolean
|
|
105
|
+
): [String!]!
|
|
106
|
+
"""The text for the main sequence"""
|
|
107
|
+
mainText(
|
|
108
|
+
"""If true, converts each whitespace character to a single space"""
|
|
109
|
+
normalizeSpace: Boolean
|
|
110
|
+
): String!
|
|
111
|
+
"""A list of the tags of this document"""
|
|
112
|
+
tags: [String!]!
|
|
113
|
+
"""A list of the tags of this document as key/value tuples"""
|
|
114
|
+
tagsKv: [KeyValue!]!
|
|
115
|
+
"""'Whether or not the document has the specified tag"""
|
|
116
|
+
hasTag(
|
|
117
|
+
tagName: String!
|
|
118
|
+
): Boolean!
|
|
119
|
+
"""Content for a Scripture reference within this document, using local versification"""
|
|
120
|
+
cv(
|
|
121
|
+
"""The chapter number (as a string)"""
|
|
122
|
+
chapter: String
|
|
123
|
+
"""'A list of verse numbers (as strings)"""
|
|
124
|
+
verses: [String!]
|
|
125
|
+
"""A chapterVerse Reference (ch:v-ch:v)"""
|
|
126
|
+
chapterVerses: String
|
|
127
|
+
"""If true, adds scope and nextToken information to each token"""
|
|
128
|
+
includeContext: Boolean
|
|
129
|
+
): [ItemGroup!]!
|
|
130
|
+
"""Content for a Scripture reference within this document, using the versification of the specified docSet"""
|
|
131
|
+
mappedCv(
|
|
132
|
+
"""The chapter number (as a string)"""
|
|
133
|
+
chapter: String!
|
|
134
|
+
"""The id of the mapped docSet"""
|
|
135
|
+
mappedDocSetId: String!
|
|
136
|
+
"""A list of verse numbers (as strings)"""
|
|
137
|
+
verses: [String!]!
|
|
138
|
+
"""If true, adds scope and nextToken information to each token"""
|
|
139
|
+
includeContext: Boolean
|
|
140
|
+
): [ItemGroup!]!
|
|
141
|
+
"""Content for each verse of a chapter within this document, using the versification of the specified docSet"""
|
|
142
|
+
mappedCvs(
|
|
143
|
+
"""The chapter number (as a string)"""
|
|
144
|
+
chapter: String!
|
|
145
|
+
"""The id of the mapped docSet"""
|
|
146
|
+
mappedDocSetId: String!
|
|
147
|
+
"""If true, adds scope and nextToken information to each token"""
|
|
148
|
+
includeContext: Boolean
|
|
149
|
+
): [[ItemGroup!]!]!
|
|
150
|
+
"""What's previous and next with respect to the specified verse"""
|
|
151
|
+
cvNavigation(
|
|
152
|
+
"""The chapter number (as a string)"""
|
|
153
|
+
chapter: String!
|
|
154
|
+
"""A verse number (as a string)"""
|
|
155
|
+
verse: String!
|
|
156
|
+
): cvNavigation
|
|
157
|
+
"""The content of the main sequence indexed by chapterVerse"""
|
|
158
|
+
cvIndexes: [cvIndex]!
|
|
159
|
+
"""The content of the specified chapter indexed by chapterVerse"""
|
|
160
|
+
cvIndex(
|
|
161
|
+
"""The chapter number"""
|
|
162
|
+
chapter: Int!
|
|
163
|
+
): cvIndex!
|
|
164
|
+
"""The content of the main sequence indexed by chapter"""
|
|
165
|
+
cIndexes: [cIndex]!
|
|
166
|
+
"""The content of a chapter"""
|
|
167
|
+
cIndex(
|
|
168
|
+
"""'The chapter number"""
|
|
169
|
+
chapter: Int!
|
|
170
|
+
): cIndex!
|
|
171
|
+
"""Verses matching the arguments"""
|
|
172
|
+
cvMatching(
|
|
173
|
+
"""Return verses containing a token whose payload is an exact match to one of the specified strings"""
|
|
174
|
+
withChars: [String!]
|
|
175
|
+
"""Return verses containing a token whose payload matches the specified regexes"""
|
|
176
|
+
withMatchingChars: [String!]
|
|
177
|
+
"""Only return blocks where the list of scopes is open"""
|
|
178
|
+
withScopes: [String!]
|
|
179
|
+
"""If true, verses where all regexes match will be included"""
|
|
180
|
+
allChars: Boolean
|
|
181
|
+
"""If true, verses where all scopes match will be included"""
|
|
182
|
+
allScopes: Boolean
|
|
183
|
+
): [ItemGroup!]!
|
|
184
|
+
"""A string of PERF JSON for this document"""
|
|
185
|
+
perf(
|
|
186
|
+
"""Format JSON string with this indent"""
|
|
187
|
+
indent: Int
|
|
188
|
+
): String!
|
|
189
|
+
"""A string of USFM for this document"""
|
|
190
|
+
usfm: String!
|
|
191
|
+
"""A string of SOFRIA JSON for this document"""
|
|
192
|
+
sofria(
|
|
193
|
+
"""Format JSON string with this indent"""
|
|
194
|
+
indent: Int
|
|
195
|
+
"""Return SOFRIA for this chapter only"""
|
|
196
|
+
chapter: Int
|
|
197
|
+
): String!
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
200
|
+
|
|
201
|
+
const documentResolvers = {
|
|
202
|
+
idParts: root => {
|
|
203
|
+
const idHeader = headerById(root, 'id');
|
|
204
|
+
|
|
205
|
+
if (!idHeader) {
|
|
206
|
+
return [null, null];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const periphMatch = xre.exec(idHeader, /^(P\d\d)\s+([A-Z0-6]{3})\s+(\S+)\s+-\s+(.*)/);
|
|
210
|
+
|
|
211
|
+
if (periphMatch) {
|
|
212
|
+
return ['periph', periphMatch.slice(1)];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const bookMatch = xre.exec(idHeader, /^([A-Z0-6]{3})\s+(.*)/);
|
|
216
|
+
|
|
217
|
+
if (bookMatch) {
|
|
218
|
+
return ['book', bookMatch.slice(1)];
|
|
219
|
+
}
|
|
220
|
+
return [null, [idHeader]];
|
|
221
|
+
},
|
|
222
|
+
headers: root => Object.entries(root.headers),
|
|
223
|
+
header: (root, args) => headerById(root, args.id),
|
|
224
|
+
mainSequence: (root, args, context) => {
|
|
225
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
226
|
+
return root.sequences[root.mainId];
|
|
227
|
+
},
|
|
228
|
+
nSequences: (root, args, context) => {
|
|
229
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
230
|
+
return Object.keys(root.sequences).length;
|
|
231
|
+
},
|
|
232
|
+
sequences: (root, args, context) => {
|
|
233
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
234
|
+
let ret = Object.values(root.sequences);
|
|
235
|
+
|
|
236
|
+
if (args.ids) {
|
|
237
|
+
ret = ret.filter(s => args.ids.includes(s.id));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (args.types) {
|
|
241
|
+
ret = ret.filter(s => args.types.includes(s.type));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (args.withTags) {
|
|
245
|
+
ret = ret.filter(s => args.withTags.filter(t => s.tags.has(t)).length === args.withTags.length);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (args.withoutTags) {
|
|
249
|
+
ret = ret.filter(s => args.withoutTags.filter(t => s.tags.has(t)).length === 0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return ret;
|
|
253
|
+
},
|
|
254
|
+
tableSequences: (root, args, context) => {
|
|
255
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
256
|
+
let ret = Object.values(root.sequences);
|
|
257
|
+
|
|
258
|
+
ret = ret.filter(s => s.type === 'table');
|
|
259
|
+
|
|
260
|
+
if (args.ids) {
|
|
261
|
+
ret = ret.filter(s => args.ids.includes(s.id));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (args.withTags) {
|
|
265
|
+
ret = ret.filter(s => args.withTags.filter(t => s.tags.has(t)).length === args.withTags.length);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (args.withoutTags) {
|
|
269
|
+
ret = ret.filter(s => args.withoutTags.filter(t => s.tags.has(t)).length === 0);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return ret;
|
|
273
|
+
},
|
|
274
|
+
treeSequences: (root, args, context) => {
|
|
275
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
276
|
+
let ret = Object.values(root.sequences);
|
|
277
|
+
|
|
278
|
+
ret = ret.filter(s => s.type === 'tree');
|
|
279
|
+
|
|
280
|
+
if (args.ids) {
|
|
281
|
+
ret = ret.filter(s => args.ids.includes(s.id));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (args.withTags) {
|
|
285
|
+
ret = ret.filter(s => args.withTags.filter(t => s.tags.has(t)).length === args.withTags.length);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (args.withoutTags) {
|
|
289
|
+
ret = ret.filter(s => args.withoutTags.filter(t => s.tags.has(t)).length === 0);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return ret;
|
|
293
|
+
},
|
|
294
|
+
kvSequences: (root, args, context) => {
|
|
295
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
296
|
+
let ret = Object.values(root.sequences);
|
|
297
|
+
|
|
298
|
+
ret = ret.filter(s => s.type === 'kv');
|
|
299
|
+
|
|
300
|
+
if (args.ids) {
|
|
301
|
+
ret = ret.filter(s => args.ids.includes(s.id));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (args.withTags) {
|
|
305
|
+
ret = ret.filter(s => args.withTags.filter(t => s.tags.has(t)).length === args.withTags.length);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (args.withoutTags) {
|
|
309
|
+
ret = ret.filter(s => args.withoutTags.filter(t => s.tags.has(t)).length === 0);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return ret;
|
|
313
|
+
},
|
|
314
|
+
textSequences: (root, args, context) => {
|
|
315
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
316
|
+
let ret = Object.values(root.sequences);
|
|
317
|
+
|
|
318
|
+
ret = ret.filter(s => s.type !== 'tree' && s.type !== 'table' && s.type !== 'kv');
|
|
319
|
+
|
|
320
|
+
if (args.ids) {
|
|
321
|
+
ret = ret.filter(s => args.ids.includes(s.id));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (args.withTags) {
|
|
325
|
+
ret = ret.filter(s => args.withTags.filter(t => s.tags.has(t)).length === args.withTags.length);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (args.withoutTags) {
|
|
329
|
+
ret = ret.filter(s => args.withoutTags.filter(t => s.tags.has(t)).length === 0);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return ret;
|
|
333
|
+
},
|
|
334
|
+
sequence: (root, args, context) => {
|
|
335
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
336
|
+
let ret = Object.values(root.sequences);
|
|
337
|
+
ret = ret.filter(s => args.id.includes(s.id));
|
|
338
|
+
return ret[0] || null;
|
|
339
|
+
},
|
|
340
|
+
tableSequence: (root, args, context) => {
|
|
341
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
342
|
+
let ret = Object.values(root.sequences);
|
|
343
|
+
ret = ret.filter(s => args.id.includes(s.id));
|
|
344
|
+
|
|
345
|
+
if (ret[0] && ret[0].type !== 'table') {
|
|
346
|
+
throw new Error(`Expected sequence id ${ret[0].id} to be of type 'table', not '${ret[0].type}'`);
|
|
347
|
+
}
|
|
348
|
+
return ret[0] || null;
|
|
349
|
+
},
|
|
350
|
+
treeSequence: (root, args, context) => {
|
|
351
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
352
|
+
let ret = Object.values(root.sequences);
|
|
353
|
+
ret = ret.filter(s => args.id.includes(s.id));
|
|
354
|
+
|
|
355
|
+
if (ret[0] && ret[0].type !== 'tree') {
|
|
356
|
+
throw new Error(`Expected sequence id ${ret[0].id} to be of type 'tree', not '${ret[0].type}'`);
|
|
357
|
+
}
|
|
358
|
+
return ret[0] || null;
|
|
359
|
+
},
|
|
360
|
+
kvSequence: (root, args, context) => {
|
|
361
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
362
|
+
let ret = Object.values(root.sequences);
|
|
363
|
+
ret = ret.filter(s => args.id.includes(s.id));
|
|
364
|
+
|
|
365
|
+
if (ret[0] && ret[0].type !== 'vk') {
|
|
366
|
+
throw new Error(`Expected sequence id ${ret[0].id} to be of type 'kv', not '${ret[0].type}'`);
|
|
367
|
+
}
|
|
368
|
+
return ret[0] || null;
|
|
369
|
+
},
|
|
370
|
+
mainBlocks: (root, args, context) => {
|
|
371
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
372
|
+
return root.sequences[root.mainId].blocks;
|
|
373
|
+
},
|
|
374
|
+
mainBlocksItems: (root, args, context) => {
|
|
375
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
376
|
+
return root.sequences[root.mainId].blocks.map(
|
|
377
|
+
b => context.docSet.unsuccinctifyItems(b.c, {}, null),
|
|
378
|
+
);
|
|
379
|
+
},
|
|
380
|
+
mainBlocksTokens: (root, args, context) => {
|
|
381
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
382
|
+
return root.sequences[root.mainId].blocks.map(
|
|
383
|
+
b => context.docSet.unsuccinctifyItems(b.c, { tokens: true }, null),
|
|
384
|
+
);
|
|
385
|
+
},
|
|
386
|
+
mainBlocksText: (root, args, context) => {
|
|
387
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
388
|
+
return root.sequences[root.mainId].blocks.map(
|
|
389
|
+
b => {
|
|
390
|
+
const tokens = context.docSet.unsuccinctifyItems(b.c, { tokens: true }, null);
|
|
391
|
+
let ret = tokens.map(t => t[2]).join('').trim();
|
|
392
|
+
|
|
393
|
+
if (args.normalizeSpace) {
|
|
394
|
+
ret = ret.replace(/[ \t\n\r]+/g, ' ');
|
|
395
|
+
}
|
|
396
|
+
return ret;
|
|
397
|
+
},
|
|
398
|
+
);
|
|
399
|
+
},
|
|
400
|
+
mainText: (root, args, context) => {
|
|
401
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
402
|
+
return root.sequences[root.mainId].blocks.map(
|
|
403
|
+
b => {
|
|
404
|
+
const tokens = context.docSet.unsuccinctifyItems(b.c, { tokens: true }, null);
|
|
405
|
+
let ret = tokens.map(t => t[2]).join('').trim();
|
|
406
|
+
|
|
407
|
+
if (args.normalizeSpace) {
|
|
408
|
+
ret = ret.replace(/[ \t\n\r]+/g, ' ');
|
|
409
|
+
}
|
|
410
|
+
return ret;
|
|
411
|
+
},
|
|
412
|
+
).join('\n');
|
|
413
|
+
},
|
|
414
|
+
tags: root => Array.from(root.tags),
|
|
415
|
+
tagsKv: root => Array.from(root.tags).map(t => {
|
|
416
|
+
if (t.includes(':')) {
|
|
417
|
+
return [t.substring(0, t.indexOf(':')), t.substring(t.indexOf(':') + 1)];
|
|
418
|
+
} else {
|
|
419
|
+
return [t, ''];
|
|
420
|
+
}
|
|
421
|
+
}),
|
|
422
|
+
hasTag: (root, args) => root.tags.has(args.tagName),
|
|
423
|
+
cv: (root, args, context) => do_cv(root, args, context, false),
|
|
424
|
+
mappedCv: (root, args, context) => {
|
|
425
|
+
if (args.verses.length !== 1) {
|
|
426
|
+
throw new Error(`mappedCv expects exactly one verse, not ${args.verses.length}`);
|
|
427
|
+
}
|
|
428
|
+
return do_cv(root, args, context, true, args.mappedDocSetId);
|
|
429
|
+
},
|
|
430
|
+
mappedCvs: (root, args, context) => {
|
|
431
|
+
const cvIndex = root.chapterVerseIndex(args.chapter);
|
|
432
|
+
const verses = cvIndex.filter(ve => ve.length > 0).map(ve => ve[0].verses);
|
|
433
|
+
let ret = [];
|
|
434
|
+
|
|
435
|
+
for (const verse of verses) {
|
|
436
|
+
ret.push(
|
|
437
|
+
do_cv(root, {
|
|
438
|
+
...args,
|
|
439
|
+
verses: [verse],
|
|
440
|
+
}, context, true, args.mappedDocSetId)
|
|
441
|
+
.map(ig => [[`fromChapter/${args.chapter}`, `fromVerse/${verse}`, ...ig[0]], ig[1]]),
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
return ret;
|
|
445
|
+
},
|
|
446
|
+
cvNavigation:
|
|
447
|
+
(root, args) => [
|
|
448
|
+
args.chapter,
|
|
449
|
+
args.verse,
|
|
450
|
+
root.chapterVerseIndex((parseInt(args.chapter) - 1).toString()),
|
|
451
|
+
root.chapterVerseIndex(args.chapter),
|
|
452
|
+
root.chapterVerseIndex((parseInt(args.chapter) + 1).toString()),
|
|
453
|
+
],
|
|
454
|
+
cvIndexes: (root, args, context) => {
|
|
455
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
456
|
+
context.doc = root;
|
|
457
|
+
return Object.entries(root.chapterVerseIndexes());
|
|
458
|
+
},
|
|
459
|
+
cvIndex: (root, args, context) => {
|
|
460
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
461
|
+
context.doc = root;
|
|
462
|
+
return [args.chapter, root.chapterVerseIndex(args.chapter) || []];
|
|
463
|
+
},
|
|
464
|
+
cIndexes: (root, args, context) => {
|
|
465
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
466
|
+
context.doc = root;
|
|
467
|
+
return Object.entries(root.chapterIndexes());
|
|
468
|
+
},
|
|
469
|
+
cIndex: (root, args, context) => {
|
|
470
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
471
|
+
context.doc = root;
|
|
472
|
+
const ci = root.chapterIndex(args.chapter);
|
|
473
|
+
return [args.chapter, ci || {}];
|
|
474
|
+
},
|
|
475
|
+
cvMatching: (root, args, context) => {
|
|
476
|
+
if (!args.withChars && !args.withMatchingChars && !args.withScopes) {
|
|
477
|
+
throw new Error('Must specify at least one of withChars or withMatchingChars or withScopes');
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (args.withChars && args.withMatchingChars) {
|
|
481
|
+
throw new Error('Must not specify both withChars and withMatchingChars');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
context.docSet = root.processor.docSets[root.docSetId];
|
|
485
|
+
|
|
486
|
+
let charsRegexes;
|
|
487
|
+
|
|
488
|
+
if (args.withChars && args.allChars) {
|
|
489
|
+
charsRegexes = args.withChars.map(s => xre(`^${s}$`));
|
|
490
|
+
} else if (args.withChars) {
|
|
491
|
+
charsRegexes = [xre.union(args.withChars.map(s => xre(`^${s}$`, 'i')))];
|
|
492
|
+
} else if (args.withMatchingChars && args.allChars) {
|
|
493
|
+
charsRegexes = args.withMatchingChars.map(s => xre(s, 'i'));
|
|
494
|
+
} else if (args.withMatchingChars) {
|
|
495
|
+
charsRegexes = [xre.union(args.withMatchingChars.map(s => xre(s, 'i')))];
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const allScopesInGroup = scopes => {
|
|
499
|
+
for (const expectedScope of args.withScopes || []) {
|
|
500
|
+
if (!scopes.includes(expectedScope)) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return true;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const anyScopesInGroup = scopes => {
|
|
508
|
+
const expectedScopes = args.withScopes || [];
|
|
509
|
+
|
|
510
|
+
for (const expectedScope of expectedScopes) {
|
|
511
|
+
if (scopes.includes(expectedScope)) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return expectedScopes.length === 0;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
const allRegexesInGroup = items => {
|
|
519
|
+
for (const regex of charsRegexes || []) {
|
|
520
|
+
let found = false;
|
|
521
|
+
|
|
522
|
+
for (const item of items) {
|
|
523
|
+
if (xre.test(item[2], regex)) {
|
|
524
|
+
found = true;
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (!found) {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return true;
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
const itemGroups = context.docSet.sequenceItemsByScopes(
|
|
537
|
+
root.sequences[root.mainId].blocks,
|
|
538
|
+
['chapter/', 'verses/'],
|
|
539
|
+
);
|
|
540
|
+
return itemGroups.filter(
|
|
541
|
+
ig =>
|
|
542
|
+
(args.allScopes ? allScopesInGroup : anyScopesInGroup)(
|
|
543
|
+
ig[1].filter(i => i[0] === 'scope' && i[1] === 'start').map(s => s[2])) &&
|
|
544
|
+
allRegexesInGroup(ig[1]),
|
|
545
|
+
);
|
|
546
|
+
},
|
|
547
|
+
perf: (root, args) => root.perf(args.indent),
|
|
548
|
+
usfm: (root) => root.usfm(),
|
|
549
|
+
sofria: (root, args) => root.sofria(args.indent, args.chapter),
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
module.exports = {
|
|
553
|
+
documentSchemaString,
|
|
554
|
+
documentResolvers,
|
|
555
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const idPartsSchemaString = `
|
|
2
|
+
"""Type-dependent parts of the ID header"""
|
|
3
|
+
type idParts {
|
|
4
|
+
"""The type of the ID"""
|
|
5
|
+
type: String
|
|
6
|
+
"""An array of parts of the ID"""
|
|
7
|
+
parts: [String]
|
|
8
|
+
"""A part of the ID, by index"""
|
|
9
|
+
part(
|
|
10
|
+
"""The numeric index of the part"""
|
|
11
|
+
index: Int!
|
|
12
|
+
): String
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
const idPartsResolvers = {
|
|
17
|
+
type: root => root[0],
|
|
18
|
+
parts: root => root[1],
|
|
19
|
+
part: (root, args) => {
|
|
20
|
+
if (!root[1] || args.index < 0 || args.index >= root[1].length) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return root[1][args.index];
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
idPartsSchemaString,
|
|
29
|
+
idPartsResolvers,
|
|
30
|
+
};
|