codexparser 0.1.76 → 0.1.78

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 +63 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.76",
3
+ "version": "0.1.78",
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": {
@@ -145,23 +145,22 @@ class CodexParser {
145
145
  }
146
146
 
147
147
  if (foundBook) {
148
- // Check if book is followed by a valid reference when booksOnly is false
148
+ // Check if book is followed by a valid reference or version when booksOnly is false
149
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 a digit (chapter number) to start a valid 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
150
+ let j = i + matchedLength
151
+ // Skip spaces
152
+ while (j < lowerCaseText.length && /\s/.test(lowerCaseText[j])) {
153
+ j++
154
+ }
155
+ // Check for digit (chapter number) or version suffix (LXX/MT)
156
+ if (
157
+ j < lowerCaseText.length &&
158
+ (/\d/.test(lowerCaseText[j]) || lowerCaseText.substring(j).match(/^(lxx|mt)\b/i))
159
+ ) {
160
+ isFollowedByReference = true
162
161
  }
163
162
 
164
- if (!isFollowedByReference) {
163
+ if (!this.config.booksOnly && !hasOpeningParen && !isFollowedByReference) {
165
164
  i++
166
165
  continue
167
166
  }
@@ -184,7 +183,10 @@ class CodexParser {
184
183
  }
185
184
 
186
185
  // Only proceed if valid reference or booksOnly is true
187
- if ((hasColon && chapterVerse.trim().length > 0) || (this.config.booksOnly && !chapterVerse.trim())) {
186
+ if (
187
+ (chapterVerse.trim().length > 0 && (hasColon || /\d/.test(chapterVerse.trim()))) ||
188
+ (this.config.booksOnly && !chapterVerse.trim())
189
+ ) {
188
190
  let endIndex = i
189
191
  let version = null
190
192
 
@@ -228,8 +230,10 @@ class CodexParser {
228
230
  }
229
231
  } else if (ref.includes("-")) {
230
232
  type = "chapter_range"
231
- } else {
233
+ } else if (/\d/.test(ref)) {
232
234
  type = "single_chapter"
235
+ } else {
236
+ type = "book_only"
233
237
  }
234
238
 
235
239
  this.found.push({
@@ -296,10 +300,31 @@ class CodexParser {
296
300
  abbr: null,
297
301
  }
298
302
 
299
- this.parseReferenceParts(parsedPassage, passage.reference.split(","))
303
+ // Clean reference for parsing, removing version suffix
304
+ let cleanReference = passage.reference
305
+ if (passage.version) {
306
+ cleanReference = cleanReference.replace(/\s*(LXX|MT)$/i, "").trim()
307
+ }
308
+
309
+ // Handle chapter-only references (e.g., "113 :" or "113")
310
+ if (!cleanReference || cleanReference.match(/^\d+\s*[:;]?\s*$/)) {
311
+ const chapterMatch = cleanReference.match(/\d+/) || ["1"]
312
+ const chapter = Number(chapterMatch[0])
313
+ parsedPassage.chapter = chapter
314
+ parsedPassage.type = this.SINGLE_CHAPTER
315
+ const chapterVerses = this.getChapterVerses(book, chapter)
316
+ if (chapterVerses.length) {
317
+ const startVerse = chapterVerses[0]
318
+ const endVerse = chapterVerses[chapterVerses.length - 1]
319
+ parsedPassage.verses = [`${startVerse}-${endVerse}`]
320
+ }
321
+ } else {
322
+ this.parseReferenceParts(parsedPassage, cleanReference.split(","))
323
+ }
324
+
300
325
  parsedPassage.passages = this.populate(parsedPassage)
301
326
  parsedPassage.scripture = this.scripturize(parsedPassage)
302
- parsedPassage.valid = this._isValid(parsedPassage, passage.reference)
327
+ parsedPassage.valid = this._isValid(parsedPassage, cleanReference)
303
328
 
304
329
  // Set abbr property using SBL-style abbreviations
305
330
  const sblEntry = Object.entries(this.sblAbbreviations).find(
@@ -307,16 +332,16 @@ class CodexParser {
307
332
  )
308
333
  if (sblEntry) {
309
334
  const { value, abbr } = sblEntry[1]
335
+ const ref = passage.reference.replace(/\s*(LXX|MT)$/i, "").trim()
310
336
  parsedPassage.abbr = abbr
311
- ? `${value}. ${passage.reference}${passage.version ? " " + passage.version : ""}`
312
- : `${value} ${passage.reference}${passage.version ? " " + passage.version : ""}`
337
+ ? `${value}. ${ref}${passage.version ? " " + passage.version : ""}`
338
+ : `${value} ${ref}${passage.version ? " " + passage.version : ""}`
313
339
  } else {
314
- // Fallback to original
315
340
  parsedPassage.abbr = parsedPassage.original
316
341
  }
317
342
 
318
343
  if (parsedPassage.type === this.MULTI_CHAPTER_RANGE) {
319
- this.handleMultiChapterRange(parsedPassage, passage.reference)
344
+ this.handleMultiChapterRange(parsedPassage, cleanReference)
320
345
  } else {
321
346
  delete parsedPassage.to
322
347
  }
@@ -370,6 +395,22 @@ class CodexParser {
370
395
  if (!part) return // Skip empty parts from trailing commas
371
396
  const isFirstPart = index === 0
372
397
 
398
+ // Handle chapter-only references (e.g., "113 :" or "113")
399
+ if (!part.includes(":") && !part.includes("-") && !singleChapterBook) {
400
+ const chapter = Number(part.replace(/[^0-9]/g, "")) // Extract number, remove trailing colon
401
+ if (chapter > 0) {
402
+ passage.chapter = chapter
403
+ passage.type = this.SINGLE_CHAPTER
404
+ const chapterVerses = this.getChapterVerses(passage.book, chapter)
405
+ if (chapterVerses.length) {
406
+ const startVerse = chapterVerses[0]
407
+ const endVerse = chapterVerses[chapterVerses.length - 1]
408
+ passage.verses = [`${startVerse}-${endVerse}`]
409
+ }
410
+ return
411
+ }
412
+ }
413
+
373
414
  if (part.includes(":")) {
374
415
  this.parseChapterVerse(passage, part, isFirstPart)
375
416
  } else if (singleChapterBook) {
@@ -381,7 +422,6 @@ class CodexParser {
381
422
  }
382
423
  })
383
424
  }
384
-
385
425
  /**
386
426
  * Parses chapter-verse references (e.g., "3:16").
387
427
  * @param {Object} passage - The passage object.