scripref 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e65b203f6111b6313c92ed4fc32753ffcf084e0f
4
- data.tar.gz: 362dddef75cfb666e6e287428fcf2e4e911d3881
3
+ metadata.gz: 373b4b572bcb6fadc58872590bc98e75f5bebe3c
4
+ data.tar.gz: be215c400b76c7327bdeb63b1bff52917c854eca
5
5
  SHA512:
6
- metadata.gz: 705ab5f7fbbce60d4d1dcc8bf4f046a5b1e0f943dd30172a89dbede3685ca9b141b485ac01329bc51d70fa25418daa5c494bded5246a9b876256629c70d823fe
7
- data.tar.gz: 0e5de450e1a2e2d2f267e01f33476959f8cff1d9966e312ff6d01ffbb45b9a94a12df41c0a482467ef821f29edbf1453943d3545749daa6ebfee5acd16604216
6
+ metadata.gz: fc24a4742a42477c252edd1c06fb52f2b41bb6411479556921b39e2512082accc7ce9270d0d87dc6b86032ba13847f3bf9074268b18ac0cce789cd90faf8918c
7
+ data.tar.gz: 31e56ca2e1000abc2a8bdcdf6b7af0c99b6c49e604dbdd0f530dd02416b4e1d188884ff4428e466c3b367439357876c4b66d4244ca61e42e6bfb4a59de283608
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ 0.8.0
2
+ Formatting of verse addons implemented.
3
+ Refactoring: Rename methods in Formatter to distinguish between format_* and process_*.
4
+ Refactoring: Move method Scripref.book_has_only_one_chapter to mixins.
5
+ New methods Parser#chapter_re and #verse_re.
6
+ New method Parser#special_abbrev_mapping to allow to parse special abbreviations, for example "Phil" to "Philipper" in German.
7
+ Some bugs fixed.
8
+
1
9
  0.7.1
2
10
  Add Psalmen as alternative German book name.
3
11
  Add E-Mail address.
@@ -37,7 +37,14 @@ module ConstReader
37
37
  consts.flatten.each do |c|
38
38
  class_exec(c.to_s, c.to_s.downcase) do |c_name, m_name|
39
39
  define_method m_name do
40
- self.singleton_class.const_get c_name
40
+ ivar = '@' << m_name
41
+ if instance_variable_defined? ivar
42
+ return instance_variable_get(ivar)
43
+ else
44
+ val = self.singleton_class.const_get c_name
45
+ instance_variable_set ivar, val
46
+ return val
47
+ end
41
48
  end
42
49
  end
43
50
  end
@@ -50,6 +50,16 @@ module Scripref
50
50
  # Regular expression to parse a reference
51
51
  REFERENCE_RE = /#{pass}(;\s*#{pass})*/o
52
52
 
53
+ # Check if book has only one chapter
54
+ # @param book book as number
55
+ def book_has_only_one_chapter? book
56
+ [31, 63, 64, 65].include?(book)
57
+ end
58
+
59
+ # Generate attr_reader methods for all constants
60
+ extend ConstReader
61
+ const_reader constants
62
+
53
63
  end
54
64
 
55
65
  end
@@ -4,16 +4,13 @@ module Scripref
4
4
 
5
5
  class Formatter
6
6
 
7
+ attr_accessor :cv_separator, :hyphen_separator, :pass_separator
8
+
9
+
7
10
  # @param mods one or more modules to include
8
11
  def initialize *mods
9
12
  @mods = mods
10
- mods.each do |m|
11
- m.class_eval do
12
- extend ConstReader
13
- const_accessor constants
14
- end
15
- extend m
16
- end
13
+ mods.each {|m| extend m}
17
14
  end
18
15
 
19
16
  # Formats a reference (array of passages)
@@ -22,56 +19,64 @@ module Scripref
22
19
  @result = ''
23
20
  reference.flatten.each do |pass|
24
21
  @pass = pass
25
- format_passage
22
+ process_passage
26
23
  end
27
24
  @result
28
25
  end
29
26
 
30
- def format_passage
31
- @changed = false
32
- format_b1
33
- end
34
-
35
27
  def format_book num
36
28
  Array(book_names[num - 1]).first
37
29
  end
38
30
 
39
- def format_b1
31
+ private
32
+
33
+ def process_passage
34
+ @changed = false
35
+ process_b1
36
+ end
37
+
38
+ def process_b1
40
39
  b1 = @pass.b1
