codexparser 0.0.84 → 0.1.0

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 (104) hide show
  1. package/all-scripture-test.js +2 -1
  2. package/package.json +1 -1
  3. package/src/CodexParser.js +301 -188
  4. package/src/abbr.js +1 -1
  5. package/src/bible.js +1 -0
  6. package/src/chapterVerseCombine.js +63 -0
  7. package/src/chapter_verses/1chronicles.js +31 -0
  8. package/src/chapter_verses/1corinthians.js +18 -0
  9. package/src/chapter_verses/1john.js +7 -0
  10. package/src/chapter_verses/1kings.js +24 -0
  11. package/src/chapter_verses/1peter.js +7 -0
  12. package/src/chapter_verses/1samuel.js +33 -0
  13. package/src/chapter_verses/1thessalonians.js +7 -0
  14. package/src/chapter_verses/1timothy.js +8 -0
  15. package/src/chapter_verses/2chronicles.js +38 -0
  16. package/src/chapter_verses/2corinthians.js +15 -0
  17. package/src/chapter_verses/2kings.js +27 -0
  18. package/src/chapter_verses/2peter.js +5 -0
  19. package/src/chapter_verses/2samuel.js +26 -0
  20. package/src/chapter_verses/2thessalonians.js +5 -0
  21. package/src/chapter_verses/2timothy.js +6 -0
  22. package/src/chapter_verses/acts.js +30 -0
  23. package/src/chapter_verses/amos.js +11 -0
  24. package/src/chapter_verses/colossians.js +6 -0
  25. package/src/chapter_verses/daniel.js +14 -0
  26. package/src/chapter_verses/deuteronomy.js +36 -0
  27. package/src/chapter_verses/ecclesiastes.js +14 -0
  28. package/src/chapter_verses/ephesians.js +8 -0
  29. package/src/chapter_verses/esther.js +12 -0
  30. package/src/chapter_verses/exodus.js +42 -0
  31. package/src/chapter_verses/ezekiel.js +50 -0
  32. package/src/chapter_verses/ezra.js +12 -0
  33. package/src/chapter_verses/galatians.js +8 -0
  34. package/src/chapter_verses/genesis.js +52 -0
  35. package/src/chapter_verses/habakkuk.js +5 -0
  36. package/src/chapter_verses/haggai.js +4 -0
  37. package/src/chapter_verses/hebrews.js +15 -0
  38. package/src/chapter_verses/hosea.js +16 -0
  39. package/src/chapter_verses/isaiah.js +68 -0
  40. package/src/chapter_verses/james.js +7 -0
  41. package/src/chapter_verses/jeremiah.js +54 -0
  42. package/src/chapter_verses/job.js +44 -0
  43. package/src/chapter_verses/joel.js +5 -0
  44. package/src/chapter_verses/john.js +23 -0
  45. package/src/chapter_verses/jonah.js +6 -0
  46. package/src/chapter_verses/joshua.js +26 -0
  47. package/src/chapter_verses/judges.js +23 -0
  48. package/src/chapter_verses/lamentations.js +7 -0
  49. package/src/chapter_verses/leviticus.js +29 -0
  50. package/src/chapter_verses/luke.js +26 -0
  51. package/src/chapter_verses/malachi.js +6 -0
  52. package/src/chapter_verses/mark.js +18 -0
  53. package/src/chapter_verses/matthew.js +30 -0
  54. package/src/chapter_verses/micah.js +9 -0
  55. package/src/chapter_verses/nahum.js +5 -0
  56. package/src/chapter_verses/nehemiah.js +15 -0
  57. package/src/chapter_verses/numbers.js +38 -0
  58. package/src/chapter_verses/philippians.js +6 -0
  59. package/src/chapter_verses/proverbs.js +33 -0
  60. package/src/chapter_verses/psalms.js +152 -0
  61. package/src/chapter_verses/revelation.js +24 -0
  62. package/src/chapter_verses/romans.js +18 -0
  63. package/src/chapter_verses/ruth.js +6 -0
  64. package/src/chapter_verses/songs.js +10 -0
  65. package/src/chapter_verses/titus.js +5 -0
  66. package/src/chapter_verses/zechariah.js +16 -0
  67. package/src/chapter_verses/zephaniah.js +5 -0
  68. package/src/versifications/1chronicles.js +592 -0
  69. package/src/versifications/1kings.js +492 -0
  70. package/src/versifications/1samuel.js +202 -0
  71. package/src/versifications/2chronicles.js +167 -0
  72. package/src/versifications/2samuel.js +222 -0
  73. package/src/versifications/daniel.js +332 -0
  74. package/src/versifications/deuteronomy.js +347 -0
  75. package/src/versifications/ecclesiastes.js +102 -0
  76. package/src/versifications/exodus.js +837 -0
  77. package/src/versifications/ezekiel.js +222 -0
  78. package/src/versifications/genesis.js +192 -0
  79. package/src/versifications/hosea.js +207 -0
  80. package/src/versifications/isaiah.js +167 -0
  81. package/src/versifications/jeremiah.js +3892 -0
  82. package/src/versifications/job.js +172 -0
  83. package/src/versifications/joel.js +132 -0
  84. package/src/versifications/jonah.js +57 -0
  85. package/src/versifications/joshua.js +22 -0
  86. package/src/versifications/leviticus.js +152 -0
  87. package/src/versifications/malachi.js +32 -0
  88. package/src/versifications/micah.js +77 -0
  89. package/src/versifications/nahum.js +72 -0
  90. package/src/versifications/nehemiah.js +312 -0
  91. package/src/versifications/numbers.js +382 -0
  92. package/src/versifications/proverbs.js +17 -0
  93. package/src/versifications/psalms.js +12059 -0
  94. package/src/versifications/song.js +72 -0
  95. package/src/versifications/zechariah.js +87 -0
  96. package/src/versified.js +28 -619
  97. package/src/CodexParser-javascript.js +0 -317
  98. package/src/bookRegex.regex +0 -1
  99. package/tests/abbreviated_verses.js +0 -8
  100. package/tests/bcv-single-test.js +0 -19
  101. package/tests/bcv_test.js +0 -14
  102. package/tests/find.js +0 -8
  103. package/tests/single.js +0 -10
  104. package/tests/versification.js +0 -8
