scripref 0.9.1 → 0.10.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a2bd9fe1cbf211fb440e24443090c3491e9ec0b
4
- data.tar.gz: d6e4bd60dd77a8aa63eef39cb4ee777a2315c4ed
3
+ metadata.gz: 605d0d995b512d6af69e3b2152228dc201085b2b
4
+ data.tar.gz: a400e265c6d777d287170fbef3edb56c0143fcc6
5
5
  SHA512:
6
- metadata.gz: b43ac2c70d71ba2420d6dadfe9abe6ae8bcad9b4914c2420d7337fe5bdfe7e11f8ac730042830fd4eff18e76a7e6f3f3e0cc2e58c7caa79b3cd81395e4383cc5
7
- data.tar.gz: 9e5b4035b11fbf2305edd243fa703be3b54f8cd0a55ad074737b6a9e9dc63edd1412f3c4272ae074bcd20e6c30b7fb6e3c0215f84738c7d6696646b1437e60a1
6
+ metadata.gz: 37506e93da2d733beaa800db74ef5d1f16fe7aee313312298752a3f442549434b5360646b62d7d754dc189efa6edf1b09372be04b0a85e8f39dca290f2082b1a
7
+ data.tar.gz: 1e74214d77ed1f74256c102ea448eba2ba703d90269dc697360494dee102900d9f2503c8310f95ce783d1c92512a9eacba62e734adb8e411729d28dacccf3f98
@@ -1,3 +1,12 @@
1
+ 0.10.0
2
+ Add methods Passage#make_comparable, #make_comparable!, #comparable?,
3
+ #overlap?, #start, #end and #<=>.
4
+ Implement formatting of more than one passage with formatter.
5
+ Allow passage separator after ranges of books and chapters.
6
+ Add tests and fixing bugs.
7
+ Doing a lot of internal refactorings.
8
+ Add documentation.
9
+
1
10
  0.9.1
2
11
  Add Philemon to book with only one chapter.
3
12
 
@@ -1,6 +1,7 @@
1
1
  # - encoding: utf-8 -
2
2
  require 'delegate'
3
3
  require 'scripref/parser'
4
+ require 'scripref/passage'
4
5
  require 'scripref/processor'
5
6
  require 'scripref/formatter'
6
7
  require 'scripref/english'
@@ -8,35 +9,25 @@ require 'scripref/german'
8
9
 
9
10
  module Scripref
10
11
 
11
- VERSION = '0.9.1'
12
+ VERSION = '0.10.0'
12
13
 
13
- Passage = Struct.new(:text, :b1, :c1, :v1, :b2, :c2, :v2, :a1, :a2) do
14
-
15
- include Comparable
16
-
17
- def initialize text, b1, c1, v1, b2, c2, v2, opts={}
18
- super text, b1, c1, v1, b2, c2, v2, opts[:a1], opts[:a2]
19
- end
20
-
21
- def to_a
22
- [b1, c1, v1, b2, c2, v2]
14
+ class Token < DelegateClass(String)
15
+ def initialize *args
16
+ super
23
17
  end
18
+ end
24
19
 
25
- def <=> o
26
- a1 = self.to_a.map {|e| e.nil? ? 0 : e}
27
- a2 = o.to_a.map {|e| e.nil? ? 0 : e}
28
- a1 <=> a2
29
- end
20
+ class Book < Token; end
21
+ class Chapter < Token; end
22
+ class Verse < Token; end
30
23
 
31
- alias to_s text
32
- end
24
+ class Addon < Token; end
25
+ class Postfix < Token; end
33
26
 
34
- class Sep < DelegateClass(String)
35
- def initialize s
36
- super s
37
- end
38
- end
27
+ class Sep < Token; end
39
28
  class PassSep < Sep; end
40
29
  class VerseSep < Sep; end
41
30
 
31
+ class Space < Token; end
32
+
42
33
  end
@@ -42,6 +42,9 @@ module Scripref
42
42
  # Regular expression to match a separator between verses.
43
43
  VERSE_SEP_RE = /,\s*/o
44
44
 
45
+ # Separator between verses.
46
+ VERSE_SEPARATOR = ','
47
+
45
48
  # Regular expression to match addons for a verse.
46
49
  VERSE_ADDON_RE = /[ab]\s*/o
47
50
 
@@ -16,20 +16,41 @@ module Scripref
16
16
  # Formats a reference (array of passages)
17
17
  def format *reference
18
18
  @last_b = @last_c = @last_v = :undefined
19
- @result = ''
20
- reference.flatten.each do |pass|
21
- @pass = pass
19
+ @result = []
20
+ reference.flatten.each do |entry|
21
+ next if entry.kind_of? Sep
22
+ @pass = entry
22
23
  process_passage
23
24
  end
24
- @result
25
+ @result.join
25
26
  end
26
27
 
27
28
  def format_book num
28
29
  Array(book_names[num - 1]).first
29
30
  end
30
31
 
32
+ def format_chapter num
33
+ num.to_s
34
+ end
35
+
36
+ def format_verse num
37
+ num.to_s
38
+ end
39
+
40
+ def format_addon a
41
+ a.to_s
42
+ end
43
+
44
+ def format_postfix p
45
+ p.to_s
46
+ end
47
+
31
48
  private
32
49
 
50
+ def last_token
51
+ @result.last
52
+ end
53
+
33
54
  def process_passage
34
55
  @changed = false
35
56
  process_b1
@@ -38,7 +59,11 @@ module Scripref
38
59
  def process_b1
39
60
  b1 = @pass.b1
40
61
  if @last_b != b1
41
- @result << format_book(b1)
62
+ case last_token
63
+ when Token
64
+ push_sep pass_separator
65
+ end
66
+ push_book b1
42
67
  @last_b = b1
43
68
  @changed = true
44
69
  end
