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,506 @@
1
+ const utils = require('../util/index.cjs');
2
+ const { Sequence } = require('./model/index.cjs');
3
+ const {
4
+ specs,
5
+ buildSpecLookup,
6
+ } = require('./parser_specs.cjs');
7
+
8
+ const { labelForScope } = utils.scopeDefs;
9
+ const parserConstantDef = utils.parserConstants;
10
+
11
+ const Parser = class {
12
+ constructor(filterOptions, customTags, emptyBlocks) {
13
+ this.filterOptions = filterOptions;
14
+ this.customTags = customTags;
15
+ this.emptyBlocks = emptyBlocks;
16
+ this.specs = specs(this);
17
+ this.specLookup = buildSpecLookup(this.specs);
18
+ this.headers = {};
19
+ this.baseSequenceTypes = parserConstantDef.usfm.baseSequenceTypes;
20
+ this.inlineSequenceTypes = parserConstantDef.usfm.inlineSequenceTypes;
21
+ this.setSequences();
22
+ this.setCurrent();
23
+ }
24
+
25
+ setSequences() {
26
+ this.sequences = {};
27
+
28
+ for (const [sType, sArity] of Object.entries({ ...this.baseSequenceTypes, ...this.inlineSequenceTypes })) {
29
+ switch (sArity) {
30
+ case '1':
31
+ this.sequences[sType] = new Sequence(sType);
32
+ break;
33
+ case '?':
34
+ this.sequences[sType] = null;
35
+ break;
36
+ case '*':
37
+ this.sequences[sType] = [];
38
+ break;
39
+ default:
40
+ throw new Error(`Unexpected sequence arity '${sArity}' for '${sType}'`);
41
+ }
42
+ }
43
+ this.mainLike = this.sequences.main;
44
+ }
45
+
46
+ setCurrent() {
47
+ this.current = {
48
+ sequence: this.sequences.main,
49
+ parentSequence: null,
50
+ baseSequenceType: 'main',
51
+ inlineSequenceType: null,
52
+ attributeContext: null,
53
+ };
54
+ }
55
+
56
+ parseItem(lexedItem) {
57
+ let changeBaseSequence = false;
58
+
59
+ if (['startTag'].includes(lexedItem.subclass)) {
60
+ this.closeActiveScopes(`startTag/${lexedItem.fullTagName}`);
61
+
62
+ if (!lexedItem.isNested) {
63
+ this.closeActiveScopes(`implicitEnd`);
64
+ }
65
+ }
66
+
67
+ if (['endTag'].includes(lexedItem.subclass)) {
68
+ this.closeActiveScopes(`endTag/${lexedItem.fullTagName}`);
69
+ }
70
+
71
+ if (['startMilestoneTag'].includes(lexedItem.subclass) && lexedItem.sOrE === 'e') {
72
+ this.closeActiveScopes(`endMilestone/${lexedItem.tagName}`);
73
+ }
74
+
75
+ if (['chapter', 'pubchapter', 'verses'].includes(lexedItem.subclass)) {
76
+ this.closeActiveScopes(lexedItem.subclass, this.sequences.main);
77
+ }
78
+
79
+ const spec = this.specForItem(lexedItem);
80
+
81
+ if (spec) {
82
+ if ('before' in spec.parser) {
83
+ spec.parser.before(this, lexedItem);
84
+ }
85
+ changeBaseSequence = false;
86
+
87
+ if (spec.parser.baseSequenceType) {
88
+ const returnSequenceType = spec.parser.baseSequenceType === 'mainLike' ? this.mainLike.type : spec.parser.baseSequenceType;
89
+
90
+ changeBaseSequence = (returnSequenceType !== this.current.baseSequenceType) ||
91
+ spec.parser.forceNewSequence;
92
+ }
93
+
94
+ if (changeBaseSequence) {
95
+ this.closeActiveScopes('baseSequenceChange');
96
+ this.changeBaseSequence(spec.parser);
97
+
98
+ if ('newBlock' in spec.parser && spec.parser.newBlock) {
99
+ this.closeActiveScopes('endBlock');
100
+ this.current.sequence.newBlock(labelForScope('blockTag', [lexedItem.fullTagName]));
101
+ }
102
+ } else if (spec.parser.inlineSequenceType) {
103
+ this.current.inlineSequenceType = spec.parser.inlineSequenceType;
104
+ this.current.parentSequence = this.current.sequence;
105
+
106
+ if (this.current.parentSequence.type === 'header') { // Not lovely, needed for \cp before first content
107
+ this.current.parentSequence = this.sequences.main;
108
+ }
109
+ this.current.sequence = new Sequence(this.current.inlineSequenceType);
110
+ this.current.sequence.newBlock(labelForScope('inline', spec.parser.inlineSequenceType));
111
+ this.sequences[this.current.inlineSequenceType].push(this.current.sequence);
112
+ this.current.parentSequence.addItem({
113
+ type: 'graft',
114
+ subType: this.current.inlineSequenceType,
115
+ payload: this.current.sequence.id,
116
+ });
117
+ } else if ('newBlock' in spec.parser && spec.parser.newBlock) {
118
+ this.current.sequence.newBlock(labelForScope('blockTag', [lexedItem.fullTagName]));
119
+ }
120
+
121
+ if ('during' in spec.parser) {
122
+ spec.parser.during(this, lexedItem);
123
+ }
124
+ this.openNewScopes(spec.parser, lexedItem);
125
+
126
+ if ('after' in spec.parser) {
127
+ spec.parser.after(this, lexedItem);
128
+ }
129
+ }
130
+ }
131
+
132
+ tidy() {
133
+ for (const introduction of this.sequences.introduction) {
134
+ introduction.graftifyIntroductionHeadings(this);
135
+ }
136
+
137
+ const allSequences = this.allSequences();
138
+
139
+ for (const seq of allSequences) {
140
+ seq.trim();
141
+ seq.reorderSpanWithAtts();
142
+ seq.makeNoteGrafts(this);
143
+ seq.moveOrphanScopes();
144
+ seq.removeEmptyBlocks(this.emptyBlocks);
145
+ }
146
+
147
+ const emptySequences = this.emptySequences(allSequences);
148
+
149
+ for (const seq of allSequences) {
150
+ if (emptySequences) {
151
+ seq.removeGraftsToEmptySequences(emptySequences);
152
+ }
153
+ seq.addTableScopes();
154
+ seq.close(this);
155
+ this.substitutePubNumberScopes(seq);
156
+ seq.moveOrphanStartScopes2();
157
+
158
+ if (seq.type === 'sidebar') {
159
+ this.substituteEsbCatScopes(seq);
160
+ }
161
+
162
+ if (['footnote', 'xref'].includes(seq.type)) {
163
+ seq.lastBlock().inlineToEnd();
164
+ }
165
+ }
166
+ }
167
+
168
+ emptySequences(sequences) {
169
+ return sequences.filter(s => s.blocks.length === 0).map(s => s.id);
170
+ }
171
+
172
+ substitutePubNumberScopes(seq) {
173
+ const scopeToGraftContent = {};
174
+ const sequenceById = this.sequenceById();
175
+
176
+ for (const block of seq.blocks) {
177
+ let spliceCount = 0;
178
+ const itItems = [...block.items];
179
+
180
+ for (const [n, item] of itItems.entries()) {
181
+ if (item.type === 'graft' && ['pubNumber', 'altNumber'].includes(item.subType)) {
182
+ const graftContent = sequenceById[item.payload].text().trim();
183
+ const scopeId = itItems[n + 1].payload.split('/')[1];
184
+ scopeToGraftContent[scopeId] = graftContent;
185
+ block.items.splice(n - spliceCount, 1);
186
+ spliceCount++;
187
+ }
188
+ }
189
+ }
190
+
191
+ // Substitute scopeIds for graft content
192
+ if (Object.keys(scopeToGraftContent).length > 0) {
193
+ for (const block of seq.blocks) {
194
+ for (const scope of block.items.filter(i => i.type === 'scope')) {
195
+ const scopeParts = scope.payload.split('/');
196
+
197
+ if (['altChapter', 'pubVerse', 'altVerse'].includes(scopeParts[0])) {
198
+ scope.payload = `${scopeParts[0]}/${scopeToGraftContent[scopeParts[1]]}`;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ substituteEsbCatScopes(seq) {
206
+ const scopeToGraftContent = {};
207
+ const sequenceById = this.sequenceById();
208
+
209
+ for (const block of seq.blocks) {
210
+ let spliceCount = 0;
211
+ const itItems = [...block.items];
212
+
213
+ for (const [n, item] of itItems.entries()) {
214
+ if (item.type === 'graft' && item.subType === 'esbCat') {
215
+ const catContent = sequenceById[item.payload].text().trim();
216
+ const scopeId = itItems[1].payload.split('/')[1];
217
+ scopeToGraftContent[scopeId] = catContent;
218
+ block.items.splice(n - spliceCount, 1);
219
+ spliceCount++;
220
+ }
221
+ }
222
+ }
223
+
224
+ // Substitute scopeIds for graft content
225
+ if (Object.keys(scopeToGraftContent).length > 0) {
226
+ for (const block of seq.blocks) {
227
+ for (const scope of block.items.filter(i => i.type === 'scope')) {
228
+ const scopeParts = scope.payload.split('/');
229
+
230
+ if (scopeParts[0] === 'esbCat') {
231
+ scope.payload = `${scopeParts[0]}/${scopeToGraftContent[scopeParts[1]]}`;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+
238
+ allSequences() {
239
+ const ret = [];
240
+
241
+ for (const [seqName, seqArity] of Object.entries({ ...this.baseSequenceTypes, ...this.inlineSequenceTypes })) {
242
+ switch (seqArity) {
243
+ case '1':
244
+ case '?':
245
+ if (this.sequences[seqName]) {
246
+ ret.push(this.sequences[seqName]);
247
+ }
248
+ break;
249
+ case '*':
250
+ this.sequences[seqName].forEach(s => {
251
+ ret.push(s);
252
+ });
253
+ break;
254
+ default:
255
+ throw new Error(`Unexpected sequence arity '${seqArity}' for '${seqName}'`);
256
+ }
257
+ }
258
+ return ret;
259
+ }
260
+
261
+ sequenceById() {
262
+ const ret = {};
263
+
264
+ this.allSequences().forEach(s => {
265
+ ret[s.id] = s;
266
+ });
267
+ return ret;
268
+ }
269
+
270
+ filter() {
271
+ const usedSequences = [];
272
+ const sequenceById = this.sequenceById();
273
+ this.filterGrafts(this.sequences.main.id, sequenceById, usedSequences, this.filterOptions);
274
+ this.removeUnusedSequences(usedSequences);
275
+ this.filterScopes(Object.values(sequenceById), this.filterOptions);
276
+ }
277
+
278
+ filterGrafts(seqId, seqById, used, options) {
279
+ used.push(seqId);
280
+ const childSequences = seqById[seqId].filterGrafts(options);
281
+
282
+ for (const si of childSequences) {
283
+ if (seqById[si].type === 'main') {
284
+ console.log('MAIN is child!');
285
+ console.log(JSON.stringify(seqById[seqId], null, 2));
286
+ process.exit(1);
287
+ }
288
+ this.filterGrafts(si, seqById, used, options);
289
+ }
290
+ }
291
+
292
+ removeUnusedSequences(usedSequences) {
293
+ for (const seq of this.allSequences()) {
294
+ if (!usedSequences.includes(seq.id)) {
295
+ const seqArity = { ...this.baseSequenceTypes, ...this.inlineSequenceTypes }[seq.type];
296
+
297
+ switch (seqArity) {
298
+ case '1':
299
+ throw new Error('Attempting to remove sequence with arity of 1');
300
+ case '?':
301
+ this.sequences[seq.type] = null;
302
+ break;
303
+ case '*':
304
+ this.sequences[seq.type] = this.sequences[seq.type].filter(s => s.id !== seq.id);
305
+ break;
306
+ default:
307
+ throw new Error(`Unexpected sequence arity '${seqArity}' for '${seq.type}'`);
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ filterScopes(sequences, options) {
314
+ sequences.forEach(s => s.filterScopes(options));
315
+ }
316
+
317
+ specForItem(item) {
318
+ const context = item.subclass;
319
+
320
+ if (!(context in this.specLookup)) {
321
+ return null;
322
+ }
323
+
324
+ for (const accessor of ['tagName', 'sOrE']) {
325
+ if (accessor in item && accessor in this.specLookup[context] && item[accessor] in this.specLookup[context][accessor]) {
326
+ return { parser: this.specLookup[context][accessor][item[accessor]] };
327
+ }
328
+ }
329
+
330
+ if ('_noAccessor' in this.specLookup[context]) {
331
+ return { parser: this.specLookup[context]['_noAccessor'] };
332
+ }
333
+
334
+ return null;
335
+ }
336
+
337
+ closeActiveScopes(closeLabel, targetSequence) {
338
+ if (targetSequence === undefined) {
339
+ targetSequence = this.current.sequence;
340
+ }
341
+
342
+ const matchedScopes = targetSequence.activeScopes.filter(
343
+ sc => sc.endedBy.includes(closeLabel),
344
+ ).reverse();
345
+
346
+ targetSequence.activeScopes = targetSequence.activeScopes.filter(
347
+ sc => !sc.endedBy.includes(closeLabel),
348
+ );
349
+ matchedScopes.forEach(ms => this.closeActiveScope(ms, targetSequence));
350
+ }
351
+
352
+ closeActiveScope(sc, targetSequence) {
353
+ this.addScope('end', sc.label, targetSequence);
354
+
355
+ if (sc.onEnd) {
356
+ sc.onEnd(this, sc.label);
357
+ }
358
+ }
359
+
360
+ changeBaseSequence(parserSpec) {
361
+ const newType = parserSpec.baseSequenceType;
362
+
363
+ if (newType === 'mainLike') {
364
+ this.current.sequence = this.mainLike;
365
+ return;
366
+ }
367
+ this.current.baseSequenceType = newType;
368
+ const arity = this.baseSequenceTypes[newType];
369
+
370
+ switch (arity) {
371
+ case '1':
372
+ this.current.sequence = this.sequences[newType];
373
+ break;
374
+ case '?':
375
+ if (!this.sequences[newType]) {
376
+ this.sequences[newType] = new Sequence(newType);
377
+ }
378
+ this.current.sequence = this.sequences[newType];
379
+ break;
380
+ case '*':
381
+ this.current.sequence = new Sequence(newType);
382
+
383
+ if (!parserSpec.useTempSequence) {
384
+ this.sequences[newType].push(this.current.sequence);
385
+ }
386
+ break;
387
+ default:
388
+ throw new Error(`Unexpected base sequence arity '${arity}' for '${newType}'`);
389
+ }
390
+
391
+ if (!parserSpec.useTempSequence && this.current.sequence.type !== 'main') {
392
+ this.mainLike.addBlockGraft({
393
+ type: 'graft',
394
+ subType: this.current.baseSequenceType,
395
+ payload: this.current.sequence.id,
396
+ });
397
+ }
398
+ }
399
+
400
+ returnToBaseSequence() {
401
+ this.current.inlineSequenceType = null;
402
+ this.current.sequence = this.current.parentSequence;
403
+ this.current.parentSequence = null;
404
+ }
405
+
406
+ openNewScopes(parserSpec, pt) {
407
+ if (parserSpec.newScopes) {
408
+ let targetSequence = this.current.sequence;
409
+
410
+ if ('mainSequence' in parserSpec && parserSpec.mainSequence) {
411
+ targetSequence = this.sequences.main;
412
+ }
413
+ parserSpec.newScopes.forEach(sc => this.openNewScope(pt, sc, true, targetSequence));
414
+ }
415
+ }
416
+
417
+ openNewScope(pt, sc, addItem, targetSequence) {
418
+ if (addItem === undefined) {
419
+ addItem = true;
420
+ }
421
+
422
+ if (targetSequence === undefined) {
423
+ targetSequence = this.current.sequence;
424
+ }
425
+
426
+ if (addItem) {
427
+ targetSequence.addItem({
428
+ type: 'scope',
429
+ subType: 'start',
430
+ payload: sc.label(pt),
431
+ });
432
+ }
433
+
434
+ const newScope = {
435
+ label: sc.label(pt),
436
+ endedBy: this.substituteEndedBys(sc.endedBy, pt),
437
+ };
438
+
439
+ if ('onEnd' in sc) {
440
+ newScope.onEnd = sc.onEnd;
441
+ }
442
+ targetSequence.activeScopes.push(newScope);
443
+ }
444
+
445
+ substituteEndedBys(endedBy, pt) {
446
+ return endedBy.map(
447
+ eb => {
448
+ let ret = eb
449
+ .replace('$fullTagName$', pt.fullTagName)
450
+ .replace('$tagName$', pt.tagName);
451
+
452
+ if (this.current.attributeContext) {
453
+ ret = ret.replace(
454
+ '$attributeContext$',
455
+ this.current.attributeContext
456
+ .replace('milestone', 'endMilestone')
457
+ .replace('spanWithAtts', 'endTag'),
458
+ );
459
+ }
460
+ return ret;
461
+ },
462
+ );
463
+ }
464
+
465
+ addToken(pt) {
466
+ this.current.sequence.addItem({
467
+ type: 'token',
468
+ subType: pt.subclass,
469
+ payload: pt.printValue,
470
+ });
471
+ }
472
+
473
+ addScope(sOrE, label, targetSequence) {
474
+ if (targetSequence === undefined) {
475
+ targetSequence = this.current.sequence;
476
+ }
477
+ targetSequence.addItem({
478
+ type: 'scope',
479
+ subType: sOrE,
480
+ payload: label,
481
+ });
482
+ }
483
+
484
+ addEmptyMilestone(label) {
485
+ this.mainLike.addItem({
486
+ type: 'scope',
487
+ subType: 'start',
488
+ payload: label,
489
+ });
490
+ this.mainLike.addItem({
491
+ type: 'scope',
492
+ subType: 'end',
493
+ payload: label,
494
+ });
495
+ }
496
+
497
+ setAttributeContext(label) {
498
+ this.current.attributeContext = label;
499
+ }
500
+
501
+ clearAttributeContext() {
502
+ this.current.attributeContext = null;
503
+ }
504
+ };
505
+
506
+ module.exports = { Parser };
@@ -0,0 +1,11 @@
1
+ const { parseUsfm } = require('./usfm.cjs');
2
+ const { parseUsx } = require('./usx/index.cjs');
3
+ const { parseTableToDocument } = require('./tsv.cjs');
4
+ const { parseNodes } = require('./nodes.cjs');
5
+
6
+ module.exports = {
7
+ parseUsfm,
8
+ parseUsx,
9
+ parseTableToDocument,
10
+ parseNodes,
11
+ };
@@ -0,0 +1,45 @@
1
+ const xre = require('xregexp');
2
+
3
+ const lexingRegexes = [
4
+ ['chapter', 'chapter', xre('([\\r\\n]*\\\\c[ \\t]+(\\d+)[ \\t\\r\\n]*)')],
5
+ [
6
+ 'pubchapter',
7
+ 'pubchapter',
8
+ xre('([\\r\\n]*\\\\cp[ \\t]+([^\\r\\n]+)[ \\t\\r\\n]*)'),
9
+ ],
10
+ ['verses', 'verses', xre('(\\\\v[ \\t]+([\\d\\-]+)[ \\t\\r\\n]*)')],
11
+ [
12
+ 'attribute',
13
+ 'attribute',
14
+ xre('([ \\t]*\\|?[ \\t]*([A-Za-z0-9\\-]+)="([^"]*)"[ \\t]?)'),
15
+ ],
16
+ [
17
+ 'attribute',
18
+ 'defaultAttribute',
19
+ xre('([ \\t]*\\|[ \\t]*([^\\|\\\\]*))'),
20
+ ],
21
+ ['milestone', 'emptyMilestone', xre('(\\\\([a-z1-9]+)\\\\[*])')],
22
+ ['milestone', 'startMilestoneTag', xre('(\\\\([a-z1-9]+)-([se]))')],
23
+ ['milestone', 'endMilestoneMarker', xre('(\\\\([*]))')],
24
+ ['tag', 'endTag', xre('(\\\\([+]?[a-z\\-]+)([1-9]?(-([1-9]))?)[*])')],
25
+ ['tag', 'startTag', xre('(\\\\([+]?[a-z\\-]+)([1-9]?(-([1-9]))?)[ \\t]?)')],
26
+ ['bad', 'bareSlash', xre('(\\\\)')],
27
+ ['printable', 'eol', xre('([ \\t]*[\\r\\n]+[ \\t]*)')],
28
+ ['break', 'noBreakSpace', xre('~')],
29
+ ['break', 'softLineBreak', xre('//')],
30
+ [
31
+ 'printable',
32
+ 'wordLike',
33
+ xre('([\\p{Letter}\\p{Number}\\p{Mark}\\u2060]{1,127})'),
34
+ ],
35
+ ['printable', 'lineSpace', xre('([\\p{Separator}\t]{1,127})')],
36
+ ['printable', 'punctuation', xre('([\\p{Punctuation}\\p{Math_Symbol}\\p{Currency_Symbol}\\p{Modifier_Symbol}\\p{Other_Symbol}])')],
37
+ ['bad', 'unknown', xre('(.)')],
38
+ ];
39
+
40
+ const mainRegex = xre.union(lexingRegexes.map((x) => x[2]));
41
+
42
+ module.exports = {
43
+ lexingRegexes,
44
+ mainRegex,
45
+ };
@@ -0,0 +1,123 @@
1
+ const utils = require('../../util/index.cjs');
2
+ const { labelForScope } = utils.scopeDefs;
3
+ const { Sequence } = require('../model/index.cjs');
4
+ const { tokenizeString } = require('../lib/tokenize.cjs');
5
+
6
+ let nextNodeId = 0;
7
+
8
+ const numberNodes = (node, parentId) => {
9
+ if (typeof parentId !== 'number') {
10
+ nextNodeId = 0;
11
+ }
12
+
13
+ const ret = {
14
+ ...node,
15
+ id: nextNodeId,
16
+ parentId: typeof parentId === 'number' ? parentId : 'none',
17
+ };
18
+ nextNodeId++;
19
+
20
+ if (node.children) {
21
+ ret.children = node.children.map(cn => numberNodes(cn, ret.id));
22
+ }
23
+ return ret;
24
+ };
25
+
26
+ const flattenNodes = node => {
27
+ const ret = [{}];
28
+ ret[0].id = node.id;
29
+ ret[0].parentId = node.parentId;
30
+
31
+ if (node.content) {
32
+ ret[0].content = node.content;
33
+ }
34
+
35
+ if (node.children) {
36
+ ret[0].children = [];
37
+
38
+ for (const cn of node.children) {
39
+ ret[0].children.push(cn.id);
40
+ flattenNodes(cn).forEach(n => ret.push(n));
41
+ }
42
+ }
43
+ return ret;
44
+ };
45
+
46
+ const parseNodes = (str, parser, bookCode) => {
47
+ parser.headers.id = bookCode;
48
+ parser.headers.bookCode = bookCode;
49
+ const treeSequence = new Sequence('tree');
50
+
51
+ for (const node of flattenNodes(numberNodes(JSON.parse(str)))) {
52
+ treeSequence.newBlock(labelForScope('tTreeNode', [`${node.id}`]));
53
+ const scopePayload = labelForScope('tTreeParent', [`${node.parentId}`]);
54
+
55
+ treeSequence.lastBlock().items.push({
56
+ type: 'scope',
57
+ subType: 'start',
58
+ payload: scopePayload,
59
+ });
60
+
61
+ if (node.content) {
62
+ for (const [name, content] of Object.entries(node.content)) {
63
+ const treeContentStart = treeSequence.lastBlock().items.length;
64
+ const tokenized = tokenizeString(content);
65
+ const scopePayload = labelForScope('tTreeContent', [name, node.id, `${treeContentStart}`, `${tokenized.length}`]);
66
+
67
+ treeSequence.lastBlock().items.push({
68
+ type: 'scope',
69
+ subType: 'start',
70
+ payload: scopePayload,
71
+ });
72
+
73
+ for (const [payload, subType] of tokenized) {
74
+ treeSequence.lastBlock().items.push({
75
+ type: 'token',
76
+ subType,
77
+ payload,
78
+ });
79
+ }
80
+ treeSequence.lastBlock().items.push({
81
+ type: 'scope',
82
+ subType: 'end',
83
+ payload: scopePayload,
84
+ });
85
+ }
86
+ }
87
+
88
+ if (node.children) {
89
+ for (const [childN, childNodeN] of node.children.entries()) {
90
+ const scopePayload = labelForScope('tTreeChild', [childN, childNodeN]);
91
+
92
+ treeSequence.lastBlock().items.push({
93
+ type: 'scope',
94
+ subType: 'start',
95
+ payload: scopePayload,
96
+ });
97
+ treeSequence.lastBlock().items.push({
98
+ type: 'scope',
99
+ subType: 'end',
100
+ payload: scopePayload,
101
+ });
102
+ }
103
+ }
104
+ treeSequence.lastBlock().items.push({
105
+ type: 'scope',
106
+ subType: 'end',
107
+ payload: scopePayload,
108
+ });
109
+ }
110
+
111
+ parser.sequences.tree.push(treeSequence);
112
+ parser.sequences.main.addBlockGraft({
113
+ type: 'graft',
114
+ subType: 'tree',
115
+ payload: treeSequence.id,
116
+ });
117
+ };
118
+
119
+ module.exports = {
120
+ flattenNodes,
121
+ numberNodes,
122
+ parseNodes,
123
+ };