41
40
  if @last_b != b1
42
41
  @result << format_book(b1)
43
42
  @last_b = b1
44
43
  @changed = true
45
44
  end
46
- format_c1
45
+ process_c1
47
46
  end
48
47
 
49
- def format_c1
48
+ def process_c1
50
49
  c1 = @pass.c1
51
50
  if c1 && (@changed || @last_c != c1)
52
51
  @result << ' '
53
- if ! Scripref.book_has_only_one_chapter?(@pass.b1)
52
+ if ! book_has_only_one_chapter?(@pass.b1)
54
53
  @result << c1.to_s
55
54
  end
56
55
  @last_c = c1
57
56
  @changed = true
58
57
  end
59
- format_v1
58
+ process_v1
60
59
  end
61
60
 
62
- def format_v1
61
+ def process_v1
63
62
  v1 = @pass.v1
64
63
  if v1 && (@changed || @last_v != v1)
65
- if ! Scripref.book_has_only_one_chapter?(@pass.b1)
64
+ if ! book_has_only_one_chapter?(@pass.b1)
66
65
  @result << cv_separator
67
66
  end
68
67
  @result << v1.to_s
69
68
  @last_v = v1
69
+ process_a1
70
70
  end
71
- format_b2
71
+ process_b2
72
72
  end
73
73
 
74
- def format_b2
74
+ def process_a1
75
+ a1 = @pass.a1
76
+ @result << a1.to_s if a1
77
+ end
78
+
79
+ def process_b2
75
80
  @changed = false
76
81
  @hyphen = false
77
82
  b2 = @pass.b2
@@ -82,10 +87,10 @@ module Scripref
82
87
  @changed = true
83
88
  @hyphen = true
84
89
  end
85
- format_c2
90
+ process_c2
86
91
  end
87
92
 
88
- def format_c2
93
+ def process_c2
89
94
  c2 = @pass.c2
90
95
  if c2 && (@changed || @last_c != c2)
91
96
  if @hyphen
@@ -94,20 +99,20 @@ module Scripref
94
99
  @result << hyphen_separator
95
100
  @hyphen = true
96
101
  end
97
- if ! Scripref.book_has_only_one_chapter?(@pass.b2)
102
+ if ! book_has_only_one_chapter?(@pass.b2)
98
103
  @result << c2.to_s
99
104
  end
100
105
  @last_c = c2
101
106
  @changed = true
102
107
  end
103
- format_v2
108
+ process_v2
104
109
  end
105
110
 
106
- def format_v2
111
+ def process_v2
107
112
  v2 = @pass.v2
108
113
  if v2 && (@changed || @last_v != v2)
109
114
  if @hyphen
110
- if ! Scripref.book_has_only_one_chapter?(@pass.b2)
115
+ if ! book_has_only_one_chapter?(@pass.b2)
111
116
  @result << cv_separator
112
117
  end
113
118
  else
@@ -117,9 +122,15 @@ module Scripref
117
122
  @result << v2.to_s
118
123
  @last_v = @v2
119
124
  @changed = true
125
+ process_a2
120
126
  end
121
127
  end
122
128
 
129
+ def process_a2
130
+ a2 = @pass.a2
131
+ @result << a2.to_s if a2
132
+ end
133
+
123
134
  alias << format
124
135
 
125
136
  end
@@ -47,6 +47,19 @@ module Scripref
47
47
  # Regular expression to parse a reference
48
48
  REFERENCE_RE = /#{pass}(;\s*#{pass})*/o
49
49
 
50
+ # Check if book has only one chapter
51
+ # @param book book as number
52
+ def book_has_only_one_chapter? book
53
+ [31, 63, 64, 65].include?(book)
54
+ end
55
+
56
+ # Hash with special abbreviations
57
+ SPECIAL_ABBREV_MAPPING = {'Phil' => 'Philipper'}
58
+
59
+ # Generate attr_reader methods for all constants
60
+ extend ConstReader
61
+ const_reader constants
62
+
50
63
  end
51
64
 
52
65
  end
@@ -7,18 +7,29 @@ module Scripref
7
7
 
8
8
  attr_reader :error
9
9
 
10
- NUMBER_RE = /\d+\s*/
10
+ NUMBER_RE = /\d+\s*/o
11
11
 
