codexparser 0.1.83 → 0.1.84

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/.trunk/trunk.yaml CHANGED
@@ -7,7 +7,7 @@ cli:
7
7
  plugins:
8
8
  sources:
9
9
  - id: trunk
10
- ref: v1.7.0
10
+ ref: v1.7.1
11
11
  uri: https://github.com/trunk-io/plugins
12
12
  # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
13
13
  runtimes:
@@ -17,11 +17,11 @@ runtimes:
17
17
  # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
18
18
  lint:
19
19
  enabled:
20
- - checkov@3.2.445
20
+ - checkov@3.2.446
21
21
  - git-diff-check
22
22
  - markdownlint@0.45.0
23
23
  - osv-scanner@2.0.3
24
- - prettier@3.6.0
24
+ - prettier@3.6.1
25
25
  - trufflehog@3.89.2
26
26
  actions:
27
27
  disabled:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.83",
3
+ "version": "0.1.84",
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": {
@@ -85,11 +85,6 @@ class CodexParser {
85
85
  return singleChapterBook ? singleChapterBook[book][chapter] || [] : this.chapterVerses[book]?.[chapter] || []
86
86
  }
87
87
 
88
- /**
89
- * Scans text for scripture references and stores them in `this.found`.
90
- * @param {string} text - The text to scan.
91
- * @returns {CodexParser} The parser instance for method chaining.
92
- */
93
88
  /**
94
89
  * Scans text for scripture references and stores them in `this.found`.
95
90
  * @param {string} text - The text to scan.
@@ -101,6 +96,8 @@ class CodexParser {
101
96
  this.found = []
102
97
  // Minimal normalization: fix periods before numbers, remove trailing periods
103
98
  let normalizedText = text.replace(/\.(?=\d)/g, ":").replace(/(\b[A-Za-z]+)\.(?=\s|$)/g, "$1")
99
+ console.log(`Input text: ${text}`)
100
+ console.log(`Normalized text: ${normalizedText}`)
104
101
  const lowercaseBibleFullNames = fullNames.map((book) => book.toLowerCase())
105
102
  const lowercaseBibleAbbreviations = abbreviations.map((abbr) => abbr.toLowerCase())
106
103
  const lowerCaseText = normalizedText.toLowerCase()
@@ -121,7 +118,7 @@ class CodexParser {
121
118
 
122
119
  while (i < lowerCaseText.length) {
123
120
  let foundBook = null
124
- let startIndex = -1
121
+ let bookStartIndex = -1
125
122
  let matchedLength = 0
126
123
 
127
124
  // Skip whitespace and special characters before checking for book
@@ -130,11 +127,13 @@ class CodexParser {
130
127
  }
131
128
  if (i >= lowerCaseText.length) break
132
129
 
130
+ console.log(`Scanning at index ${i}: ${lowerCaseText.slice(i, i + 10)}...`)
131
+
133
132
  for (let j = 0; j < lowercaseBibleFullNames.length; j++) {
134
133
  const book = lowercaseBibleFullNames[j]
135
134
  if (lowerCaseText.startsWith(book, i) && book.length > matchedLength) {
136
135
  foundBook = fullNames[j]
137
- startIndex = i
136
+ bookStartIndex = i
138
137
  matchedLength = book.length
139
138
  }
140
139
  }
@@ -144,24 +143,42 @@ class CodexParser {
144
143
  const abbreviation = lowercaseBibleAbbreviations[k]
145
144
  if (lowerCaseText.startsWith(abbreviation, i) && abbreviation.length > matchedLength) {
146
145
  foundBook = this.abbreviations[abbreviations[k]]
147
- startIndex = i
146
+ bookStartIndex = i
148
147
  matchedLength = abbreviation.length
149
148
  }
150
149
  }
151
150
  }
152
151
 
153
152
  if (foundBook) {
153
+ console.log(`Found book: ${foundBook} at index ${bookStartIndex}, length ${matchedLength}`)
154
154
  i += matchedLength
155
155
  let chapterVerse = ""
156
156
  const references = []
157
- const startOfReference = startIndex
157
+ let refStartIndex = bookStartIndex // Start of reference (including book) in normalizedText
158
+ let originalRefStartIndex = bookStartIndex // Start in original text
158
159
 
159
160
  while (i < normalizedText.length && isValidChapterVerseChar(normalizedText[i])) {
160
- if (isNextBibleBook(i)) break
161
+ if (isNextBibleBook(i)) {
162
+ console.log(`Next book detected at index ${i}, stopping reference parsing`)
163
+ break
164
+ }
161
165
  if (normalizedText[i] === ";") {
162
- const formattedReference = chapterVerse.trim().replace(/[^a-zA-Z0-9]+$/, "")
163
- if (formattedReference) references.push(formattedReference)
166
+ const formattedReference = chapterVerse.trim()
167
+ if (formattedReference) {
168
+ const refEndIndex = i
169
+ references.push({
170
+ ref: formattedReference,
171
+ start: refStartIndex,
172
+ end: refEndIndex,
173
+ })
174
+ console.log(
175
+ `Reference found: ${formattedReference}, normalized indices ${refStartIndex}-${refEndIndex}`
176
+ )
177
+ }
164
178
  chapterVerse = ""
179
+ refStartIndex = i + 1
180
+ const semicolonIndex = text.indexOf(";", originalRefStartIndex)
181
+ originalRefStartIndex = semicolonIndex !== -1 ? semicolonIndex + 1 : refStartIndex
165
182
  i++
166
183
  continue
167
184
  }
@@ -170,25 +187,29 @@ class CodexParser {
170
187
  }
171
188
 
172
189
  if (chapterVerse.trim().length > 0) {
173
- const formattedReference = chapterVerse.trim().replace(/[^a-zA-Z0-9]+$/, "")
174
- if (formattedReference) references.push(formattedReference)
175
- }
176
-
177
- // Set endIndex to the current position
178
- let endIndex = i
179
- const suffixData = detectSuffix(i)
180
- const suffix = suffixData ? suffixData.suffix : null
181
- if (suffixData) {
182
- endIndex += suffixData.length
183
- i += suffixData.length
190
+ const formattedReference = chapterVerse.trim()
191
+ if (formattedReference) {
192
+ const refEndIndex = i
193
+ references.push({
194
+ ref: formattedReference,
195
+ start: refStartIndex,
196
+ end: refEndIndex,
197
+ })
198
+ console.log(
199
+ `Final reference found: ${formattedReference}, normalized indices ${refStartIndex}-${refEndIndex}`
200
+ )
201
+ }
184
202
  }
185
203
 
186
- // Trim endIndex to exclude trailing whitespace or non-reference characters
187
- while (endIndex > startOfReference && /[\s]/.test(normalizedText[endIndex - 1])) {
188
- endIndex--
189
- }
204
+ // Align indices with original text
205
+ const originalBookText = text.slice(bookStartIndex, bookStartIndex + matchedLength)
206
+ const originalBookStartIndex =
207
+ text.indexOf(originalBookText, bookStartIndex) !== -1
208
+ ? text.indexOf(originalBookText, bookStartIndex)
209
+ : bookStartIndex
210
+ console.log(`Original book text: ${originalBookText}, original start index: ${originalBookStartIndex}`)
190
211
 
191
- references.forEach((ref) => {
212
+ references.forEach(({ ref, start, end }, refIndex) => {
192
213
  let type
193
214
  if (ref.includes(":")) {
194
215
  if (ref.includes("-")) {
@@ -212,14 +233,56 @@ class CodexParser {
212
233
  type = "single_chapter"
213
234
  }
214
235
 
236
+ // Construct full reference text for original text
237
+ const fullRefText = `${originalBookText} ${ref.replace(":", ".")}`
238
+ const suffixData = detectSuffix(end)
239
+ const suffix = suffixData ? suffixData.suffix : null
240
+ let refEndIndex = end
241
+ if (suffixData) {
242
+ refEndIndex += suffixData.length
243
+ i += suffixData.length // Skip suffix
244
+ }
245
+
246
+ // Map to original text
247
+ let originalStartIndex =
248
+ text.indexOf(fullRefText, originalRefStartIndex) !== -1
249
+ ? text.indexOf(fullRefText, originalRefStartIndex)
250
+ : originalBookStartIndex
251
+ console.log(
252
+ `Searching for fullRefText: ${fullRefText} at index ${originalRefStartIndex}, found at ${originalStartIndex}`
253
+ )
254
+
255
+ let originalEndIndex = originalStartIndex + fullRefText.length
256
+ let originalText = text.slice(originalStartIndex, originalEndIndex)
257
+
258
+ // Adjust for suffix in original text
259
+ if (suffixData) {
260
+ originalEndIndex += suffixData.length
261
+ originalText = text.slice(originalStartIndex, originalEndIndex)
262
+ }
263
+
264
+ // Trim trailing whitespace from originalText
265
+ while (originalEndIndex > originalStartIndex && /[\s]/.test(text[originalEndIndex - 1])) {
266
+ originalEndIndex--
267
+ originalText = text.slice(originalStartIndex, originalEndIndex)
268
+ }
269
+
270
+ console.log(
271
+ `Reference ${
272
+ refIndex + 1
273
+ }: ${originalText}, original indices ${originalStartIndex}-${originalEndIndex}, type: ${type}, suffix: ${
274
+ suffix || "none"
275
+ }, search text: ${fullRefText}`
276
+ )
277
+
215
278
  this.found.push({
216
279
  book: foundBook,
217
280
  reference: ref,
218
- startIndex: startOfReference + 1,
219
- endIndex: endIndex + 1,
281
+ startIndex: originalStartIndex,
282
+ endIndex: originalEndIndex,
220
283
  version: suffix || null,
221
284
  type,
222
- originalText: text.slice(startOfReference, endIndex), // Use original text
285
+ originalText: originalText,
223
286
  })
224
287
  })
225
288
  } else {
@@ -227,6 +290,7 @@ class CodexParser {
227
290
  }
228
291
  }
229
292
 
293
+ console.log(`Found references: ${JSON.stringify(this.found, null, 2)}`)
230
294
  return this
231
295
  }
232
296
 
@@ -276,6 +340,7 @@ class CodexParser {
276
340
 
277
341
  // Clean reference for parsing
278
342
  let cleanReference = passage.reference.replace(/\s*(LXX|MT)$/i, "").trim()
343
+ console.log(`Parsing reference: ${cleanReference}, type: ${passage.type}`)
279
344
  if (cleanReference.endsWith(",")) {
280
345
  cleanReference = cleanReference.slice(0, -1).trim()
281
346
  }
@@ -283,6 +348,7 @@ class CodexParser {
283
348
  // Handle book-only or empty references
284
349
  if (!cleanReference && this.config.booksOnly) {
285
350
  parsedPassage.type = "book_only"
351
+ console.log(`Book-only reference: ${book}`)
286
352
  } else if (!cleanReference || cleanReference.match(/^\d+\s*[:;]?\s*$/)) {
287
353
  const chapterMatch = cleanReference.match(/\d+/) || ["1"]
288
354
  const chapter = Number(chapterMatch[0])
@@ -294,8 +360,18 @@ class CodexParser {
294
360
  const endVerse = chapterVerses[chapterVerses.length - 1]
295
361
  parsedPassage.verses = [`${startVerse}-${endVerse}`]
296
362
  }
363
+ console.log(`Single chapter: ${chapter}, verses: ${parsedPassage.verses}`)
364
+ } else if (passage.type === "comma_separated_verses") {
365
+ // Handle comma-separated verses (e.g., "1:7,18")
366
+ const [chapter, verses] = cleanReference.split(":")
367
+ parsedPassage.chapter = Number(chapter)
368
+ parsedPassage.verses = verses.split(",").map((v) => v.trim())
369
+ console.log(`Comma-separated verses: chapter ${chapter}, verses ${parsedPassage.verses}`)
297
370
  } else {
298
371
  this.parseReferenceParts(parsedPassage, cleanReference)
372
+ console.log(
373
+ `Parsed with parseReferenceParts: chapter ${parsedPassage.chapter}, verses ${parsedPassage.verses}`
374
+ )
299
375
  }
300
376
 
301
377
  parsedPassage.passages = this.populate(parsedPassage)
@@ -315,6 +391,7 @@ class CodexParser {
315
391
  } else {
316
392
  parsedPassage.abbr = parsedPassage.original
317
393
  }
394
+ console.log(`Abbreviation set: ${parsedPassage.abbr}`)
318
395
 
319
396
  if (parsedPassage.type === this.MULTI_CHAPTER_RANGE) {
320
397
  this.handleMultiChapterRange(parsedPassage, cleanReference)
@@ -340,6 +417,7 @@ class CodexParser {
340
417
  chapter: lastPassage.chapter,
341
418
  verse: lastPassage.verse,
342
419
  }
420
+ console.log(`Start: ${JSON.stringify(parsedPassage.start)}, End: ${JSON.stringify(parsedPassage.end)}`)
343
421
  }
344
422
 
345
423
  if (!parsedPassage.version) {
@@ -354,9 +432,9 @@ class CodexParser {
354
432
  })
355
433
 
356
434
  this.versification()
435
+ console.log(`Final passages: ${JSON.stringify(this.passages, null, 2)}`)
357
436
  return this
358
437
  }
359
-
360
438
  /**
361
439
  * Parses reference parts into chapter and verse components.
362
440
  * @param {Object} passage - The passage object to populate.