@@ -48,9 +73,14 @@ module Scripref
48
73
  def process_c1
49
74
  c1 = @pass.c1
50
75
  if c1 && (@changed || @last_c != c1)
51
- @result << ' '
52
76
  if ! book_has_only_one_chapter?(@pass.b1)
53
- @result << c1.to_s
77
+ case last_token
78
+ when Book
79
+ push_space
80
+ when Token
81
+ push_sep pass_separator
82
+ end
83
+ push_chapter c1
54
84
  end
55
85
  @last_c = c1
56
86
  @changed = true
@@ -62,9 +92,16 @@ module Scripref
62
92
  v1 = @pass.v1
63
93
  if v1 && (@changed || @last_v != v1)
64
94
  if ! book_has_only_one_chapter?(@pass.b1)
65
- @result << cv_separator
95
+ case last_token
96
+ when Verse
97
+ push_sep verse_separator
98
+ when Token
99
+ push_sep cv_separator
100
+ end
101
+ else
102
+ push_space
66
103
  end
67
- @result << v1.to_s
104
+ push_verse v1
68
105
  @last_v = v1
69
106
  process_a1
70
107
  end
@@ -73,7 +110,7 @@ module Scripref
73
110
 
74
111
  def process_a1
75
112
  a1 = @pass.a1
76
- @result << a1.to_s if a1
113
+ push_addon a1
77
114
  end
78
115
 
79
116
  def process_b2
@@ -81,8 +118,8 @@ module Scripref
81
118
  @hyphen = false
82
119
  b2 = @pass.b2
83
120
  if b2 && (@changed || @last_b != b2)
84
- @result << hyphen_separator
85
- @result << format_book(b2)
121
+ push_sep hyphen_separator
122
+ push_book(b2)
86
123
  @last_b = b2
87
124
  @changed = true
88
125
  @hyphen = true
@@ -94,13 +131,13 @@ module Scripref
94
131
  c2 = @pass.c2
95
132
  if c2 && (@changed || @last_c != c2)
96
133
  if @hyphen
97
- @result << ' '
134
+ push_space
98
135
  else
99
- @result << hyphen_separator
136
+ push_sep hyphen_separator
100
137
  @hyphen = true
101
138
  end
102
139
  if ! book_has_only_one_chapter?(@pass.b2)
103
- @result << c2.to_s
140
+ push_chapter c2
104
141
  end
105
142
  @last_c = c2
106
143
  @changed = true
@@ -112,22 +149,22 @@ module Scripref
112
149
  v2 = @pass.v2
113
150
  case v2
114
151
  when :f
115
- @result << postfix_one_following_verse
152
+ push_postfix postfix_one_following_verse
116
153
  return
117
154
  when :ff
118
- @result << postfix_more_following_verses
155
+ push_postfix postfix_more_following_verses
119
156
  return
120
157
  end
121
158
  if v2 && (@changed || @last_v != v2)
122
159
  if @hyphen
123
160
  if ! book_has_only_one_chapter?(@pass.b2)
124
- @result << cv_separator
161
+ push_sep cv_separator
125
162
  end
126
163
  else
127
- @result << hyphen_separator
164
+ push_sep hyphen_separator
128
165
  @hyphen = true
129
166
  end
130
- @result << v2.to_s
167
+ push_verse v2
131
168
  @last_v = @v2
132
169
  @changed = true
133
170
  process_a2
@@ -136,7 +173,37 @@ module Scripref
136
173
 
137
174
  def process_a2
138
175
  a2 = @pass.a2
139
- @result << a2.to_s if a2
176
+ push_addon a2
177
+ end
178
+
179
+ def push_book b
180
+ @result << Book.new(format_book(b))
181
+ end
182
+
183
+ def push_chapter c
184
+ @result << Chapter.new(format_chapter(c))
185
+ end
186
+
187
+ def push_verse v
188
+ @result << Verse.new(format_verse(v))
189
+ end
190
+
191
+ def push_addon a
192
+ if a
193
+ @result << Addon.new(format_addon(a))
194
+ end
195
+ end
196
+
197
+ def push_postfix p
198
+ @result << Postfix.new(format_postfix(p))
199
+ end
200
+
201
+ def push_space
202
+ @result << Space.new(' ')
203
+ end
204
+
205
+ def push_sep s
206
+ @result << Sep.new(s)
140
207
  end
141
208
 
142
209
  alias << format
@@ -39,6 +39,9 @@ module Scripref
39
39
  # Regular expression to match a separator between verses.
40
40
  VERSE_SEP_RE = /\.\s*/o
41
41
 
42
+ # Separator between verses.
43
+ VERSE_SEPARATOR = '.'
44
+
42
45
  # Regular expression to match addons for a verse.
43
46
  VERSE_ADDON_RE = /[ab]\s*/o
44
47
 
@@ -52,8 +52,11 @@ module Scripref
52
52
  s = scan(book_re) or return nil
53
53
  @text << s
54
54
  @b1 = @b2 = abbrev2num(s)
55
+ @c1 = @v1 = @c2 = @v2 = nil
55
56
 
56
- if check(Regexp.new(chapter_re.source + cv_sep_re.source))
57
+ if pass_sep
58
+ b1 or give_up 'EOS or book expected!'
59
+ elsif check(Regexp.new(chapter_re.source + cv_sep_re.source))
57
60
  @c1 = @v1 = nil
58
61
  @c2 = @v2 = nil
59
62
  c1
@@ -74,6 +77,7 @@ module Scripref
74
77
  s = scan(chapter_re) or return nil
75
78
  @text << s
76
79
  @c1 = @c2 = s.to_i
80
+ @v1 = @v2 = nil
77
81
 
78
82
  if cv_sep
79
83
  v1 or give_up 'Verse expected!'