12
12
  # @param mods one or more modules to include
13
13
  def initialize *mods
14
14
  @mods = mods
15
- mods.each do |m|
16
- m.class_eval do
17
- extend ConstReader
18
- const_reader constants
19
- end
20
- extend m
21
- end
15
+ mods.each {|m| extend m}
16
+ end
17
+
18
+ # Regular expression to match a chapter
19
+ def chapter_re
20
+ NUMBER_RE
21
+ end
22
+
23
+ # Regular expression to match a verse
24
+ def verse_re
25
+ NUMBER_RE
26
+ end
27
+
28
+ # Hash with special abbreviations
29
+ # for example {'Phil' => 'Philipper'}
30
+ # usual overwritten in Mixins
31
+ def special_abbrev_mapping
32
+ Hash.new
22
33
  end
23
34
 
24
35
  # Parsing a string of a scripture reference
@@ -42,12 +53,12 @@ module Scripref
42
53
  @text << s
43
54
  @b1 = @b2 = abbrev2num(s)
44
55
 
45
- if check(Regexp.new(NUMBER_RE.source + cv_sep_re.source))
56
+ if check(Regexp.new(chapter_re.source + cv_sep_re.source))
46
57
  @c1 = @v1 = nil
47
58
  @c2 = @v2 = nil
48
59
  c1
49
60
  else
50
- if Scripref.book_has_only_one_chapter?(@b1)
61
+ if book_has_only_one_chapter?(@b1)
51
62
  @c1 = @c2 = 1
52
63
  epsilon or (hyphen and b2) or v1 or give_up 'EOS or hyphen and book or verse expected!'
53
64
  else
@@ -60,7 +71,7 @@ module Scripref
60
71
 
61
72
  # try parse first chapter
62
73
  def c1
63
- s = scan(NUMBER_RE) or return nil
74
+ s = scan(chapter_re) or return nil
64
75
  @text << s
65
76
  @c1 = @c2 = s.to_i
66
77
 
@@ -77,7 +88,7 @@ module Scripref
77
88
 
78
89
  # try to parse first verse
79
90
  def v1
80
- s = scan(NUMBER_RE) or return nil
91
+ s = scan(verse_re) or return nil
81
92
  @text << s
82
93
  @v1 = @v2 = s.to_i
83
94
 
@@ -92,7 +103,7 @@ module Scripref
92
103
 
93
104
  if hyphen
