pericope 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|