@@ -123,14 +127,16 @@ module Scripref
123
127
  @b2 = abbrev2num(s)
124
128
  @c2 = @v2 = nil
125
129
 
126
- if check(Regexp.new(chapter_re.source + cv_sep_re.source))
130
+ if pass_sep
131
+ b1 or give_up 'EOS or book expected!'
132
+ elsif check(Regexp.new(chapter_re.source + cv_sep_re.source))
127
133
  c2
128
134
  else
129
135
  if book_has_only_one_chapter?(@b2)
130
136
  @c2 = 1
131
137
  epsilon or v2 or give_up 'EOS or chapter or verse expected!'
132
138
  else
133
- epsilon or c2 or ('EOS or chapter expected')
139
+ epsilon or c2 or give_up 'EOS or chapter expected!'
134
140
  end
135
141
  end
136
142
  end
@@ -143,6 +149,8 @@ module Scripref
143
149
 
144
150
  if cv_sep
145
151
  v2 or give_up 'Verse expected!'
152
+ elsif pass_sep
153
+ b1 or c1 or give_up 'Book or chapter expected!'
146
154
  else
147
155
  epsilon or give_up 'EOS or chapter verse separator expected!'
148
156
  end
@@ -0,0 +1,76 @@
1
+ # - encoding: utf-8 -
2
+ module Scripref
3
+
4
+ Passage = Struct.new(:text, :b1, :c1, :v1, :b2, :c2, :v2, :a1, :a2) do
5
+
6
+ include Comparable
7
+
8
+ def initialize text, b1, c1, v1, b2, c2, v2, a1: nil, a2: nil
9
+ super text, b1, c1, v1, b2, c2, v2, a1, a2
10
+ end
11
+
12
+ def to_a
13
+ [b1, c1, v1, b2, c2, v2]
14
+ end
15
+
16
+ def <=> other
17
+ return unless other.kind_of? Passage
18
+ self.make_comparable.to_a <=> other.make_comparable.to_a
19
+ end
20
+
21
+ # Returns a copy which is comparable, that means
22
+ # all values are numeric.
23
+ # This is a heuristic approach.
24
+ def make_comparable max: 999, ff: 3
25
+ self.dup.make_comparable! max: max, ff: ff
26
+ end
27
+
28
+ # Makes the Passage instance comparable, that means
29
+ # all values are numeric.
30
+ # This is a heuristic approach.
31
+ def make_comparable! max: 999, ff: 3
32
+ self.b1 ||= 1
33
+ self.c1 ||= 1
34
+ self.v1 ||= 1
35
+ self.b2 ||= max
36
+ self.c2 ||= max
37
+ self.v2 ||= max
38
+ if self.v2 == :f
39
+ self.v2 = self.v1 + 1
40
+ end
41
+ if self.v2 == :ff
42
+ self.v2 = self.v1 + ff
43
+ end
44
+ self
45
+ end
46
+
47
+ # Checks if the instance is comparable, that means
48
+ # all values are numeric and so the <=> method
49
+ # can be applied.
50
+ def comparable?
51
+ to_a.map {|e| Numeric === e}.uniq == [true]
52
+ end
53
+
54
+ # Returns true if the instance and the given passage overlap.
55
+ # That means both has at least one verse in common.
56
+ def overlap? passage
57
+ fail ArgumentError, 'value must be a passage' unless passage.kind_of? Passage
58
+ a = self.make_comparable.to_a
59
+ b = passage.make_comparable.to_a
60
+ [a[0..2] <=> b[3..5], b[0..2] <=> a[3..5]].max < 1
61
+ end
62
+
63
+ # Returns an array of b1, c1, v1
64
+ def start
65
+ [b1, c1, v1]
66
+ end
67
+
68
+ # Returns an array of b2, c2, v2
69
+ def end
70
+ [b2, c2, v2]
71
+ end
72
+
73
+ alias to_s text
74
+ end
75
+
76
+ end
@@ -340,10 +340,10 @@ result:
340
340
  - :text: '4'
341
341
  :b1: 8
342
342
  :c1: 4
343
- :v1: 9
343
+ :v1:
344
344
  :b2: 8
345
345
  :c2: 4
346
- :v2: 12
346
+ :v2:
347
347
  :a1:
348
348
  :a2:
349
349
  - "; "
@@ -369,9 +369,9 @@ result:
369
369
  ---
370
370
  sample: Ruth 2,1a-11.15a; 3,7b.9-12b; Markus ; 5,3a.18b-21a
371
371
  exception: |-
372
- EOS or hyphen and book or chapter expected!
372
+ EOS or book expected!
373
373
  Ruth 2,1a-11.15a; 3,7b.9-12b; Markus ; 5,3a.18b-21a
374
- ^
374
+ ^
375
375
  ---
376
376
  sample: Ruth 2,1a-11.15a; 3,7b.9-12b; Markus 45,3a.18b-21a
377
377
  result:
@@ -18,126 +18,248 @@ class TestFormatter < Test::Unit::TestCase
18
18
  end
19
19
 
20
20
  def test_only_book
21
- @german = 'Römer'
22
- @english = 'Romans'
23
- check_formatting
21
+ text = 'Ruth'
22
+ assert_formated_text_for_ast text, [pass(text, 8, nil, nil, 8, nil, nil)]
24
23
  end
25
24
 
26
25
  def test_book_and_chapter
27
- @german = 'Römer 8'
28
- @english = 'Romans 8'
29
- check_formatting
26
+ text = 'Ruth 2'
27
+ assert_formated_text_for_ast text, [pass(text, 8, 2, nil, 8, 2, nil)]
30
28
  end
31
29
 
32
- def test_one_verse
33
- @german = 'Römer 6,23'
34
- @english = 'Romans 6:23'
35
- check_formatting
30
+ def test_book_chapter_and_verse
31
+ text = 'Ruth 2,5'
32
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, 5)]
36
33
  end
