codexparser 0.1.71 → 0.1.73

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 +31 -29
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
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": {
@@ -124,7 +124,7 @@ class CodexParser {
124
124
  for (let book of fullNames) {
125
125
  if (
126
126
  lowerCaseText.startsWith(book.toLowerCase(), i) &&
127
- (i + book.length >= lowerCaseText.length || /\s|:|\d/.test(lowerCaseText[i + book.length]))
127
+ (i + book.length >= lowerCaseText.length || /[\s:;\d]/.test(lowerCaseText[i + book.length]))
128
128
  ) {
129
129
  foundBook = book
130
130
  matchedLength = book.length
@@ -135,7 +135,7 @@ class CodexParser {
135
135
  for (let abbr of abbreviations) {
136
136
  if (
137
137
  lowerCaseText.startsWith(abbr.toLowerCase(), i) &&
138
- (i + abbr.length >= lowerCaseText.length || /\s|:|\d/.test(lowerCaseText[i + abbr.length]))
138
+ (i + abbr.length >= lowerCaseText.length || /[\s:;\d]/.test(lowerCaseText[i + abbr.length]))
139
139
  ) {
140
140
  foundBook = this.abbreviations[abbr]
141
141
  matchedLength = abbr.length
@@ -145,11 +145,23 @@ class CodexParser {
145
145
  }
146
146
 
147
147
  if (foundBook) {
148
- // Check if book is followed by a number when booksOnly is false
149
- const nextCharIndex = i + matchedLength
150
- const isFollowedByNumber =
151
- nextCharIndex < lowerCaseText.length && /\d/.test(lowerCaseText[nextCharIndex])
152
- if (!this.config.booksOnly && !isFollowedByNumber && !hasOpeningParen) {
148
+ // Check if book is followed by a valid reference when booksOnly is false
149
+ let isFollowedByReference = false
150
+ if (!this.config.booksOnly && !hasOpeningParen) {
151
+ let j = i + matchedLength
152
+ // Skip spaces
153
+ while (j < lowerCaseText.length && /\s/.test(lowerCaseText[j])) {
154
+ j++
155
+ }
156
+ // Check for digit or colon indicating a reference
157
+ if (j < lowerCaseText.length && /[\d:]/.test(lowerCaseText[j])) {
158
+ isFollowedByReference = true
159
+ }
160
+ } else {
161
+ isFollowedByReference = true // Allow if booksOnly or in parentheses
162
+ }
163
+
164
+ if (!isFollowedByReference) {
153
165
  i++
154
166
  continue
155
167
  }
@@ -164,21 +176,15 @@ class CodexParser {
164
176
  i++
165
177
  }
166
178
 
167
- // Capture chapter-verse
168
- while (
169
- i < lowerCaseText.length &&
170
- (/[\d]/.test(normalizedText[i]) ||
171
- normalizedText[i] === ":" ||
172
- normalizedText[i] === "," ||
173
- normalizedText[i] === "-")
174
- ) {
179
+ // Capture chapter-verse (allow digits, colons, commas, dashes, spaces)
180
+ while (i < lowerCaseText.length && (/[\d:,\-]/.test(normalizedText[i]) || normalizedText[i] === " ")) {
175
181
  if (normalizedText[i] === ":") hasColon = true
176
182
  chapterVerse += normalizedText[i]
177
183
  i++
178
184
  }
179
185
 
180
186
  // Only proceed if valid reference or booksOnly is true
181
- if ((hasColon && chapterVerse.trim().length > 0) || this.config.booksOnly) {
187
+ if ((hasColon && chapterVerse.trim().length > 0) || (this.config.booksOnly && !chapterVerse.trim())) {
182
188
  let endIndex = i
183
189
  let version = null
184
190
 
@@ -268,9 +274,6 @@ class CodexParser {
268
274
  parse(reference) {
269
275
  this.scan(reference)
270
276
 
271
- // Define non-abbreviated books per SBL/Crossway
272
- const nonAbbreviatedBooks = ["John", "Luke", "Acts", "Jude", "James", "Titus"]
273
-
274
277
  this.passages = this.found.map((passage) => {
275
278
  const book = this.bookify(passage.book)
276
279
  const testament = this.bible.old.includes(book) ? "old" : "new"
@@ -298,18 +301,17 @@ class CodexParser {
298
301
  parsedPassage.scripture = this.scripturize(parsedPassage)
299
302
  parsedPassage.valid = this._isValid(parsedPassage, passage.reference)
300
303
 
301
- // Set abbr property using SBL-style rules
302
- const abbrKey = Object.keys(this.abbreviations).find(
303
- (abbr) => this.abbreviations[abbr].toLowerCase() === book.toLowerCase()
304
+ // Set abbr property using SBL-style abbreviations
305
+ const sblEntry = Object.entries(this.sblAbbreviations).find(
306
+ ([key]) => key.toLowerCase() === book.toLowerCase()
304
307
  )
305
- if (nonAbbreviatedBooks.includes(book)) {
306
- // Use full book name without period for non-abbreviated books
307
- parsedPassage.abbr = `${book} ${passage.reference}${passage.version ? " " + passage.version : ""}`
308
- } else if (abbrKey) {
309
- // Use abbreviation with period for abbreviated books
310
- parsedPassage.abbr = `${abbrKey}. ${passage.reference}${passage.version ? " " + passage.version : ""}`
308
+ if (sblEntry) {
309
+ const { value, abbr } = sblEntry[1]
310
+ parsedPassage.abbr = abbr
311
+ ? `${value}. ${passage.reference}${passage.version ? " " + passage.version : ""}`
312
+ : `${value} ${passage.reference}${passage.version ? " " + passage.version : ""}`
311
313
  } else {
312
- // Fallback to original if no abbreviation
314
+ // Fallback to original
313
315
  parsedPassage.abbr = parsedPassage.original
314
316
  }
315
317