scripref 0.2.0

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