37
34
 
38
- def test_book_range
39
- @german = 'Römer-Hebräer'
40
- @english = 'Romans-Hebrews'
41
- check_formatting
35
+ def test_verse_range
36
+ text = 'Ruth 2,5-11'
37
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, 11)]
38
+ end
39
+
40
+ def test_chapter_verse_range
41
+ text = 'Ruth 2,5-3,7'
42
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 3, 7)]
42
43
  end
43
44
 
44
45
  def test_chapter_range
45
- @german = 'Römer 1-8'
46
- @english = 'Romans 1-8'
47
- check_formatting
46
+ text = 'Ruth 2-3'
47
+ assert_formated_text_for_ast text, [pass(text, 8, 2, nil, 8, 3, nil)]
48
+ end
49
+
50
+ def test_book_range
51
+ text = '1. Mose-Offenbarung'
52
+ assert_formated_text_for_ast text, [pass(text, 1, nil, nil, 66, nil, nil)]
53
+ end
54
+
55
+ def test_book_chapter_range
56
+ text = '1. Mose 1-Offenbarung 22'
57
+ assert_formated_text_for_ast text, [pass(text, 1, 1, nil, 66, 22, nil)]
58
+ end
59
+
60
+ def test_book_chapter_verse_range
61
+ text = '1. Mose 1,1-Offenbarung 22,21'
62
+ assert_formated_text_for_ast text, [pass(text, 1, 1, 1, 66, 22, 21)]
63
+ end
64
+
65
+ def test_one_following_verse
66
+ text = 'Ruth 2,5f'
67
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, :f)]
68
+ end
69
+
70
+ def test_more_following_verse
71
+ text = 'Ruth 2,5ff'
72
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, :ff)]
48
73
  end
49
74
 
50
- def test_simple_passage
51
- @german = 'Römer 8,1-10'
52
- @english = 'Romans 8:1-10'
53
- check_formatting
75
+ def test_first_addon
76
+ text = 'Ruth 2,5a'
77
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, 5, a1: :a)]
54
78
  end
55
79
 
56
- def test_passage_with_chapter_change
57
- @german = 'Römer 1,1-5,11'
58
- @english = 'Romans 1:1-5:11'
59
- check_formatting
80
+ def test_second_addon
81
+ text = 'Ruth 2,5-7a'
82
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, 7, a2: :a)]
60
83
  end
61
84
 
62
- def test_passage_with_book_change
63
- @german = '1. Korinther 1,1-2. Korinther 13,13'
64
- @english = '1 Corinthians 1:1-2 Corinthians 13:13'
65
- check_formatting
85
+ def test_both_addons
86
+ text = 'Ruth 2,5b-7a'
87
+ assert_formated_text_for_ast text, [pass(text, 8, 2, 5, 8, 2, 7, a1: :b, a2: :a)]
66
88
  end
67
89
 
68
- def test_passage_with_different_chapter_and_same_verse
69
- @german = '2. Petrus 1,13-2,13'
70
- @english = '2 Peter 1:13-2:13'
71
- check_formatting
90
+ def test_reset_addons
91
+ @parser.parse 'Ruth 2,5b-7a'
92
+ text = 'Ruth'
93
+ assert_formated_text_for_ast text, [pass(text, 8, nil, nil, 8, nil, nil)]
72
94
  end
73
95
 
74
96
  def test_book_with_only_one_chapter
75
- @german = 'Obadja 3'
76
- @english = 'Obadiah 3'
77
- check_formatting
97
+ text = 'Obadja 3'
98
+ assert_formated_text_for_ast text, [pass(text, 31, 1, 3, 31, 1, 3)]
99
+ text = 'Obadja 1'
100
+ assert_formated_text_for_ast text, [pass(text, 31, 1, 1, 31, 1, 1)]
78
101
  end
79
102
 
80
103
  def test_book_with_only_one_chapter_range
81
- @german = 'Obadja 3-5'
82
- @english = 'Obadiah 3-5'
83
- check_formatting
104
+ text = 'Obadja 3-5'
105
+ assert_formated_text_for_ast text, [pass(text, 31, 1, 3, 31, 1, 5)]
106
+ text = 'Obadja 1-4'
107
+ assert_formated_text_for_ast text, [pass(text, 31, 1, 1, 31, 1, 4)]
108
+ end
109
+
110
+ def test_book_with_only_one_chapter_at_begin_of_range
111
+ text = 'Obadja-Jona'
112
+ assert_formated_text_for_ast text, [pass(text, 31, 1, nil, 32, nil, nil)]
113
+ text = 'Obadja 3-Jona 2,4'
114
+ assert_formated_text_for_ast text, [pass(text, 31, 1, 3, 32, 2, 4)]
84
115
  end
85
116
 
86
117
  def test_book_with_only_one_chapter_at_end_of_range
87
- @german = 'Amos 2,4-Obadja 3'
88
- @english = 'Amos 2:4-Obadiah 3'
89
- check_formatting
118
+ text = 'Amos 2,4-Obadja 3'
119
+ assert_formated_text_for_ast text, [pass(text, 30, 2, 4, 31, 1, 3)]
120
+ text = 'Amos 2,4-Obadja 1'
121
+ assert_formated_text_for_ast text, [pass(text, 30, 2, 4, 31, 1, 1)]
90
122
  end
91
123
 
92
- def test_attr_writer_overrides_value_of_mixin
93
- @german = '1. Korinther 1,1 - 2. Korinther 13,13'
94
- @english = '1 Corinthians 1:1 - 2 Corinthians 13:13'
95
- @german_formatter.hyphen_separator = ' - '
96
- @english_formatter.hyphen_separator = ' - '
97
- check_formatting
124
+ ######################################################################
125
+ # more than one passage
126
+ ######################################################################
127
+
128
+ def test_two_books
129
+ text = 'Ruth; Markus'
130
+ t1, t2 = text.split(semi)
131
+ assert_formated_text_for_ast text, [pass(t1, 8, nil, nil, 8, nil, nil), semi, pass(t2, 41, nil, nil, 41, nil, nil)]
98
132
  end