94
105
  b2 or (
95
- if check(Regexp.new(NUMBER_RE.source + cv_sep_re.source))
106
+ if check(Regexp.new(chapter_re.source + cv_sep_re.source))
96
107
  c2
97
108
  else
98
109
  v2 or give_up 'Chapter or verse expected!'
@@ -113,10 +124,10 @@ module Scripref
113
124
  @b2 = abbrev2num(s)
114
125
  @c2 = @v2 = nil
115
126
 
116
- if check(Regexp.new(NUMBER_RE.source + cv_sep_re.source))
127
+ if check(Regexp.new(chapter_re.source + cv_sep_re.source))
117
128
  c2
118
129
  else
119
- if Scripref.book_has_only_one_chapter?(@b2)
130
+ if book_has_only_one_chapter?(@b2)
120
131
  @c2 = 1
121
132
  epsilon or v2 or give_up 'EOS or chapter or verse expected!'
122
133
  else
@@ -127,7 +138,7 @@ module Scripref
127
138
 
128
139
  # try to parse second chapter
129
140
  def c2
130
- s = scan(NUMBER_RE) or return nil
141
+ s = scan(chapter_re) or return nil
131
142
  @text << s
132
143
  @c2 = s.to_i
133
144
 
@@ -140,7 +151,7 @@ module Scripref
140
151
 
141
152
  # try to parse second verse
142
153
  def v2
143
- s = scan(NUMBER_RE) or return nil
154
+ s = scan(verse_re) or return nil
144
155
  @text << s
145
156
  @v2 = s.to_i
146
157
 
@@ -241,11 +252,18 @@ module Scripref
241
252
  end
242
253
 
243
254
  def abbrev2book str
255
+ s = str.strip
256
+ if name = special_abbrev_mapping[s]
257
+ return name
258
+ end
244
259
  @books_str ||= ('#' << book_names.flatten.join('#') << '#')
245
- pattern = str.strip.chars.map {|c| Regexp.escape(c) << '[^#]*'}.join
260
+ pattern = s.chars.map {|c| Regexp.escape(c) << '[^#]*'}.join
246
261
  re = /(?<=#)#{pattern}(?=#)/
247
262
  names = @books_str.scan(re)
248
- give_up format("Abbreviation %s is ambiguous it matches %s!", str, names.join(', ')) unless names.size == 1
263
+ if names.size != 1
264
+ unscan
265
+ give_up format("Abbreviation %s is ambiguous it matches %s!", s, names.join(', '))
266
+ end
249
267
  names.first
250
268
  end
251
269
 
@@ -15,9 +15,7 @@ module Scripref
15
15
  def initialize text=nil, *mods
16
16
  @text = text
17
17
  @mods = mods
18
- mods.each do |m|
19
- extend m
20
- end
18
+ mods.each {|m| extend m}
21
19
  @parser = Parser.new(*mods)
22
20
  end
23
21
 
data/lib/scripref.rb CHANGED
@@ -8,7 +8,7 @@ require 'scripref/german'
8
8
 
9
9
  module Scripref
10
10
 
11
- VERSION = '0.7.1'
11
+ VERSION = '0.8.0'
12
12
 
13
13
  Passage = Struct.new(:text, :b1, :c1, :v1, :b2, :c2, :v2, :a1, :a2) do
14
14
 
@@ -39,9 +39,4 @@ module Scripref
39
39
  class PassSep < Sep; end
40
40
  class VerseSep < Sep; end
41
41
 
42
- # check if the book has only one chapter
43
- def self.book_has_only_one_chapter? book
44
- [31, 63, 64, 65].include?(book)
45
- end
46
-
47
42
  end
@@ -89,7 +89,7 @@ class TestFormatter < Test::Unit::TestCase
89
89
  check_formatting
90
90
  end
91
91
 
92
- def test_changed_hyphen_separator
92
+ def test_attr_writer_overrides_value_of_mixin
93
93
  @german = '1. Korinther 1,1 - 2. Korinther 13,13'
94
94
  @english = '1 Corinthians 1:1 - 2 Corinthians 13:13'
95
95
  @german_formatter.hyphen_separator = ' - '
@@ -102,6 +102,24 @@ class TestFormatter < Test::Unit::TestCase
102
102
  assert_equal 'Zefanja 1,8', @german_formatter.format(ast)
103
103
  end
104
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
+
105
123
  private
106
124
 
107
125
  def check_formatting
data/test/test_german.rb CHANGED
@@ -36,6 +36,7 @@ class TestGerman < Test::Unit::TestCase
36
36
  assert_book_num 1, '1.Mo'
37
37
  assert_book_num 1, '1M'
38
38
  assert_book_num 40, 'Mat'
39
+ assert_book_num 50, 'Phil'
39
40
  assert_book_num 66, 'Off'
40
41
  end
41
42
 
data/test/test_parser.rb CHANGED
@@ -229,4 +229,28 @@ class TestParser < Test::Unit::TestCase
229
229
  assert_equal formated_error, @parser.format_error
230
230
  end
231
231
 
232
+ def test_error_message_for_unambiguous_book
233
+ text = 'Ruth 2,4; M 3,8'
234
+ begin
235
+ @parser.parse text
236
+ rescue Scripref::ParserError
237
+ end
238
+ assert_match /^Abbreviation M is ambiguous/, @parser.error
239
+ formated_error = "Abbreviation M is ambiguous it matches Micha, Maleachi, Matthäus, Markus!\nRuth 2,4; M 3,8\n ^"
240
+ assert_equal formated_error, @parser.format_error
241
+ end
242
+
243
+ ######################################################################
244
+ # special things
245
+ ######################################################################
246
+
247
+ def test_special_book_abbrev
248
+ # Abbrev "Phil" would technical match "Philipper" and "Philemon"
249
+ # and therefore throw a ParserError because it's ambiguous,
250
+ # but in German the abbrev "Phil" is generally used for "Philipper",
251
+ # so the parser should be able to support such behaviour.
252
+ text = 'Phil 4,4'
253
+ assert_parsed_ast_for_text [pass(text, 50, 4, 4, 50, 4, 4)], text
254
+ end
255
+
232
256
  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.7.1
4
+ version: 0.8.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-06 00:00:00.000000000 Z
11
+ date: 2016-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rim