codexparser 0.1.59 → 0.1.60
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/package.json +1 -1
- package/src/CodexParser.js +238 -18
- package/src/abbr.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codexparser",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"description": "This is a Javascript Bible parser and text scanner. It will search through texts and collate all scripture references into an array and parse them into objects, and it will parse passages into objects by book, chapter, verse, and testament. ",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
package/src/CodexParser.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodexParser.js
|
|
3
|
+
* A class for scanning and parsing scripture references from text, supporting various formats
|
|
4
|
+
* (e.g., single verses, ranges, multi-chapter references) with validation and version-specific
|
|
5
|
+
* versification. Handles book names, abbreviations, and SBL-style formatting.
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
const versified = require("./versified")
|
|
2
9
|
const bible = require("./bible")
|
|
3
10
|
const { bookRegex, chapterRegex, verseRegex, scripturesRegex } = require("./regex")
|
|
@@ -8,28 +15,37 @@ const dd = require("./functions").dd
|
|
|
8
15
|
const sch = require("./functions").sch
|
|
9
16
|
const chapter_verses = require("./chapterVerseCombine")
|
|
10
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Class for parsing and validating scripture references.
|
|
20
|
+
* @class
|
|
21
|
+
*/
|
|
11
22
|
class CodexParser {
|
|
23
|
+
/**
|
|
24
|
+
* Initializes the parser with default properties and data.
|
|
25
|
+
*/
|
|
12
26
|
constructor() {
|
|
13
|
-
this.found = []
|
|
14
|
-
this.passages = []
|
|
15
|
-
this.bible = bible
|
|
16
|
-
this.bookRegex = bookRegex
|
|
17
|
-
this.chapterRegex = chapterRegex
|
|
18
|
-
this.verseRegex = verseRegex
|
|
19
|
-
this.scripturesRegex = scripturesRegex
|
|
20
|
-
this.abbreviations = abbreviations
|
|
21
|
-
this.sblAbbreviations = sblAbbreviations
|
|
22
|
-
this.versificationDifferences = versified
|
|
27
|
+
this.found = [] // Array to store detected references
|
|
28
|
+
this.passages = [] // Array to store parsed passages
|
|
29
|
+
this.bible = bible // Bible data (Old/New Testament books)
|
|
30
|
+
this.bookRegex = bookRegex // Regex for book names
|
|
31
|
+
this.chapterRegex = chapterRegex // Regex for chapters
|
|
32
|
+
this.verseRegex = verseRegex // Regex for verses
|
|
33
|
+
this.scripturesRegex = scripturesRegex // Regex for full references
|
|
34
|
+
this.abbreviations = abbreviations // Book abbreviation mappings
|
|
35
|
+
this.sblAbbreviations = sblAbbreviations // SBL-style abbreviation mappings
|
|
36
|
+
this.versificationDifferences = versified // Version-specific verse differences
|
|
23
37
|
this.singleChapterBook = [
|
|
38
|
+
// Books with a single chapter and their verse counts
|
|
24
39
|
sch("Jude", 25),
|
|
25
40
|
sch("2 John", 13),
|
|
26
41
|
sch("3 John", 15),
|
|
27
42
|
sch("Obadiah", 21),
|
|
28
43
|
sch("Philemon", 25),
|
|
29
44
|
]
|
|
30
|
-
this.chapterVerses = chapter_verses
|
|
31
|
-
this.error = false
|
|
32
|
-
this.version = null
|
|
45
|
+
this.chapterVerses = chapter_verses // Chapter-verse mappings
|
|
46
|
+
this.error = false // Error flag
|
|
47
|
+
this.version = null // Bible version (e.g., lxx, mt, eng)
|
|
48
|
+
// Reference type constants
|
|
33
49
|
this.SINGLE_CHAPTER = "single_chapter"
|
|
34
50
|
this.CHAPTER_VERSE = "chapter_verse"
|
|
35
51
|
this.CHAPTER_VERSE_RANGE = "chapter_verse_range"
|
|
@@ -38,15 +54,27 @@ class CodexParser {
|
|
|
38
54
|
this.MULTI_CHAPTER_RANGE = "multi_chapter_verse_range"
|
|
39
55
|
}
|
|
40
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Retrieves available verses for a given book and chapter.
|
|
59
|
+
* @param {string} book - The book name (e.g., "Genesis").
|
|
60
|
+
* @param {number} chapter - The chapter number.
|
|
61
|
+
* @returns {number[]} Array of valid verse numbers.
|
|
62
|
+
*/
|
|
41
63
|
getChapterVerses(book, chapter) {
|
|
42
64
|
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === book)
|
|
43
65
|
return singleChapterBook ? singleChapterBook[book][chapter] || [] : this.chapterVerses[book]?.[chapter] || []
|
|
44
66
|
}
|
|
45
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Scans text for scripture references and stores them in `this.found`.
|
|
70
|
+
* @param {string} text - The text to scan.
|
|
71
|
+
* @returns {CodexParser} The parser instance for method chaining.
|
|
72
|
+
*/
|
|
46
73
|
scan(text) {
|
|
47
74
|
const fullNames = [...this.bible.old, ...this.bible.new]
|
|
48
75
|
const abbreviations = Object.keys(this.abbreviations)
|
|
49
76
|
this.found = []
|
|
77
|
+
// Normalize text: replace periods before digits with colons, remove trailing periods, collapse spaces
|
|
50
78
|
let normalizedText = text
|
|
51
79
|
.replace(/\.(?=\d)/g, ":")
|
|
52
80
|
.replace(/(\b[A-Za-z]+)\.(?=\s|$)/g, "$1")
|
|
@@ -56,7 +84,9 @@ class CodexParser {
|
|
|
56
84
|
const lowerCaseText = normalizedText.toLowerCase()
|
|
57
85
|
let i = 0
|
|
58
86
|
|
|
87
|
+
// Check if a character is valid for chapter/verse (non-letter)
|
|
59
88
|
const isValidChapterVerseChar = (char) => /[^A-Za-z]/.test(char)
|
|
89
|
+
// Check if the next segment starts with a Bible book
|
|
60
90
|
const isNextBibleBook = (startIndex) => {
|
|
61
91
|
const textAfterCurrentPosition = lowerCaseText.substring(startIndex).trim()
|
|
62
92
|
return (
|
|
@@ -64,16 +94,19 @@ class CodexParser {
|
|
|
64
94
|
lowercaseBibleAbbreviations.some((abbr) => textAfterCurrentPosition.startsWith(abbr))
|
|
65
95
|
)
|
|
66
96
|
}
|
|
97
|
+
// Detect version suffix (LXX or MT)
|
|
67
98
|
const detectSuffix = (startIndex) => {
|
|
68
99
|
const suffixMatch = normalizedText.substring(startIndex).match(/\b(LXX|MT)\b/i)
|
|
69
100
|
return suffixMatch ? suffixMatch[0].toUpperCase() : null
|
|
70
101
|
}
|
|
71
102
|
|
|
103
|
+
// Iterate through text to find book names or abbreviations
|
|
72
104
|
while (i < lowerCaseText.length) {
|
|
73
105
|
let foundBook = null
|
|
74
106
|
let foundIndex = -1
|
|
75
107
|
let matchedLength = 0
|
|
76
108
|
|
|
109
|
+
// Check for full book names
|
|
77
110
|
for (let j = 0; j < lowercaseBibleFullNames.length; j++) {
|
|
78
111
|
const book = lowercaseBibleFullNames[j]
|
|
79
112
|
if (lowerCaseText.startsWith(book, i) && book.length > matchedLength) {
|
|
@@ -83,6 +116,7 @@ class CodexParser {
|
|
|
83
116
|
}
|
|
84
117
|
}
|
|
85
118
|
|
|
119
|
+
// Check for abbreviations if no full name found
|
|
86
120
|
if (!foundBook) {
|
|
87
121
|
for (let k = 0; k < lowercaseBibleAbbreviations.length; k++) {
|
|
88
122
|
const abbreviation = lowercaseBibleAbbreviations[k]
|
|
@@ -99,6 +133,7 @@ class CodexParser {
|
|
|
99
133
|
let chapterVerse = ""
|
|
100
134
|
const references = []
|
|
101
135
|
|
|
136
|
+
// Collect chapter-verse reference until next book or invalid character
|
|
102
137
|
while (i < normalizedText.length && isValidChapterVerseChar(normalizedText[i])) {
|
|
103
138
|
if (isNextBibleBook(i)) break
|
|
104
139
|
if (normalizedText[i] === ";") {
|
|
@@ -112,6 +147,7 @@ class CodexParser {
|
|
|
112
147
|
i++
|
|
113
148
|
}
|
|
114
149
|
|
|
150
|
+
// Add final reference if present
|
|
115
151
|
if (chapterVerse.trim().length > 0) {
|
|
116
152
|
const formattedReference = chapterVerse.trim().replace(/[^a-zA-Z0-9]+$/, "")
|
|
117
153
|
if (formattedReference) references.push(formattedReference)
|
|
@@ -119,6 +155,7 @@ class CodexParser {
|
|
|
119
155
|
|
|
120
156
|
const suffix = detectSuffix(i)
|
|
121
157
|
|
|
158
|
+
// Process each reference and determine its type
|
|
122
159
|
references.forEach((ref) => {
|
|
123
160
|
let type
|
|
124
161
|
if (ref.includes(":")) {
|
|
@@ -159,6 +196,11 @@ class CodexParser {
|
|
|
159
196
|
return this
|
|
160
197
|
}
|
|
161
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Sets the Bible version for parsing.
|
|
201
|
+
* @param {string} version - The version (e.g., "lxx", "mt", "eng").
|
|
202
|
+
* @returns {CodexParser} The parser instance.
|
|
203
|
+
*/
|
|
162
204
|
bibleVersion(version) {
|
|
163
205
|
const lowerVersion = version.toLowerCase()
|
|
164
206
|
this.version =
|
|
@@ -168,6 +210,11 @@ class CodexParser {
|
|
|
168
210
|
return this
|
|
169
211
|
}
|
|
170
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Parses a scripture reference into structured passage objects.
|
|
215
|
+
* @param {string} reference - The reference to parse (e.g., "John 3:16").
|
|
216
|
+
* @returns {CodexParser} The parser instance.
|
|
217
|
+
*/
|
|
171
218
|
parse(reference) {
|
|
172
219
|
this.scan(reference)
|
|
173
220
|
|
|
@@ -190,12 +237,13 @@ class CodexParser {
|
|
|
190
237
|
end: null,
|
|
191
238
|
}
|
|
192
239
|
|
|
240
|
+
// Parse reference parts (chapter, verses, ranges)
|
|
193
241
|
this.parseReferenceParts(parsedPassage, passage.reference.split(","))
|
|
194
242
|
parsedPassage.passages = this.populate(parsedPassage)
|
|
195
243
|
parsedPassage.scripture = this.scripturize(parsedPassage)
|
|
196
244
|
parsedPassage.valid = this._isValid(parsedPassage, passage.reference)
|
|
197
245
|
|
|
198
|
-
//
|
|
246
|
+
// Generate SBL abbreviation with conditional period
|
|
199
247
|
const sblEntry = this.sblAbbreviations[book] || { value: book, abbr: false }
|
|
200
248
|
const sblBook = sblEntry.value + (sblEntry.abbr ? "." : "")
|
|
201
249
|
let abbr = parsedPassage.scripture.passage.replace(book, sblBook).replace(/-/g, "–")
|
|
@@ -205,12 +253,14 @@ class CodexParser {
|
|
|
205
253
|
}
|
|
206
254
|
parsedPassage.abbr = abbr
|
|
207
255
|
|
|
256
|
+
// Handle multi-chapter ranges
|
|
208
257
|
if (parsedPassage.type === this.MULTI_CHAPTER_RANGE) {
|
|
209
258
|
this.handleMultiChapterRange(parsedPassage, passage.reference)
|
|
210
259
|
} else {
|
|
211
260
|
delete parsedPassage.to
|
|
212
261
|
}
|
|
213
262
|
|
|
263
|
+
// Set start and end points for passage range
|
|
214
264
|
if (parsedPassage.passages.length > 0) {
|
|
215
265
|
const sortedPassages = parsedPassage.passages.slice().sort((a, b) => {
|
|
216
266
|
if (a.chapter !== b.chapter) return a.chapter - b.chapter
|
|
@@ -230,6 +280,7 @@ class CodexParser {
|
|
|
230
280
|
}
|
|
231
281
|
}
|
|
232
282
|
|
|
283
|
+
// Default to English version if none specified
|
|
233
284
|
if (!parsedPassage.version) {
|
|
234
285
|
parsedPassage.version = {
|
|
235
286
|
name: "English",
|
|
@@ -238,7 +289,7 @@ class CodexParser {
|
|
|
238
289
|
}
|
|
239
290
|
}
|
|
240
291
|
|
|
241
|
-
// Attach
|
|
292
|
+
// Attach reference method to passage
|
|
242
293
|
parsedPassage.reference = function () {
|
|
243
294
|
return this.scripture.passage
|
|
244
295
|
}
|
|
@@ -250,6 +301,12 @@ class CodexParser {
|
|
|
250
301
|
return this
|
|
251
302
|
}
|
|
252
303
|
|
|
304
|
+
/**
|
|
305
|
+
* Parses reference parts into chapter and verse components.
|
|
306
|
+
* @param {Object} passage - The passage object to populate.
|
|
307
|
+
* @param {string[]} parts - Array of reference parts.
|
|
308
|
+
* @private
|
|
309
|
+
*/
|
|
253
310
|
parseReferenceParts(passage, parts) {
|
|
254
311
|
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === passage.book)
|
|
255
312
|
|
|
@@ -269,6 +326,13 @@ class CodexParser {
|
|
|
269
326
|
})
|
|
270
327
|
}
|
|
271
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Parses chapter-verse references (e.g., "3:16").
|
|
331
|
+
* @param {Object} passage - The passage object.
|
|
332
|
+
* @param {string} part - The reference part.
|
|
333
|
+
* @param {boolean} isFirstPart - Whether this is the first part.
|
|
334
|
+
* @private
|
|
335
|
+
*/
|
|
272
336
|
parseChapterVerse(passage, part, isFirstPart) {
|
|
273
337
|
const [chapter, verse] = part.split(":")
|
|
274
338
|
if (isFirstPart) passage.chapter = Number(chapter)
|
|
@@ -276,6 +340,13 @@ class CodexParser {
|
|
|
276
340
|
passage.verses.push(verse.includes("-") ? verse : Number(verse))
|
|
277
341
|
}
|
|
278
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Parses references for single-chapter books (e.g., "Jude 5").
|
|
345
|
+
* @param {Object} passage - The passage object.
|
|
346
|
+
* @param {string} part - The reference part.
|
|
347
|
+
* @param {boolean} isWholeChapter - Whether the reference is for the whole chapter.
|
|
348
|
+
* @private
|
|
349
|
+
*/
|
|
279
350
|
parseSingleChapterBook(passage, part, isWholeChapter) {
|
|
280
351
|
const verseCount = this.getChapterVerses(passage.book, 1).length
|
|
281
352
|
if (part === "1" && isWholeChapter) {
|
|
@@ -296,6 +367,13 @@ class CodexParser {
|
|
|
296
367
|
}
|
|
297
368
|
}
|
|
298
369
|
|
|
370
|
+
/**
|
|
371
|
+
* Parses range references (e.g., "1-3").
|
|
372
|
+
* @param {Object} passage - The passage object.
|
|
373
|
+
* @param {string} part - The reference part.
|
|
374
|
+
* @param {boolean} isFirstPart - Whether this is the first part.
|
|
375
|
+
* @private
|
|
376
|
+
*/
|
|
299
377
|
parseRange(passage, part, isFirstPart) {
|
|
300
378
|
if (!passage.chapter && isFirstPart) {
|
|
301
379
|
const [start, end] = part.split("-").map(Number)
|
|
@@ -318,6 +396,13 @@ class CodexParser {
|
|
|
318
396
|
}
|
|
319
397
|
}
|
|
320
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Parses single number references (e.g., "3" for chapter or verse).
|
|
401
|
+
* @param {Object} passage - The passage object.
|
|
402
|
+
* @param {string} part - The reference part.
|
|
403
|
+
* @param {boolean} isFirstPart - Whether this is the first part.
|
|
404
|
+
* @private
|
|
405
|
+
*/
|
|
321
406
|
parseSingleNumber(passage, part, isFirstPart) {
|
|
322
407
|
if (isFirstPart && !passage.chapter) {
|
|
323
408
|
passage.chapter = Number(part)
|
|
@@ -332,6 +417,12 @@ class CodexParser {
|
|
|
332
417
|
}
|
|
333
418
|
}
|
|
334
419
|
|
|
420
|
+
/**
|
|
421
|
+
* Handles multi-chapter range references (e.g., "3:16-4:5").
|
|
422
|
+
* @param {Object} passage - The passage object.
|
|
423
|
+
* @param {string} reference - The full reference string.
|
|
424
|
+
* @private
|
|
425
|
+
*/
|
|
335
426
|
handleMultiChapterRange(passage, reference) {
|
|
336
427
|
const parts = reference.split(",")
|
|
337
428
|
const lastPart = parts[parts.length - 1]
|
|
@@ -345,6 +436,13 @@ class CodexParser {
|
|
|
345
436
|
}
|
|
346
437
|
}
|
|
347
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Generates a range of numbers.
|
|
441
|
+
* @param {number} start - Start number.
|
|
442
|
+
* @param {number} end - End number.
|
|
443
|
+
* @returns {number[]} Array of numbers.
|
|
444
|
+
* @private
|
|
445
|
+
*/
|
|
348
446
|
_generateRange(start, end) {
|
|
349
447
|
const range = []
|
|
350
448
|
for (let i = start; i <= end; i++) {
|
|
@@ -353,10 +451,47 @@ class CodexParser {
|
|
|
353
451
|
return range
|
|
354
452
|
}
|
|
355
453
|
|
|
454
|
+
/**
|
|
455
|
+
* Searches for versification differences for a book and chapter.
|
|
456
|
+
* @param {string} book - The book name.
|
|
457
|
+
* @param {number} chapter - The chapter number.
|
|
458
|
+
* @param {string} version - The Bible version.
|
|
459
|
+
* @returns {Object|undefined} Updated chapter verses or undefined.
|
|
460
|
+
* @private
|
|
461
|
+
*/
|
|
356
462
|
_searchVersificationDifferences(book, chapter, version) {
|
|
357
463
|
version = version.toLowerCase()
|
|
358
|
-
|
|
359
|
-
|
|
464
|
+
|
|
465
|
+
// Handle single-chapter book "Obadiah"
|
|
466
|
+
if (book === "Obadiah") {
|
|
467
|
+
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === "Obadiah")
|
|
468
|
+
if (!singleChapterBook || !singleChapterBook[book][chapter]) {
|
|
469
|
+
return // No data for Obadiah or chapter
|
|
470
|
+
}
|
|
471
|
+
if (!this.versificationDifferences[book]) {
|
|
472
|
+
return // No versification differences for Obadiah
|
|
473
|
+
}
|
|
474
|
+
// Process versification differences
|
|
475
|
+
for (const [key, value] of Object.entries(this.versificationDifferences[book])) {
|
|
476
|
+
if (value[version].startsWith(`${chapter}:`)) {
|
|
477
|
+
if (value[version]) {
|
|
478
|
+
const verse = value[version].split(":")[1]
|
|
479
|
+
singleChapterBook[book][chapter].push(Number(verse))
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
// Ensure unique verses and update the singleChapterBook entry
|
|
484
|
+
singleChapterBook[book][chapter] = Array.from(new Set(singleChapterBook[book][chapter]))
|
|
485
|
+
return singleChapterBook[book] // Return updated chapter data
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Handle all other books using chapterVerses
|
|
489
|
+
if (!this.chapterVerses[book][chapter]) {
|
|
490
|
+
return // No data for this book/chapter
|
|
491
|
+
}
|
|
492
|
+
if (!this.versificationDifferences[book]) {
|
|
493
|
+
return // No versification differences
|
|
494
|
+
}
|
|
360
495
|
for (const [key, value] of Object.entries(this.versificationDifferences[book])) {
|
|
361
496
|
if (value[version].startsWith(`${chapter}:`)) {
|
|
362
497
|
if (value[version]) {
|
|
@@ -366,9 +501,16 @@ class CodexParser {
|
|
|
366
501
|
}
|
|
367
502
|
}
|
|
368
503
|
this.chapterVerses[book][chapter] = Array.from(this.chapterVerses[book][chapter])
|
|
369
|
-
return this.chapterVerses
|
|
504
|
+
return this.chapterVerses // Return updated chapterVerses
|
|
370
505
|
}
|
|
371
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Sets the Bible version and applies versification differences.
|
|
509
|
+
* @param {string} book - The book name.
|
|
510
|
+
* @param {number} chapter - The chapter number.
|
|
511
|
+
* @param {string} version - The Bible version.
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
372
514
|
_setVersion(book, chapter, version) {
|
|
373
515
|
this.version = version ? version : "eng"
|
|
374
516
|
if (this.version !== "eng") {
|
|
@@ -376,6 +518,9 @@ class CodexParser {
|
|
|
376
518
|
}
|
|
377
519
|
}
|
|
378
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Applies versification differences to parsed passages.
|
|
523
|
+
*/
|
|
379
524
|
versification() {
|
|
380
525
|
this.passages.forEach((passage) => {
|
|
381
526
|
const hasVersification = this.versificationDifferences[passage.book]
|
|
@@ -407,6 +552,11 @@ class CodexParser {
|
|
|
407
552
|
})
|
|
408
553
|
}
|
|
409
554
|
|
|
555
|
+
/**
|
|
556
|
+
* Populates passage with expanded verse objects.
|
|
557
|
+
* @param {Object} passage - The passage object.
|
|
558
|
+
* @returns {Object[]} Array of verse objects.
|
|
559
|
+
*/
|
|
410
560
|
populate(passage) {
|
|
411
561
|
const { book, chapter, verses, type, to } = passage
|
|
412
562
|
const version = passage.version?.abbreviation || "eng"
|
|
@@ -449,6 +599,13 @@ class CodexParser {
|
|
|
449
599
|
return []
|
|
450
600
|
}
|
|
451
601
|
|
|
602
|
+
/**
|
|
603
|
+
* Expands verse references into individual verse objects.
|
|
604
|
+
* @param {string} book - The book name.
|
|
605
|
+
* @param {number} chapter - The chapter number.
|
|
606
|
+
* @param {Array<string|number>} verses - Array of verses or ranges.
|
|
607
|
+
* @returns {Object[]} Array of verse objects.
|
|
608
|
+
*/
|
|
452
609
|
expandVerses(book, chapter, verses) {
|
|
453
610
|
const passages = []
|
|
454
611
|
const chapterVerses = this.getChapterVerses(book, chapter)
|
|
@@ -466,6 +623,11 @@ class CodexParser {
|
|
|
466
623
|
return passages
|
|
467
624
|
}
|
|
468
625
|
|
|
626
|
+
/**
|
|
627
|
+
* Normalizes book names using abbreviations or full names.
|
|
628
|
+
* @param {string|Array} book - The book name or array.
|
|
629
|
+
* @returns {string} Normalized book name.
|
|
630
|
+
*/
|
|
469
631
|
bookify(book) {
|
|
470
632
|
if (typeof book !== "string") {
|
|
471
633
|
book = book[0]
|
|
@@ -487,6 +649,10 @@ class CodexParser {
|
|
|
487
649
|
return bookified
|
|
488
650
|
}
|
|
489
651
|
|
|
652
|
+
/**
|
|
653
|
+
* Returns parsed passages with utility methods.
|
|
654
|
+
* @returns {Object[]} Array of passages with methods.
|
|
655
|
+
*/
|
|
490
656
|
getPassages() {
|
|
491
657
|
const passagesArray = [...this.passages]
|
|
492
658
|
|
|
@@ -553,10 +719,19 @@ class CodexParser {
|
|
|
553
719
|
return passagesArray
|
|
554
720
|
}
|
|
555
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Returns the first parsed passage.
|
|
724
|
+
* @returns {Object|null} The first passage or null.
|
|
725
|
+
*/
|
|
556
726
|
first() {
|
|
557
727
|
return this.passages.length > 0 ? this.passages[0] : null
|
|
558
728
|
}
|
|
559
729
|
|
|
730
|
+
/**
|
|
731
|
+
* Formats a passage into a human-readable reference.
|
|
732
|
+
* @param {Object} passage - The passage object.
|
|
733
|
+
* @returns {Object} Formatted passage data.
|
|
734
|
+
*/
|
|
560
735
|
scripturize(passage) {
|
|
561
736
|
const formatChapterVerse = (chapter, verses) => {
|
|
562
737
|
if (!chapter || !verses || verses.length === 0) return ""
|
|
@@ -602,6 +777,11 @@ class CodexParser {
|
|
|
602
777
|
}
|
|
603
778
|
}
|
|
604
779
|
|
|
780
|
+
/**
|
|
781
|
+
* Combines multiple passages into a single reference.
|
|
782
|
+
* @param {Object[]} passages - Array of passages to combine.
|
|
783
|
+
* @returns {Object} Combined passage object.
|
|
784
|
+
*/
|
|
605
785
|
combine(passages) {
|
|
606
786
|
if (!passages || passages.length === 0) {
|
|
607
787
|
throw new Error("No passages provided to join.")
|
|
@@ -717,6 +897,11 @@ class CodexParser {
|
|
|
717
897
|
return combined
|
|
718
898
|
}
|
|
719
899
|
|
|
900
|
+
/**
|
|
901
|
+
* Merges verses into ranges or comma-separated lists.
|
|
902
|
+
* @param {number[]} verses - Array of verse numbers.
|
|
903
|
+
* @returns {string[]} Array of verse strings.
|
|
904
|
+
*/
|
|
720
905
|
mergeRanges(verses) {
|
|
721
906
|
const sortedVerses = [...new Set(verses)].sort((a, b) => a - b)
|
|
722
907
|
const merged = []
|
|
@@ -746,6 +931,11 @@ class CodexParser {
|
|
|
746
931
|
return merged
|
|
747
932
|
}
|
|
748
933
|
|
|
934
|
+
/**
|
|
935
|
+
* Generates a table of contents for the Bible.
|
|
936
|
+
* @param {string} [version="ESV"] - The Bible version.
|
|
937
|
+
* @returns {Object} TOC with book-chapter-verse mappings.
|
|
938
|
+
*/
|
|
749
939
|
getToc(version = "ESV") {
|
|
750
940
|
const toc = {}
|
|
751
941
|
this.bible.old.forEach((book) => {
|
|
@@ -775,6 +965,13 @@ class CodexParser {
|
|
|
775
965
|
return orderedToc
|
|
776
966
|
}
|
|
777
967
|
|
|
968
|
+
/**
|
|
969
|
+
* Validates a passage for correctness.
|
|
970
|
+
* @param {Object} passage - The passage object.
|
|
971
|
+
* @param {string} reference - The original reference.
|
|
972
|
+
* @returns {boolean|Object} True if valid, error object if invalid.
|
|
973
|
+
* @private
|
|
974
|
+
*/
|
|
778
975
|
_isValid(passage, reference) {
|
|
779
976
|
const { book, chapter, verses, type } = passage
|
|
780
977
|
|
|
@@ -806,6 +1003,15 @@ class CodexParser {
|
|
|
806
1003
|
return this.validateVerses(book, chapter, verses, reference)
|
|
807
1004
|
}
|
|
808
1005
|
|
|
1006
|
+
/**
|
|
1007
|
+
* Validates verse numbers for a chapter.
|
|
1008
|
+
* @param {string} book - The book name.
|
|
1009
|
+
* @param {number} chapter - The chapter number.
|
|
1010
|
+
* @param {Array<string|number>} verses - Array of verses or ranges.
|
|
1011
|
+
* @param {string} reference - The original reference.
|
|
1012
|
+
* @returns {boolean|Object} True if valid, error object if invalid.
|
|
1013
|
+
* @private
|
|
1014
|
+
*/
|
|
809
1015
|
validateVerses(book, chapter, verses, reference) {
|
|
810
1016
|
const chapterVerses = this.getChapterVerses(book, chapter)
|
|
811
1017
|
for (const verse of verses) {
|
|
@@ -826,6 +1032,13 @@ class CodexParser {
|
|
|
826
1032
|
return true
|
|
827
1033
|
}
|
|
828
1034
|
|
|
1035
|
+
/**
|
|
1036
|
+
* Creates an error object for validation failures.
|
|
1037
|
+
* @param {number} code - Error code.
|
|
1038
|
+
* @param {string} message - Error message.
|
|
1039
|
+
* @returns {Object} Error object.
|
|
1040
|
+
* @private
|
|
1041
|
+
*/
|
|
829
1042
|
validationError(code, message) {
|
|
830
1043
|
return {
|
|
831
1044
|
error: true,
|
|
@@ -834,6 +1047,13 @@ class CodexParser {
|
|
|
834
1047
|
}
|
|
835
1048
|
}
|
|
836
1049
|
|
|
1050
|
+
/**
|
|
1051
|
+
* Determines the Bible version for a passage.
|
|
1052
|
+
* @param {string} version - The version (e.g., "lxx").
|
|
1053
|
+
* @param {string} testament - The testament ("old" or "new").
|
|
1054
|
+
* @returns {Object} Version object.
|
|
1055
|
+
* @private
|
|
1056
|
+
*/
|
|
837
1057
|
_handleVersion(version, testament) {
|
|
838
1058
|
const effectiveVersion = this.version || version || "eng"
|
|
839
1059
|
const lowerVersion = effectiveVersion.toLowerCase()
|