99
133
 
100
- def test_alternative_booknames
101
- ast = @parser.parse('Zephanja 1,8')
102
- assert_equal 'Zefanja 1,8', @german_formatter.format(ast)
134
+ def test_two_complete_refs
135
+ text = 'Ruth 2,1; Markus 4,8'
136
+ t1, t2 = text.split(semi)
137
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 1), semi, pass(t2, 41, 4, 8, 41, 4, 8)]
103
138
  end
104
139
 
105
- def test_addon1
106
- @german = 'Markus 2,4b'
107
- @english = 'Mark 2:4b'
108
- check_formatting
140
+ def test_two_refs_same_book
141
+ text = 'Ruth 2,1; 5,4'
142
+ t1, t2 = text.split(semi)
143
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 1), semi, pass(t2, 8, 5, 4, 8, 5, 4)]
109
144
  end
110
145
 
111
- def test_addon2
112
- @german = 'Markus 2,2-4b'
113
- @english = 'Mark 2:2-4b'
114
- check_formatting
146
+ def test_two_chapters_same_book
147
+ text = 'Ruth 2; 5'
148
+ t1, t2 = text.split(semi)
149
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, nil, 8, 2, nil), semi, pass(t2, 8, 5, nil, 8, 5, nil)]
115
150
  end
116
151
 
117
- def test_both_addons
118
- @german = 'Markus 2,2b-4a'
119
- @english = 'Mark 2:2b-4a'
120
- check_formatting
152
+ def test_two_chapters_different_book
153
+ text = 'Ruth 2; Markus 4'
154
+ t1, t2 = text.split(semi)
155
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, nil, 8, 2, nil), semi, pass(t2, 41, 4, nil, 41, 4, nil)]
121
156
  end
122
157
 
123
- def test_postfix_one_following_verse
124
- @german = 'Markus 2,2f'
125
- @english = 'Mark 2:2f'
126
- check_formatting
158
+ def test_two_verses
159
+ text = 'Ruth 2,5.11'
160
+ t1, t2 = text.split(dot)
161
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 5, 8, 2, 5), dot, pass(t2, 8, 2, 11, 8, 2, 11)]
127
162
  end
128
163
 
129
- def test_postfix_more_following_verses
130
- @german = 'Markus 2,2ff'
131
- @english = 'Mark 2:2ff'
132
- check_formatting
164
+ def test_partial_passage_after_full_passage
165
+ text = 'Ruth 2,5; 4'
166
+ t1, t2 = text.split(semi)
167
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 8, 4, nil, 8, 4, nil)]
168
+ text = 'Ruth 2,5; Markus'
169
+ t1, t2 = text.split(semi)
170
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 41, nil, nil, 41, nil, nil)]
171
+ text = 'Ruth 2,5; Markus 4'
172
+ t1, t2 = text.split(semi)
173
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 41, 4, nil, 41, 4, nil)]
174
+ end
175
+
176
+ ######################################################################
177
+ # mixed variants of more than one passage
178
+ ######################################################################
179
+
180
+ def test_verse_range_and_separated_verse
181
+ text = 'Ruth 2,1-3.11'
182
+ t1, t2 = text.split(dot)
183
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 3), dot, pass(t2, 8, 2, 11, 8, 2, 11)]
184
+ end
185
+
186
+ def test_separate_verse_and_verse_range
187
+ text = 'Ruth 2,1.3-11'
188
+ t1, t2 = text.split(dot)
189
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 1), dot, pass(t2, 8, 2, 3, 8, 2, 11)]
190
+ end
191
+
192
+ def test_two_verse_ranges
193
+ text = 'Ruth 2,1-3.7-11'
194
+ t1, t2 = text.split(dot)
195
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 3), dot, pass(t2, 8, 2, 7, 8, 2, 11)]
196
+ end
197
+
198
+ def test_two_verse_range_different_books
199
+ text = 'Ruth 2,1-11; Markus 4,3-7'
200
+ t1, t2 = text.split(semi)
201
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 11), semi, pass(t2, 41, 4, 3,41, 4, 7)]
202
+ end
203
+
204
+ def test_two_verse_range_different_chapters
205
+ text = 'Ruth 2,1-11; 3,10-19'
206
+ t1, t2 = text.split(semi)
207
+ assert_formated_text_for_ast text, [pass(t1, 8, 2, 1, 8, 2, 11), semi, pass(t2, 8, 3, 10, 8, 3, 19)]
208
+ end
209
+
210
+ def test_book_range_and_following_book
211
+ text = 'Ruth-Markus; Johannes'
212
+ t1, t2 = text.split(semi)
213
+ assert_formated_text_for_ast text, [pass(t1, 8, nil, nil, 41, nil, nil), semi, pass(t2, 43, nil, nil, 43, nil, nil)]
214
+ end
215
+
216
+ def test_chapter_range_and_following_book
217
+ text = 'Ruth 1-2; Johannes 4'
218
+ t1, t2 = text.split(semi)
219
+ assert_formated_text_for_ast text, [pass(t1, 8, 1, nil, 8, 2, nil), semi, pass(t2, 43, 4, nil, 43, 4, nil)]
220
+ end
221
+
222
+ def test_chapter_range_and_following_chapter
223
+ text = 'Ruth 1-2; 4'
224
+ t1, t2 = text.split(semi)
225
+ assert_formated_text_for_ast text, [pass(t1, 8, 1, nil, 8, 2, nil), semi, pass(t2, 8, 4, nil, 8, 4, nil)]
226
+ end
227
+
228
+ def test_book_only_after_full_passage
229
+ text = 'Matthäus 3,4; Markus; Johannes 3,16'
230
+ t1, t2, t3 = text.split(semi)
231
+ assert_formated_text_for_ast text, [pass(t1, 40, 3, 4, 40, 3, 4), semi, pass(t2, 41, nil, nil, 41, nil, nil), semi, pass(t3, 43, 3, 16, 43, 3, 16)]
232
+ end
233
+
234
+ def test_chapter_only_after_full_passage
235
+ text = 'Matthäus 3,4; 8; Johannes 3,16'
236
+ t1, t2, t3 = text.split(semi)
237
+ assert_formated_text_for_ast text, [pass(t1, 40, 3, 4, 40, 3, 4), semi, pass(t2, 40, 8, nil, 40, 8, nil), semi, pass(t3, 43, 3, 16, 43, 3, 16)]
238
+ end
239
+
240
+ ######################################################################
241
+ # complex variants of references
242
+ ######################################################################
243
+
244
+ def test_complex_example
245
+ text = 'Ruth 2,1-11.15; 3,7.9-12; Markus 4; 5,3.18-21'
246
+ t1, t2, t3, t4, t5, t6, t7 = text.split(/; |\./)
247
+ ast = [
248
+ pass(t1, 8, 2, 1, 8, 2, 11), dot,
249
+ pass(t2, 8, 2, 15, 8, 2, 15), semi,
250
+ pass(t3, 8, 3, 7, 8, 3, 7), dot,
251
+ pass(t4, 8, 3, 9, 8, 3, 12), semi,
252
+ pass(t5, 41, 4, nil, 41, 4, nil), semi,
253
+ pass(t6, 41, 5, 3, 41, 5, 3), dot,
254
+ pass(t7, 41, 5, 18, 41, 5, 21)
255
+ ]
256
+ assert_formated_text_for_ast text, ast
133
257
  end
