Class: Scripref::Parser
- Inherits:
-
StringScanner
- Object
- StringScanner
- Scripref::Parser
- Includes:
- BasicMethods
- Defined in:
- lib/scripref/parser.rb
Constant Summary
Constants included from BasicMethods
Instance Attribute Summary collapse
-
#error ⇒ Object
readonly
Returns the value of attribute error.
Instance Method Summary collapse
- #abbrev2book(str) ⇒ Object
- #abbrev2osis_book_id(str) ⇒ Object
-
#b1 ⇒ Object
try to parse first book.
-
#b2 ⇒ Object
try to parse second book.
-
#c1 ⇒ Object
try parse first chapter.
-
#c2 ⇒ Object
try to parse second chapter.
-
#cv_sep ⇒ Object
try to parse separator or chapter and verse.
-
#epsilon ⇒ Object
try to parse
end of string
. - #format_error ⇒ Object
- #give_up(msg) ⇒ Object
-
#hyphen ⇒ Object
try to parse hyphen.
- #init_str2osis_book_id ⇒ Object
-
#initialize(*mods) ⇒ Parser
constructor
A new instance of Parser.
- #inspect ⇒ Object
-
#parse(str) ⇒ Object
(also: #<<)
Parsing a string of a scripture reference.
-
#pass_sep ⇒ Object
try to parse separator between passages.
- #push_passage ⇒ Object
-
#start ⇒ Object
start of parsing grammer.
- #str2osis_book_id(str) ⇒ Object
-
#v1 ⇒ Object
try to parse first verse.
-
#v2 ⇒ Object
try to parse second verse.
-
#verse_addon ⇒ Object
try to parse addons for verses.
-
#verse_postfix ⇒ Object
try to parse postfixes for verse.
-
#verse_sep ⇒ Object
try to parse verse separator.
Methods included from BasicMethods
#book_re, #chapter_re, #verse_re
Constructor Details
#initialize(*mods) ⇒ Parser
Returns a new instance of Parser.
16 17 18 19 |
# File 'lib/scripref/parser.rb', line 16 def initialize *mods @mods = mods mods.each {|m| extend m} end |
Instance Attribute Details
#error ⇒ Object (readonly)
Returns the value of attribute error.
11 12 13 |
# File 'lib/scripref/parser.rb', line 11 def error @error end |
Instance Method Details
#abbrev2book(str) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/scripref/parser.rb', line 248 def abbrev2book str s = str.strip s.sub! /\.$/, '' @books_str ||= ('#' << book_names.map(&:names).flatten.join('#') << '#') pattern = s.chars.map {|c| Regexp.escape(c) << '[^#]*'}.join re = /(?<=#)#{pattern}(?=#)/ names = @books_str.scan(re) uniq_numbers = names.map {|n| str2osis_book_id(n)}.uniq if uniq_numbers.size != 1 unscan give_up format("Abbreviation %s is ambiguous it matches %s!", s, names.join(', ')) end names.first end |
#abbrev2osis_book_id(str) ⇒ Object
242 243 244 245 246 |
# File 'lib/scripref/parser.rb', line 242 def abbrev2osis_book_id str s = str.strip s.sub! /\.$/, '' str2osis_book_id(s) or str2osis_book_id(abbrev2book(s)) end |
#b1 ⇒ Object
try to parse first book
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/scripref/parser.rb', line 37 def b1 s = scan(book_re) or return nil @text << s @b1 = @b2 = abbrev2osis_book_id(s) @c1 = @v1 = @c2 = @v2 = nil if pass_sep b1 or give_up 'EOS or book expected!' elsif check(Regexp.new(chapter_re.source + cv_sep_re.source)) @c1 = @v1 = nil @c2 = @v2 = nil c1 else if book_has_only_one_chapter?(@b1) @c1 = @c2 = 1 epsilon or (hyphen and b2) or v1 or give_up 'EOS or hyphen and book or verse expected!' else @c1 = @v1 = nil @c2 = @v2 = nil epsilon or (hyphen and b2) or c1 or give_up 'EOS or hyphen and book or chapter expected!' end end end |
#b2 ⇒ Object
try to parse second book
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/scripref/parser.rb', line 110 def b2 s = scan(book_re) or return nil @text << s @b2 = abbrev2osis_book_id(s) @c2 = @v2 = nil if pass_sep b1 or give_up 'EOS or book expected!' elsif check(Regexp.new(chapter_re.source + cv_sep_re.source)) c2 else if book_has_only_one_chapter?(@b2) @c2 = 1 epsilon or v2 or give_up 'EOS or chapter or verse expected!' else epsilon or c2 or give_up 'EOS or chapter expected!' end end end |
#c1 ⇒ Object
try parse first chapter
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/scripref/parser.rb', line 62 def c1 s = scan(chapter_re) or return nil @text << s @c1 = @c2 = s.to_i @v1 = @v2 = nil if cv_sep v1 or give_up 'Verse expected!' elsif hyphen b2 or c2 or give_up 'Book or chapter expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or chapter verse separator or hyphen and book or hyphen and chapter or passage separator and book or passage separator and chapter expected!' end end |
#c2 ⇒ Object
try to parse second chapter
131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/scripref/parser.rb', line 131 def c2 s = scan(chapter_re) or return nil @text << s @c2 = s.to_i if cv_sep v2 or give_up 'Verse expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or chapter verse separator expected!' end end |
#cv_sep ⇒ Object
try to parse separator or chapter and verse
174 175 176 177 178 179 180 181 |
# File 'lib/scripref/parser.rb', line 174 def cv_sep if s = scan(cv_sep_re) @text << s s else nil end end |
#epsilon ⇒ Object
try to parse end of string
165 166 167 168 169 170 171 |
# File 'lib/scripref/parser.rb', line 165 def epsilon if eos? push_passage return @result end nil end |
#format_error ⇒ Object
291 292 293 294 295 296 297 |
# File 'lib/scripref/parser.rb', line 291 def format_error if error format("%s\n%s\n%s^", error, string, ' ' * pointer) else '' end end |
#give_up(msg) ⇒ Object
286 287 288 289 |
# File 'lib/scripref/parser.rb', line 286 def give_up msg @error = msg fail ParserError, format_error end |
#hyphen ⇒ Object
try to parse hyphen
184 185 186 187 188 189 190 191 |
# File 'lib/scripref/parser.rb', line 184 def hyphen if s = scan(hyphen_re) @text << s s else nil end end |
#init_str2osis_book_id ⇒ Object
263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/scripref/parser.rb', line 263 def init_str2osis_book_id unless @str2osis_book_id @str2osis_book_id = {} book_names.each do |bn| bn.names.each do |n| @str2osis_book_id[n] = bn.osis_id end bn.abbrevs.each do |n| @str2osis_book_id[n] = bn.osis_id end end end end |
#inspect ⇒ Object
282 283 284 |
# File 'lib/scripref/parser.rb', line 282 def inspect "#<#{self.class} #{@mods.inspect}>" end |
#parse(str) ⇒ Object Also known as: <<
Parsing a string of a scripture reference
23 24 25 26 27 28 |
# File 'lib/scripref/parser.rb', line 23 def parse str self.string = str @result = [] @error = nil start end |
#pass_sep ⇒ Object
try to parse separator between passages
194 195 196 197 198 199 200 201 202 |
# File 'lib/scripref/parser.rb', line 194 def pass_sep if s = scan(pass_sep_re) push_passage @result << PassSep.new(s) s else nil end end |
#push_passage ⇒ Object
236 237 238 239 240 |
# File 'lib/scripref/parser.rb', line 236 def push_passage @result << Passage.new(text: @text, b1: @b1, c1: @c1, v1: @v1, b2: @b2, c2: @c2, v2: @v2, a1: @a1, a2: @a2) @text = '' @a1 = @a2 = nil end |
#start ⇒ Object
start of parsing grammer
31 32 33 34 |
# File 'lib/scripref/parser.rb', line 31 def start @text = '' b1 or give_up 'Book expected!' end |
#str2osis_book_id(str) ⇒ Object
277 278 279 280 |
# File 'lib/scripref/parser.rb', line 277 def str2osis_book_id str init_str2osis_book_id @str2osis_book_id[str] end |
#v1 ⇒ Object
try to parse first verse
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/scripref/parser.rb', line 80 def v1 s = scan(verse_re) or return nil @text << s @v1 = @v2 = s.to_i if addon = verse_addon @a1 = addon end if postfix = verse_postfix @v2 = postfix end if hyphen b2 or ( if check(Regexp.new(chapter_re.source + cv_sep_re.source)) c2 else v2 or give_up 'Chapter or verse expected!' end) elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' elsif verse_sep v1 or give_up 'Verse expected!' else epsilon or give_up 'EOS or passage separator or verse separator or hyphen expected!' end end |
#v2 ⇒ Object
try to parse second verse
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/scripref/parser.rb', line 146 def v2 s = scan(verse_re) or return nil @text << s @v2 = s.to_i if addon = verse_addon @a2 = addon end if verse_sep v1 or give_up 'Verse expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or verse separator or passage separator expected!' end end |
#verse_addon ⇒ Object
try to parse addons for verses
216 217 218 219 220 221 222 223 |
# File 'lib/scripref/parser.rb', line 216 def verse_addon if s = scan(verse_addon_re) @text << s s.to_sym else nil end end |
#verse_postfix ⇒ Object
try to parse postfixes for verse
226 227 228 229 230 231 232 233 234 |
# File 'lib/scripref/parser.rb', line 226 def verse_postfix s = (scan(postfix_one_following_verse_re) or scan(postfix_more_following_verses_re)) if s @text << s s.to_sym else nil end end |