@@ -10,10 +10,11 @@ const parser = new CodexParser({
10
10
  invalid_passage_strategy: "include",
11
11
  })
12
12
  const text = `Joel 10:13 The passages Luke 2:32 and Lk 1:23 that we are looking at tonight 1 Cor 12:34 2 Cor 3:4 are found Jude 6, in Jude 5, Genesis 2:1 - 3:19, 1 John 3:16-17, 1 Peter 1:1, and Romans 10:13, 15, 17. Please turn in your Bibles. Ps 109:4,5,6,8. Isaiah 61.2-3 Mt 5.4`
13
- const single = "Ge 27.27-29,89-40 Heb 11.20 Heb. 12.17 Jonah 3"
13
+ const single = "Ge 27.27-29,39-41 Heb 11.20 Heb. 12.17 Jonah 3 "
14
14
  const jd = "Jd. 5"
15
15
  const cor = "1 Cor 12:4 2 Cor 3:4"
16
16
  const noSpace = "Re13.8 "
17
17
  const ezra = " Ez 1:3"
18
18
  const passages = parser.parse(text + single + jd + cor + noSpace + ezra)
19
+ console.log(text + single + jd + cor + noSpace + ezra)
19
20
  dump(passages.getPassages())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.0.84",
3
+ "version": "0.1.0",
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": {
@@ -1,11 +1,10 @@
1
1
  const versified = require("./versified")
2
2
  const bible = require("./bible")
3
- const { bookRegex, chapterRegex, verseRegex, scripturesRegex, EzraAbbrv } = require("./regex")
3
+ const { bookRegex, chapterRegex, verseRegex, scripturesRegex } = require("./regex")
4
4
  const abbrevations = require("./abbr")
5
- const crawler = require("bible-passage-reference-parser/js/en_bcv_parser").bcv_parser
6
- const util = require("util")
7
5
  const dump = require("./functions").dump
8
6
  const dd = require("./functions").dd
7
+ const chapter_verses = require("./chapterVerseCombine")
9
8
 
10
9
  class CodexParser {
11
10
  constructor() {
@@ -16,135 +15,308 @@ class CodexParser {
16
15
  this.chapterRegex = chapterRegex
17
16
  this.verseRegex = verseRegex
18
17
  this.scripturesRegex = scripturesRegex
19
- this.abbrevations = abbrevations
20
- this.EzraAbbrv = EzraAbbrv
21
- //this.toc = toc
22
- this.crawler = new crawler()
18
+ this.abbreviations = abbrevations
23
19
  this.versificationDifferences = versified
20
+ this.singleChapterBook = [
21
+ {
22
+ Jude: {
23
+ 1: Array.from({ length: 25 }, (_, i) => i + 1),
24
+ }, // Jude has 25 verses
25
+ },
26
+ {
27
+ "2 John": {
28
+ 1: Array.from({ length: 13 }, (_, i) => i + 1),
29
+ }, // 2 John has 13 verses
30
+ },
31
+ {
32
+ "3 John": {
33
+ 1: Array.from({ length: 15 }, (_, i) => i + 1),
34
+ }, // 3 John has 15 verses
35
+ },
36
+ {
37
+ Obadiah: {
38
+ 1: Array.from({ length: 21 }, (_, i) => i + 1),
39
+ }, // Obadiah has 21 verses
40
+ },
41
+ {
42
+ Philemon: {
43
+ 1: Array.from({ length: 25 }, (_, i) => i + 1),
44
+ }, // Philemon has 25 verses
45
+ },
46
+ ]
47
+ this.chapterVerses = chapter_verses
48
+ this.error = false
24
49
  }
25
50
 
26
51
  /**
27
- * Sets the options for the crawler and returns the current instance.
28
- *
29
- * @param {Object} options - The options to set.
30
- * @return {Object} The current instance.
31
- */
32
- options(options) {
33
- this.crawler.set_options(options)
34
- return this
35
- }
36
-
37
- /**
38
- * Scans the input text using the specified scriptures regex.
39
- *
40
- * @param {string} text - The text to scan.
41
- * @return {array} The found passages from the text.
52
+ * Scans the given text for Bible references, and stores all found references in the `found` property of the instance.
53
+ * @param {string} text The text to scan for Bible references.
54
+ * @return {CodexParser} This instance, for method chaining.
42
55
  */
43
56
  scan(text) {
44
- text = text.replace(/Rev(?=\s|\.)/gim, "Revelation")
45
- const regex = /(?:He(?=\s?\d+))/g
46
- let match
47
- const matches = []
48
-
49
- while ((match = regex.exec(text)) !== null) {
50
- const index = match.index
51
- const book = this.bookify(match[0])
52
- matches.push({
53
- abbr: match[0],
54
- book: book,
55
- index: index,
56
- })
57
- }
58
- for (let i = matches.length - 1; i >= 0; i--) {
59
- const match = matches[i]
60
- text = text.substring(0, match.index) + match.book + text.substring(match.index + match.abbr.length)
57
+ const fullNames = [...this.bible.old, ...this.bible.new] // Full Bible book names
58
+ const abbreviations = Object.keys(this.abbreviations) // Abbreviations for Bible books
59
+
60
+ this.found = []
61
+
62
+ // Convert the Bible book names and text to lowercase for case-insensitive matching
63
+ const lowercaseBibleFullNames = fullNames.map((book) => book.toLowerCase())
64
+ const lowercaseBibleAbbreviations = abbreviations.map((abbr) => abbr.toLowerCase())
65
+ const lowerCaseText = text.toLowerCase()
66
+
67
+ let i = 0
68
+
69
+ // Function to determine if a character is a valid part of a chapter or verse reference (non-word characters)
70
+ const isValidChapterVerseChar = (char) => {
71
+ return /[^A-Za-z]/.test(char) // Allow any non-word characters
61
72
  }
62
- const bookShouldBeEra = text.match(this.EzraAbbrv)
63
73
 
64
- if (bookShouldBeEra) {
65
- text = text.replace(this.EzraAbbrv, "Ezra")
74
+ // Function to check if a character at a given index is non-alphabetic or at the boundary of the text
75
+ const isBoundaryOrNonAlphabetic = (index, text) => {
76
+ return index < 0 || index >= text.length || /[^a-z]/i.test(text[index])
66
77
  }
67
- const passages = this.crawler.parse(text).parsed_entities()
68
78
 
69
- for (let j = 0; j < passages.length; j++) {
70
- const passage = passages[j]
71
- for (let i = 0; i < passage.entities.length; i++) {
72
- const entity = passage.entities[i]
73
- this.found.push(entity)
79
+ // Function to check if the next part of the text starts with a new Bible book (e.g., "2 Corinthians")
80
+ const isNextBibleBook = (startIndex) => {
81
+ const textAfterCurrentPosition = lowerCaseText.substring(startIndex).trim()
82
+
83
+ // Check if the next part of the text matches any full Bible book name
84
+ for (let j = 0; j < lowercaseBibleFullNames.length; j++) {
85
+ if (textAfterCurrentPosition.startsWith(lowercaseBibleFullNames[j])) {
86
+ return true // Found another Bible book
87
+ }
74
88
  }
75
- }
76
- }
77
89
 
78
- /**
79
- * Parses the given reference to extract passages.
80
- *
81
- * @param {string} reference - The reference to parse.
82
- * @return {array} An array of parsed passages.
83
- */
84
- parse(reference) {
85
- if (!reference) {
86
- this.passages = []
87
- return this
88
- }
89
- this.passages = []
90
- this.scan(reference)
91
- const books = []
92
- for (let i = 0; i < this.found.length; i++) {
93
- const result = this.found[i]
94
- if (result.type === "range" && result.start.b !== result.end.b) {
95
- const newPassageFound = result.end.b + " " + result.end.c + ":" + result.end.v
96
- const newPassageToAdd = this.crawler.parse(newPassageFound).parsed_entities()[0].entities
97
- this.found.splice(i + 1, 0, ...newPassageToAdd)
98
- result.end.b = result.start.b
99
- result.end.c = result.start.c
100
- result.end.v = result.start.v
90
+ for (let j = 0; j < lowercaseBibleAbbreviations.length; j++) {
91
+ if (textAfterCurrentPosition.startsWith(lowercaseBibleAbbreviations[j])) {
92
+ return true // Found another Bible book abbreviation
93
+ }
101
94
  }
102
95
 
103
- const passage = {
104
- book: this.bookify(result.start.b),
105
- chapter: result.start.c,
106
- verses: this.versify(result),
107
- type: result.type,
108
- ...result["entities"][0],
96
+ return false
97
+ }
98
+
99
+ // Loop through the text and check for full names and abbreviations
100
+ while (i < lowerCaseText.length) {
101
+ let foundBook = null
102
+ let foundIndex = -1
103
+ let matchedLength = 0
104
+
105
+ // Check full names first, to prioritize longer matches
106
+ for (let j = 0; j < lowercaseBibleFullNames.length; j++) {
107
+ const book = lowercaseBibleFullNames[j]
108
+
109
+ // Check if the text starting at position `i` matches the Bible book
110
+ if (lowerCaseText.startsWith(book, i)) {
111
+ if (book.length > matchedLength) {
112
+ foundBook = fullNames[j] // Store the original full name
113
+ foundIndex = i // Record the index where the book is found
114
+ matchedLength = book.length // Update the length of the match
115
+ }
116
+ }
109
117
  }
110
- passage.testament = this.bible.old.includes(passage.book) ? "old" : "new"
111
- let next = this.found[i + 1]
112
- if (next && next.type === "integer" && next.start.b === result.end.b && next.end.c === result.start.c) {
113
- while (
114
- next &&
115
- next.type === "integer" &&
116
- next.start.b === result.end.b &&
117
- next.end.c === result.start.c
118
- ) {
119
- if (next.start.v > result.start.v) {
120
- passage.verses.push(next.start.v)
121
- if (next.end.v !== next.start.v) passage.verses.push(next.end.v)
122
- passage.subType = next.type
118
+
119
+ // If no full book name was found, check for abbreviations
120
+ if (!foundBook) {
121
+ for (let k = 0; k < lowercaseBibleAbbreviations.length; k++) {
122
+ const abbreviation = lowercaseBibleAbbreviations[k]
123
+ const abbreviationWithDot = abbreviation + "."
124
+
125
+ // Ensure abbreviation is not part of a larger word (check boundaries)
126
+ if (lowerCaseText.startsWith(abbreviationWithDot, i)) {
127
+ if (
128
+ isBoundaryOrNonAlphabetic(i - 1, lowerCaseText) &&
129
+ isBoundaryOrNonAlphabetic(i + abbreviationWithDot.length, lowerCaseText)
130
+ ) {
131
+ foundBook = abbreviations[k] // Store the abbreviation without the dot
132
+ foundIndex = i // Record the index where the abbreviation is found
133
+ matchedLength = abbreviationWithDot.length // Update the length of the match to include the dot
134
+ break // Exit once found
135
+ }
136
+ } else if (lowerCaseText.startsWith(abbreviation, i)) {
137
+ if (
138
+ isBoundaryOrNonAlphabetic(i - 1, lowerCaseText) &&
139
+ isBoundaryOrNonAlphabetic(i + abbreviation.length, lowerCaseText)
140
+ ) {
141
+ if (abbreviation.length > matchedLength) {
142
+ foundBook = abbreviations[k] // Store the abbreviation without the dot
143
+ foundIndex = i // Record the index where the abbreviation is found
144
+ matchedLength = abbreviation.length // Update the length of the match
145
+ }
146
+ }
123
147
  }
124
- i++
125
- next = this.found[i + 1]
126
148
  }
127
149
  }
128
150
 
129
- if (passage.type === "range" && result.start.b === result.end.b) {
130
- if (result.start.c !== result.end.c) {
131
- passage.verses = [result.start.v]
132
- passage.to = {
133
- book: this.bookify(result.end.b),
134
- chapter: result.end.c,
135
- verses: result.end.v,
151
+ // If a book or abbreviation was found, look for chapter and verse patterns after the book
152
+ if (foundBook !== null) {
153
+ i += matchedLength // Skip ahead by the length of the found book
154
+ let chapterVerse = ""
155
+
156
+ while (i < text.length && isValidChapterVerseChar(text[i])) {
157
+ // Look ahead to see if the next characters form a new Bible book
158
+ if (isNextBibleBook(i)) {
159
+ // Stop adding to chapterVerse if a new Bible book is found
160
+ break
136
161
  }
162
+
163
+ chapterVerse += text[i]
164
+ i++
137
165
  }
166
+
167
+ // Trim any period from the end of the reference
168
+ chapterVerse = chapterVerse.trim().replace(/[.,:;!?]+$/, "")
169
+
170
+ // Replace any periods within the reference with colons for easier parsing
171
+ const formattedReference = chapterVerse.replace(/\./g, ":")
172
+
173
+ if (formattedReference.length > 0) {
174
+ this.found.push({
175
+ book: foundBook,
176
+ reference: formattedReference, // Store the formatted reference
177
+ index: foundIndex,
178
+ })
179
+ } else {
180
+ this.found.push({
181
+ book: foundBook,
182
+ reference: null,
183
+ index: foundIndex,
184
+ })
185
+ }
186
+ } else {
187
+ i++
138
188
  }
139
- passage.original = result.osis
140
- passage.scripture = this.scripturize(passage)
141
- passage.passages = this.populate(result.entities[0], passage.verses)
142
- passage.indices = result.indices
143
- this.passages.push(passage)
144
189
  }
145
- this.found = []
190
+
191
+ return this // Return this instance for method chaining
192
+ }
193
+
194
+ parse(reference) {
195
+ this.scan(reference) // Call scan to populate this.found
196
+
197
+ this.passages = this.found.map((passage) => {
198
+ const book = this.bookify(passage.book)
199
+
200
+ // Initialize the parsed passage object
201
+ const parsedPassage = {
202
+ original: passage.book + " " + passage.reference,
203
+ hashed: book.toLowerCase().replace(/\s+/, "_") + "." + passage.reference.replace(/[:\.]/g, "."), // Handle both : and .
204
+ book: book,
205
+ chapter: null,
206
+ verses: [], // Verse stored as an array
207
+ type: null, // Set type based on reference
208
+ testament: this.bible.old.find((bible) => bible === book) ? "old" : "new",
209
+ index: passage.index,
210
+ }
211
+
212
+ // Split reference by commas to handle multiple ranges or verses (e.g., "Ge 27:27-29,39-41")
213
+ let parts = passage.reference.split(",")
214
+
215
+ // Check for single chapter books
216
+ const singleChapterBook = this.singleChapterBook.find((bible) => bible[book])
217
+
218
+ parts.forEach((part) => {
219
+ part = part.trim() // Clean up spaces
220
+ // Detect whether it uses ":" or "." for chapter:verse separation
221
+ const separator = part.includes(":") ? ":" : "."
222
+
223
+ if (part.includes("-")) {
224
+ // Handle ranges (e.g., "27:27-29" or "39-41")
225
+
226
+ let [start, end] = part.split("-")
227
+ // Handle the starting part
228
+ let [startChapter, startVerse] = start.includes(separator)
229
+ ? start.split(separator)
230
+ : [parsedPassage.chapter, start] // Default to same chapter if no chapter is provided
231
+
232
+ parsedPassage.chapter = Number(startChapter) // Set the chapter
233
+ // Checks to see if we are in a multi chapter verse range, if so, include only relevant verses from the this.chapterVerse to
234
+ // the end of the chapter.
235
+ if (start.includes(separator) && end.includes(separator)) {
236
+ parsedPassage.verses = this.chapterVerses[book][startChapter].slice(
237
+ this.chapterVerses[book][startChapter].indexOf(Number(startVerse))
238
+ )
239
+ } else {
240
+ parsedPassage.verses.push(startVerse.trim())
241
+ }
242
+
243
+ // Handle same-chapter ranges (e.g., "27:27-29") and multi-chapter ranges (e.g., "Ex 2:1-3:4")
244
+ //TODO: Need to check for a multi chapter verse range and if fill out the verses before the verse of
245
+ // The second chapter.
246
+ if (end.includes(separator)) {
247
+ let [endChapter, endVerse] = end.split(separator)
248
+ if (Number(endChapter) !== Number(startChapter)) {
249
+ // Cross-chapter range, set 'to' property
250
+ parsedPassage.to = {
251
+ book: book,
252
+ chapter: Number(endChapter), // End chapter
253
+ }
254
+ if (endVerse > 1) {
255
+ parsedPassage.to.verses = this.chapterVerses[book][Number(endChapter)].slice(
256
+ 0,
257
+ this.chapterVerses[book][Number(endChapter)].indexOf(Number(endVerse)) + 1
258
+ )
259
+ }
260
+ parsedPassage.type = "chapter_verse_range" // Set type to chapter range
261
+ } else {
262
+ // Same-chapter range, just add to the verse array
263
+ parsedPassage.verses.push(`${startVerse}-${endVerse}`)
264
+ }
265
+ } else {
266
+ // Single-chapter range (e.g., "27:27-29" or "39-41")
267
+ if (!singleChapterBook) {
268
+ if (!startChapter) {
269
+ // Then we have a chapter range with no verses
270
+ parsedPassage.chapter = start
271
+ parsedPassage.verses = this.chapterVerses[book][start]
272
+ parsedPassage.to = {
273
+ book: book,
274
+ chapter: Number(end),
275
+ verse: this.chapterVerses[book][end],
276
+ }
277
+ } else {
278
+ parsedPassage.verses.push(`${startVerse}-${end}`)
279
+ }
280
+ } else {
281
+ parsedPassage.chapter = 1
282
+ parsedPassage.verses.push(`${startVerse}-${end}`)
283
+ }
284
+ }
285
+ } else {
286
+ // Handle individual chapter:verse references (e.g., "27:27")
287
+
288
+ let [chapterPart, versePart] = part.includes(separator)
289
+ ? part.split(separator)
290
+ : [parsedPassage.chapter, part]
291
+ if (singleChapterBook) {
292
+ if (!chapterPart) {
293
+ parsedPassage.chapter = 1
294
+ parsedPassage.verses.push(versePart) // Add single verse to array
295
+ } else {
296
+ parsedPassage.chapter = Number(chapterPart)
297
+ parsedPassage.verses.push(versePart) // Add single verse to array
298
+ }
299
+ } else {
300
+ // Need to check if chapterPart is undefined
301
+ // If it's undefined, then versePart actually is the chapter and we need to populate the
302
+ // verses from this.chapterVerses
303
+
304
+ if (chapterPart) {
305
+ parsedPassage.chapter = Number(chapterPart)
306
+ parsedPassage.verses.push(versePart) // Add single verse to array
307
+ } else {
308
+ parsedPassage.chapter = Number(versePart)
309
+ parsedPassage.verses = this.chapterVerses[book][parsedPassage.chapter]
310
+ }
311
+ }
312
+ }
313
+ parsedPassage.passages = this.populate(parsedPassage)
314
+ })
315
+
316
+ return parsedPassage
317
+ })
146
318
  this.versification()
147
- return this
319
+ return this // Return this instance
148
320
  }
149
321
 
150
322
  versification() {
@@ -170,87 +342,32 @@ class CodexParser {
170
342
  * @param {Array} verses - Array of verse numbers to add to the set of passages
171
343
  * @return {Array} Array of passage objects
172
344
  */
173
- populate(entities, verses) {
174
- let passages = []
175
- for (let i = entities.start.v; i <= entities.end.v; i++) {
176
- passages.push({
177
- book: this.bookify(entities.start.b),
178
- chapter: entities.start.c,
179
- verse: i,
180
- })
181
- }
345
+ populate(parsedPassage) {
346
+ const passages = []
182
347
 
183
- if (verses.length > 1) {
184
- dump(verses)
185
- const hasDashes = verses.find((verse) => /[-–—]/gim.test(verse))
186
- if (hasDashes) {
187
- const newVerses = []
188
- for (let i = 0; i < verses.length; i++) {
189
- const verse = verses[i]
190
- if (/[-–—]/gim.verse) {
191
- const [start, end] = verse.split("-").map((v) => parseInt(v))
192
- for (let j = start; j <= end; j++) {
193
- newVerses.push(j)
194
- }
195
- } else {
196
- newVerses.push(parseInt(verse))
348
+ // Helper function to process a parsed passage's verses
349
+ const processVerses = (chapter, verses, book) => {
350
+ verses.forEach((verse) => {
351
+ if (isNaN(verse)) {
352
+ const [start, end] = verse.split("-").map(Number) // Handle ranges
353
+ for (let i = start; i <= end; i++) {
354
+ passages.push({ book, chapter: Number(chapter), verse: i })
197
355
  }
356
+ } else {
357
+ passages.push({ book, chapter: Number(chapter), verse: Number(verse) })
198
358
  }
199
- verses = newVerses.sort((a, b) => a - b)
200
- }
201
- for (let i = 0; i < verses.length; i++) {
202
- const passage = {
203
- book: this.bookify(entities.start.b),
204
- chapter: entities.start.c,
205
- verse: verses[i],
206
- }
207
- if (
208
- !passages.find(
209
- (p) => p.book === passage.book && p.chapter === passage.chapter && p.verse === passage.verse
210
- )
211
- ) {
212
- passages.push(passage)
213
- }
214
- }
359
+ })
215
360
  }
216
361
 
217
- return [...new Set(passages)]
218
- }
219
-
220
- chapterify(chapter) {
221
- return chapter.start.c
222
- }
362
+ // Process main passage
363
+ processVerses(parsedPassage.chapter, parsedPassage.verses, parsedPassage.book)
223
364
 
224
- /**
225
- * Given a passage, return an array of verses. If the passage is a range, the
226
- * array will contain a single string in the format "start-end". If the passage
227
- * is not a range, the array will contain each verse number as a separate element.
228
- *
229
- * @param {Object} passage - A passage object from the bible-passage-reference-parser
230
- * @return {Array} Array of verse numbers
231
- */
232
- versify(passage) {
233
- if (passage.start.v !== passage.end.v) {
234
- if (passage.type === "range" || passage.type === "ff") {
235
- if (passage.start.b === passage.end.b) {
236
- return [`${passage.start.v}-${passage.end.v}`]
237
- } else {
238
- return [passage.start.v]
239
- }
240
- } else {
241
- if (passage.type !== "bc") {
242
- const verses = []
243
- for (let i = passage.start.v; i <= passage.end.v; i++) {
244
- verses.push(i)
245
- }
246
- return verses
247
- } else {
248
- return [passage.start.v + "-" + passage.end.v]
249
- }
250
- }
251
- } else {
252
- return [passage.start.v]
365
+ // Process 'to' object if it exists (for cross-chapter ranges)
366
+ if (parsedPassage.to) {
367
+ processVerses(parsedPassage.to.chapter, parsedPassage.to.verses, parsedPassage.to.book)
253
368
  }
369
+
370
+ return passages
254
371
  }
255
372
 
256
373
  /**
@@ -263,10 +380,10 @@ class CodexParser {
263
380
  if (typeof book !== "string") {
264
381
  book = book[0]
265
382
  }
266
- let bookified = Object.keys(this.abbrevations).find((abbr) => {
383
+ let bookified = Object.keys(this.abbreviations).find((abbr) => {
267
384
  return abbr.toLowerCase() === book.toLowerCase()
268
385
  })
269
- bookified = this.abbrevations[bookified]
386
+ bookified = this.abbreviations[bookified]
270
387
  if (!bookified) {
271
388
  bookified = this.bible.new.find(
272
389
  (b) => b.toLowerCase() === book.toLowerCase() && b.toLowerCase().includes(book.toLowerCase())
@@ -316,8 +433,4 @@ class CodexParser {
316
433
  }
317
434
  }
318
435
 
319
- if (typeof window !== "undefined" && window) {
320
- if (!window.CodexParser) window.CodexParser = CodexParser
321
- }
322
-
323
436
  module.exports = CodexParser
package/src/abbr.js CHANGED
@@ -236,9 +236,9 @@ const abbrevations = {
236
236
  Phlm: "Philemon",
237
237
  Phm: "Philemon",
238
238
  Philem: "Philemon",
239
+ He: "Hebrews",
239
240
  Hebr: "Hebrews",
240
241
  Heb: "Hebrews",
241
- He: "Hebrews",
242
242
  Jas: "James",
243
243
  Jm: "James",
244
244
  James: "James",
package/src/bible.js CHANGED
@@ -19,6 +19,7 @@ module.exports = {
19
19
  "Esther",
20
20
  "Job",
21
21
  "Psalms",
22
+ "Psalm",
22
23
  "Proverbs",
23
24
  "Ecclesiastes",
24
25
  "Song of Solomon",
@@ -0,0 +1,63 @@
1
+ module.exports = {
2
+ Genesis: require("./chapter_verses/genesis"),
3
+ Exodus: require("./chapter_verses/exodus"),
4
+ Leviticus: require("./chapter_verses/leviticus"),
5
+ Numbers: require("./chapter_verses/numbers"),
6
+ Deuteronomy: require("./chapter_verses/deuteronomy"),
7
+ Joshua: require("./chapter_verses/joshua"),
8
+ Judges: require("./chapter_verses/judges"),
9
+ Ruth: require("./chapter_verses/ruth"),
10
+ "1 Samuel": require("./chapter_verses/1samuel"),
11
+ "2 Samuel": require("./chapter_verses/2samuel"),
12
+ "1 Kings": require("./chapter_verses/1kings"),
13
+ "2 Kings": require("./chapter_verses/2kings"),
14
+ "1 Chronicles": require("./chapter_verses/1chronicles.js"),
15
+ "2 Chronicles": require("./chapter_verses/2chronicles.js"),
16
+ Ezra: require("./chapter_verses/ezra.js"),
17
+ Nehemiah: require("./chapter_verses/nehemiah"),
18
+ Esther: require("./chapter_verses/esther.js"),
19
+ Job: require("./chapter_verses/job"),
20
+ Psalms: require("./chapter_verses/psalms"),
21
+ Proverbs: require("./chapter_verses/proverbs"),
22
+ Ecclesiastes: require("./chapter_verses/ecclesiastes"),
23
+ "Song of Songs": require("./chapter_verses/songs"),
24
+ Isaiah: require("./chapter_verses/isaiah"),
25
+ Jeremiah: require("./chapter_verses/jeremiah"),
26
+ Lamentations: require("./chapter_verses/lamentations"),
27
+ Ezekiel: require("./chapter_verses/ezekiel"),
28
+ Daniel: require("./chapter_verses/daniel"),
29
+ Hosea: require("./chapter_verses/hosea"),
30
+ Joel: require("./chapter_verses/joel"),
31
+ Amos: require("./chapter_verses/amos"),
32
+ Jonah: require("./chapter_verses/jonah"),
33
+ Micah: require("./chapter_verses/micah"),
34
+ Nahum: require("./chapter_verses/nahum"),
35
+ Habakkuk: require("./chapter_verses/habakkuk.js"),
36
+ Zephaniah: require("./chapter_verses/zephaniah"),
37
+ Haggai: require("./chapter_verses/haggai"),
38
+ Zechariah: require("./chapter_verses/zechariah"),
39
+ Malachi: require("./chapter_verses/malachi"),
40
+ Matthew: require("./chapter_verses/matthew"),
41
+ Mark: require("./chapter_verses/mark"),
42
+ Luke: require("./chapter_verses/luke"),
43
+ John: require("./chapter_verses/john"),
44
+ Acts: require("./chapter_verses/acts"),
45
+ Romans: require("./chapter_verses/romans"),
46
+ "1 Corinthians": require("./chapter_verses/1corinthians"),
47
+ "2 Corinthians": require("./chapter_verses/2corinthians"),
48
+ Galatians: require("./chapter_verses/galatians"),
49
+ Ephesians: require("./chapter_verses/ephesians"),
50
+ Philippians: require("./chapter_verses/philippians"),
51
+ Colossians: require("./chapter_verses/colossians"),
52
+ "1 Thessalonians": require("./chapter_verses/1thessalonians"),
53
+ "2 Thessalonians": require("./chapter_verses/2thessalonians"),
54
+ "1 Timothy": require("./chapter_verses/1timothy"),
55
+ "2 Timothy": require("./chapter_verses/2timothy"),
56
+ Titus: require("./chapter_verses/titus"),
57
+ Hebrews: require("./chapter_verses/hebrews"),
58
+ James: require("./chapter_verses/james"),
59
+ "1 Peter": require("./chapter_verses/1peter"),
60
+ "2 Peter": require("./chapter_verses/2peter"),
61
+ "1 John": require("./chapter_verses/1john"),
62
+ Revelation: require("./chapter_verses/revelation"),
63
+ }