134
258
 
135
259
  private
136
260
 
137
- def check_formatting
138
- ast = @parser.parse(@german)
139
- assert_equal @german, @german_formatter.format(ast)
140
- assert_equal @english, @english_formatter.format(ast)
261
+ def assert_formated_text_for_ast text, ast
262
+ assert_equal text, @german_formatter.format(ast)
141
263
  end
142
264
 
143
265
  end
@@ -0,0 +1,143 @@
1
+ # - encoding: utf-8 -
2
+ require 'test/unit'
3
+ require 'test_helper'
4
+ require 'scripref'
5
+ require 'scripref/english'
6
+ require 'scripref/formatter'
7
+ require 'scripref/german'
8
+ require 'scripref/parser'
9
+
10
+ class TestIntegration < Test::Unit::TestCase
11
+
12
+ include Test::Helper
13
+
14
+ def setup
15
+ @parser = Scripref::Parser.new(Scripref::German)
16
+ @german_formatter = Scripref::Formatter.new(Scripref::German)
17
+ @english_formatter = Scripref::Formatter.new(Scripref::English)
18
+ end
19
+
20
+ def test_only_book
21
+ @german = 'Römer'
22
+ @english = 'Romans'
23
+ check_formatting
24
+ end
25
+
26
+ def test_book_and_chapter
27
+ @german = 'Römer 8'
28
+ @english = 'Romans 8'
29
+ check_formatting
30
+ end
31
+
32
+ def test_one_verse
33
+ @german = 'Römer 6,23'
34
+ @english = 'Romans 6:23'
35
+ check_formatting
36
+ end
37
+
38
+ def test_book_range
39
+ @german = 'Römer-Hebräer'
40
+ @english = 'Romans-Hebrews'
41
+ check_formatting
42
+ end
43
+
44
+ def test_chapter_range
45
+ @german = 'Römer 1-8'
46
+ @english = 'Romans 1-8'
47
+ check_formatting
48
+ end
49
+
50
+ def test_simple_passage
51
+ @german = 'Römer 8,1-10'
52
+ @english = 'Romans 8:1-10'
53
+ check_formatting
54
+ end
55
+
56
+ def test_passage_with_chapter_change
57
+ @german = 'Römer 1,1-5,11'
58
+ @english = 'Romans 1:1-5:11'
59
+ check_formatting
60
+ end
61
+
62
+ def test_passage_with_book_change
63
+ @german = '1. Korinther 1,1-2. Korinther 13,13'
64
+ @english = '1 Corinthians 1:1-2 Corinthians 13:13'
65
+ check_formatting
66
+ end
67
+
68
+ def test_passage_with_different_chapter_and_same_verse
69
+ @german = '2. Petrus 1,13-2,13'
70
+ @english = '2 Peter 1:13-2:13'
71
+ check_formatting
72
+ end
73
+
74
+ def test_book_with_only_one_chapter
75
+ @german = 'Obadja 3'
76
+ @english = 'Obadiah 3'
77
+ check_formatting
78
+ end
79
+
80
+ def test_book_with_only_one_chapter_range
81
+ @german = 'Obadja 3-5'
82
+ @english = 'Obadiah 3-5'
83
+ check_formatting
84
+ end
85
+
86
+ def test_book_with_only_one_chapter_at_end_of_range
87
+ @german = 'Amos 2,4-Obadja 3'
88
+ @english = 'Amos 2:4-Obadiah 3'
89
+ check_formatting
90
+ end
91
+
92
+ def test_attr_writer_overrides_value_of_mixin
93
+ @german = '1. Korinther 1,1 - 2. Korinther 13,13'
94
+ @english = '1 Corinthians 1:1 - 2 Corinthians 13:13'
95
+ @german_formatter.hyphen_separator = ' - '
96
+ @english_formatter.hyphen_separator = ' - '
97
+ check_formatting
98
+ end
99
+
100
+ def test_alternative_booknames
101
+ ast = @parser.parse('Zephanja 1,8')
102
+ assert_equal 'Zefanja 1,8', @german_formatter.format(ast)
103
+ end
104
+
105
+ def test_addon1
106
+ @german = 'Markus 2,4b'
107
+ @english = 'Mark 2:4b'
108
+ check_formatting
109
+ end
110
+
111
+ def test_addon2
112
+ @german = 'Markus 2,2-4b'
113
+ @english = 'Mark 2:2-4b'
114
+ check_formatting
115
+ end
116
+
117
+ def test_both_addons
118
+ @german = 'Markus 2,2b-4a'
119
+ @english = 'Mark 2:2b-4a'
120
+ check_formatting
121
+ end
122
+
123
+ def test_postfix_one_following_verse
124
+ @german = 'Markus 2,2f'
125
+ @english = 'Mark 2:2f'
126
+ check_formatting
127
+ end
128
+
129
+ def test_postfix_more_following_verses
130
+ @german = 'Markus 2,2ff'
131
+ @english = 'Mark 2:2ff'
132
+ check_formatting
133
+ end
134
+
135
+ private
136
+
137
+ def check_formatting
138
+ ast = @parser.parse(@german)
139
+ assert_equal @german, @german_formatter.format(ast)
140
+ assert_equal @english, @english_formatter.format(ast)
141
+ end
142
+
143
+ end
@@ -116,6 +116,15 @@ class TestParser < Test::Unit::TestCase
116
116
  assert_parsed_ast_for_text [pass(text, 31, 1, 1, 31, 1, 4)], text
