scripref 0.2.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.
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ 0.2.0
2
+ Improve doc and refactoring ref_sep -> pass_sep.
3
+
4
+ 0.1.0
5
+ First public release.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2012 Jan Friedrich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rim'
2
+ require 'rim/check_version'
3
+ require 'rim/gem'
4
+ require 'rim/git'
5
+ require 'rim/rimrc'
6
+ require 'rim/test'
7
+
8
+ $:.unshift File.dirname(__FILE__) + '/lib'
9
+ require 'scripref'
10
+
11
+ Rim.setup do
12
+ name 'scripref'
13
+ authors 'Jan Friedrich'
14
+ homepage 'http://gitorious.org/scripref'
15
+ version Scripref::VERSION
16
+ summary 'Library for parsing scripture references in real texts.'
17
+ end
@@ -0,0 +1,46 @@
1
+ # - encoding: utf-8 -
2
+
3
+ # Mixin to generate instance methods to access of mixin constants.
4
+ #
5
+ # Example:
6
+ # module M
7
+ # A = :a
8
+ # B = :b
9
+ # extend ConstReader
10
+ # const_reader constants
11
+ # end
12
+ #
13
+ # # Include in class
14
+ # class C
15
+ # include M
16
+ # end
17
+ # c = C.new
18
+ # c.a # => :a
19
+ # c.b # => :b
20
+ #
21
+ # # Extend an instance
22
+ # o = Object.new
23
+ # o.extend M
24
+ # o.a # => :a
25
+ # o.b # => :b
26
+ module ConstReader
27
+
28
+ # Define a getter method for one or more constants.
29
+ #
30
+ # Example:
31
+ # # all defined constants
32
+ # const_reader constants
33
+ #
34
+ # # constants A and B
35
+ # const_reader :A, :B
36
+ def const_reader *consts
37
+ consts.flatten.each do |c|
38
+ class_exec(c.to_s, c.to_s.downcase) do |c_name, m_name|
39
+ define_method m_name do
40
+ self.singleton_class.const_get c_name
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,59 @@
1
+ # - encoding: utf-8 -
2
+ require 'scripref/const_reader'
3
+
4
+ module Scripref
5
+
6
+ # Mixin for parsing references in English.
7
+ module English
8
+
9
+ # Array of book names.
10
+ BOOK_NAMES = <<-END.strip.split(/,\s*/)
11
+ Genesis, Exodus, Leviticus, Numbers, Deuteronomy, Joshua, Judges,
12
+ Ruth, 1 Samuel, 2 Samuel, 1 Kings, 2 Kings, 1 Chronicles,
13
+ 2 Chronicles, Ezra, Nehemiah, Esther, Job, Psalms, Proverbs,
14
+ Ecclesiastes, Song of Songs, Isaiah, Jeremiah, Lamentations,
15
+ Ezekiel, Daniel, Hosea, Joel, Amos, Obadiah, Jonah, Micah, Nahum,
16
+ Habakkuk, Zephaniah, Haggai, Zechariah, Malachi,
17
+ Matthew, Mark, Luke, John, Acts, Romans, 1 Corinthians,
18
+ 2 Corinthians, Galatians, Ephesians, Philippians, Colossians,
19
+ 1 Thessalonians, 2 Thessalonians, 1 Timothy, 2 Timothy, Titus,
20
+ Philemon, Hebrews, James, 1 Peter, 2 Peter, 1 John, 2 John, 3 John,
21
+ Jude, Revelation
22
+ END
23
+
24
+ # Array of regular expressions to match book names.
25
+ BOOKS_RES = BOOK_NAMES.map do |bn|
26
+ Regexp.new(bn.gsub(/([^1-3A-Z])/, '\1?').gsub('.', '\.') << '\b\s*')
27
+ end
28
+
29
+ # Regular expression to match a book.
30
+ BOOK_RE = Regexp.new(BOOKS_RES.map {|re| '(^' << re.to_s << ')' }.join('|'))
31
+
32
+ # Regular expression to match a separator between chapter and verse.
33
+ CV_SEP_RE = /:\s*/o
34
+
35
+ # Regular expression to match a hyphen.
36
+ HYPHEN_RE = /\s*-\s*/o
37
+
38
+ # Regular expression to match a separator between passages.
39
+ PASS_SEP_RE = /;\s*/o
40
+
41
+ # Regular expression to match a separator between verses.
42
+ VERSE_SEP_RE = /,\s*/o
43
+
44
+ # Regular expression to match addons for a verse.
45
+ VERSE_ADDON_RE = /([ab]|ff?)\s*/o
46
+
47
+ pass = '([1-3]\s*)?[A-Z][a-z]+\.?\s*(\d+\s*[,.\-]\s*)*\d+\s*'
48
+
49
+ # Regular expression to parse a reference
50
+ REFERENCE_RE = /#{pass}(;\s*#{pass})*/o
51
+
52
+ # Define instance methods for the mixin.
53
+
54
+ extend ConstReader
55
+ const_reader constants
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,56 @@
1
+ # - encoding: utf-8 -
2
+ require 'scripref/const_reader'
3
+
4
+ module Scripref
5
+
6
+ # Mixin for parsing references in German.
7
+ module German
8
+
9
+ # Array of book names.
10
+ BOOK_NAMES = <<-END.strip.split(/,\s*/)
11
+ 1. Mose, 2. Mose, 3. Mose, 4. Mose, 5. Mose, Josua, Richter, Ruth, 1. Samuel, 2. Samuel,
12
+ 1. Könige, 2.Könige, 1. Chronika, 2. Chronika, Esra, Nehemia, Esther, Hiob, Psalm,
13
+ Sprüche, Prediger, Hohelied, Jesaja, Jeremia, Klagelieder, Hesekiel, Daniel, Hosea, Joel,
14
+ Amos, Obadja, Jona, Micha, Nahum, Habakuk, Zephanja, Haggai, Sacharja, Maleachi,
15
+ Matthäus, Markus, Lukas, Johannes, Apostelgeschichte, Römer, 1. Korinther, 2. Korinther,
16
+ Galater, Epheser, Philipper, Kolosser, 1. Thessalonicher, 2. Thessalonicher, 1. Timotheus,
17
+ 2. Timotheus, Titus, Philemon, Hebräer, Jakobus, 1. Petrus, 2. Petrus, 1. Johannes,
18
+ 2. Johannes, 3. Johannes, Judas, Offenbarung
19
+ END
20
+
21
+ # Array of regular expressions to match book names.
22
+ BOOKS_RES = BOOK_NAMES.map do |bn|
23
+ Regexp.new(bn.gsub(/([^1-5A-Z])/, '\1?').gsub('.', '\.') << '\b\s*')
24
+ end
25
+
26
+ # Regular expression to match a book.
27
+ BOOK_RE = Regexp.new(BOOKS_RES.map {|re| '(^' << re.to_s << ')' }.join('|'))
28
+
29
+ # Regular expression to match a separator between chapter and verse.
30
+ CV_SEP_RE = /,\s*/o
31
+
32
+ # Regular expression to match a hyphen.
33
+ HYPHEN_RE = /\s*-\s*/o
34
+
35
+ # Regular expression to match a separator between passages.
36
+ PASS_SEP_RE = /;\s*/o
37
+
38
+ # Regular expression to match a separator between verses.
39
+ VERSE_SEP_RE = /\.\s*/o
40
+
41
+ # Regular expression to match addons for a verse.
42
+ VERSE_ADDON_RE = /([ab]|ff?)\s*/o
43
+
44
+ pass = '([1-5]\.?\s*)?[A-Z][a-zäöü]+\.?\s*(\d+\s*[,.\-]\s*)*\d+\s*'
45
+
46
+ # Regular expression to parse a reference
47
+ REFERENCE_RE = /#{pass}(;\s*#{pass})*/o
48
+
49
+ # Define instance methods for the mixin.
50
+
51
+ extend ConstReader
52
+ const_reader constants
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,198 @@
1
+ # - encoding: utf-8 -
2
+ require 'strscan'
3
+
4
+ module Scripref
5
+
6
+ class Parser < StringScanner
7
+
8
+ NUMBER_RE = /\d+\s*/
9
+
10
+ # @param mods on ore more modules to include
11
+ def initialize *mods
12
+ @mods = mods
13
+ mods.each do |m|
14
+ extend m
15
+ end
16
+ end
17
+
18
+ # Parsing a string of a scripture reference
19
+ # @param str string to parse
20
+ def parse str
21
+ self.string = str
22
+ @result = []
23
+ start
24
+ end
25
+
26
+ # start of parsing grammer
27
+ def start
28
+ @text = ''
29
+ b1 or []
30
+ end
31
+
32
+ # try to parse first book
33
+ def b1
34
+ s = scan(book_re) or return nil
35
+ @text << s
36
+ @b1 = @b2 = book2num(s)
37
+ @c1 = @v1 = 1
38
+ @c2 = @v2 = :max
39
+
40
+ epsilon or c1 or nil
41
+ end
42
+
43
+ # try parse first chapter
44
+ def c1
45
+ s = scan(NUMBER_RE) or return nil
46
+ @text << s
47
+ @c1 = @c2 = s.to_i
48
+
49
+ if cv_sep
50
+ v1 or nil
51
+ elsif hyphen
52
+ c2 or nil
53
+ elsif pass_sep
54
+ b1 or c1
55
+ else
56
+ epsilon or nil
57
+ end
58
+ end
59
+
60
+ # try to parse first verse
61
+ def v1
62
+ s = scan(NUMBER_RE) or return nil
63
+ @text << s
64
+ @v1 = @v2 = s.to_i
65
+
66
+ if addon = verse_addon
67
+ case addon
68
+ when :f, :ff
69
+ @v2 = addon
70
+ end
71
+ end
72
+
73
+ if hyphen
74
+ if check(Regexp.new(NUMBER_RE.source + cv_sep_re.source))
75
+ c2
76
+ else
77
+ v2 or nil
78
+ end
79
+ elsif pass_sep
80
+ b1 or c1
81
+ elsif verse_sep
82
+ v1
83
+ else
84
+ epsilon or nil
85
+ end
86
+ end
87
+
88
+ # try to parse second chapter
89
+ def c2
90
+ s = scan(NUMBER_RE) or return nil
91
+ @text << s
92
+ @c2 = s.to_i
93
+
94
+ if cv_sep
95
+ v2 or nil
96
+ else
97
+ epsilon or nil
98
+ end
99
+ end
100
+
101
+ # try to parse second verse
102
+ def v2
103
+ s = scan(NUMBER_RE) or return nil
104
+ @text << s
105
+ @v2 = s.to_i
106
+
107
+ if verse_sep
108
+ v1
109
+ elsif pass_sep
110
+ b1 or c1
111
+ else
112
+ epsilon or nil
113
+ end
114
+ end
115
+
116
+ # try to parse <tt>end of string</tt>
117
+ def epsilon
118
+ if eos?
119
+ push_passage
120
+ return @result
121
+ end
122
+ nil
123
+ end
124
+
125
+ # try to parse separator or chapter and verse
126
+ def cv_sep
127
+ if s = scan(cv_sep_re)
128
+ @text << s
129
+ s
130
+ else
131
+ nil
132
+ end
133
+ end
134
+
135
+ # try to parse hyphen
136
+ def hyphen
137
+ if s = scan(hyphen_re)
138
+ @text << s
139
+ s
140
+ else
141
+ nil
142
+ end
143
+ end
144
+
145
+ # try to parse separator between passages
146
+ def pass_sep
147
+ if s = scan(pass_sep_re)
148
+ push_passage
149
+ @result << s
150
+ s
151
+ else
152
+ nil
153
+ end
154
+ end
155
+
156
+ # try to parse verse separator
157
+ def verse_sep
158
+ if s = scan(verse_sep_re)
159
+ push_passage
160
+ @result << s
161
+ s
162
+ else
163
+ nil
164
+ end
165
+ end
166
+
167
+ # try to parse addons for verses
168
+ def verse_addon
169
+ if s = scan(verse_addon_re)
170
+ @text << s
171
+ s.to_sym
172
+ else
173
+ nil
174
+ end
175
+ end
176
+
177
+ def push_passage
178
+ @result << Passage.new(@text, @b1, @c1, @v1, @b2, @c2, @v2)
179
+ @text = ''
180
+ end
181
+
182
+ def book2num str
183
+ return nil unless book_re =~str
184
+ books_res.each_with_index do |re, i|
185
+ if str =~ Regexp.new('^' << re.to_s << '$')
186
+ num = i + 1
187
+ return num
188
+ end
189
+ end
190
+ end
191
+
192
+ def inspect
193
+ "#<#{self.class} #{@mods.inspect}>"
194
+ end
195
+
196
+ end
197
+
198
+ end
@@ -0,0 +1,60 @@
1
+ # - encoding: utf-8 -
2
+ require 'strscan'
3
+ require 'scripref/parser'
4
+
5
+ module Scripref
6
+
7
+ class Processor
8
+
9
+ include Enumerable
10
+
11
+ attr_accessor :text
12
+
13
+ # @param text text to parse
14
+ # @param mods on ore more modules to include in processor and parser
15
+ def initialize text=nil, *mods
16
+ @text = text
17
+ @mods = mods
18
+ mods.each do |m|
19
+ extend m
20
+ end
21
+ @parser = Parser.new(*mods)
22
+ end
23
+
24
+ # Iterate over each parsed reference if block given, gets an iterator
25
+ # over each parsed reference otherwise.
26
+ def each_ref
27
+ if block_given?
28
+ scanner = StringScanner.new(text)
29
+ while scanner.scan_until(reference_re)
30
+ yield @parser.parse(scanner.matched)
31
+ end
32
+ self
33
+ else
34
+ enum_for :each_ref
35
+ end
36
+ end
37
+
38
+ # Iterate over each piece of <tt>str</tt> (text and parsed references)
39
+ # if block given, gets an iterator over the pieces otherwise.
40
+ def each
41
+ if block_given?
42
+ scanner = StringScanner.new(text)
43
+ while scanner.scan(/(.*?)(#{Regexp.new(reference_re.to_s)})/)
44
+ yield scanner[1]
45
+ yield @parser.parse(scanner[2])
46
+ end
47
+ yield scanner.rest if scanner.rest
48
+ self
49
+ else
50
+ enum_for :each
51
+ end
52
+ end
53
+
54
+ def inspect
55
+ "#<#{self.class} #{@mods.inspect}>"
56
+ end
57
+
58
+ end
59
+
60
+ end
data/lib/scripref.rb ADDED
@@ -0,0 +1,17 @@
1
+ # - encoding: utf-8 -
2
+ require 'scripref/parser'
3
+ require 'scripref/processor'
4
+ require 'scripref/english'
5
+ require 'scripref/german'
6
+
7
+ module Scripref
8
+
9
+ VERSION = '0.2.0'
10
+
11
+ Passage = Struct.new(:text, :b1, :c1, :v1, :b2, :c2, :v2)
12
+
13
+ class Passage
14
+ alias to_s text
15
+ end
16
+
17
+ end
@@ -0,0 +1,43 @@
1
+ # - encoding: utf-8 -
2
+ require 'test/unit'
3
+ require 'scripref/english'
4
+
5
+ class TestEnglish < Test::Unit::TestCase
6
+
7
+ include Scripref::English
8
+
9
+ def test_book_re
10
+ assert_match 'Genesis', book_re
11
+ assert_match 'Exodus', book_re
12
+ assert_match 'Matthew', book_re
13
+ assert_match '2 Timothy', book_re
14
+ assert_not_match '2 2 Timothy', book_re
15
+ assert_match 'Revelation', book_re
16
+ assert_not_match 'something', book_re
17
+ assert_match 'Gen', book_re
18
+ assert_match 'Ex', book_re
19
+ assert_match 'Mat', book_re
20
+ assert_match '2 Tim', book_re
21
+ assert_match 'Rev', book_re
22
+ end
23
+
24
+ def test_book2num
25
+ assert_book_num 1, 'Genesis'
26
+ assert_book_num 40, 'Matthew'
27
+ assert_book_num 66, 'Revelation'
28
+ assert_book_num 1, 'Gen'
29
+ assert_book_num 1, 'Ge'
30
+ assert_book_num 1, 'G'
31
+ assert_book_num 55, '2 Tim'
32
+ assert_book_num 55, '2Tim'
33
+ assert_book_num 55, '2Tm'
34
+ assert_book_num 40, 'Mat'
35
+ assert_book_num 66, 'Rev'
36
+ end
37
+
38
+ def assert_book_num num, str
39
+ @parser ||= Scripref::Parser.new(Scripref::English)
40
+ assert_equal num, @parser.parse(str).first.b1
41
+ end
42
+
43
+ end
@@ -0,0 +1,40 @@
1
+ # - encoding: utf-8 -
2
+ require 'test/unit'
3
+ require 'scripref/german'
4
+
5
+ class TestGerman < Test::Unit::TestCase
6
+
7
+ include Scripref::German
8
+
9
+ def test_book_re
10
+ assert_match '1. Mose', book_re
11
+ assert_match '2. Mose', book_re
12
+ assert_match 'Matthäus', book_re
13
+ assert_match '2. Timotheus', book_re
14
+ assert_not_match '2. 2. Timotheus', book_re
15
+ assert_match 'Offenbarung', book_re
16
+ assert_not_match 'something', book_re
17
+ assert_match '1. Mo', book_re
18
+ assert_match '2.Mo', book_re
19
+ assert_match 'Mat', book_re
20
+ assert_match '2. Tim', book_re
21
+ assert_match 'Off', book_re
22
+ end
23
+
24
+ def test_book2num
25
+ assert_book_num 1, '1. Mose'
26
+ assert_book_num 40, 'Matthäus'
27
+ assert_book_num 66, 'Offenbarung'
28
+ assert_book_num 1, '1. Mo'
29
+ assert_book_num 1, '1.Mo'
30
+ assert_book_num 1, '1M'
31
+ assert_book_num 40, 'Mat'
32
+ assert_book_num 66, 'Off'
33
+ end
34
+
35
+ def assert_book_num num, str
36
+ @parser ||= Scripref::Parser.new(Scripref::German)
37
+ assert_equal num, @parser.parse(str).first.b1
38
+ end
39
+
40
+ end
@@ -0,0 +1,166 @@
1
+ # - encoding: utf-8 -
2
+ require 'test/unit'
3
+ require 'scripref'
4
+
5
+ class TestParser < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @parser = Scripref::Parser.new(Scripref::German)
9
+ end
10
+
11
+ def test_only_book
12
+ text = 'Ruth'
13
+ assert_parsed_ast_for_text [pass(text, 8, 1, 1, 8, :max, :max)], text
14
+ end
15
+
16
+ def test_book_and_chapter
17
+ text = 'Ruth 2'
18
+ assert_parsed_ast_for_text [pass(text, 8, 2, 1, 8, 2, :max)], text
19
+ end
20
+
21
+ def test_book_chapter_and_verse
22
+ text = 'Ruth 2,5'
23
+ assert_parsed_ast_for_text [pass(text, 8, 2, 5, 8, 2, 5)], text
24
+ end
25
+
26
+ def test_verse_range
27
+ text = 'Ruth 2,5-11'
28
+ assert_parsed_ast_for_text [pass(text, 8, 2, 5, 8, 2, 11)], text
29
+ end
30
+
31
+ def test_chapter_verse_range
32
+ text = 'Ruth 2,5-3,7'
33
+ assert_parsed_ast_for_text [pass(text, 8, 2, 5, 8, 3, 7)], text
34
+ end
35
+
36
+ def test_chapter_range
37
+ text = 'Ruth 2-3'
38
+ assert_parsed_ast_for_text [pass(text, 8, 2, 1, 8, 3, :max)], text
39
+ end
40
+
41
+ def test_one_following_verse
42
+ text = 'Ruth 2,5f'
43
+ assert_parsed_ast_for_text [pass(text, 8, 2, 5, 8, 2, :f)], text
44
+ end
45
+
46
+ def test_more_following_verse
47
+ text = 'Ruth 2,5ff'
48
+ assert_parsed_ast_for_text [pass(text, 8, 2, 5, 8, 2, :ff)], text
49
+ end
50
+
51
+ ######################################################################
52
+ # more than one reference
53
+ ######################################################################
54
+
55
+ def test_two_complete_refs
56
+ text = 'Ruth 2,1; Markus 4,8'
57
+ t1, t2 = text.split('; ')
58
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 1), '; ', pass(t2, 41, 4, 8, 41, 4, 8)], text
59
+ end
60
+
61
+ def test_two_refs_same_book
62
+ text = 'Ruth 2,1; 5,4'
63
+ t1, t2 = text.split('; ')
64
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 1), '; ', pass(t2, 8, 5, 4, 8, 5, 4)], text
65
+ end
66
+
67
+ def test_two_chapters_same_book
68
+ text = 'Ruth 2; 5'
69
+ t1, t2 = text.split('; ')
70
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, :max), '; ', pass(t2, 8, 5, 1, 8, 5, :max)], text
71
+ end
72
+
73
+ def test_two_chapters_different_book
74
+ text = 'Ruth 2; Markus 4'
75
+ t1, t2 = text.split('; ')
76
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, :max), '; ', pass(t2, 41, 4, 1, 41, 4, :max)], text
77
+ end
78
+
79
+ def test_two_verses
80
+ text = 'Ruth 2,5.11'
81
+ t1, t2 = text.split('.')
82
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 5, 8, 2, 5), '.', pass(t2, 8, 2, 11, 8, 2, 11)], text
83
+ end
84
+
85
+ ######################################################################
86
+ # mixed variants of more than one reference
87
+ ######################################################################
88
+
89
+ def test_verse_range_and_separated_verse
90
+ text = 'Ruth 2,1-3.11'
91
+ t1, t2 = text.split('.')
92
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 3), '.', pass(t2, 8, 2, 11, 8, 2, 11)], text
93
+ end
94
+
95
+ def test_separate_verse_and_verse_range
96
+ text = 'Ruth 2,1.3-11'
97
+ t1, t2 = text.split('.')
98
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 1), '.', pass(t2, 8, 2, 3, 8, 2, 11)], text
99
+ end
100
+
101
+ def test_two_verse_ranges
102
+ text = 'Ruth 2,1-3.7-11'
103
+ t1, t2 = text.split('.')
104
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 3), '.', pass(t2, 8, 2, 7, 8, 2, 11)], text
105
+ end
106
+
107
+ def test_two_verse_range_different_books
108
+ text = 'Ruth 2,1-11; Markus 4,3-7'
109
+ t1, t2 = text.split('; ')
110
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 11), '; ', pass(t2, 41, 4, 3,41, 4, 7)], text
111
+ end
112
+
113
+ def test_two_verse_range_different_chapters
114
+ text = 'Ruth 2,1-11; 3,10-19'
115
+ t1, t2 = text.split('; ')
116
+ assert_parsed_ast_for_text [pass(t1, 8, 2, 1, 8, 2, 11), '; ', pass(t2, 8, 3, 10, 8, 3, 19)], text
117
+ end
118
+
119
+ ######################################################################
120
+ # complex variants of references
121
+ ######################################################################
122
+
123
+ def test_complex_example
124
+ text = 'Ruth 2,1-11.15; 3,7.9-12; Markus 4; 5,3.18-21'
125
+ t1, t2, t3, t4, t5, t6, t7 = text.split(/; |\./)
126
+ ast = [
127
+ pass(t1, 8, 2, 1, 8, 2, 11), '.',
128
+ pass(t2, 8, 2, 15, 8, 2, 15), '; ',
129
+ pass(t3, 8, 3, 7, 8, 3, 7), '.',
130
+ pass(t4, 8, 3, 9, 8, 3, 12), '; ',
131
+ pass(t5, 41, 4, 1, 41, 4, :max), '; ',
132
+ pass(t6, 41, 5, 3, 41, 5, 3), '.',
133
+ pass(t7, 41, 5, 18, 41, 5, 21)
134
+ ]
135
+ assert_parsed_ast_for_text ast, text
136
+ end
137
+
138
+ protected
139
+
140
+ def pass *args
141
+ Scripref::Passage.new(*args)
142
+ end
143
+
144
+ def assert_equal_passage expected, actual
145
+ assert_equal expected.text, actual.text, 'Parsed text'
146
+ assert_equal expected.b1, actual.b1, 'First book'
147
+ assert_equal expected.c1, actual.c1, 'First chapter'
148
+ assert_equal expected.v1, actual.v1, 'First verse'
149
+ assert_equal expected.b2, actual.b2, 'Second book'
150
+ assert_equal expected.c2, actual.c2, 'Second chapter'
151
+ assert_equal expected.v2, actual.v2, 'Second verse'
152
+ end
153
+
154
+ def assert_parsed_ast_for_text expected_ast, text
155
+ res = @parser.parse(text)
156
+ assert_equal expected_ast.size, res.size, 'Array size of AST'
157
+ expected_ast.zip(res) do |expected_elem, actual_elem|
158
+ if !expected_elem.kind_of?(String)
159
+ assert_equal_passage expected_elem, actual_elem
160
+ else
161
+ assert_equal expected_elem, actual_elem
162
+ end
163
+ end
164
+ end
165
+
166
+ end
@@ -0,0 +1,41 @@
1
+ # - encoding: utf-8 -
2
+ require 'test/unit'
3
+ require 'scripref'
4
+
5
+ class TestProcessor < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @text = 'Some text Mt 1,1 and Mr 2 and so on ...'
9
+ @mt = [Scripref::Passage.new('Mt 1,1 ', 40, 1, 1, 40, 1, 1)]
10
+ @mr = [Scripref::Passage.new('Mr 2 ', 41, 2, 1, 41, 2, :max)]
11
+ @processor = Scripref::Processor.new(@text, Scripref::German)
12
+ @chunks = ['Some text ', @mt, 'and ', @mr, 'and so on ...']
13
+ end
14
+
15
+ def test_each_with_block
16
+ @processor.each do |chunk|
17
+ assert_equal @chunks.shift, chunk
18
+ end
19
+ end
20
+
21
+ def test_each_without_block
22
+ enum = @processor.each
23
+ assert_kind_of Enumerator, enum
24
+ assert_equal @chunks, enum.to_a
25
+ end
26
+
27
+ def test_each_ref_with_block
28
+ refs = @chunks.select {|c| c.kind_of? Array}
29
+ @processor.each_ref do |ref|
30
+ assert_equal refs.shift, ref
31
+ end
32
+ end
33
+
34
+ def test_each_ref_without_block
35
+ enum = @processor.each_ref
36
+ refs = @chunks.select {|c| c.kind_of? Array}
37
+ assert_kind_of Enumerator, enum
38
+ assert_equal refs, enum.to_a
39
+ end
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scripref
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.2.0
6
+ platform: ruby
7
+ authors:
8
+ - Jan Friedrich
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-03-28 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: ""
17
+ email:
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - CHANGELOG
26
+ - LICENSE
27
+ - Rakefile
28
+ - lib/scripref/const_reader.rb
29
+ - lib/scripref/english.rb
30
+ - lib/scripref/german.rb
31
+ - lib/scripref/parser.rb
32
+ - lib/scripref/processor.rb
33
+ - lib/scripref.rb
34
+ - test/test_english.rb
35
+ - test/test_german.rb
36
+ - test/test_parser.rb
37
+ - test/test_processor.rb
38
+ homepage: http://gitorious.org/scripref
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.19
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Library for parsing scripture references in real texts.
65
+ test_files: []
66
+