codexparser 0.1.74 → 0.1.76

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/CodexParser.js +50 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.74",
3
+ "version": "0.1.76",
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": {
@@ -367,6 +367,7 @@ class CodexParser {
367
367
 
368
368
  parts.forEach((part, index) => {
369
369
  part = part.trim()
370
+ if (!part) return // Skip empty parts from trailing commas
370
371
  const isFirstPart = index === 0
371
372
 
372
373
  if (part.includes(":")) {
@@ -829,10 +830,10 @@ class CodexParser {
829
830
 
830
831
  /**
831
832
  * Combines multiple passages into a single reference.
832
- * @param {Object[]} passages - Array of passages to combine.
833
+ * @param {Object[]} [passages=this.passages] - Array of passages to combine, defaults to this.passages.
833
834
  * @returns {Object} Combined passage object.
834
835
  */
835
- combine(passages) {
836
+ combine(passages = this.passages) {
836
837
  if (!passages || passages.length === 0) {
837
838
  throw new Error("No passages provided to join.")
838
839
  }
@@ -880,10 +881,6 @@ class CodexParser {
880
881
  lastVerse = p.verse
881
882
  }
882
883
  })
883
-
884
- const chapters = passage.passages.map((p) => p.chapter)
885
- firstChapter = firstChapter === null ? Math.min(...chapters) : Math.min(firstChapter, ...chapters)
886
- lastChapter = lastChapter === null ? Math.max(...chapters) : Math.max(lastChapter, ...chapters)
887
884
  })
888
885
 
889
886
  combined.passages = Array.from(new Set(combined.passages.map(JSON.stringify))).map(JSON.parse)
@@ -894,27 +891,34 @@ class CodexParser {
894
891
  .sort((a, b) => a - b)
895
892
 
896
893
  sortedChapters.forEach((chapter) => {
897
- const verses = Array.from(chapterVerses[chapter]).sort((a, b) => a - b)
898
- const mergedVerses = this.mergeRanges(verses)
899
- chapterStrings.push(`${chapter}:${mergedVerses.join(",")}`)
900
- if (chapter === firstChapter) {
901
- combined.verses = mergedVerses
894
+ const verses = Array.from(chapterVerses[chapter])
895
+ .map(Number)
896
+ .filter((verse) => verse > 0) // Exclude invalid verse 0
897
+ .sort((a, b) => a - b)
898
+ if (verses.length > 0) {
899
+ const mergedVerses = this.mergeRanges(verses)
900
+ chapterStrings.push(`${chapter}:${mergedVerses.join(",")}`)
901
+ if (chapter === firstChapter) {
902
+ combined.verses = mergedVerses
903
+ }
902
904
  }
903
905
  })
904
906
 
907
+ if (chapterStrings.length === 0) {
908
+ throw new Error("No valid verses found in passages.")
909
+ }
910
+
905
911
  if (firstChapter !== lastChapter) {
906
912
  combined.type = this.MULTI_CHAPTER_RANGE
907
913
  combined.to = {
908
914
  book: combined.book,
909
915
  chapter: lastChapter,
910
- verses: this.mergeRanges(Array.from(chapterVerses[lastChapter])),
916
+ verses: this.mergeRanges(Array.from(chapterVerses[lastChapter]).filter((verse) => verse > 0)),
911
917
  }
912
- combined.original = `${combined.book} ${firstChapter}:${combined.verses.join(
913
- ","
914
- )}; ${lastChapter}:${combined.to.verses.join(",")}`
918
+ combined.original = `${combined.book} ${chapterStrings.join("; ")}`
915
919
  } else {
916
920
  combined.type = combined.verses.length > 1 ? this.CHAPTER_VERSE_RANGE : this.CHAPTER_VERSE
917
- combined.original = `${combined.book} ${firstChapter}:${combined.verses.join(",")}`
921
+ combined.original = `${combined.book} ${chapterStrings[0]}`
918
922
  }
919
923
 
920
924
  const chapterString = chapterStrings.join(";")
@@ -927,12 +931,18 @@ class CodexParser {
927
931
  combined.start = {
928
932
  book: combined.book,
929
933
  chapter: firstChapter,
930
- verse: firstVerse || Math.min(...Array.from(chapterVerses[firstChapter])),
934
+ verse:
935
+ firstVerse > 0
936
+ ? firstVerse
937
+ : Math.min(...Array.from(chapterVerses[firstChapter]).filter((verse) => verse > 0)),
931
938
  }
932
939
  combined.end = {
933
940
  book: combined.book,
934
941
  chapter: lastChapter,
935
- verse: lastVerse || Math.max(...Array.from(chapterVerses[lastChapter])),
942
+ verse:
943
+ lastVerse > 0
944
+ ? lastVerse
945
+ : Math.max(...Array.from(chapterVerses[lastChapter]).filter((verse) => verse > 0)),
936
946
  }
937
947
 
938
948
  // Reattach the reference method to the combined passage
@@ -1134,9 +1144,7 @@ class CodexParser {
1134
1144
  const { originalText, abbr, original } = passage
1135
1145
  const newReference = useAbbreviations ? abbr : original
1136
1146
 
1137
- // Create regex to match originalText with optional parentheses
1138
- const escapedOriginalText = originalText.replace(/([:.])/g, "\\$1").replace(/\s+/g, "\\s*")
1139
- const regex = new RegExp(`(\\()?\\s*${escapedOriginalText}\\s*(\\))?`, "g")
1147
+ const regex = new RegExp(`${originalText}`, "g")
1140
1148
 
1141
1149
  // Find all matches
1142
1150
  const matches = [...result.matchAll(regex)]
@@ -1146,9 +1154,15 @@ class CodexParser {
1146
1154
  const match = matches[j]
1147
1155
  const startIndex = match.index
1148
1156
  const endIndex = startIndex + match[0].length
1149
- // Preserve parentheses if present in the match
1150
- const hasParens = match[1] === "(" && match[2] === ")"
1151
- const replacement = hasParens ? `(${newReference})` : newReference
1157
+ const leadingSpace = match[1] || "" // Capture leading spaces
1158
+ const hasOpeningParen = match[2] === "("
1159
+ const hasClosingParen = match[3] === ")"
1160
+ const trailingSpace = match[4] || " " // Capture trailing spaces
1161
+ // Preserve parentheses if present
1162
+ const replacement =
1163
+ hasOpeningParen && hasClosingParen
1164
+ ? `${leadingSpace}(${newReference})${trailingSpace}`
1165
+ : `${leadingSpace}${newReference}${trailingSpace}`
1152
1166
  result = result.slice(0, startIndex) + replacement + result.slice(endIndex)
1153
1167
  }
1154
1168
  }
@@ -1156,6 +1170,18 @@ class CodexParser {
1156
1170
 
1157
1171
  return result
1158
1172
  }
1173
+ /**
1174
+ * Checks if all references in the passages array are from the same book.
1175
+ * @returns {boolean} True if all passages are from the same book, false otherwise.
1176
+ */
1177
+ same() {
1178
+ if (this.passages.length <= 1) {
1179
+ return true
1180
+ }
1181
+
1182
+ const firstBook = this.passages[0].book.toLowerCase()
1183
+ return this.passages.every((passage) => passage.book.toLowerCase() === firstBook)
1184
+ }
1159
1185
  }
1160
1186
 
1161
1187
  module.exports = CodexParser