pericope 0.6.1 → 0.6.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.
- checksums.yaml +7 -0
- data/README.mdown +12 -9
- data/data/book_abbreviations.txt +66 -66
- data/data/chapter_verse_count.txt +1189 -1189
- data/lib/cli/base.rb +18 -18
- data/lib/cli/command.rb +13 -13
- data/lib/pericope.rb +174 -226
- data/lib/pericope/cli.rb +41 -41
- data/lib/pericope/version.rb +1 -1
- metadata +30 -24
data/lib/cli/base.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
module CLI
|
2
2
|
class Base
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
|
5
|
+
|
6
6
|
def self.command(name, description, &block)
|
7
|
-
|
7
|
+
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
|
11
|
+
|
12
12
|
def self.print_commands
|
13
13
|
usage = ""
|
14
|
-
|
14
|
+
|
15
15
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
|
17
|
+
|
18
|
+
|
19
19
|
private
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
|
21
|
+
|
22
|
+
|
23
23
|
def commands
|
24
24
|
@commands || {}
|
25
25
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
|
27
|
+
|
28
|
+
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
data/lib/cli/command.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
module CLI
|
2
2
|
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
|
5
|
+
|
6
6
|
def initialize(name, description, &block)
|
7
7
|
@name, @description, @block = name, description, &block
|
8
8
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
|
11
|
+
|
12
12
|
attr_reader :name, :description
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
|
14
|
+
|
15
|
+
|
16
16
|
def execute
|
17
17
|
@block.call
|
18
18
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
|
20
|
+
|
21
|
+
|
22
22
|
end
|
23
|
-
end
|
23
|
+
end
|
data/lib/pericope.rb
CHANGED
@@ -8,53 +8,57 @@ class Pericope
|
|
8
8
|
:book_name,
|
9
9
|
:original_string,
|
10
10
|
:ranges
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
|
13
|
+
|
13
14
|
def self.book_names
|
14
|
-
@book_names
|
15
|
+
load_book_abbreviations! unless defined?(@book_names)
|
16
|
+
@book_names
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
def self.book_name_regexes
|
18
|
-
@book_name_regexes
|
20
|
+
load_book_abbreviations! unless defined?(@book_name_regexes)
|
21
|
+
@book_name_regexes
|
19
22
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
|
24
|
+
|
25
|
+
|
23
26
|
def initialize(arg)
|
24
27
|
case arg
|
25
28
|
when String
|
26
29
|
attributes = Pericope.match_one(arg)
|
27
30
|
raise "no pericope found in #{arg} (#{arg.class})" if attributes.nil?
|
28
|
-
|
31
|
+
|
29
32
|
@original_string = attributes[:original_string]
|
30
33
|
set_book attributes[:book]
|
31
34
|
@ranges = attributes[:ranges]
|
32
|
-
|
35
|
+
|
33
36
|
when Array
|
37
|
+
arg = arg.map(&:to_i)
|
34
38
|
set_book Pericope.get_book(arg.first)
|
35
39
|
@ranges = Pericope.group_array_into_ranges(arg)
|
36
|
-
|
40
|
+
|
37
41
|
else
|
38
42
|
attributes = arg
|
39
43
|
@original_string = attributes[:original_string]
|
40
44
|
set_book attributes[:book]
|
41
45
|
@ranges = attributes[:ranges]
|
42
|
-
|
46
|
+
|
43
47
|
end
|
44
48
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
|
50
|
+
|
51
|
+
|
48
52
|
def self.book_has_chapters?(book)
|
49
53
|
book_chapter_counts[book - 1] > 1
|
50
54
|
end
|
51
|
-
|
55
|
+
|
52
56
|
def book_has_chapters?
|
53
57
|
book_chapter_count > 1
|
54
58
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
|
60
|
+
|
61
|
+
|
58
62
|
# Differs from Pericope.new in that it won't raise an exception
|
59
63
|
# if text does not contain a pericope but will return nil instead.
|
60
64
|
def self.parse_one(text)
|
@@ -63,9 +67,9 @@ class Pericope
|
|
63
67
|
end
|
64
68
|
nil
|
65
69
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
|
71
|
+
|
72
|
+
|
69
73
|
def self.parse(text)
|
70
74
|
pericopes = []
|
71
75
|
match_all(text) do |attributes|
|
@@ -78,39 +82,39 @@ class Pericope
|
|
78
82
|
end
|
79
83
|
block_given? ? text : pericopes
|
80
84
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
85
|
+
|
86
|
+
|
87
|
+
|
84
88
|
def self.split(text, pattern=nil)
|
85
89
|
puts "DEPRECATION NOTICE: split will no longer accept a 'pattern' argument in Pericope 0.7.0" if pattern
|
86
90
|
segments = []
|
87
91
|
start = 0
|
88
|
-
|
92
|
+
|
89
93
|
match_all(text) do |attributes, match|
|
90
|
-
|
94
|
+
|
91
95
|
pretext = text.slice(start...match.begin(0))
|
92
96
|
if pretext.length > 0
|
93
97
|
segments << pretext
|
94
98
|
yield pretext if block_given?
|
95
99
|
end
|
96
|
-
|
100
|
+
|
97
101
|
pericope = Pericope.new(attributes)
|
98
102
|
segments << pericope
|
99
103
|
yield pericope if block_given?
|
100
|
-
|
104
|
+
|
101
105
|
start = match.end(0)
|
102
106
|
end
|
103
|
-
|
107
|
+
|
104
108
|
pretext = text.slice(start...text.length)
|
105
109
|
if pretext.length > 0
|
106
110
|
segments << pretext
|
107
111
|
yield pretext if block_given?
|
108
112
|
end
|
109
|
-
|
113
|
+
|
110
114
|
segments = ___split_segments_by_pattern(segments, pattern) if pattern
|
111
115
|
segments
|
112
116
|
end
|
113
|
-
|
117
|
+
|
114
118
|
def self.___split_segments_by_pattern(segments, pattern)
|
115
119
|
segments2 = []
|
116
120
|
segments.each do |segment|
|
@@ -122,9 +126,9 @@ class Pericope
|
|
122
126
|
end
|
123
127
|
segments2
|
124
128
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
129
|
+
|
130
|
+
|
131
|
+
|
128
132
|
def self.extract(text)
|
129
133
|
puts "DEPRECATION NOTICE: the 'extract' method will be removed in Pericope 0.7.0"
|
130
134
|
segments = split(text)
|
@@ -139,9 +143,9 @@ class Pericope
|
|
139
143
|
end
|
140
144
|
{:text => text, :pericopes => pericopes}
|
141
145
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
146
|
+
|
147
|
+
|
148
|
+
|
145
149
|
def self.sub(text)
|
146
150
|
segments = split(text)
|
147
151
|
segments.inject("") do |text, segment|
|
@@ -152,31 +156,31 @@ class Pericope
|
|
152
156
|
end
|
153
157
|
end
|
154
158
|
end
|
155
|
-
|
156
|
-
|
157
|
-
|
159
|
+
|
160
|
+
|
161
|
+
|
158
162
|
def self.rsub(text)
|
159
163
|
text.gsub(/\{\{(\d{7,8} ?)+\}\}/) do |match|
|
160
164
|
ids = match[2...-2].split.collect(&:to_i)
|
161
165
|
Pericope.new(ids).to_s
|
162
166
|
end
|
163
167
|
end
|
164
|
-
|
165
|
-
|
166
|
-
|
168
|
+
|
169
|
+
|
170
|
+
|
167
171
|
def to_s
|
168
172
|
"#{book_name} #{self.well_formatted_reference}"
|
169
173
|
end
|
170
|
-
|
171
|
-
|
172
|
-
|
174
|
+
|
175
|
+
|
176
|
+
|
173
177
|
def report
|
174
178
|
puts "DEPRECATION NOTICE: the 'report' method will be removed in Pericope 0.7.0"
|
175
179
|
" #{self.original_string} => #{self}"
|
176
180
|
end
|
177
|
-
|
178
|
-
|
179
|
-
|
181
|
+
|
182
|
+
|
183
|
+
|
180
184
|
def to_a
|
181
185
|
# one range per chapter
|
182
186
|
chapter_ranges = []
|
@@ -195,12 +199,12 @@ class Pericope
|
|
195
199
|
chapter_ranges << Range.new(Pericope.get_first_verse(book, max_chapter), range.end)
|
196
200
|
end
|
197
201
|
end
|
198
|
-
|
202
|
+
|
199
203
|
chapter_ranges.inject([]) {|array, range| array.concat(range.to_a)}
|
200
204
|
end
|
201
|
-
|
202
|
-
|
203
|
-
|
205
|
+
|
206
|
+
|
207
|
+
|
204
208
|
def well_formatted_reference
|
205
209
|
recent_chapter = nil # e.g. in 12:1-8, remember that 12 is the chapter when we parse the 8
|
206
210
|
recent_chapter = 1 unless book_has_chapters?
|
@@ -210,7 +214,7 @@ class Pericope
|
|
210
214
|
max_chapter = Pericope.get_chapter(range.end)
|
211
215
|
max_verse = Pericope.get_verse(range.end)
|
212
216
|
s = ""
|
213
|
-
|
217
|
+
|
214
218
|
if min_verse == 1 and max_verse >= Pericope.get_max_verse(book, max_chapter)
|
215
219
|
s << min_chapter.to_s
|
216
220
|
s << "-#{max_chapter}" if max_chapter > min_chapter
|
@@ -221,9 +225,9 @@ class Pericope
|
|
221
225
|
recent_chapter = min_chapter
|
222
226
|
s << "#{min_chapter}:#{min_verse}"
|
223
227
|
end
|
224
|
-
|
228
|
+
|
225
229
|
if range.count > 1
|
226
|
-
|
230
|
+
|
227
231
|
s << "-"
|
228
232
|
if min_chapter == max_chapter
|
229
233
|
s << max_verse.to_s
|
@@ -233,124 +237,124 @@ class Pericope
|
|
233
237
|
end
|
234
238
|
end
|
235
239
|
end
|
236
|
-
|
240
|
+
|
237
241
|
s
|
238
242
|
end.join(", ")
|
239
243
|
end
|
240
|
-
|
241
|
-
|
242
|
-
|
244
|
+
|
245
|
+
|
246
|
+
|
243
247
|
def intersects?(pericope)
|
244
248
|
return false unless pericope.is_a?(Pericope)
|
245
249
|
return false unless (self.book == pericope.book)
|
246
|
-
|
250
|
+
|
247
251
|
self.ranges.each do |self_range|
|
248
252
|
pericope.ranges.each do |other_range|
|
249
253
|
return true if (self_range.end >= other_range.begin) and (self_range.begin <= other_range.end)
|
250
254
|
end
|
251
255
|
end
|
252
|
-
|
256
|
+
|
253
257
|
false
|
254
258
|
end
|
255
|
-
|
256
|
-
|
257
|
-
|
259
|
+
|
260
|
+
|
261
|
+
|
258
262
|
def self.get_max_verse(book, chapter)
|
259
263
|
id = (book * 1000000) + (chapter * 1000)
|
260
264
|
chapter_verse_counts[id]
|
261
265
|
end
|
262
|
-
|
266
|
+
|
263
267
|
def self.get_max_chapter(book)
|
264
268
|
book_chapter_counts[book - 1]
|
265
269
|
end
|
266
|
-
|
267
|
-
|
268
|
-
|
270
|
+
|
271
|
+
|
272
|
+
|
269
273
|
private
|
270
|
-
|
271
|
-
|
272
|
-
|
274
|
+
|
275
|
+
|
276
|
+
|
273
277
|
def set_book(value)
|
274
278
|
@book = value || raise(ArgumentError, "must specify book")
|
275
279
|
@book_name = Pericope.book_names[@book - 1]
|
276
280
|
@book_chapter_count = Pericope.book_chapter_counts[@book - 1]
|
277
281
|
end
|
278
|
-
|
279
|
-
|
280
|
-
|
282
|
+
|
283
|
+
|
284
|
+
|
281
285
|
def self.get_first_verse(book, chapter)
|
282
286
|
get_id(book, chapter, 1)
|
283
287
|
end
|
284
|
-
|
288
|
+
|
285
289
|
def self.get_last_verse(book, chapter)
|
286
290
|
get_id(book, chapter, get_max_verse(book, chapter))
|
287
291
|
end
|
288
|
-
|
292
|
+
|
289
293
|
def self.get_next_verse(id)
|
290
294
|
id + 1
|
291
295
|
end
|
292
|
-
|
296
|
+
|
293
297
|
def self.get_start_of_next_chapter(id)
|
294
298
|
book = get_book(id)
|
295
299
|
chapter = get_chapter(id) + 1
|
296
300
|
verse = 1
|
297
301
|
get_id(book, chapter, verse)
|
298
302
|
end
|
299
|
-
|
303
|
+
|
300
304
|
def self.to_valid_book(book)
|
301
305
|
coerce_to_range(book, 1..66)
|
302
306
|
end
|
303
|
-
|
307
|
+
|
304
308
|
def self.to_valid_chapter(book, chapter)
|
305
309
|
coerce_to_range(chapter, 1..get_max_chapter(book))
|
306
310
|
end
|
307
|
-
|
311
|
+
|
308
312
|
def self.to_valid_verse(book, chapter, verse)
|
309
313
|
coerce_to_range(verse, 1..get_max_verse(book, chapter))
|
310
314
|
end
|
311
|
-
|
315
|
+
|
312
316
|
def self.coerce_to_range(number, range)
|
313
317
|
return range.begin if number < range.begin
|
314
318
|
return range.end if number > range.end
|
315
319
|
number
|
316
320
|
end
|
317
|
-
|
321
|
+
|
318
322
|
def self.get_id(book, chapter, verse)
|
319
323
|
book = to_valid_book(book)
|
320
324
|
chapter = to_valid_chapter(book, chapter)
|
321
325
|
verse = to_valid_verse(book, chapter, verse)
|
322
|
-
|
326
|
+
|
323
327
|
(book * 1000000) + (chapter * 1000) + verse
|
324
328
|
end
|
325
|
-
|
329
|
+
|
326
330
|
def self.get_book(id)
|
327
331
|
id / 1000000 # the book is everything left of the least significant 6 digits
|
328
332
|
end
|
329
|
-
|
333
|
+
|
330
334
|
def self.get_chapter(id)
|
331
335
|
(id % 1000000) / 1000 # the chapter is the 3rd through 6th most significant digits
|
332
336
|
end
|
333
|
-
|
337
|
+
|
334
338
|
def self.get_verse(id)
|
335
339
|
id % 1000 # the verse is the 3 least significant digits
|
336
340
|
end
|
337
|
-
|
338
|
-
|
339
|
-
|
341
|
+
|
342
|
+
|
343
|
+
|
340
344
|
def self.group_array_into_ranges(array)
|
341
345
|
return [] if array.nil? or array.empty?
|
342
|
-
|
346
|
+
|
343
347
|
array.flatten!
|
344
348
|
array.compact!
|
345
349
|
array.sort!
|
346
|
-
|
350
|
+
|
347
351
|
ranges = []
|
348
352
|
range_start = array.shift
|
349
353
|
range_end = range_start
|
350
354
|
while true
|
351
355
|
next_value = array.shift
|
352
356
|
break if next_value.nil?
|
353
|
-
|
357
|
+
|
354
358
|
if (next_value == get_next_verse(range_end)) ||
|
355
359
|
(next_value == get_start_of_next_chapter(range_end))
|
356
360
|
range_end = next_value
|
@@ -360,12 +364,12 @@ private
|
|
360
364
|
end
|
361
365
|
end
|
362
366
|
ranges << (range_start..range_end)
|
363
|
-
|
367
|
+
|
364
368
|
ranges
|
365
369
|
end
|
366
|
-
|
367
|
-
|
368
|
-
|
370
|
+
|
371
|
+
|
372
|
+
|
369
373
|
# matches the first valid Bible reference in the supplied string
|
370
374
|
def self.match_one(text)
|
371
375
|
match_all(text) do |attributes|
|
@@ -373,30 +377,30 @@ private
|
|
373
377
|
end
|
374
378
|
nil
|
375
379
|
end
|
376
|
-
|
377
|
-
|
378
|
-
|
380
|
+
|
381
|
+
|
382
|
+
|
379
383
|
# matches all valid Bible references in the supplied string
|
380
384
|
def self.match_all(text)
|
381
385
|
text.scan(Pericope::PERICOPE_PATTERN) do
|
382
386
|
match = Regexp.last_match
|
383
|
-
|
387
|
+
|
384
388
|
book = recognize_book(match[1])
|
385
389
|
next unless book
|
386
|
-
|
390
|
+
|
387
391
|
ranges = parse_reference(book, match[2])
|
388
392
|
next if ranges.empty?
|
389
|
-
|
393
|
+
|
390
394
|
attributes = {
|
391
395
|
:original_string => match.to_s,
|
392
396
|
:book => book,
|
393
397
|
:ranges => ranges
|
394
398
|
}
|
395
|
-
|
399
|
+
|
396
400
|
yield attributes, match
|
397
401
|
end
|
398
402
|
end
|
399
|
-
|
403
|
+
|
400
404
|
def self.recognize_book(book)
|
401
405
|
book = book.to_s.downcase
|
402
406
|
book_name_regexes.each do |book_regex|
|
@@ -404,18 +408,18 @@ private
|
|
404
408
|
end
|
405
409
|
nil
|
406
410
|
end
|
407
|
-
|
411
|
+
|
408
412
|
def self.parse_reference(book, reference)
|
409
413
|
reference = normalize_reference(reference)
|
410
414
|
parse_ranges(book, reference.split(/[,;]/))
|
411
415
|
end
|
412
|
-
|
416
|
+
|
413
417
|
def self.normalize_reference(reference)
|
414
418
|
reference = reference.to_s
|
415
419
|
NORMALIZATIONS.each { |(regex, replacement)| reference.gsub!(regex, replacement) }
|
416
420
|
reference
|
417
421
|
end
|
418
|
-
|
422
|
+
|
419
423
|
def self.parse_ranges(book, ranges)
|
420
424
|
recent_chapter = nil # e.g. in 12:1-8, remember that 12 is the chapter when we parse the 8
|
421
425
|
recent_chapter = 1 if !book_has_chapters?(book)
|
@@ -424,14 +428,14 @@ private
|
|
424
428
|
range << range[0] if (range.length < 2) # treat 12:4 as 12:4-12:4
|
425
429
|
lower_chapter_verse = range[0].split(':').map(&:to_i) # parse "3:28" to [3,28]
|
426
430
|
upper_chapter_verse = range[1].split(':').map(&:to_i) # parse "3:28" to [3,28]
|
427
|
-
|
431
|
+
|
428
432
|
# treat Mark 3-1 as Mark 3-3 and, eventually, Mark 3:1-35
|
429
433
|
if (lower_chapter_verse.length == 1) &&
|
430
434
|
(upper_chapter_verse.length == 1) &&
|
431
435
|
(upper_chapter_verse[0] < lower_chapter_verse[0])
|
432
436
|
upper_chapter_verse = lower_chapter_verse.dup
|
433
437
|
end
|
434
|
-
|
438
|
+
|
435
439
|
# make sure the low end of the range and the high end of the range
|
436
440
|
# are composed of arrays with two appropriate values: [chapter, verse]
|
437
441
|
chapter_range = false
|
@@ -447,7 +451,7 @@ private
|
|
447
451
|
lower_chapter_verse[0] = Pericope.to_valid_chapter(book, lower_chapter_verse[0])
|
448
452
|
end
|
449
453
|
lower_chapter_verse[1] = Pericope.to_valid_verse(book, *lower_chapter_verse)
|
450
|
-
|
454
|
+
|
451
455
|
if upper_chapter_verse.length < 2
|
452
456
|
if chapter_range
|
453
457
|
upper_chapter_verse[0] = Pericope.to_valid_chapter(book, upper_chapter_verse[0])
|
@@ -459,147 +463,91 @@ private
|
|
459
463
|
upper_chapter_verse[0] = Pericope.to_valid_chapter(book, upper_chapter_verse[0])
|
460
464
|
end
|
461
465
|
upper_chapter_verse[1] = Pericope.to_valid_verse(book, *upper_chapter_verse)
|
462
|
-
|
466
|
+
|
463
467
|
recent_chapter = upper_chapter_verse[0] # remember the last chapter
|
464
|
-
|
468
|
+
|
465
469
|
Range.new(
|
466
470
|
Pericope.get_id(book, *lower_chapter_verse),
|
467
471
|
Pericope.get_id(book, *upper_chapter_verse))
|
468
472
|
end
|
469
473
|
end
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
def self.
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
def self.load_chapter_verse_count_books!
|
478
|
+
current_book_id = nil
|
479
|
+
chapters = 0
|
480
|
+
@chapter_verse_counts = {}
|
481
|
+
@book_chapter_counts = []
|
482
|
+
|
474
483
|
path = File.expand_path(File.dirname(__FILE__) + "/../data/chapter_verse_count.txt")
|
475
|
-
chapter_verse_counts = []
|
476
484
|
File.open(path) do |file|
|
477
485
|
file.each do |text|
|
478
|
-
|
486
|
+
row = text.chomp.split("\t")
|
487
|
+
id, verses = row[0].to_i, row[1].to_i
|
488
|
+
book_id = get_book(id)
|
489
|
+
|
490
|
+
@chapter_verse_counts[id] = verses
|
491
|
+
|
492
|
+
unless current_book_id == book_id
|
493
|
+
@book_chapter_counts.push chapters if current_book_id
|
494
|
+
current_book_id = book_id
|
495
|
+
end
|
496
|
+
|
497
|
+
chapters = get_chapter(id)
|
479
498
|
end
|
480
499
|
end
|
481
|
-
|
500
|
+
|
501
|
+
@book_chapter_counts.push chapters
|
482
502
|
end
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
def self.load_book_abbreviations
|
503
|
+
|
504
|
+
|
505
|
+
|
506
|
+
def self.load_book_abbreviations!
|
507
|
+
@book_names = []
|
508
|
+
@book_name_regexes = {}
|
509
|
+
|
487
510
|
path = File.expand_path(File.dirname(__FILE__) + "/../data/book_abbreviations.txt")
|
488
|
-
book_abbreviations = []
|
489
511
|
File.open(path) do |file|
|
490
512
|
file.each do |text|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
513
|
+
next if text.start_with?("#") # skip comments
|
514
|
+
|
515
|
+
# the file contains tab-separated values.
|
516
|
+
# the first value is the ordinal of the book, subsequent values
|
517
|
+
# represent abbreviations and misspellings that should be recognized
|
518
|
+
# as the aforementioned book.
|
519
|
+
segments = text.chomp.split("\t")
|
520
|
+
book_id = segments.shift.to_i
|
521
|
+
@book_names[book_id - 1] = segments.shift
|
522
|
+
@book_name_regexes[book_id] = /\b(?:#{segments.join("|")})\b/
|
500
523
|
end
|
501
524
|
end
|
502
|
-
Hash[book_abbreviations]
|
503
525
|
end
|
504
|
-
|
505
|
-
|
506
|
-
|
526
|
+
|
527
|
+
|
528
|
+
|
507
529
|
def self.chapter_verse_counts
|
508
|
-
@chapter_verse_counts
|
530
|
+
load_chapter_verse_count_books! unless defined?(@chapter_verse_counts)
|
531
|
+
@chapter_verse_counts
|
509
532
|
end
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
def self.book_abbreviations
|
514
|
-
@book_abbreviations ||= load_book_abbreviations
|
515
|
-
end
|
516
|
-
|
517
|
-
|
518
|
-
|
533
|
+
|
534
|
+
|
535
|
+
|
519
536
|
def self.book_chapter_counts
|
520
|
-
@book_chapter_counts
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
36, # Numbers 4
|
526
|
-
34, # Deuteronomy 5
|
527
|
-
24, # Joshua 6
|
528
|
-
21, # Judges 7
|
529
|
-
4, # Ruth 8
|
530
|
-
31, # 1 Samuel 9
|
531
|
-
24, # 2 Samuel 10
|
532
|
-
22, # 1 Kings 11
|
533
|
-
25, # 2 Kings 12
|
534
|
-
29, # 1 Chronicles 13
|
535
|
-
36, # 2 Chronicles 14
|
536
|
-
10, # Ezra 15
|
537
|
-
13, # Nehemiah 16
|
538
|
-
10, # Esther 17
|
539
|
-
42, # Job 18
|
540
|
-
150, # Psalm 19
|
541
|
-
31, # Proverbs 20
|
542
|
-
12, # Ecclesiastes 21
|
543
|
-
8, # Song of Songs 22
|
544
|
-
66, # Isaiah 23
|
545
|
-
52, # Jeremiah 24
|
546
|
-
5, # Lamentations 25
|
547
|
-
48, # Ezekiel 26
|
548
|
-
12, # Daniel 27
|
549
|
-
14, # Hosea 28
|
550
|
-
3, # Joel 29
|
551
|
-
9, # Amos 30
|
552
|
-
1, # Obadiah 31
|
553
|
-
4, # Jonah 32
|
554
|
-
7, # Micah 33
|
555
|
-
3, # Nahum 34
|
556
|
-
3, # Habakkuk 35
|
557
|
-
3, # Zephaniah 36
|
558
|
-
2, # Haggai 37
|
559
|
-
14, # Zechariah 38
|
560
|
-
4, # Malachi 39
|
561
|
-
28, # Matthew 40
|
562
|
-
16, # Mark 41
|
563
|
-
24, # Luke 42
|
564
|
-
21, # John 43
|
565
|
-
28, # Acts 44
|
566
|
-
16, # Romans 45
|
567
|
-
16, # 1 Corinthians 46
|
568
|
-
13, # 2 Corinthians 47
|
569
|
-
6, # Galatians 48
|
570
|
-
6, # Ephesians 49
|
571
|
-
4, # Philippians 50
|
572
|
-
4, # Colossians 51
|
573
|
-
5, # 1 Thessalonians 52
|
574
|
-
3, # 2 Thessalonians 53
|
575
|
-
6, # 1 Timothy 54
|
576
|
-
4, # 2 Timothy 55
|
577
|
-
3, # Titus 56
|
578
|
-
1, # Philemon 57
|
579
|
-
13, # Hebrews 58
|
580
|
-
5, # James 59
|
581
|
-
5, # 1 Peter 60
|
582
|
-
3, # 2 Peter 61
|
583
|
-
5, # 1 John 62
|
584
|
-
1, # 2 John 63
|
585
|
-
1, # 3 John 64
|
586
|
-
1, # Jude 65
|
587
|
-
22] # Revelation 66
|
588
|
-
end
|
589
|
-
|
590
|
-
|
537
|
+
load_chapter_verse_count_books! unless defined?(@book_chapter_counts)
|
538
|
+
@book_chapter_counts
|
539
|
+
end
|
540
|
+
|
541
|
+
|
591
542
|
BOOK_PATTERN = /\b(?:(?:1|2|3|i+|first|second|third|1st|2nd|3rd) )?(?:\w+| of )\b/
|
592
|
-
|
543
|
+
|
593
544
|
REFERENCE_PATTERN = '(?:\s*\d{1,3})(?:\s*[:\"\.]\s*\d{1,3}[ab]?(?:\s*[,;]\s*(?:\d{1,3}[:\"\.])?\s*\d{1,3}[ab]?)*)?(?:\s*[-–—]\s*(?:\d{1,3}\s*[:\"\.])?(?:\d{1,3}[ab]?)(?:\s*[,;]\s*(?:\d{1,3}\s*[:\"\.])?\s*\d{1,3}[ab]?)*)*'
|
594
|
-
|
545
|
+
|
595
546
|
PERICOPE_PATTERN = /(#{BOOK_PATTERN})\.? (#{REFERENCE_PATTERN})/i
|
596
|
-
|
547
|
+
|
597
548
|
NORMALIZATIONS = [
|
598
549
|
[/(\d+)[".](\d+)/, '\1:\2'], # 12"5 and 12.5 -> 12:5
|
599
550
|
[/[–—]/, '-'], # convert em dash and en dash to -
|
600
551
|
[/[^0-9,:;\-–—]/, ''] # remove everything but [0-9,;:-]
|
601
552
|
]
|
602
|
-
|
603
|
-
|
604
|
-
|
605
553
|
end
|