117
117
  end
118
118
 
119
+ def test_book_with_only_one_chapter_at_begin_of_range
120
+ text = 'Obad - Jona'
121
+ assert_parsed_ast_for_text [pass(text, 31, 1, nil, 32, nil, nil)], text
122
+ text = 'Obad 3 - Jona 2,4'
123
+ assert_parsed_ast_for_text [pass(text, 31, 1, 3, 32, 2, 4)], text
124
+ text = 'Obad 1,3 - Jona 2,4'
125
+ assert_parsed_ast_for_text [pass(text, 31, 1, 3, 32, 2, 4)], text
126
+ end
127
+
119
128
  def test_book_with_only_one_chapter_at_end_of_range
120
129
  text = 'Amos 2,4 - Obad 3'
121
130
  assert_parsed_ast_for_text [pass(text, 30, 2, 4, 31, 1, 3)], text
@@ -128,9 +137,15 @@ class TestParser < Test::Unit::TestCase
128
137
  end
129
138
 
130
139
  ######################################################################
131
- # more than one reference
140
+ # more than one passage
132
141
  ######################################################################
133
142
 
143
+ def test_two_books
144
+ text = 'Ruth; Markus'
145
+ t1, t2 = text.split(semi)
146
+ assert_parsed_ast_for_text [pass(t1, 8, nil, nil, 8, nil, nil), semi, pass(t2, 41, nil, nil, 41, nil, nil)], text
147
+ end
148
+
134
149
  def test_two_complete_refs
135
150
  text = 'Ruth 2,1; Markus 4,8'
136
151
  t1, t2 = text.split(semi)
@@ -161,8 +176,20 @@ class TestParser < Test::Unit::TestCase
161
176
  assert_parsed_ast_for_text [pass(t1, 8, 2, 5, 8, 2, 5), dot, pass(t2, 8, 2, 11, 8, 2, 11)], text
162
177
  end
163
178
 
179
+ def test_partial_passage_after_full_passage
180
+ text = 'Ruth 2,5; 4'
181
+ t1, t2 = text.split(semi)
182
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 8, 4, nil, 8, 4, nil)], text
183
+ text = 'Ruth 2,5; Markus'
184
+ t1, t2 = text.split(semi)
185
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 41, nil, nil, 41, nil, nil)], text
186
+ text = 'Ruth 2,5; Markus 4'
187
+ t1, t2 = text.split(semi)
188
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 5, 8, 2, 5), semi, pass(t2, 41, 4, nil, 41, 4, nil)], text
189
+ end
190
+
164
191
  ######################################################################
165
- # mixed variants of more than one reference
192
+ # mixed variants of more than one passage
166
193
  ######################################################################
167
194
 
168
195
  def test_verse_range_and_separated_verse
@@ -195,6 +222,36 @@ class TestParser < Test::Unit::TestCase
195
222
  assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 11), semi, pass(t2, 8, 3, 10, 8, 3, 19)], text
196
223
  end
197
224
 
225
+ def test_book_range_and_following_book
226
+ text = 'Ruth-Markus; Johannes'
227
+ t1, t2 = text.split(semi)
228
+ assert_parsed_ast_for_text [pass(t1, 8, nil, nil, 41, nil, nil), semi, pass(t2, 43, nil, nil, 43, nil, nil)], text
229
+ end
230
+
231
+ def test_chapter_range_and_following_book
232
+ text = 'Ruth 1-2; Joh 4'
233
+ t1, t2 = text.split(semi)
234
+ assert_parsed_ast_for_text [pass(t1, 8, 1, nil, 8, 2, nil), semi, pass(t2, 43, 4, nil, 43, 4, nil)], text
235
+ end
236
+
237
+ def test_chapter_range_and_following_chapter
238
+ text = 'Ruth 1-2; 4'
239
+ t1, t2 = text.split(semi)
240
+ assert_parsed_ast_for_text [pass(t1, 8, 1, nil, 8, 2, nil), semi, pass(t2, 8, 4, nil, 8, 4, nil)], text
241
+ end
242
+
243
+ def test_book_only_after_full_passage
244
+ text = 'Matt 3,4; Mar; Joh 3,16'
245
+ t1, t2, t3 = text.split(semi)
246
+ assert_parsed_ast_for_text [pass(t1, 40, 3, 4, 40, 3, 4), semi, pass(t2, 41, nil, nil, 41, nil, nil), semi, pass(t3, 43, 3, 16, 43, 3, 16)], text
247
+ end
248
+
249
+ def test_chapter_only_after_full_passage
250
+ text = 'Matt 3,4; 8; Joh 3,16'
251
+ t1, t2, t3 = text.split(semi)
252
+ assert_parsed_ast_for_text [pass(t1, 40, 3, 4, 40, 3, 4), semi, pass(t2, 40, 8, nil, 40, 8, nil), semi, pass(t3, 43, 3, 16, 43, 3, 16)], text
253
+ end
254
+
198
255
  ######################################################################
