codexparser 0.1.51 → 0.1.53

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 +84 -143
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.51",
3
+ "version": "0.1.53",
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": {
@@ -186,148 +186,88 @@ class CodexParser {
186
186
  * @returns {object} An object with the parsed passage.
187
187
  */
188
188
  parse(reference) {
189
- this.scan(reference) // Call scan to populate this.found
189
+ this.scan(reference) // Populate this.found
190
190
 
191
191
  this.passages = this.found.map((passage) => {
192
192
  const book = this.bookify(passage.book)
193
- const testament = this.bible.old.find((bible) => bible === book) ? "old" : "new"
194
-
195
- // Initialize the parsed passage object
193
+ const testament = this.bible.old.includes(book) ? "old" : "new"
196
194
  const parsedPassage = {
197
195
  original: passage.book + " " + passage.reference,
198
196
  book: book,
199
197
  chapter: null,
200
- verses: [], // Verses stored as an array
201
- type: passage.type, // Set type based on reference
198
+ verses: [],
199
+ type: passage.type,
202
200
  testament: testament,
203
201
  index: passage.index,
204
202
  version: this._handleVersion(passage.version, testament),
205
203
  }
206
204
 
207
- // Split reference by commas to handle multiple ranges or verses (e.g., "Isaiah 8:22-9:1,5")
208
- let parts = passage.reference.split(",")
209
-
210
- // Check for single-chapter books
211
- const singleChapterBook = this.singleChapterBook.find((bible) => bible[book])
205
+ // Split reference into parts (e.g., "40:3-5,8-9" -> ["40:3-5", "8-9"])
206
+ const parts = passage.reference.split(",")
212
207
 
213
208
  parts.forEach((part, partIndex) => {
214
- part = part.trim() // Clean up spaces
215
- const separator = part.includes(":") ? ":" : "."
216
-
217
- if (part.includes("-")) {
218
- // Handle ranges (e.g., "8:22-9:1")
219
- let [start, end] = part.split("-")
220
-
221
- // Handle the starting part
222
- let [startChapter, startVerse] = start.includes(separator)
223
- ? start.split(separator)
224
- : [parsedPassage.chapter, start] // Default to same chapter if no chapter is provided
225
-
226
- parsedPassage.chapter = Number(startChapter) // Set the chapter
227
-
228
- // Multi-chapter verse range logic
229
- if (start.includes(separator) && end.includes(separator)) {
230
- let [endChapter, endVerse] = end.split(separator)
231
-
232
- parsedPassage.verses = this.chapterVerses[book][startChapter].slice(
233
- this.chapterVerses[book][startChapter].indexOf(Number(startVerse))
234
- )
235
-
236
- if (Number(endChapter) !== Number(startChapter)) {
237
- const endVerses = this.chapterVerses[book][endChapter].slice(
238
- 0,
239
- this.chapterVerses[book][endChapter].indexOf(Number(endVerse)) + 1
240
- )
241
- // Construct ranges for the `to` object
242
- parsedPassage.to = {
243
- book: book,
244
- chapter: Number(endChapter),
245
- verses: [endVerse],
246
- }
209
+ part = part.trim()
247
210
 
248
- parsedPassage.type = "multi_chapter_verse_range"
249
- } else {
250
- parsedPassage.verses.push(`${startVerse}-${endVerse}`)
251
- }
211
+ if (part.includes(":")) {
212
+ // Explicit chapter:verse (e.g., "40:3-5")
213
+ const [chapterPart, versePart] = part.split(":")
214
+ if (partIndex === 0) {
215
+ parsedPassage.chapter = Number(chapterPart) // Set chapter only on first part
216
+ }
217
+
218
+ if (versePart.includes("-")) {
219
+ // Verse range (e.g., "3-5")
220
+ parsedPassage.verses.push(versePart)
252
221
  } else {
253
- if (separator !== ":") {
254
- // then this is a chapter_range
255
- let [startChapter, endChapter] = part.split("-")
256
- parsedPassage.chapter = Number(startChapter)
257
- parsedPassage.verses = [
258
- `${this.chapterVerses[book][parsedPassage.chapter][0]}-${
259
- this.chapterVerses[book][parsedPassage.chapter][
260
- this.chapterVerses[book][parsedPassage.chapter].length - 1
261
- ]
262
- }`,
263
- ]
264
- parsedPassage.to = {
265
- book: book,
266
- chapter: Number(endChapter),
267
- verses: [
268
- `${this.chapterVerses[book][endChapter][0]}-${
269
- this.chapterVerses[book][endChapter][
270
- this.chapterVerses[book][endChapter].length - 1
271
- ]
272
- }`,
273
- ],
274
- }
275
- } else {
276
- // Handles when verses are present.
277
- parsedPassage.verses = [part.split(separator)[1]]
278
- }
222
+ parsedPassage.verses.push(Number(versePart))
223
+ }
224
+ } else if (part.includes("-")) {
225
+ // Verse range without chapter (e.g., "8-9")
226
+ if (parsedPassage.chapter === null) {
227
+ // Assume chapter 1 for single-chapter books if no chapter yet
228
+ const singleChapterBook = this.singleChapterBook.find((b) => b[book])
229
+ parsedPassage.chapter = singleChapterBook ? 1 : Number(part.split("-")[0])
230
+ parsedPassage.verses.push(part)
231
+ } else {
232
+ parsedPassage.verses.push(part) // Add as verse range in current chapter
279
233
  }
280
234
  } else {
281
- // Handle individual chapter:verse references (e.g., "9:5" in "8:22-9:1,5")
282
-
283
- let [chapterPart, versePart] = part.includes(separator)
284
- ? part.split(separator)
285
- : [parsedPassage.chapter, part]
286
-
287
- if (separator.trim() !== ":" && !parsedPassage.chapter) {
288
- if (singleChapterBook) {
289
- parsedPassage.chapter = 1
290
- parsedPassage.verses.push(versePart) // Add single verse to array
291
- } else {
292
- parsedPassage.chapter = Number(part)
293
- parsedPassage.verses = [
294
- `${this.chapterVerses[book][parsedPassage.chapter][0]}-${
295
- this.chapterVerses[book][parsedPassage.chapter][
296
- this.chapterVerses[book][parsedPassage.chapter].length - 1
297
- ]
298
- }`,
299
- ]
300
- }
235
+ // Single verse without chapter (e.g., "8")
236
+ if (parsedPassage.chapter === null) {
237
+ const singleChapterBook = this.singleChapterBook.find((b) => b[book])
238
+ parsedPassage.chapter = singleChapterBook ? 1 : Number(part)
301
239
  } else {
302
- if (chapterPart) {
303
- if (partIndex === parts.length - 1 && parsedPassage.to) {
304
- // Add additional verses to the last chapter in multi-chapter range
305
- if (!parsedPassage.to.verses) parsedPassage.to.verses = []
306
- parsedPassage.to.verses.push(Number(versePart))
307
- } else {
308
- parsedPassage.chapter = Number(chapterPart)
309
- parsedPassage.verses.push(Number(versePart))
310
- }
311
- }
240
+ parsedPassage.verses.push(Number(part))
312
241
  }
313
242
  }
314
-
315
- parsedPassage.passages = this.populate(parsedPassage)
316
- parsedPassage.scripture = this.scripturize(parsedPassage)
317
243
  })
318
244
 
319
- // Handle range merging in `to` object
320
- if (parsedPassage.to && Array.isArray(parsedPassage.to.verses)) {
321
- parsedPassage.to.verses = this.mergeRanges(parsedPassage.to.verses)
322
- }
323
-
245
+ // Populate passages and scripture after processing all parts
246
+ parsedPassage.passages = this.populate(parsedPassage)
247
+ parsedPassage.scripture = this.scripturize(parsedPassage)
324
248
  parsedPassage.valid = this._isValid(parsedPassage, passage.reference)
325
249
 
250
+ // Handle multi-chapter range if applicable
251
+ if (
252
+ parsedPassage.type === "multi_chapter_verse_range" &&
253
+ parts.some((p) => p.includes(":") && p.split(":")[0] !== String(parsedPassage.chapter))
254
+ ) {
255
+ const lastPart = parts[parts.length - 1]
256
+ const [endChapter, endVerse] = lastPart.split(":")
257
+ parsedPassage.to = {
258
+ book: book,
259
+ chapter: Number(endChapter),
260
+ verses: endVerse.includes("-") ? [endVerse] : [Number(endVerse)],
261
+ }
262
+ } else {
263
+ delete parsedPassage.to // Ensure no erroneous 'to' property
264
+ }
265
+
326
266
  return parsedPassage
327
267
  })
328
268
 
329
269
  this.versification()
330
- return this // Return this instance
270
+ return this
331
271
  }
332
272
  /**
333
273
  * Generates an array of numbers representing a range from start to end, inclusive.
@@ -343,6 +283,7 @@ class CodexParser {
343
283
  _searchVersificationDifferences(book, chapter, version) {
344
284
  version = version.toLowerCase()
345
285
  if (!this.chapterVerses[book][chapter]) return
286
+ if (!this.versificationDifferences[book]) return
346
287
  // Loop through each key-value pair in the dictionary
347
288
  for (const [key, value] of Object.entries(this.versificationDifferences[book])) {
348
289
  // Check if the key starts with the desired chapter
@@ -418,28 +359,39 @@ class CodexParser {
418
359
  * @param {Object} parsedPassage - The parsed passage object containing book, chapter, and verses information.
419
360
  * @return {Array} An array of passage objects with individual verses.
420
361
  */
362
+ /**
363
+ * Populate all verses from a parsed passage, including all verses in ranges or chapters.
364
+ *
365
+ * @param {Object} parsedPassage - The parsed passage object containing book, chapter, and verses information.
366
+ * @return {Array} An array of passage objects with individual verses.
367
+ */
421
368
  populate(parsedPassage) {
422
369
  const passages = []
423
-
424
370
  const { book, chapter, verses, type, to } = parsedPassage
425
371
  const version = parsedPassage.version ? parsedPassage.version.abbreviation : "eng"
426
372
  this._setVersion(book, chapter, version) // Set version data if needed
427
373
 
428
374
  if (type === "single_chapter") {
429
- // Handle entire chapter references
375
+ // Handle entire chapter references (e.g., "Isaiah 40")
430
376
  if (this.chapterVerses[book] && this.chapterVerses[book][chapter]) {
431
377
  this.chapterVerses[book][chapter].forEach((verse) => {
432
378
  passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
433
379
  })
434
380
  }
435
- } else if (type === "comma_separated_verses") {
436
- // Handle explicitly mentioned verses (e.g., 3:1,3,6)
437
-
381
+ } 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 "Isaiah 40:3-5")
438
383
  verses.forEach((verse) => {
439
- passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
384
+ if (typeof verse === "string" && verse.includes("-")) {
385
+ const [start, end] = verse.split("-").map(Number)
386
+ for (let i = start; i <= end; i++) {
387
+ passages.push({ book, chapter: Number(chapter), verse: i })
388
+ }
389
+ } else {
390
+ passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
391
+ }
440
392
  })
441
393
  } else if (type === "chapter_range") {
442
- // Handle ranges of chapters (e.g., 3-5)
394
+ // Handle ranges of chapters (e.g., "Isaiah 3-5")
443
395
  for (let currentChapter = chapter; currentChapter <= to.chapter; currentChapter++) {
444
396
  if (this.chapterVerses[book] && this.chapterVerses[book][currentChapter]) {
445
397
  this.chapterVerses[book][currentChapter].forEach((verse) => {
@@ -448,18 +400,17 @@ class CodexParser {
448
400
  }
449
401
  }
450
402
  } else if (type === "multi_chapter_verse_range") {
451
- // Handle multi-chapter verse ranges (e.g., 3:1-5:6)
403
+ // Handle multi-chapter verse ranges (e.g., "Isaiah 3:1-5:6")
452
404
  const startChapter = chapter
453
- const startVerse = verses[0]
405
+ const startVerse = verses[0].includes("-") ? Number(verses[0].split("-")[0]) : Number(verses[0])
454
406
  const endChapter = to.chapter
455
- const endVerse = to.verses[to.verses.length - 1]
407
+ const endVerse = to.verses[0].includes("-") ? Number(to.verses[0].split("-")[1]) : Number(to.verses[0])
456
408
 
457
409
  for (let currentChapter = startChapter; currentChapter <= endChapter; currentChapter++) {
458
410
  const chapterVerses = this.chapterVerses[book][currentChapter]
459
411
  if (!chapterVerses) continue
460
412
 
461
- // Determine start and end verses for each chapter
462
- const chapterStartVerse = currentChapter === startChapter ? startVerse : 1
413
+ const chapterStartVerse = currentChapter === startChapter ? startVerse : chapterVerses[0]
463
414
  const chapterEndVerse =
464
415
  currentChapter === endChapter ? endVerse : chapterVerses[chapterVerses.length - 1]
465
416
 
@@ -467,22 +418,13 @@ class CodexParser {
467
418
  passages.push({ book, chapter: currentChapter, verse })
468
419
  }
469
420
  }
470
- } else if (type === "chapter_verse" || type === "chapter_verse_range") {
471
- // Handle single chapter:verse or chapter:verse ranges (e.g., 3:1 or 3:1-5)
472
- if (this.chapterVerses[book] && this.chapterVerses[book][chapter]) {
473
- verses.forEach((verse) => {
474
- if (typeof verse === "string" && verse.includes("-")) {
475
- const [start, end] = verse.split("-").map(Number)
476
- for (let i = start; i <= end; i++) {
477
- passages.push({ book, chapter: Number(chapter), verse: i })
478
- }
479
- } else {
480
- passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
481
- }
482
- })
483
- }
421
+ } else if (type === "chapter_verse") {
422
+ // Handle single chapter:verse references (e.g., "Isaiah 40:3")
423
+ verses.forEach((verse) => {
424
+ passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
425
+ })
484
426
  } else if (type === "single_chapter_book_verse_range") {
485
- // Handle ranges in single-chapter books (e.g., Jude 5-7)
427
+ // Handle ranges in single-chapter books (e.g., "Jude 5-7")
486
428
  const [startVerse, endVerse] = verses[0].split("-").map(Number)
487
429
  for (let i = startVerse; i <= endVerse; i++) {
488
430
  passages.push({ book, chapter: 1, verse: i })
@@ -568,10 +510,10 @@ class CodexParser {
568
510
 
569
511
  // Start constructing the passage string
570
512
  let combined = `${passage.book}`
571
-
513
+
572
514
  if (passage.type === "multi_chapter_verse_range" && passage.to) {
573
515
  // Multi-chapter verse range
574
-
516
+
575
517
  combined += ` ${formatChapterVerse(passage.chapter, passage.verses)}-${formatChapterVerse(
576
518
  passage.to.chapter,
577
519
  passage.to.verses
@@ -683,7 +625,6 @@ class CodexParser {
683
625
 
684
626
  // Handle multi-chapter ranges
685
627
  if (firstChapter !== lastChapter) {
686
-
687
628
  combined.type = "multi_chapter_verse_range"
688
629
  combined.to = {
689
630
  book: combined.book,