codexparser 0.4.1 → 0.5.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to this project are documented here. For full details, see the Release Notes in README and the GitHub Releases page.
4
4
 
5
+ ## 0.5.2 — 2026-05-25
6
+
7
+ ### Fixed
8
+
9
+ - **Minor Prophets LXX versification used Rahlfs instead of Göttingen.** Extending the 0.5.1 Zechariah fix to the other Göttingen-edition Minor Prophets the app reads. For each, `lxx` now carries the Göttingen number (verified against Göttingen *Duodecim Prophetae* XIII), not the Rahlfs/MT number:
10
+ - **Hosea** — `lxx=eng` for ch1–2 and ch11–12; ch13/14 follows MT (ESV 13:16 = Göttingen 14:1), and the previously missing ESV 14:1–9 → 14:2–10 entries were added.
11
+ - **Joel** — `lxx=eng` (Göttingen keeps ESV 2:28–32 in ch2 and ESV ch3 as ch3; MT uses 3:1–5 / ch4).
12
+ - **Micah** — `lxx=eng`; Göttingen 5:1 = ESV 5:1 (the file previously mapped it to 4:14).
13
+ - **Malachi** — `lxx=eng` with sequential `mt` 3:19–24; dropped the Rahlfs verse reorder (Göttingen ch4 is sequential).
14
+
15
+ ### Added
16
+
17
+ - **Zephaniah** and **Haggai** versification files (new). Göttingen moves ESV/MT 2:15→3:1 (Zephaniah) and 1:15→2:1 (Haggai), each merging into the following verse.
18
+
19
+ ## 0.5.1 — 2026-05-25
20
+
21
+ ### Fixed
22
+
23
+ - **Zechariah LXX versification used Rahlfs instead of Göttingen.** The app reads Zechariah from the Göttingen edition (Duodecim Prophetae XIII), where Zechariah is numbered the same as English — the lead verse number is Göttingen and the parenthetical is Rahlfs (e.g. `(14)10 τέρπου καὶ εὐφραίνου, θύγατερ Σιων` = Göttingen 2:10 / Rahlfs 2:14). The data wrongly set `lxx` equal to the MT/Rahlfs number, so `Zechariah 2:10 ENG` reported `lxx: "2:14"` and parsing the Göttingen reference `2:10` as LXX back-mapped to `eng: "2:6"`. `lxx` now equals the Göttingen (= English) number for all 1:18–2:13 entries; `mt` is unchanged.
24
+
5
25
  ## 0.4.1 — 2026-04-28
6
26
 
