pericope 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/pericope.rb +111 -35
- data/lib/pericope/cli.rb +19 -7
- data/lib/pericope/version.rb +1 -1
- metadata +4 -4
data/lib/pericope.rb
CHANGED
@@ -2,28 +2,45 @@ require 'yaml'
|
|
2
2
|
require 'pericope/version'
|
3
3
|
|
4
4
|
class Pericope
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :book,
|
6
|
+
:book_chapter_count,
|
7
|
+
:book_name,
|
8
|
+
:index,
|
9
|
+
:original_string,
|
10
|
+
:ranges
|
6
11
|
|
7
12
|
|
8
13
|
|
9
|
-
def
|
10
|
-
|
11
|
-
raise "no pericope found in input" unless match.is_a?(MatchData)
|
12
|
-
|
13
|
-
@original_string = match.to_s
|
14
|
-
@index = match.begin(0)
|
15
|
-
@book = match.instance_variable_get("@book")
|
16
|
-
@book_name = Pericope.book_names[@book-1]
|
17
|
-
@book_chapter_count = Pericope.book_chapter_counts[@book-1]
|
18
|
-
@book_has_chapters = (book_chapter_count > 1)
|
19
|
-
reference = normalize_reference(match[1])
|
20
|
-
@ranges = parse_ranges(reference.split(/[,;]/))
|
14
|
+
def self.book_names
|
15
|
+
@@book_names ||= ["Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalm", "Proverbs", "Ecclesiastes", "Song of Songs", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John ", "2 John", "3 John", "Jude", "Revelation"]
|
21
16
|
end
|
22
17
|
|
23
18
|
|
24
19
|
|
25
|
-
def
|
26
|
-
|
20
|
+
def initialize(string_or_array)
|
21
|
+
case string_or_array
|
22
|
+
when String, MatchData
|
23
|
+
match = string_or_array.is_a?(String) ? Pericope.match_one(string_or_array) : string_or_array
|
24
|
+
raise "no pericope found in #{string_or_array} (#{string_or_array.class})" if match.nil?
|
25
|
+
|
26
|
+
@original_string = match.to_s
|
27
|
+
@index = match.begin(0)
|
28
|
+
set_book match.instance_variable_get('@book')
|
29
|
+
@ranges = parse_reference(match[1])
|
30
|
+
|
31
|
+
when Array
|
32
|
+
set_book Pericope.get_book(string_or_array.first)
|
33
|
+
@ranges = Pericope.group_array_into_ranges(string_or_array)
|
34
|
+
|
35
|
+
else
|
36
|
+
raise ArgumentError, "#{string_or_array.class} is not a recognized input for pericope"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
def book_has_chapters?
|
43
|
+
(book_chapter_count > 1)
|
27
44
|
end
|
28
45
|
|
29
46
|
|
@@ -81,7 +98,6 @@ class Pericope
|
|
81
98
|
pericopes << segment
|
82
99
|
end
|
83
100
|
end
|
84
|
-
#segments.delete_if {|segment| !segment.is_a?(String)}
|
85
101
|
{:text => text, :pericopes => pericopes}
|
86
102
|
end
|
87
103
|
|
@@ -93,13 +109,22 @@ class Pericope
|
|
93
109
|
if segment.is_a?(String)
|
94
110
|
text << segment
|
95
111
|
else
|
96
|
-
text << segment.to_a.join(" ")
|
112
|
+
text << "{{#{segment.to_a.join(" ")}}}"
|
97
113
|
end
|
98
114
|
end
|
99
115
|
end
|
100
116
|
|
101
117
|
|
102
118
|
|
119
|
+
def self.rsub(text)
|
120
|
+
text.gsub(/\{\{(\d{7,8} ?)+\}\}/) do |match|
|
121
|
+
ids = match[2...-2].split.collect(&:to_i)
|
122
|
+
Pericope.new(ids).to_s
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
103
128
|
def to_s
|
104
129
|
"#{book_name} #{self.well_formatted_reference}"
|
105
130
|
end
|
@@ -138,7 +163,7 @@ class Pericope
|
|
138
163
|
|
139
164
|
def well_formatted_reference
|
140
165
|
recent_chapter = nil # e.g. in 12:1-8, remember that 12 is the chapter when we parse the 8
|
141
|
-
recent_chapter = 1 if !self.book_has_chapters
|
166
|
+
recent_chapter = 1 if !self.book_has_chapters?
|
142
167
|
ranges.map do |range|
|
143
168
|
min_chapter = Pericope.get_chapter(range.min)
|
144
169
|
min_verse = Pericope.get_verse(range.min)
|
@@ -158,9 +183,9 @@ class Pericope
|
|
158
183
|
recent_chapter = min_chapter
|
159
184
|
s << "#{min_chapter}:#{min_verse}"
|
160
185
|
end
|
161
|
-
|
186
|
+
|
162
187
|
if range.count > 1
|
163
|
-
|
188
|
+
|
164
189
|
s << "-"
|
165
190
|
if min_chapter == max_chapter
|
166
191
|
s << max_verse.to_s
|
@@ -193,12 +218,33 @@ class Pericope
|
|
193
218
|
def self.get_max_verse(book, chapter)
|
194
219
|
id = (book * 1000000) + (chapter * 1000)
|
195
220
|
chapter_verse_counts[id]
|
196
|
-
# ActiveRecord::Base.connection.select_value("SELECT verses FROM chapter_verse_count WHERE id=#{id}").to_i
|
197
221
|
end
|
198
222
|
|
199
223
|
|
200
224
|
|
201
|
-
|
225
|
+
private
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
def set_book(value)
|
230
|
+
@book = value || raise(ArgumentError, "must specify book")
|
231
|
+
@book_name = Pericope.book_names[@book-1]
|
232
|
+
@book_chapter_count = Pericope.book_chapter_counts[@book-1]
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
def parse_reference(reference)
|
238
|
+
reference = normalize_reference(reference)
|
239
|
+
(reference.nil? || reference.empty?) ? [] : parse_ranges(reference.split(/[,;]/))
|
240
|
+
end
|
241
|
+
|
242
|
+
def normalize_reference(reference)
|
243
|
+
{ %r{(\d+)[".](\d+)} => '\1:\2', # 12"5 and 12.5 -> 12:5
|
244
|
+
%r{[^0-9,:;-]} => '' # remove everything but [0-9,;:-]
|
245
|
+
}.each {|pattern, replacement| reference.gsub!(pattern, replacement)}
|
246
|
+
reference
|
247
|
+
end
|
202
248
|
|
203
249
|
|
204
250
|
|
@@ -210,6 +256,17 @@ protected
|
|
210
256
|
get_id(book, chapter, get_max_verse(book, chapter))
|
211
257
|
end
|
212
258
|
|
259
|
+
def self.get_next_verse(id)
|
260
|
+
id + 1
|
261
|
+
end
|
262
|
+
|
263
|
+
def self.get_start_of_next_chapter(id)
|
264
|
+
book = get_book(id)
|
265
|
+
chapter = get_chapter(id) + 1
|
266
|
+
verse = 1
|
267
|
+
get_id(book, chapter, verse)
|
268
|
+
end
|
269
|
+
|
213
270
|
def self.get_id(book, chapter, verse) #, constrain_verse=false)
|
214
271
|
book = book.to_i
|
215
272
|
book = 1 if book < 1
|
@@ -244,12 +301,41 @@ protected
|
|
244
301
|
|
245
302
|
|
246
303
|
|
304
|
+
def self.group_array_into_ranges(array)
|
305
|
+
return [] if array.nil? or array.empty?
|
306
|
+
|
307
|
+
array.flatten!
|
308
|
+
array.compact!
|
309
|
+
array.sort!
|
310
|
+
|
311
|
+
ranges = []
|
312
|
+
range_start = array.shift
|
313
|
+
range_end = range_start
|
314
|
+
while true
|
315
|
+
next_value = array.shift
|
316
|
+
break if next_value.nil?
|
317
|
+
|
318
|
+
if (next_value == get_next_verse(range_end)) ||
|
319
|
+
(next_value == get_start_of_next_chapter(range_end))
|
320
|
+
range_end = next_value
|
321
|
+
else
|
322
|
+
ranges << (range_start..range_end)
|
323
|
+
range_start = range_end = next_value
|
324
|
+
end
|
325
|
+
end
|
326
|
+
ranges << (range_start..range_end)
|
327
|
+
|
328
|
+
ranges
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
|
247
333
|
# matches the first valid Bible reference in the supplied string
|
248
334
|
def self.match_one(text)
|
249
335
|
match_all(text) do |match|
|
250
336
|
return match
|
251
337
|
end
|
252
|
-
|
338
|
+
nil
|
253
339
|
end
|
254
340
|
|
255
341
|
|
@@ -267,8 +353,7 @@ protected
|
|
267
353
|
# after matching "2 Peter" don't match "Peter" again as "1 Peter"
|
268
354
|
# but keep the same number of characters in the string so indices work
|
269
355
|
unmatched = match.pre_match + ("*" * length) + match.post_match
|
270
|
-
match.instance_variable_set(
|
271
|
-
# match = [match, book[0]]
|
356
|
+
match.instance_variable_set('@book', book[0])
|
272
357
|
if block_given?
|
273
358
|
yield match
|
274
359
|
else
|
@@ -283,7 +368,7 @@ protected
|
|
283
368
|
|
284
369
|
def parse_ranges(ranges)
|
285
370
|
recent_chapter = nil # e.g. in 12:1-8, remember that 12 is the chapter when we parse the 8
|
286
|
-
recent_chapter = 1 if !self.book_has_chapters
|
371
|
+
recent_chapter = 1 if !self.book_has_chapters?
|
287
372
|
ranges.map do |range|
|
288
373
|
range = range.split('-') # parse the low end of a verse range and the high end separately
|
289
374
|
range << range[0] if (range.length < 2) # treat 12:4 as 12:4-12:4
|
@@ -348,15 +433,6 @@ protected
|
|
348
433
|
|
349
434
|
|
350
435
|
|
351
|
-
def normalize_reference(reference)
|
352
|
-
{ %r{(\d+)[".](\d+)} => '\1:\2', # 12"5 and 12.5 -> 12:5
|
353
|
-
%r{[^0-9,:;-]} => '' # remove everything but [0-9,;:-]
|
354
|
-
}.each {|pattern, replacement| reference.gsub!(pattern, replacement)}
|
355
|
-
reference
|
356
|
-
end
|
357
|
-
|
358
|
-
|
359
|
-
|
360
436
|
def self.chapter_verse_counts
|
361
437
|
@chapter_verse_counts ||= load_chapter_verse_counts
|
362
438
|
end
|
data/lib/pericope/cli.rb
CHANGED
@@ -6,13 +6,14 @@ class Pericope
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
ALLOWED_COMMANDS = %w{help normalize parse substitute usage}
|
9
|
+
ALLOWED_COMMANDS = %w{help normalize parse substitute reverse-substitute usage}
|
10
10
|
|
11
11
|
|
12
12
|
|
13
13
|
def self.run(command, *args)
|
14
14
|
if ALLOWED_COMMANDS.member?(command)
|
15
|
-
|
15
|
+
command = command.gsub(/-/, '_').to_sym
|
16
|
+
CLI.new(*args).send(command)
|
16
17
|
else
|
17
18
|
CLI.new(*args).usage
|
18
19
|
end
|
@@ -65,6 +66,16 @@ Glossary
|
|
65
66
|
|
66
67
|
|
67
68
|
|
69
|
+
def reverse_substitute
|
70
|
+
begin
|
71
|
+
print Pericope.rsub(input)
|
72
|
+
rescue
|
73
|
+
print $!.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
68
79
|
def usage
|
69
80
|
print <<-USAGE
|
70
81
|
|
@@ -74,11 +85,12 @@ Usage
|
|
74
85
|
|
75
86
|
Commands
|
76
87
|
|
77
|
-
help
|
78
|
-
normalize
|
79
|
-
parse
|
80
|
-
substitute
|
81
|
-
|
88
|
+
help Prints more information about pericope
|
89
|
+
normalize Accepts a pericope and returns a properly-formatted pericope
|
90
|
+
parse Accepts a pericope and returns a list of verse IDs
|
91
|
+
substitute Accepts a block of text and replaces all pericopes in the text with verse IDs
|
92
|
+
reverse-substitute Accepts a block of text and replaces collections of verse IDs with pericopes
|
93
|
+
usage Prints this message
|
82
94
|
|
83
95
|
USAGE
|
84
96
|
end
|
data/lib/pericope/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pericope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 2
|
10
|
+
version: 0.5.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bob Lail
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-26 00:00:00 -05:00
|
19
19
|
default_executable: pericope
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|