codexparser 0.1.91 → 0.1.92

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 +137 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.1.91",
3
+ "version": "0.1.92",
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": {
@@ -1286,6 +1286,143 @@ class CodexParser {
1286
1286
  combined.abbr = `${combined.book} ${combined.scripture.cv}`
1287
1287
  }
1288
1288
 
1289
+ const self = this
1290
+ combined.getVersion = function (targetVersion) {
1291
+ const cloned = JSON.parse(JSON.stringify(this))
1292
+ const targetAbbr = targetVersion.toLowerCase() === "bhs" ? "mt" : targetVersion.toLowerCase()
1293
+ let versionObj
1294
+ if (targetAbbr === "eng") {
1295
+ versionObj = { name: "English", value: "ENG", abbreviation: "eng" }
1296
+ } else if (targetAbbr === "mt") {
1297
+ versionObj = { name: "Masoretic Text", value: "MT", abbreviation: "mt" }
1298
+ } else if (targetAbbr === "lxx") {
1299
+ versionObj = { name: "Septuagint", value: "LXX", abbreviation: "lxx" }
1300
+ } else {
1301
+ throw new Error("Invalid version: must be one of 'eng', 'mt', 'bhs', 'lxx'")
1302
+ }
1303
+
1304
+ cloned.version = versionObj
1305
+
1306
+ cloned.passages.forEach((sub) => {
1307
+ if (sub.versification && sub.versification[targetAbbr]) {
1308
+ const [ch, v] = sub.versification[targetAbbr].split(":").map(Number)
1309
+ sub.chapter = ch
1310
+ sub.verse = v
1311
+ }
1312
+ // else remain unchanged
1313
+ })
1314
+
1315
+ // Recompute summary fields
1316
+ cloned.passages.sort((a, b) => a.chapter - b.chapter || a.verse - b.verse)
1317
+
1318
+ if (cloned.passages.length > 0) {
1319
+ cloned.start = {
1320
+ book: cloned.book,
1321
+ chapter: cloned.passages[0].chapter,
1322
+ verse: cloned.passages[0].verse,
1323
+ }
1324
+ cloned.end = {
1325
+ book: cloned.book,
1326
+ chapter: cloned.passages[cloned.passages.length - 1].chapter,
1327
+ verse: cloned.passages[cloned.passages.length - 1].verse,
1328
+ }
1329
+ }
1330
+
1331
+ const chapterVersesMap = {}
1332
+ cloned.passages.forEach((p) => {
1333
+ if (!chapterVersesMap[p.chapter]) chapterVersesMap[p.chapter] = new Set()
1334
+ chapterVersesMap[p.chapter].add(p.verse)
1335
+ })
1336
+
1337
+ const sortedChs = Object.keys(chapterVersesMap)
1338
+ .map(Number)
1339
+ .sort((a, b) => a - b)
1340
+ const chapterStrs = []
1341
+
1342
+ const mergeFunc = (verses) => {
1343
+ const sorted = [...verses].sort((a, b) => a - b)
1344
+ const merged = []
1345
+ if (sorted.length === 0) return merged
1346
+ let start = sorted[0]
1347
+ let end = sorted[0]
1348
+ for (let i = 1; i < sorted.length; i++) {
1349
+ if (sorted[i] === end + 1) {
1350
+ end = sorted[i]
1351
+ } else {
1352
+ merged.push(start === end ? `${start}` : `${start}-${end}`)
1353
+ start = end = sorted[i]
1354
+ }
1355
+ }
1356
+ merged.push(start === end ? `${start}` : `${start}-${end}`)
1357
+ return merged
1358
+ }
1359
+
1360
+ sortedChs.forEach((ch) => {
1361
+ const vs = Array.from(chapterVersesMap[ch])
1362
+ .filter((v) => v > 0)
1363
+ .sort((a, b) => a - b)
1364
+ if (vs.length > 0) {
1365
+ const merged = mergeFunc(vs)
1366
+ chapterStrs.push(`${ch}:${merged.join(",")}`)
1367
+ }
1368
+ })
1369
+
1370
+ if (chapterStrs.length === 0) {
1371
+ return cloned // no verses, perhaps error but return as is
1372
+ }
1373
+
1374
+ const firstCh = sortedChs[0]
1375
+ const lastCh = sortedChs[sortedChs.length - 1]
1376
+ cloned.chapter = firstCh
1377
+
1378
+ const mergedFirst = mergeFunc(chapterVersesMap[firstCh] || new Set())
1379
+ cloned.verses = mergedFirst
1380
+
1381
+ if (firstCh !== lastCh) {
1382
+ cloned.type = "multi_chapter_verse_range"
1383
+ cloned.to = {
1384
+ book: cloned.book,
1385
+ chapter: lastCh,
1386
+ verses: mergeFunc(chapterVersesMap[lastCh] || new Set()),
1387
+ }
1388
+ cloned.original = `${cloned.book} ${chapterStrs.join("; ")}`
1389
+ } else {
1390
+ const hasRangeOrMultiple =
1391
+ mergedFirst.length > 1 || (mergedFirst.length === 1 && mergedFirst[0].includes("-"))
1392
+ cloned.type = hasRangeOrMultiple ? "chapter_verse_range" : "chapter_verse"
1393
+ if (cloned.to) delete cloned.to
1394
+ cloned.original = `${cloned.book} ${chapterStrs[0]}`
1395
+ }
1396
+
1397
+ const chString = chapterStrs.join("; ")
1398
+ cloned.scripture = {
1399
+ passage: `${cloned.book} ${chString}`,
1400
+ cv: chString,
1401
+ hash: `${cloned.book.toLowerCase()}_${chString
1402
+ .replace(/:/g, ".")
1403
+ .replace(/-/g, ".")
1404
+ .replace(/[,; ]/g, ".")}`,
1405
+ }
1406
+
1407
+ // Set abbr
1408
+ const sblEntry = Object.entries(self.sblAbbreviations).find(
1409
+ ([key]) => key.toLowerCase() === cloned.book.toLowerCase()
1410
+ )
1411
+ const suffix = versionObj.abbreviation === "eng" ? "" : ` ${versionObj.value}`
1412
+ if (sblEntry) {
1413
+ const { value, abbr } = sblEntry[1]
1414
+ cloned.abbr = abbr
1415
+ ? `${value}. ${cloned.scripture.cv}${suffix}`
1416
+ : `${value} ${cloned.scripture.cv}${suffix}`
1417
+ } else {
1418
+ cloned.abbr = `${cloned.book} ${cloned.scripture.cv}${suffix}`
1419
+ }
1420
+
1421
+ cloned.getVersion = this.getVersion
1422
+
1423
+ return cloned
1424
+ }
1425
+
1289
1426
  return combined
1290
1427
  }
1291
1428