7
27
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexparser",
3
- "version": "0.4.1",
3
+ "version": "0.5.2",
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
  "files": [
@@ -82,7 +82,10 @@ class ScriptureScanner {
82
82
  let refStartIndex = bookStartIndex
83
83
  let originalRefStartIndex = bookStartIndex
84
84
 
85
- while (i < normalizedText.length && this.#isValidChapterVerseChar(normalizedText[i])) {
85
+ while (
86
+ i < normalizedText.length &&
87
+ this.#isValidChapterVerseChar(normalizedText[i], normalizedText[i - 1])
88
+ ) {
86
89
  if (this.#isNextBibleBook(i, lowerCaseText, lowercaseBibleFullNames, lowercaseBibleAbbreviations)) {
87
90
  break
88
91
  }
@@ -178,11 +181,15 @@ class ScriptureScanner {
178
181
  }
179
182
 
180
183
  /**
181
- * Checks if character is valid for chapter/verse references
184
+ * Checks if character is valid for chapter/verse references.
185
+ * Letter suffixes (a-e) only count when they directly follow a digit, so
186
+ * "6:1a" continues the token but "6:1 Amos" still breaks at "A".
182
187
  * @private
183
188
  */
184
- #isValidChapterVerseChar(char) {
185
- return /[\d:,\-;\s]/.test(char)
189
+ #isValidChapterVerseChar(char, prevChar) {
190
+ if (/[\d:,\-;\s]/.test(char)) return true
191
+ if (/[a-eA-E]/.test(char) && prevChar && /\d/.test(prevChar)) return true
192
+ return false
186
193
  }
187
194
 
188
195
  /**
@@ -92,10 +92,13 @@ class VersificationHandler {
92
92
  const hasVersification = this.#versificationDifferences[passage.book]
93
93
 
94
94
  passage.passages.forEach((subPassage) => {
95
+ const verseRef = subPassage.verseSuffix
96
+ ? `${subPassage.chapter}:${subPassage.verse}${subPassage.verseSuffix}`
97
+ : `${subPassage.chapter}:${subPassage.verse}`
98
+
95
99
  if (hasVersification) {
96
- const key = `${subPassage.chapter}:${subPassage.verse}`
97
- if (this.#versificationDifferences[passage.book][key]) {
98
- subPassage.versification = this.#versificationDifferences[passage.book][key]
100
+ if (this.#versificationDifferences[passage.book][verseRef]) {
101
+ subPassage.versification = this.#versificationDifferences[passage.book][verseRef]
99
102
  }
100
103
  }
101
104
 
@@ -105,11 +108,9 @@ class VersificationHandler {
105
108
  versionAbbreviation === "lxx" ? "lxx" : versionAbbreviation === "mt" ? "mt" : null
106
109
 
107
110
  if (versionType) {
108
- const versionReference = `${subPassage.chapter}:${subPassage.verse}`
109
111
  for (const versification in this.#versificationDifferences[passage.book]) {
110
112
  if (
111
- this.#versificationDifferences[passage.book][versification][versionType] ===
112
- versionReference
113
+ this.#versificationDifferences[passage.book][versification][versionType] === verseRef
113
114
  ) {
114
115
  subPassage.versification = this.#versificationDifferences[passage.book][versification]
115
116
  break
@@ -169,6 +169,54 @@ module.exports = {
169
169
  mt: "5:32",
170
170
  eng: "5:18",
171
171
  },
172
+ // Chapter 6: LXX 3 Reigns adds material between 6:1 and 6:14 (6:1a-d) and
173
+ // omits MT/Eng 6:11-14 (the divine promise speech) and 6:18 (cedar carving).
174
+ // Reference: Rahlfs, Septuaginta, ad loc.
175
+ "6:1a": {
176
+ lxx: "6:1a",
177
+ mt: "",
178
+ eng: "",
179
+ },
180
+ "6:1b": {
181
+ lxx: "6:1b",
182
+ mt: "",
183
+ eng: "",
184
+ },
185
+ "6:1c": {
186
+ lxx: "6:1c",
187
+ mt: "",
188
+ eng: "",
189
+ },
190
+ "6:1d": {
191
+ lxx: "6:1d",
192
+ mt: "",
193
+ eng: "",
194
+ },
195
+ "6:11": {
196
+ lxx: "",
197
+ mt: "6:11",
198
+ eng: "6:11",
199
+ },
200
+ "6:12": {
201
+ lxx: "",
202
+ mt: "6:12",
203
+ eng: "6:12",
204
+ },
205
+ "6:13": {
206
+ lxx: "",
207
+ mt: "6:13",
208
+ eng: "6:13",
209
+ },
210
+ "6:14": {
211
+ lxx: "",
212
+ mt: "6:14",
213
+ eng: "6:14",
214
+ },
215
+ "6:18": {
216
+ lxx: "",
217
+ mt: "6:18",
218
+ eng: "6:18",
219
+ },
172
220
  "7:13": {
173
221
  lxx: "7:1",
174
222
  mt: "7:13",
@@ -0,0 +1,13 @@
1
+ // Versification mappings for Haggai.
2
+ // The app reads Haggai from the Göttingen edition, which moves ESV/MT 1:15 into
3
+ // chapter 2 as its verse 1 (Göttingen ch1 has 14 verses, vs 15 in ESV/MT) and
4
+ // merges it with ESV 2:1 under Göttingen 2:1 (the lone "(1)" in the text is a
5
+ // Rahlfs cross-reference). Everything from 2:2 on is identity, so only the
6
+ // shifted verse needs an entry.
7
+ module.exports = {
8
+ "1:15": {
9
+ lxx: "2:1",
10
+ mt: "1:15",
11
+ eng: "1:15",
12
+ },
13
+ }
@@ -1,201 +1,207 @@
1
+ // Versification mappings for Hosea.
2
+ // The app reads Hosea from the Göttingen edition. Göttingen numbers ch1–2 and
3
+ // ch11–12 like English (Rahlfs/MT in parens), so `lxx` = `eng` there. At the
4
+ // ch13/14 boundary Göttingen follows MT (no parenthetical): ESV 13:16 =
5
+ // Göttingen/MT 14:1, and ESV 14:1–9 = Göttingen/MT 14:2–10 — so `lxx` = `mt`
6
+ // for those.
1
7
  module.exports = {
2
8
  "1:10": {
3
- lxx: "2:1",
9
+ lxx: "1:10",
4
10
  mt: "2:1",
5
11
  eng: "1:10",
6
12
  },
7
13
  "1:11": {
8
- lxx: "2:2",
14
+ lxx: "1:11",
9
15
  mt: "2:2",
10
16
  eng: "1:11",
11
17
  },
12
18
  "2:1": {
13
- lxx: "2:3",
19
+ lxx: "2:1",
14
20
  mt: "2:3",
15
21
  eng: "2:1",
16
22
  },
17
23
  "2:2": {
18
- lxx: "2:4",
24
+ lxx: "2:2",
19
25
  mt: "2:4",
20
26
  eng: "2:2",
21
27
  },
22
28
  "2:3": {
23
- lxx: "2:5",
29
+ lxx: "2:3",
24
30
  mt: "2:5",
25
31
  eng: "2:3",
26
32
  },
27
33
  "2:4": {
28
- lxx: "2:6",
34
+ lxx: "2:4",
29
35
  mt: "2:6",
30
36
  eng: "2:4",
31
37
  },
32
38
  "2:5": {
33
- lxx: "2:7",
39
+ lxx: "2:5",
34
40
  mt: "2:7",
35
41
  eng: "2:5",
36
42
  },
37
43
  "2:6": {
38
- lxx: "2:8",
44
+ lxx: "2:6",
39
45
  mt: "2:8",
40
46
  eng: "2:6",
41
47
  },
42
48
  "2:7": {
43
- lxx: "2:9",
49
+ lxx: "2:7",
44
50
  mt: "2:9",
45
51
  eng: "2:7",
46
52
  },
47
53
  "2:8": {
48
- lxx: "2:10",
54
+ lxx: "2:8",
49
55
  mt: "2:10",
50
56
  eng: "2:8",
51
57
  },
52
58
  "2:9": {
53
- lxx: "2:11",
59
+ lxx: "2:9",
54
60
  mt: "2:11",
55
61
  eng: "2:9",
56
62
  },
57
63
  "2:10": {
58
- lxx: "2:12",
64
+ lxx: "2:10",
59
65
  mt: "2:12",
60
66
  eng: "2:10",
61
67
  },
62
68
  "2:11": {
63
- lxx: "2:13",
69
+ lxx: "2:11",
64
70
  mt: "2:13",
65
71
  eng: "2:11",
66
72
  },
67
73
  "2:12": {
68
- lxx: "2:14",
74
+ lxx: "2:12",
69
75
  mt: "2:14",
70
76
  eng: "2:12",
71
77
  },
72
78
  "2:13": {
73
- lxx: "2:15",
79
+ lxx: "2:13",
74
80
  mt: "2:15",
75
81
  eng: "2:13",
76
82
  },
77
83
  "2:14": {
78
- lxx: "2:16",
84
+ lxx: "2:14",
79
85
  mt: "2:16",
80
86
  eng: "2:14",
81
87
  },
82
88
  "2:15": {
83
- lxx: "2:17",
89
+ lxx: "2:15",
84
90
  mt: "2:17",
85
91
  eng: "2:15",
86
92
  },
87
93
  "2:16": {
88
- lxx: "2:18",
94
+ lxx: "2:16",
89
95
  mt: "2:18",
90
96
  eng: "2:16",
91
97
  },
92
98
  "2:17": {
93
- lxx: "2:19",
99
+ lxx: "2:17",
94
100
  mt: "2:19",
95
101
  eng: "2:17",
96
102
  },
97
103
  "2:18": {
98
- lxx: "2:20",
104
+ lxx: "2:18",
99
105
  mt: "2:20",
100
106
  eng: "2:18",
101
107
  },
102
108
  "2:19": {
103
- lxx: "2:21",
109
+ lxx: "2:19",
104
110
  mt: "2:21",
105
111
  eng: "2:19",
106
112
  },
107
113
  "2:20": {
108
- lxx: "2:22",
114
+ lxx: "2:20",
109
115
  mt: "2:22",
110
116
  eng: "2:20",
111
117
  },
112
118
  "2:21": {
113
- lxx: "2:23",
119
+ lxx: "2:21",
114
120
  mt: "2:23",
115
121
  eng: "2:21",
116
122
  },
117
123
  "2:22": {
118
- lxx: "2:24",
124
+ lxx: "2:22",
119
125
  mt: "2:24",
120
126
  eng: "2:22",
121
127
  },
122
128
  "2:23": {
123
- lxx: "2:25",
129
+ lxx: "2:23",
124
130
  mt: "2:25",
125
131
  eng: "2:23",
126
132
  },
127
133
  "11:12": {
128
- lxx: "12:1",
134
+ lxx: "11:12",
129
135
  mt: "12:1",
130
136
  eng: "11:12",
131
137
  },
132
138
  "12:1": {
133
- lxx: "12:2",
139
+ lxx: "12:1",
134
140
  mt: "12:2",
135
141
  eng: "12:1",
136
142
  },
137
143
  "12:2": {
138
- lxx: "12:3",
144
+ lxx: "12:2",
139
145
  mt: "12:3",
140
146
  eng: "12:2",
141
147
  },
142
148
  "12:3": {
143
- lxx: "12:4",
149
+ lxx: "12:3",
144
150
  mt: "12:4",
145
151
  eng: "12:3",
146
152
  },
147
153
  "12:4": {
148
- lxx: "12:5",
154
+ lxx: "12:4",
149
155
  mt: "12:5",
150
156
  eng: "12:4",
151
157
  },
152
158
  "12:5": {
153
- lxx: "12:6",
159
+ lxx: "12:5",
154
160
  mt: "12:6",
155
161
  eng: "12:5",
156
162
  },
157
163
  "12:6": {
158
- lxx: "12:7",
164
+ lxx: "12:6",
159
165
  mt: "12:7",
160
166
  eng: "12:6",
161
167
  },
162
168
  "12:7": {
163
- lxx: "12:8",
169
+ lxx: "12:7",
164
170
  mt: "12:8",
165
171
  eng: "12:7",
166
172
  },
167
173
  "12:8": {
168
- lxx: "12:9",
174
+ lxx: "12:8",
169
175
  mt: "12:9",
170
176
  eng: "12:8",
171
177
  },
172
178
  "12:9": {
173
- lxx: "12:10",
179
+ lxx: "12:9",
174
180
  mt: "12:10",
175
181
  eng: "12:9",
176
182
  },
177
183
  "12:10": {
178
- lxx: "12:11",
184
+ lxx: "12:10",
179
185
  mt: "12:11",
180
186
  eng: "12:10",
181
187
  },
182
188
  "12:11": {
183
- lxx: "12:12",
189
+ lxx: "12:11",
184
190
  mt: "12:12",
185
191
  eng: "12:11",
186
192
  },
187
193
  "12:12": {
188
- lxx: "12:13",
194
+ lxx: "12:12",
189
195
  mt: "12:13",
190
196
  eng: "12:12",
191
197
  },
192
198
  "12:13": {
193
- lxx: "12:14",
199
+ lxx: "12:13",
194
200
  mt: "12:14",
195
201
  eng: "12:13",
196
202
  },
197
203
  "12:14": {
198
- lxx: "12:15",
204
+ lxx: "12:14",
199
205
  mt: "12:15",
200
206
  eng: "12:14",
201
207
  },
@@ -204,4 +210,49 @@ module.exports = {
204
210
  mt: "14:1",
205
211
  eng: "13:16",
206
212
  },
213
+ "14:1": {
214
+ lxx: "14:2",
215
+ mt: "14:2",
216
+ eng: "14:1",
217
+ },
218
+ "14:2": {
219
+ lxx: "14:3",
220
+ mt: "14:3",
221
+ eng: "14:2",
222
+ },
223
+ "14:3": {
224
+ lxx: "14:4",
225
+ mt: "14:4",
226
+ eng: "14:3",
227
+ },
228
+ "14:4": {
229
+ lxx: "14:5",
230
+ mt: "14:5",
231
+ eng: "14:4",
232
+ },
233
+ "14:5": {
234
+ lxx: "14:6",
235
+ mt: "14:6",
236
+ eng: "14:5",
237
+ },
238
+ "14:6": {
239
+ lxx: "14:7",
240
+ mt: "14:7",
241
+ eng: "14:6",
242
+ },
243
+ "14:7": {
244
+ lxx: "14:8",
245
+ mt: "14:8",
246
+ eng: "14:7",
247
+ },
248
+ "14:8": {
249
+ lxx: "14:9",
250
+ mt: "14:9",
251
+ eng: "14:8",
252
+ },
253
+ "14:9": {
254
+ lxx: "14:10",
255
+ mt: "14:10",
256
+ eng: "14:9",
257
+ },
207
258
  }
@@ -1,131 +1,136 @@
1
+ // Versification mappings for Joel.
2
+ // The app reads Joel from the Göttingen edition, which numbers it like English:
3
+ // Göttingen keeps ESV 2:28–32 in ch2 (Rahlfs (R1)G28 …) and ESV 3:1–21 in ch3.
4
+ // MT uses the Hebrew division: ESV 2:28–32 = MT 3:1–5, ESV 3:1–21 = MT 4:1–21.
5
+ // So `lxx` = `eng`; only `mt` differs.
1
6
  module.exports = {
2
7
  "2:28": {
3
- lxx: "3:1",
8
+ lxx: "2:28",
4
9
  mt: "3:1",
5
10
  eng: "2:28",
6
11
  },
7
12
  "2:29": {
8
- lxx: "3:2",
13
+ lxx: "2:29",
9
14
  mt: "3:2",
10
15
  eng: "2:29",
11
16
  },
12
17
  "2:30": {
13
- lxx: "3:3",
18
+ lxx: "2:30",
14
19
  mt: "3:3",
15
20
  eng: "2:30",
16
21
  },
17
22
  "2:31": {
18
- lxx: "3:4",
23
+ lxx: "2:31",
19
24
  mt: "3:4",
20
25
  eng: "2:31",
21
26
  },
22
27
  "2:32": {
23
- lxx: "3:5",
28
+ lxx: "2:32",
24
29
  mt: "3:5",
25
30
  eng: "2:32",
26
31
  },
27
32
  "3:1": {
28
- lxx: "4:1",
33
+ lxx: "3:1",
29
34
  mt: "4:1",
30
35
  eng: "3:1",
31
36
  },
32
37
  "3:2": {
33
- lxx: "4:2",
38
+ lxx: "3:2",
34
39
  mt: "4:2",
35
40
  eng: "3:2",
36
41
  },
37
42
  "3:3": {
38
- lxx: "4:3",
43
+ lxx: "3:3",
39
44
  mt: "4:3",
40
45
  eng: "3:3",
41
46
  },
42
47
  "3:4": {
43
- lxx: "4:4",
48
+ lxx: "3:4",
44
49
  mt: "4:4",
45
50
  eng: "3:4",
46
51
  },
47
52
  "3:5": {
48
- lxx: "4:5",
53
+ lxx: "3:5",
49
54
  mt: "4:5",
50
55
  eng: "3:5",
51
56
  },
52
57
  "3:6": {
53
- lxx: "4:6",
58
+ lxx: "3:6",
54
59
  mt: "4:6",
55
60
  eng: "3:6",
56
61
  },
57
62
  "3:7": {
58
- lxx: "4:7",
63
+ lxx: "3:7",
59
64
  mt: "4:7",
60
65
  eng: "3:7",
61
66
  },
62
67
  "3:8": {
63
- lxx: "4:8",
68
+ lxx: "3:8",
64
69
  mt: "4:8",
65
70
  eng: "3:8",
66
71
  },
67
72
  "3:9": {
68
- lxx: "4:9",
73
+ lxx: "3:9",
69
74
  mt: "4:9",
70
75
  eng: "3:9",
71
76
  },
72
77
  "3:10": {
73
- lxx: "4:10",
78
+ lxx: "3:10",
74
79
  mt: "4:10",
75
80
  eng: "3:10",
76
81
  },
77
82
  "3:11": {
78
- lxx: "4:11",
83
+ lxx: "3:11",
79
84
  mt: "4:11",
80
85
  eng: "3:11",
81
86
  },
82
87
  "3:12": {
83
- lxx: "4:12",
88
+ lxx: "3:12",
84
89
  mt: "4:12",
85
90
  eng: "3:12",
86
91
  },
87
92
  "3:13": {
88
- lxx: "4:13",
93
+ lxx: "3:13",
89
94
  mt: "4:13",
90
95
  eng: "3:13",
91
96
  },
92
97
  "3:14": {
93
- lxx: "4:14",
98
+ lxx: "3:14",
94
99
  mt: "4:14",
95
100
  eng: "3:14",
96
101
  },
97
102
  "3:15": {
98
- lxx: "4:15",
103
+ lxx: "3:15",
99
104
  mt: "4:15",
100
105
  eng: "3:15",
101
106
  },
102
107
  "3:16": {
103
- lxx: "4:16",
108
+ lxx: "3:16",
104
109
  mt: "4:16",
105
110
  eng: "3:16",
106
111
  },
107
112
  "3:17": {
108
- lxx: "4:17",
113
+ lxx: "3:17",
109
114
  mt: "4:17",
110
115
  eng: "3:17",
111
116
  },
112
117
  "3:18": {
113
- lxx: "4:18",
118
+ lxx: "3:18",
114
119
  mt: "4:18",
115
120
  eng: "3:18",
116
121
  },
117
122
  "3:19": {
118
- lxx: "4:19",
123
+ lxx: "3:19",
119
124
  mt: "4:19",
120
125
  eng: "3:19",
121
126
  },
122
127
  "3:20": {
123
- lxx: "4:20",
128
+ lxx: "3:20",
124
129
  mt: "4:20",
125
130
  eng: "3:20",
126
131
  },
127
132
  "3:21": {
128
- lxx: "4:21",
133
+ lxx: "3:21",
129
134
  mt: "4:21",
130
135
  eng: "3:21",
131
136
  },
@@ -1,35 +1,38 @@
1
- // Versification mappings for Malachi, aligning ESV (English), BHS (Masoretic Text), and Göttingen LXX (Septuagint).
2
- // ESV uses 4 chapters, with 4:1–6 corresponding to BHS 3:19–24 and LXX 3:19–24.
3
- // Note: LXX reorders verses 4–6: ESV 4:4 = LXX 3:24, ESV 4:5 = LXX 3:22, ESV 4:6 = LXX 3:23.
4
- // Chapters 1–3 have identical versification across all three (e.g., 1:1 = 1:1).
1
+ // Versification mappings for Malachi.
2
+ // The app reads Malachi from the Göttingen edition (Duodecim Prophetae XIII),
3
+ // which has a chapter 4 numbered like English: Göttingen 4:1–6 = ESV 4:1–6,
4
+ // sequential, with Rahlfs in parens ((R19)G1 (R24)G6). MT folds these into
5
+ // chapter 3 as 3:19–24. So `lxx` = `eng`; `mt` = 3:19–24 sequential.
6
+ // (Note: the Rahlfs edition reorders 3:22–24; the Göttingen edition does not,
7
+ // and the app uses Göttingen — so no reorder here.)
5
8
  module.exports = {
6
9
  "4:1": {
7
- lxx: "3:19",
10
+ lxx: "4:1",
8
11
  mt: "3:19",
9
12
  eng: "4:1",
10
13
  },
11
14
  "4:2": {
12
- lxx: "3:20",
15
+ lxx: "4:2",
13
16
  mt: "3:20",
14
17
  eng: "4:2",
15
18
  },
16
19
  "4:3": {
17
- lxx: "3:21",
20
+ lxx: "4:3",
18
21
  mt: "3:21",
19
22
  eng: "4:3",
20
23
  },
21
24
  "4:4": {
22
- lxx: "3:24", // Law of Moses (matches BHS 3:22 content)
25
+ lxx: "4:4",
23
26
  mt: "3:22",
24
27
  eng: "4:4",
25
28
  },
26
29
  "4:5": {
27
- lxx: "3:22", // Elijah’s coming (matches BHS 3:23 content)
30
+ lxx: "4:5",
28
31
  mt: "3:23",
29
32
  eng: "4:5",
30
33
  },
31
34
  "4:6": {
32
- lxx: "3:23", // Hearts restored (matches BHS 3:24 content)
35
+ lxx: "4:6",
33
36
  mt: "3:24",
34
37
  eng: "4:6",
35
38
  },
@@ -1,79 +1,81 @@
1
1
  // Versification mappings for Micah.
2
- // ENG Mic 5:1 ("Now muster yourselves in troops") = MT/LXX Mic 4:14.
3
- // ENG Mic 5:2-15 = MT/LXX Mic 5:1-14. LXX follows the MT chapter division.
2
+ // The app reads Micah from the Göttingen edition, which numbers it like English:
3
+ // Göttingen 5:1 ("νῦν ἐμφραχθήσεται") = ESV 5:1, and Göttingen 5:2–15 = ESV 5:2–15
4
+ // (Rahlfs in parens: (R1)G2 … (R14)G15). MT keeps the Hebrew division where
5
+ // ESV 5:1 = MT 4:14 and ESV 5:2–15 = MT 5:1–14. So `lxx` = `eng`; `mt` differs.
4
6
  module.exports = {
5
7
  "5:1": {
6
- lxx: "4:14",
8
+ lxx: "5:1",
7
9
  mt: "4:14",
8
10
  eng: "5:1",
9
11
  },
10
12
  "5:2": {
11
- lxx: "5:1",
13
+ lxx: "5:2",
12
14
  mt: "5:1",
13
15
  eng: "5:2",
14
16
  },
15
17
  "5:3": {
16
- lxx: "5:2",
18
+ lxx: "5:3",
17
19
  mt: "5:2",
18
20
  eng: "5:3",
19
21
  },
20
22
  "5:4": {
21
- lxx: "5:3",
23
+ lxx: "5:4",
22
24
  mt: "5:3",
23
25
  eng: "5:4",
24
26
  },
25
27
  "5:5": {
26
- lxx: "5:4",
28
+ lxx: "5:5",
27
29
  mt: "5:4",
28
30
  eng: "5:5",
29
31
  },
30
32
  "5:6": {
31
- lxx: "5:5",
33
+ lxx: "5:6",
32
34
  mt: "5:5",
33
35
  eng: "5:6",
34
36
  },
35
37
  "5:7": {
36
- lxx: "5:6",
38
+ lxx: "5:7",
37
39
  mt: "5:6",
38
40
  eng: "5:7",
39
41
  },
40
42
  "5:8": {
41
- lxx: "5:7",
43
+ lxx: "5:8",
42
44
  mt: "5:7",
43
45
  eng: "5:8",
44
46
  },
45
47
  "5:9": {
46
- lxx: "5:8",
48
+ lxx: "5:9",
47
49
  mt: "5:8",
48
50
  eng: "5:9",
49
51
  },
50
52
  "5:10": {
51
- lxx: "5:9",
53
+ lxx: "5:10",
52
54
  mt: "5:9",
53
55
  eng: "5:10",
54
56
  },
55
57
  "5:11": {
56
- lxx: "5:10",
58
+ lxx: "5:11",
57
59
  mt: "5:10",
58
60
  eng: "5:11",
59
61
  },
60
62
  "5:12": {
61
- lxx: "5:11",
63
+ lxx: "5:12",
62
64
  mt: "5:11",
63
65
  eng: "5:12",
64
66
  },
65
67
  "5:13": {
66
- lxx: "5:12",
68
+ lxx: "5:13",
67
69
  mt: "5:12",
68
70
  eng: "5:13",
69
71
  },
70
72
  "5:14": {
71
- lxx: "5:13",
73
+ lxx: "5:14",
72
74
  mt: "5:13",
73
75
  eng: "5:14",
74
76
  },
75
77
  "5:15": {
76
- lxx: "5:14",
78
+ lxx: "5:15",
77
79
  mt: "5:14",
78
80
  eng: "5:15",
79
81
  },
@@ -1,86 +1,94 @@
1
+ // Zechariah versification.
2
+ // LXX-G (Göttingen / Ziegler, Duodecim Prophetae XIII) numbers Zechariah the
3
+ // same as English; only MT (Hebrew) differs across the 1:18–2:13 boundary.
4
+ // In the Göttingen text the lead verse number is Göttingen and the
5
+ // parenthetical is Rahlfs (e.g. "(14)10 τέρπου καὶ εὐφραίνου, θύγατερ Σιων" =
6
+ // Göttingen 2:10 / Rahlfs 2:14). The app uses the Göttingen edition for
7
+ // Zechariah, so `lxx` here is the Göttingen number and equals `eng`; `mt`
8
+ // carries the Hebrew (and Rahlfs) numbering.
1
9
  module.exports = {
2
10
  "1:18": {
3
- lxx: "2:1",
11
+ lxx: "1:18",
4
12
  mt: "2:1",
5
13
  eng: "1:18",
6
14
  },
7
15
  "1:19": {
8
- lxx: "2:2",
16
+ lxx: "1:19",
9
17
  mt: "2:2",
10
18
  eng: "1:19",
11
19
  },
12
20
  "1:20": {
13
- lxx: "2:3",
21
+ lxx: "1:20",
14
22
  mt: "2:3",
15
23
  eng: "1:20",
16
24
  },
17
25
  "1:21": {
18
- lxx: "2:4",
26
+ lxx: "1:21",
19
27
  mt: "2:4",
20
28
  eng: "1:21",
21
29
  },
22
30
  "2:1": {
23
- lxx: "2:5",
31
+ lxx: "2:1",
24
32
  mt: "2:5",
25
33
  eng: "2:1",
26
34
  },
27
35
  "2:2": {
28
- lxx: "2:6",
36
+ lxx: "2:2",
29
37
  mt: "2:6",
30
38
  eng: "2:2",
31
39
  },
32
40
  "2:3": {
33
- lxx: "2:7",
41
+ lxx: "2:3",
34
42
  mt: "2:7",
35
43
  eng: "2:3",
36
44
  },
37
45
  "2:4": {
38
- lxx: "2:8",
46
+ lxx: "2:4",
39
47
  mt: "2:8",
40
48
  eng: "2:4",
41
49
  },
42
50
  "2:5": {
43
- lxx: "2:9",
51
+ lxx: "2:5",
44
52
  mt: "2:9",
45
53
  eng: "2:5",
46
54
  },
47
55
  "2:6": {
48
- lxx: "2:10",
56
+ lxx: "2:6",
49
57
  mt: "2:10",
50
58
  eng: "2:6",
51
59
  },
52
60
  "2:7": {
53
- lxx: "2:11",
61
+ lxx: "2:7",
54
62
  mt: "2:11",
55
63
  eng: "2:7",
56
64
  },
57
65
  "2:8": {
58
- lxx: "2:12",
66
+ lxx: "2:8",
59
67
  mt: "2:12",
60
68
  eng: "2:8",
61
69
  },
62
70
  "2:9": {
63
- lxx: "2:13",
71
+ lxx: "2:9",
64
72
  mt: "2:13",
65
73
  eng: "2:9",
66
74
  },
67
75
  "2:10": {
68
- lxx: "2:14",
76
+ lxx: "2:10",
69
77
  mt: "2:14",
70
78
  eng: "2:10",
71
79
  },
72
80
  "2:11": {
73
- lxx: "2:15",
81
+ lxx: "2:11",
74
82
  mt: "2:15",
75
83
  eng: "2:11",
76
84
  },
77
85
  "2:12": {
78
- lxx: "2:16",
86
+ lxx: "2:12",
79
87
  mt: "2:16",
80
88
  eng: "2:12",
81
89
  },
82
90
  "2:13": {
83
- lxx: "2:17",
91
+ lxx: "2:13",
84
92
  mt: "2:17",
85
93
  eng: "2:13",
86
94
  },
@@ -0,0 +1,19 @@
1
+ // Versification mappings for Zephaniah.
2
+ // The app reads Zephaniah from the Göttingen edition, which moves ESV/MT 2:15
3
+ // into chapter 3 as its verse 1 (Göttingen ch2 has 14 verses, vs 15 in
4
+ // ESV/MT). So Göttingen 3:1 = ESV 2:15 and Göttingen 3:2 = ESV 3:1; Göttingen
5
+ // then merges ESV 3:1+3:2 under 3:2 (the lone "(2)" in the text is a Rahlfs
6
+ // cross-reference), realigning from 3:3 on. Only the two shifted verses need an
7
+ // entry; everything else is identity.
8
+ module.exports = {
9
+ "2:15": {
10
+ lxx: "3:1",
11
+ mt: "2:15",
12
+ eng: "2:15",
13
+ },
14
+ "3:1": {
15
+ lxx: "3:2",
16
+ mt: "3:1",
17
+ eng: "3:1",
18
+ },
19
+ }
@@ -30,6 +30,8 @@ const versified = {
30
30
  Jonah: require("./versifications/jonah"),
31
31
  Micah: require("./versifications/micah"),
32
32
  Nahum: require("./versifications/nahum"),
33
+ Zephaniah: require("./versifications/zephaniah"),
34
+ Haggai: require("./versifications/haggai"),
33
35
  Zechariah: require("./versifications/zechariah"),
34
36
  Malachi: require("./versifications/malachi"),
35
37
  }
@@ -46,6 +46,16 @@ class PassageUtils {
46
46
  for (let i = start; i <= end && i <= chapterVerses[chapterVerses.length - 1]; i++) {
47
47
  passages.push({ book, chapter, verse: i })
48
48
  }
49
+ } else if (typeof verse === "string") {
50
+ const match = verse.trim().match(/^(\d+)([a-eA-E])?$/)
51
+ if (match) {
52
+ const verseNum = Number(match[1])
53
+ if (verseNum > 0) {
54
+ const entry = { book, chapter, verse: verseNum }
55
+ if (match[2]) entry.verseSuffix = match[2].toLowerCase()
56
+ passages.push(entry)
57
+ }
58
+ }
49
59
  } else {
50
60
  const verseNum = Number(verse)
51
61
  if (!isNaN(verseNum) && verseNum > 0) {