codexparser 0.1.53 → 0.1.55
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 +155 -56
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codexparser",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
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
|
@@ -191,6 +191,7 @@ class CodexParser {
|
|
|
191
191
|
this.passages = this.found.map((passage) => {
|
|
192
192
|
const book = this.bookify(passage.book)
|
|
193
193
|
const testament = this.bible.old.includes(book) ? "old" : "new"
|
|
194
|
+
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === book)
|
|
194
195
|
const parsedPassage = {
|
|
195
196
|
original: passage.book + " " + passage.reference,
|
|
196
197
|
book: book,
|
|
@@ -202,42 +203,81 @@ class CodexParser {
|
|
|
202
203
|
version: this._handleVersion(passage.version, testament),
|
|
203
204
|
}
|
|
204
205
|
|
|
205
|
-
// Split reference into parts (e.g., "
|
|
206
|
+
// Split reference into parts (e.g., "Matthew 1", "2 John 2", "Matthew 1:1-3,5")
|
|
206
207
|
const parts = passage.reference.split(",")
|
|
207
208
|
|
|
208
209
|
parts.forEach((part, partIndex) => {
|
|
209
210
|
part = part.trim()
|
|
210
211
|
|
|
211
212
|
if (part.includes(":")) {
|
|
212
|
-
// Explicit chapter:verse (e.g., "
|
|
213
|
+
// Explicit chapter:verse (e.g., "1:1-3")
|
|
213
214
|
const [chapterPart, versePart] = part.split(":")
|
|
214
215
|
if (partIndex === 0) {
|
|
215
216
|
parsedPassage.chapter = Number(chapterPart) // Set chapter only on first part
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
if (versePart.includes("-")) {
|
|
219
|
-
//
|
|
220
|
-
parsedPassage.verses.push(versePart)
|
|
220
|
+
parsedPassage.verses.push(versePart) // Add range (e.g., "1-3")
|
|
221
221
|
} else {
|
|
222
|
-
parsedPassage.verses.push(Number(versePart))
|
|
222
|
+
parsedPassage.verses.push(Number(versePart)) // Add single verse
|
|
223
223
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
parsedPassage.
|
|
224
|
+
parsedPassage.type = versePart.includes("-") ? "chapter_verse_range" : "chapter_verse"
|
|
225
|
+
} else if (singleChapterBook) {
|
|
226
|
+
// Handle single-chapter books
|
|
227
|
+
const verseCount = singleChapterBook[book][1].length
|
|
228
|
+
if (part === "1" && parts.length === 1 && partIndex === 0) {
|
|
229
|
+
// "2 John 1" means the whole chapter
|
|
230
|
+
parsedPassage.chapter = 1
|
|
231
|
+
parsedPassage.type = "single_chapter"
|
|
232
|
+
parsedPassage.verses = [`1-${verseCount}`] // e.g., "1-13"
|
|
233
|
+
} else if (part.includes("-")) {
|
|
234
|
+
// "2 John 2-5" → "2 John 1:2-5"
|
|
235
|
+
parsedPassage.chapter = 1
|
|
236
|
+
parsedPassage.verses.push(part) // e.g., "2-5"
|
|
237
|
+
parsedPassage.type = "chapter_verse_range"
|
|
231
238
|
} else {
|
|
232
|
-
|
|
239
|
+
// "2 John 2" → "2 John 1:2"
|
|
240
|
+
const num = Number(part)
|
|
241
|
+
if (num > 1 || (num === 1 && parts.length > 1)) {
|
|
242
|
+
parsedPassage.chapter = 1
|
|
243
|
+
parsedPassage.verses.push(num) // Treat as verse number
|
|
244
|
+
parsedPassage.type = "chapter_verse"
|
|
245
|
+
}
|
|
233
246
|
}
|
|
247
|
+
} else if (part.includes("-") && !parsedPassage.chapter) {
|
|
248
|
+
// Range without chapter for multi-chapter books (e.g., "Matthew 3-5")
|
|
249
|
+
const [start, end] = part.split("-").map(Number)
|
|
250
|
+
parsedPassage.chapter = start
|
|
251
|
+
parsedPassage.verses = [
|
|
252
|
+
`${this.chapterVerses[book][start][0]}-${this.chapterVerses[book][start].slice(-1)[0]}`,
|
|
253
|
+
]
|
|
254
|
+
parsedPassage.to = {
|
|
255
|
+
book,
|
|
256
|
+
chapter: end,
|
|
257
|
+
verses: [`${this.chapterVerses[book][end][0]}-${this.chapterVerses[book][end].slice(-1)[0]}`],
|
|
258
|
+
}
|
|
259
|
+
parsedPassage.type = "chapter_range"
|
|
260
|
+
} else if (part.includes("-")) {
|
|
261
|
+
// Verse range in current chapter (e.g., "8-9" after "40:3-5")
|
|
262
|
+
parsedPassage.verses.push(part)
|
|
263
|
+
parsedPassage.type = "chapter_verse_range"
|
|
234
264
|
} else {
|
|
235
|
-
// Single verse
|
|
236
|
-
if (parsedPassage.chapter
|
|
237
|
-
|
|
238
|
-
parsedPassage.
|
|
265
|
+
// Single number (chapter or verse) for multi-chapter books
|
|
266
|
+
if (partIndex === 0 && !parsedPassage.chapter) {
|
|
267
|
+
parsedPassage.chapter = Number(part)
|
|
268
|
+
parsedPassage.type = "single_chapter"
|
|
269
|
+
// For multi-chapter books, set verses to full chapter range
|
|
270
|
+
if (
|
|
271
|
+
!singleChapterBook &&
|
|
272
|
+
this.chapterVerses[book] &&
|
|
273
|
+
this.chapterVerses[book][parsedPassage.chapter]
|
|
274
|
+
) {
|
|
275
|
+
const chapterVerses = this.chapterVerses[book][parsedPassage.chapter]
|
|
276
|
+
parsedPassage.verses = [`${chapterVerses[0]}-${chapterVerses[chapterVerses.length - 1]}`]
|
|
277
|
+
}
|
|
239
278
|
} else {
|
|
240
279
|
parsedPassage.verses.push(Number(part))
|
|
280
|
+
parsedPassage.type = "comma_separated_verses"
|
|
241
281
|
}
|
|
242
282
|
}
|
|
243
283
|
})
|
|
@@ -260,7 +300,7 @@ class CodexParser {
|
|
|
260
300
|
verses: endVerse.includes("-") ? [endVerse] : [Number(endVerse)],
|
|
261
301
|
}
|
|
262
302
|
} else {
|
|
263
|
-
delete parsedPassage.to //
|
|
303
|
+
delete parsedPassage.to // Remove erroneous 'to' property
|
|
264
304
|
}
|
|
265
305
|
|
|
266
306
|
return parsedPassage
|
|
@@ -345,20 +385,6 @@ class CodexParser {
|
|
|
345
385
|
})
|
|
346
386
|
}
|
|
347
387
|
|
|
348
|
-
/**
|
|
349
|
-
* Populate a Set of passages from entities.start.v to entities.end.v,
|
|
350
|
-
* and then add any additional verses from the verses array.
|
|
351
|
-
*
|
|
352
|
-
* @param {Object} entities - Entities object from the bible-passage-reference-parser
|
|
353
|
-
* @param {Array} verses - Array of verse numbers to add to the set of passages
|
|
354
|
-
* @return {Array} Array of passage objects
|
|
355
|
-
*/
|
|
356
|
-
/**
|
|
357
|
-
* Populate all verses from a parsed passage, including all verses in ranges or chapters.
|
|
358
|
-
*
|
|
359
|
-
* @param {Object} parsedPassage - The parsed passage object containing book, chapter, and verses information.
|
|
360
|
-
* @return {Array} An array of passage objects with individual verses.
|
|
361
|
-
*/
|
|
362
388
|
/**
|
|
363
389
|
* Populate all verses from a parsed passage, including all verses in ranges or chapters.
|
|
364
390
|
*
|
|
@@ -371,15 +397,24 @@ class CodexParser {
|
|
|
371
397
|
const version = parsedPassage.version ? parsedPassage.version.abbreviation : "eng"
|
|
372
398
|
this._setVersion(book, chapter, version) // Set version data if needed
|
|
373
399
|
|
|
400
|
+
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === book)
|
|
401
|
+
|
|
374
402
|
if (type === "single_chapter") {
|
|
375
|
-
// Handle entire chapter references (e.g., "Isaiah 40")
|
|
376
|
-
if (
|
|
403
|
+
// Handle entire chapter references (e.g., "Isaiah 40" or "2 John 1")
|
|
404
|
+
if (singleChapterBook) {
|
|
405
|
+
// Single-chapter book: populate all verses from singleChapterBook
|
|
406
|
+
const verseCount = singleChapterBook[book][1].length
|
|
407
|
+
for (let verse = 1; verse <= verseCount; verse++) {
|
|
408
|
+
passages.push({ book, chapter: 1, verse })
|
|
409
|
+
}
|
|
410
|
+
} else if (this.chapterVerses[book] && this.chapterVerses[book][chapter]) {
|
|
411
|
+
// Multi-chapter book: populate all verses in the chapter
|
|
377
412
|
this.chapterVerses[book][chapter].forEach((verse) => {
|
|
378
413
|
passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
|
|
379
414
|
})
|
|
380
415
|
}
|
|
381
416
|
} else if (type === "comma_separated_verses" || type === "chapter_verse_range") {
|
|
382
|
-
// Handle comma-separated verses or single-chapter verse ranges (e.g., "Isaiah 40:3-5,8-9" or "
|
|
417
|
+
// Handle comma-separated verses or single-chapter verse ranges (e.g., "Isaiah 40:3-5,8-9" or "2 John 1:1-3")
|
|
383
418
|
verses.forEach((verse) => {
|
|
384
419
|
if (typeof verse === "string" && verse.includes("-")) {
|
|
385
420
|
const [start, end] = verse.split("-").map(Number)
|
|
@@ -419,7 +454,7 @@ class CodexParser {
|
|
|
419
454
|
}
|
|
420
455
|
}
|
|
421
456
|
} else if (type === "chapter_verse") {
|
|
422
|
-
// Handle single chapter:verse references (e.g., "
|
|
457
|
+
// Handle single chapter:verse references (e.g., "2 John 1:1")
|
|
423
458
|
verses.forEach((verse) => {
|
|
424
459
|
passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
|
|
425
460
|
})
|
|
@@ -727,31 +762,35 @@ class CodexParser {
|
|
|
727
762
|
return orderedToc
|
|
728
763
|
}
|
|
729
764
|
|
|
765
|
+
/**
|
|
766
|
+
* Validates a parsed passage to ensure the chapter and verses exist.
|
|
767
|
+
*
|
|
768
|
+
* @param {Object} passage - The parsed passage object to validate.
|
|
769
|
+
* @param {string} reference - The original reference string for error messaging.
|
|
770
|
+
* @return {boolean|Object} True if valid, or an error object if invalid.
|
|
771
|
+
*/
|
|
730
772
|
_isValid(passage, reference) {
|
|
731
|
-
const singleChapterBook = this.singleChapterBook.find((
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
message: {
|
|
737
|
-
chapter_exists: false,
|
|
738
|
-
content: "Possible invalid chapter: " + reference,
|
|
739
|
-
},
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
if (!singleChapterBook) {
|
|
743
|
-
if (!this.chapterVerses[passage.book][passage.chapter]) {
|
|
773
|
+
const singleChapterBook = this.singleChapterBook.find((b) => Object.keys(b)[0] === passage.book)
|
|
774
|
+
|
|
775
|
+
// Check if verses exist at all
|
|
776
|
+
if (!passage.verses || passage.verses.length === 0) {
|
|
777
|
+
if (passage.type !== "single_chapter") {
|
|
744
778
|
return {
|
|
745
779
|
error: true,
|
|
746
|
-
code:
|
|
780
|
+
code: 101,
|
|
747
781
|
message: {
|
|
748
782
|
chapter_exists: false,
|
|
749
|
-
content:
|
|
783
|
+
content: "Possible invalid chapter: " + reference,
|
|
750
784
|
},
|
|
751
785
|
}
|
|
752
786
|
}
|
|
753
|
-
}
|
|
754
|
-
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Handle single-chapter books
|
|
790
|
+
if (singleChapterBook) {
|
|
791
|
+
const verseCount = singleChapterBook[passage.book][1].length
|
|
792
|
+
|
|
793
|
+
if (passage.chapter !== 1) {
|
|
755
794
|
return {
|
|
756
795
|
error: true,
|
|
757
796
|
code: 103,
|
|
@@ -761,19 +800,78 @@ class CodexParser {
|
|
|
761
800
|
},
|
|
762
801
|
}
|
|
763
802
|
}
|
|
803
|
+
|
|
804
|
+
if (passage.type === "single_chapter") {
|
|
805
|
+
// For "2 John 1", validate the full range
|
|
806
|
+
const [range] = passage.verses // e.g., "1-13"
|
|
807
|
+
if (range) {
|
|
808
|
+
const [start, end] = range.split("-").map(Number)
|
|
809
|
+
if (start < 1 || end > verseCount) {
|
|
810
|
+
return {
|
|
811
|
+
error: true,
|
|
812
|
+
code: 104,
|
|
813
|
+
message: {
|
|
814
|
+
verse_exists: false,
|
|
815
|
+
content: `Verse range ${start}-${end} exceeds available verses (1-${verseCount}) in ${passage.book} 1`,
|
|
816
|
+
},
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return true // If no specific verses or range matches, it’s valid
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// For specific verses in single-chapter books (e.g., "2 John 1:1-3")
|
|
824
|
+
for (let i = 0; i < passage.verses.length; i++) {
|
|
825
|
+
const verseRange = String(passage.verses[i])
|
|
826
|
+
let versesToCheck = verseRange.includes("-") ? verseRange.split("-").map(Number) : [Number(verseRange)]
|
|
827
|
+
|
|
828
|
+
if (versesToCheck.length === 2) {
|
|
829
|
+
const [start, end] = versesToCheck
|
|
830
|
+
versesToCheck = Array.from({ length: end - start + 1 }, (_, idx) => start + idx)
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
for (const verse of versesToCheck) {
|
|
834
|
+
if (verse < 1 || verse > verseCount) {
|
|
835
|
+
return {
|
|
836
|
+
error: true,
|
|
837
|
+
code: 104,
|
|
838
|
+
message: {
|
|
839
|
+
verse_exists: false,
|
|
840
|
+
content: `Verse number ${verse} does not exist in ${passage.book} 1`,
|
|
841
|
+
},
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return true
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// Handle multi-chapter books
|
|
850
|
+
if (!this.chapterVerses[passage.book] || !this.chapterVerses[passage.book][passage.chapter]) {
|
|
851
|
+
return {
|
|
852
|
+
error: true,
|
|
853
|
+
code: 102,
|
|
854
|
+
message: {
|
|
855
|
+
chapter_exists: false,
|
|
856
|
+
content: `Chapter ${passage.chapter} does not exist in ${passage.book}`,
|
|
857
|
+
},
|
|
858
|
+
}
|
|
764
859
|
}
|
|
860
|
+
|
|
861
|
+
if (passage.type === "single_chapter") {
|
|
862
|
+
return true // For multi-chapter books, whole chapter is valid if it exists
|
|
863
|
+
}
|
|
864
|
+
|
|
765
865
|
for (let i = 0; i < passage.verses.length; i++) {
|
|
766
866
|
const passageVerses = String(passage.verses[i])
|
|
767
|
-
let verses = passageVerses.split("-").map(Number)
|
|
867
|
+
let verses = passageVerses.includes("-") ? passageVerses.split("-").map(Number) : [Number(passageVerses)]
|
|
768
868
|
|
|
769
869
|
if (verses.length === 2) {
|
|
770
870
|
// Expand the range if there are two numbers
|
|
771
871
|
verses = Array.from({ length: verses[1] - verses[0] + 1 }, (_, index) => verses[0] + index)
|
|
772
872
|
}
|
|
773
873
|
|
|
774
|
-
// The verses array now contains all values between the range or remains as a single value
|
|
775
874
|
for (const verse of verses) {
|
|
776
|
-
// Check if the verse exists in the chapterVerses structure
|
|
777
875
|
const isValidVerse =
|
|
778
876
|
this.chapterVerses[passage.book] &&
|
|
779
877
|
this.chapterVerses[passage.book][passage.chapter] &&
|
|
@@ -791,6 +889,7 @@ class CodexParser {
|
|
|
791
889
|
}
|
|
792
890
|
}
|
|
793
891
|
}
|
|
892
|
+
|
|
794
893
|
return true
|
|
795
894
|
}
|
|
796
895
|
_handleVersion(version, testament) {
|