codexparser 0.1.29 → 0.1.30
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 +102 -72
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codexparser",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
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
|
@@ -223,7 +223,7 @@ class CodexParser {
|
|
|
223
223
|
i++
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
-
|
|
226
|
+
dump(this.found)
|
|
227
227
|
return this // Return this instance for method chaining
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -476,7 +476,20 @@ class CodexParser {
|
|
|
476
476
|
* @return {array} The passages stored in the object.
|
|
477
477
|
*/
|
|
478
478
|
getPassages() {
|
|
479
|
-
|
|
479
|
+
// Return the array of passages and add a custom first() method to it
|
|
480
|
+
const passagesArray = [...this.passages] // Clone the array to avoid mutation
|
|
481
|
+
|
|
482
|
+
// Add first() method directly to the array
|
|
483
|
+
passagesArray.first = function () {
|
|
484
|
+
return this.length > 0 ? this[0] : null
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return passagesArray
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// New first() method that can be chained after getPassages()
|
|
491
|
+
first() {
|
|
492
|
+
return this.passages.length > 0 ? this.passages[0] : null
|
|
480
493
|
}
|
|
481
494
|
|
|
482
495
|
/**
|
|
@@ -572,96 +585,113 @@ class CodexParser {
|
|
|
572
585
|
* @return {object} The combined passage object.
|
|
573
586
|
*/
|
|
574
587
|
join(passages) {
|
|
575
|
-
const newObject = { ...passages[0] }
|
|
576
|
-
|
|
577
|
-
for (let i = 1; i < passages.length; i++) {
|
|
578
|
-
// Combine passages, but check for duplicates
|
|
579
|
-
passages[i].passages.forEach((passage) => {
|
|
580
|
-
// Add passage only if it's not already in newObject.passages
|
|
581
|
-
const isDuplicate = newObject.passages.some(
|
|
582
|
-
(p) => p.book === passage.book && p.chapter === passage.chapter && p.verse === passage.verse
|
|
583
|
-
)
|
|
584
|
-
if (!isDuplicate) {
|
|
585
|
-
newObject.passages = newObject.passages.concat(passage)
|
|
586
|
-
}
|
|
587
|
-
})
|
|
588
|
-
const verses = passages[i].verses
|
|
589
|
-
for (let j = 0; j < verses.length; j++) {
|
|
590
|
-
const verse = verses[j]
|
|
591
|
-
newObject.verses = newObject.verses.concat(verse)
|
|
592
|
-
}
|
|
593
|
-
}
|
|
588
|
+
const newObject = { ...passages[0] } // Start with the first passage
|
|
594
589
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
return num >= start && num <= end
|
|
603
|
-
}
|
|
604
|
-
return false
|
|
605
|
-
})
|
|
606
|
-
}
|
|
607
|
-
return true // Keep ranges
|
|
590
|
+
const chapters = {} // Store verses by chapters
|
|
591
|
+
const uniquePassages = new Set() // Track unique passages to prevent duplicates
|
|
592
|
+
|
|
593
|
+
// Add initial passages to the unique set to avoid duplication
|
|
594
|
+
newObject.passages.forEach((p) => {
|
|
595
|
+
const passageKey = `${p.book}-${p.chapter}-${p.verse}`
|
|
596
|
+
uniquePassages.add(passageKey)
|
|
608
597
|
})
|
|
609
598
|
|
|
610
|
-
//
|
|
611
|
-
|
|
599
|
+
// Iterate through all the passages and group verses by chapter
|
|
600
|
+
passages.forEach((passage) => {
|
|
601
|
+
if (!chapters[passage.chapter]) {
|
|
602
|
+
chapters[passage.chapter] = new Set() // Use Set to avoid duplicates
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Add verses to their corresponding chapter
|
|
606
|
+
passage.passages.forEach((p) => {
|
|
607
|
+
chapters[p.chapter].add(p.verse)
|
|
612
608
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
const num = Number(v)
|
|
621
|
-
return { start: num, end: num }
|
|
609
|
+
// Create a unique key for each passage (book-chapter-verse)
|
|
610
|
+
const passageKey = `${p.book}-${p.chapter}-${p.verse}`
|
|
611
|
+
|
|
612
|
+
// Add to the passages array if it hasn't been added yet
|
|
613
|
+
if (!uniquePassages.has(passageKey)) {
|
|
614
|
+
newObject.passages.push(p) // Add the passage
|
|
615
|
+
uniquePassages.add(passageKey) // Mark it as added
|
|
622
616
|
}
|
|
623
617
|
})
|
|
618
|
+
})
|
|
624
619
|
|
|
625
|
-
|
|
626
|
-
|
|
620
|
+
// Prepare to build the final result
|
|
621
|
+
const chapterStrings = []
|
|
622
|
+
let firstChapter = null
|
|
623
|
+
let lastChapter = null
|
|
627
624
|
|
|
628
|
-
|
|
629
|
-
|
|
625
|
+
for (const chapter in chapters) {
|
|
626
|
+
const verses = Array.from(chapters[chapter]).sort((a, b) => a - b)
|
|
627
|
+
const mergedVerses = this.mergeRanges(verses) // Merge adjacent verses into ranges
|
|
628
|
+
chapterStrings.push(`${chapter}:${mergedVerses.join(",")}`)
|
|
630
629
|
|
|
631
|
-
|
|
632
|
-
|
|
630
|
+
// Track the first and last chapters for the 'to' key
|
|
631
|
+
if (!firstChapter) firstChapter = Number(chapter) // Ensure chapter is a number
|
|
632
|
+
lastChapter = Number(chapter) // Always update to the current chapter as a number
|
|
633
633
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
} else {
|
|
638
|
-
// No overlap, push the current range and start a new one
|
|
639
|
-
merged.push(currentRange)
|
|
640
|
-
currentRange = nextRange
|
|
641
|
-
}
|
|
634
|
+
// Update the newObject.verses with the merged ranges for the current chapter
|
|
635
|
+
if (Number(chapter) === firstChapter) {
|
|
636
|
+
newObject.verses = mergedVerses
|
|
642
637
|
}
|
|
638
|
+
}
|
|
643
639
|
|
|
644
|
-
|
|
645
|
-
|
|
640
|
+
// Build the final combined object with `to` key for multi-chapter passages
|
|
641
|
+
newObject.original = `${newObject.book} ${firstChapter}:${newObject.verses.join(",")}`
|
|
646
642
|
|
|
647
|
-
|
|
648
|
-
|
|
643
|
+
if (firstChapter !== lastChapter) {
|
|
644
|
+
newObject.to = {
|
|
645
|
+
book: newObject.book,
|
|
646
|
+
chapter: lastChapter,
|
|
647
|
+
verses: this.mergeRanges(Array.from(chapters[lastChapter])), // Ensure merged range
|
|
648
|
+
}
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
-
//
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
// Build the original and scripture properties
|
|
655
|
-
newObject.original = newObject.book + " " + newObject.chapter + ":" + newObject.verses.join(",")
|
|
651
|
+
// Build the scripture string with combined chapters (without spaces after commas)
|
|
652
|
+
const chapterString = chapterStrings.join(",") // No space after comma
|
|
656
653
|
newObject.scripture = {
|
|
657
|
-
passage: newObject.book
|
|
658
|
-
cv:
|
|
659
|
-
hash: newObject.book
|
|
654
|
+
passage: `${newObject.book} ${chapterString}`,
|
|
655
|
+
cv: chapterString,
|
|
656
|
+
hash: `${newObject.book.toLowerCase()}_${chapterString.replace(/:/g, ".").replace(/,/g, ".")}`,
|
|
660
657
|
}
|
|
661
|
-
newObject.scripture.hash = newObject.scripture.hash.toLowerCase()
|
|
662
658
|
|
|
663
659
|
return newObject
|
|
664
660
|
}
|
|
661
|
+
mergeRanges(verses) {
|
|
662
|
+
const sortedVerses = [...new Set(verses)].sort((a, b) => a - b)
|
|
663
|
+
const merged = []
|
|
664
|
+
let start = sortedVerses[0]
|
|
665
|
+
let end = sortedVerses[0]
|
|
666
|
+
|
|
667
|
+
for (let i = 1; i < sortedVerses.length; i++) {
|
|
668
|
+
if (sortedVerses[i] === end + 1) {
|
|
669
|
+
end = sortedVerses[i]
|
|
670
|
+
} else {
|
|
671
|
+
// Push the current range if it's more than 2 consecutive numbers, otherwise separate by commas
|
|
672
|
+
if (start === end) {
|
|
673
|
+
merged.push(`${start}`)
|
|
674
|
+
} else if (end === start + 1) {
|
|
675
|
+
merged.push(`${start},${end}`)
|
|
676
|
+
} else {
|
|
677
|
+
merged.push(`${start}-${end}`)
|
|
678
|
+
}
|
|
679
|
+
start = sortedVerses[i]
|
|
680
|
+
end = sortedVerses[i]
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Push the final range or pair
|
|
685
|
+
if (start === end) {
|
|
686
|
+
merged.push(`${start}`)
|
|
687
|
+
} else if (end === start + 1) {
|
|
688
|
+
merged.push(`${start},${end}`)
|
|
689
|
+
} else {
|
|
690
|
+
merged.push(`${start}-${end}`)
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
return merged
|
|
694
|
+
}
|
|
665
695
|
|
|
666
696
|
_isValid(passage, reference) {
|
|
667
697
|
const singleChapterBook = this.singleChapterBook.find((bible) => bible[passage.book])
|