199
256
  # complex variants of references
200
257
  ######################################################################
@@ -14,10 +14,75 @@ class TestPassage < Test::Unit::TestCase
14
14
  assert_equal [41, 1, 2, 42, 3, 4], pass.to_a
15
15
  end
16
16
 
17
- def test_ordering
17
+ def test_spaceship_operator
18
+ ast = @parser.parse('Mar 2,3; Joh 1,5')
19
+ p1, p2 = ast[0], ast[2]
20
+ assert_nil p1 <=> :other_value
21
+ assert_nil :other_value <=> p1
22
+ assert_equal (-1), p1 <=> p2
23
+ assert_equal 0, p1 <=> p1
24
+ assert_equal 1, p2 <=> p1
25
+ end
26
+
27
+ def test_comparable_with_sort
18
28
  ast = @parser.parse('Joh 8,1-9,11; 8,2-9,12; 8,2-9,11; 8,1-9,12; Joh 8')
19
- passages = ast.select {|e| Scripref::Passage === e}
20
- assert_equal ["Joh 8", "Joh 8,1-9,11", "8,1-9,12", "8,2-9,11", "8,2-9,12"], passages.sort.map(&:text)
29
+ passages = ast.grep(Scripref::Passage)
30
+ expect = ['Joh 8',
31
+ 'Joh 8,1-9,11',
32
+ '8,1-9,12',
33
+ '8,2-9,11',
34
+ '8,2-9,12']
35
+ assert_equal expect, passages.sort.map(&:text)
36
+
37
+ ast = @parser.parse('Mar 1; 1,1; 1,1f; 1,1ff; 1,2; 1,1-2,2; Mar 1-2; Markus; Markus-Lukas; Mar 1-Luk 2; Mar 1,1-Luk 2,2')
38
+ passages = ast.grep(Scripref::Passage)
39
+ formatter = Scripref::Formatter.new(Scripref::German)
40
+ expect = ['Markus 1,1',
41
+ 'Markus 1,1f',
42
+ 'Markus 1,1ff',
43
+ 'Markus 1',
44
+ 'Markus 1,1-2,2',
45
+ 'Markus 1-2',
46
+ 'Markus',
47
+ 'Markus 1,1-Lukas 2,2',
48
+ 'Markus 1-Lukas 2',
49
+ 'Markus-Lukas',
50
+ 'Markus 1,2']
51
+ assert_equal expect, passages.sort.map {|e| formatter << e}
52
+ end
53
+
54
+ def test_overlap
55
+ a = @parser.parse('Joh 8,1-9').first
56
+ b = @parser.parse('Joh 8,8-11').first
57
+ c = @parser.parse('Joh 8,12-15').first
58
+ d = @parser.parse('Joh 8,15-18').first
59
+ e = @parser.parse('Joh 8').first
60
+ assert_overlap a, a
61
+ assert_overlap a, b
62
+ assert_not_overlap b, c
63
+ assert_overlap c, d
64
+ assert_overlap d, e
65
+ end
66
+
67
+ def test_start
68
+ p = Scripref::Passage.new('', 1, 2, 3, 4, 5, 6)
69
+ assert_equal [1, 2, 3], p.start
21
70
  end
22
71
 
72
+ def test_end
73
+ p = Scripref::Passage.new('', 1, 2, 3, 4, 5, 6)
74
+ assert_equal [4, 5, 6], p.end
75
+ end
76
+
77
+ protected
78
+
79
+ def assert_overlap a, b
80
+ assert a.overlap?(b)
81
+ assert b.overlap?(a)
82
+ end
83
+
84
+ def assert_not_overlap a, b
85
+ assert !a.overlap?(b)
86
+ assert !b.overlap?(a)
87
+ end
23
88
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scripref
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Friedrich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-19 00:00:00.000000000 Z
11
+ date: 2016-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rim
@@ -44,7 +44,7 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
- - CHANGELOG
47
+ - Changelog
48
48
  - LICENSE
49
49
  - README.md
50
50
  - Rakefile
@@ -54,6 +54,7 @@ files:
54
54
  - lib/scripref/formatter.rb
55
55
  - lib/scripref/german.rb
56
56
  - lib/scripref/parser.rb
57
+ - lib/scripref/passage.rb
57
58
  - lib/scripref/pipelining.rb
58
59
  - lib/scripref/processor.rb
59
60
  - regtest/formatter.rb
@@ -64,6 +65,7 @@ files:
64
65
  - test/test_formatter.rb
65
66
  - test/test_german.rb
66
67
  - test/test_helper.rb
68
+ - test/test_integration.rb
67
69
  - test/test_parser.rb
68
70
  - test/test_passage.rb
69
71
  - test/test_pipelining.rb
@@ -87,9 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
89
  version: '0'
88
90
  requirements: []
89
91
  rubyforge_project:
90
- rubygems_version: 2.5.1
92
+ rubygems_version: 2.6.3
91
93
  signing_key:
92
94
  specification_version: 4
93
95
  summary: Library for parsing scripture references in real texts.
94
96
  test_files: []
95
- has_rdoc: