codexparser 0.1.63 → 0.1.65
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.
- package/package.json +1 -1
- package/src/CodexParser.js +30 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codexparser",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.65",
|
|
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": {
|
package/src/CodexParser.js
CHANGED
|
@@ -81,7 +81,7 @@ class CodexParser {
|
|
|
81
81
|
const lowerCaseText = normalizedText.toLowerCase()
|
|
82
82
|
let i = 0
|
|
83
83
|
|
|
84
|
-
const isValidChapterVerseChar = (char) => /[\d
|
|
84
|
+
const isValidChapterVerseChar = (char) => /[\d:,\-;\s]/.test(char)
|
|
85
85
|
const isNextBibleBook = (startIndex) => {
|
|
86
86
|
const textAfterCurrentPosition = lowerCaseText.substring(startIndex).trim()
|
|
87
87
|
return (
|
|
@@ -99,8 +99,8 @@ class CodexParser {
|
|
|
99
99
|
let startIndex = -1
|
|
100
100
|
let matchedLength = 0
|
|
101
101
|
|
|
102
|
-
// Skip
|
|
103
|
-
while (i < lowerCaseText.length &&
|
|
102
|
+
// Skip whitespace and special characters before checking for book
|
|
103
|
+
while (i < lowerCaseText.length && /[\s—-]/.test(lowerCaseText[i])) {
|
|
104
104
|
i++
|
|
105
105
|
}
|
|
106
106
|
if (i >= lowerCaseText.length) break
|
|
@@ -131,14 +131,10 @@ class CodexParser {
|
|
|
131
131
|
const references = []
|
|
132
132
|
const startOfReference = startIndex
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
while (
|
|
136
|
-
i < normalizedText.length &&
|
|
137
|
-
(isValidChapterVerseChar(normalizedText[i]) || normalizedText[i] === " ")
|
|
138
|
-
) {
|
|
134
|
+
while (i < normalizedText.length && isValidChapterVerseChar(normalizedText[i])) {
|
|
139
135
|
if (isNextBibleBook(i)) break
|
|
140
136
|
if (normalizedText[i] === ";") {
|
|
141
|
-
const formattedReference = chapterVerse.trim()
|
|
137
|
+
const formattedReference = chapterVerse.trim().replace(/[^a-zA-Z0-9]+$/, "")
|
|
142
138
|
if (formattedReference) references.push(formattedReference)
|
|
143
139
|
chapterVerse = ""
|
|
144
140
|
i++
|
|
@@ -149,7 +145,7 @@ class CodexParser {
|
|
|
149
145
|
}
|
|
150
146
|
|
|
151
147
|
if (chapterVerse.trim().length > 0) {
|
|
152
|
-
const formattedReference = chapterVerse.trim()
|
|
148
|
+
const formattedReference = chapterVerse.trim().replace(/[^a-zA-Z0-9]+$/, "")
|
|
153
149
|
if (formattedReference) references.push(formattedReference)
|
|
154
150
|
}
|
|
155
151
|
|
|
@@ -162,16 +158,16 @@ class CodexParser {
|
|
|
162
158
|
i += suffixData.length
|
|
163
159
|
}
|
|
164
160
|
|
|
165
|
-
// Trim endIndex to exclude trailing non-reference characters
|
|
166
|
-
while (endIndex > startOfReference && /[
|
|
161
|
+
// Trim endIndex to exclude trailing whitespace or non-reference characters
|
|
162
|
+
while (endIndex > startOfReference && /[\s]/.test(normalizedText[endIndex - 1])) {
|
|
167
163
|
endIndex--
|
|
168
164
|
}
|
|
169
165
|
|
|
170
|
-
references.forEach((
|
|
166
|
+
references.forEach((ref) => {
|
|
171
167
|
let type
|
|
172
|
-
if (
|
|
173
|
-
if (
|
|
174
|
-
const [start, end] =
|
|
168
|
+
if (ref.includes(":")) {
|
|
169
|
+
if (ref.includes("-")) {
|
|
170
|
+
const [start, end] = ref.split("-")
|
|
175
171
|
const startParts = start.split(":")
|
|
176
172
|
const endParts = end.split(":")
|
|
177
173
|
type =
|
|
@@ -180,12 +176,12 @@ class CodexParser {
|
|
|
180
176
|
startParts[0].trim() !== endParts[0].trim()
|
|
181
177
|
? "multi_chapter_verse_range"
|
|
182
178
|
: "chapter_verse_range"
|
|
183
|
-
} else if (
|
|
179
|
+
} else if (ref.includes(",")) {
|
|
184
180
|
type = "comma_separated_verses"
|
|
185
181
|
} else {
|
|
186
182
|
type = "chapter_verse"
|
|
187
183
|
}
|
|
188
|
-
} else if (
|
|
184
|
+
} else if (ref.includes("-")) {
|
|
189
185
|
type = "chapter_range"
|
|
190
186
|
} else {
|
|
191
187
|
type = "single_chapter"
|
|
@@ -193,12 +189,12 @@ class CodexParser {
|
|
|
193
189
|
|
|
194
190
|
this.found.push({
|
|
195
191
|
book: foundBook,
|
|
196
|
-
reference:
|
|
192
|
+
reference: ref,
|
|
197
193
|
startIndex: startOfReference + 1,
|
|
198
194
|
endIndex: endIndex + 1,
|
|
199
195
|
version: suffix || null,
|
|
200
196
|
type,
|
|
201
|
-
originalText: text.slice(startOfReference, endIndex),
|
|
197
|
+
originalText: text.slice(startOfReference, endIndex), // Use original text
|
|
202
198
|
})
|
|
203
199
|
})
|
|
204
200
|
} else {
|
|
@@ -231,6 +227,9 @@ class CodexParser {
|
|
|
231
227
|
parse(reference) {
|
|
232
228
|
this.scan(reference)
|
|
233
229
|
|
|
230
|
+
// Define non-abbreviated books per SBL/Crossway
|
|
231
|
+
const nonAbbreviatedBooks = ["John", "Luke", "Acts", "Jude", "James", "Titus"]
|
|
232
|
+
|
|
234
233
|
this.passages = this.found.map((passage) => {
|
|
235
234
|
const book = this.bookify(passage.book)
|
|
236
235
|
const testament = this.bible.old.includes(book) ? "old" : "new"
|
|
@@ -258,13 +257,20 @@ class CodexParser {
|
|
|
258
257
|
parsedPassage.scripture = this.scripturize(parsedPassage)
|
|
259
258
|
parsedPassage.valid = this._isValid(parsedPassage, passage.reference)
|
|
260
259
|
|
|
261
|
-
// Set abbr property using SBL-style
|
|
260
|
+
// Set abbr property using SBL-style rules
|
|
262
261
|
const abbrKey = Object.keys(this.abbreviations).find(
|
|
263
262
|
(abbr) => this.abbreviations[abbr].toLowerCase() === book.toLowerCase()
|
|
264
263
|
)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
:
|
|
264
|
+
if (nonAbbreviatedBooks.includes(book)) {
|
|
265
|
+
// Use full book name without period for non-abbreviated books
|
|
266
|
+
parsedPassage.abbr = `${book} ${passage.reference}${passage.version ? " " + passage.version : ""}`
|
|
267
|
+
} else if (abbrKey) {
|
|
268
|
+
// Use abbreviation with period for abbreviated books
|
|
269
|
+
parsedPassage.abbr = `${abbrKey}. ${passage.reference}${passage.version ? " " + passage.version : ""}`
|
|
270
|
+
} else {
|
|
271
|
+
// Fallback to original if no abbreviation (shouldn't occur with proper data)
|
|
272
|
+
parsedPassage.abbr = parsedPassage.original
|
|
273
|
+
}
|
|
268
274
|
|
|
269
275
|
if (parsedPassage.type === this.MULTI_CHAPTER_RANGE) {
|
|
270
276
|
this.handleMultiChapterRange(parsedPassage, passage.reference)
|