class BiblePassage::Reference

Attributes

book[R]
book_key[R]
child[R]
error[R]
parent[W]

Public Class Methods

new(book_key, from_chapter = nil, from_verse = nil, to_chapter = nil, to_verse = nil, options = {}) click to toggle source
# File lib/bible_passage/reference.rb, line 128
def initialize(book_key, from_chapter = nil, from_verse = nil, 
               to_chapter = nil, to_verse = nil, options = {})
  @raise_errors = options.has_key?(:raise_errors) ? options[:raise_errors] : true
  @data_store = options[:data_store] || BookDataStore.new
  self.book_key = book_key
  self.from_chapter = int_param(from_chapter)
  self.from_verse = int_param(from_verse)
  self.to_chapter = calculate_to_chapter(to_chapter)
  self.to_verse = calculate_to_verse(to_verse)
end
parse(passage, options = {}) click to toggle source

The main method used for parsing passage strings

# File lib/bible_passage/reference.rb, line 14
def parse(passage, options = {})
  options = {raise_errors: true}.merge(options)
  translator = options.delete(:translator) || BookKeyTranslator.new
  data_store = options[:data_store] ||= BookDataStore.new
  match = match_passage_format(passage)
  if !match
    message = "#{passage} is not a valid reference"
    if options[:raise_errors]
      raise InvalidReferenceError.new(message)
    else
      return InvalidReference.new(message)
    end
  end
  book_key = translator.keyify(match[1], options[:raise_errors]) || (return InvalidReference.new("#{match[1]} is not a valid book"))
  if data_store.number_of_chapters(book_key) == 1
    ref = process_single_chapter_match(book_key, match, options)
  else
    ref = process_multi_chapter_match(book_key, match, options)
  end
  ref.parse_child(match[6].gsub(/^,\s*/, '')) if match[6]
  ref
end
parse_child(passage, parent, options = {}) click to toggle source

Parses a child reference in a compound passage string

# File lib/bible_passage/reference.rb, line 39
def parse_child(passage, parent, options = {})
  if match_passage_format(passage)
    ref = parse(passage, options)
  else
    match = passage.match(/\s*(\d+)?:?(\d+)?\s*(-?)\s*(\d+)?:?(\d+)?\s*(,.+)?$/)
    book_key = parent.book_key
    attrs = parent.inheritable_attributes
    if attrs[:from_chapter]
      if match[2]
        attrs[:from_chapter] = match[1].to_i 
        attrs[:from_verse] = match[2].to_i
      else
        attrs[:from_verse] = match[1].to_i
      end
    else
      attrs[:from_chapter] = match[1].to_i
      if match[2]
        attrs[:from_verse] = match[2].to_i
      else
      end
    end
    if match[5]
      attrs[:to_chapter] = int_param(match[4])
      attrs[:to_verse] = int_param(match[5])
    elsif attrs[:from_verse]
      attrs[:to_verse] = int_param(match[4]) 
    else
      attrs[:to_chapter] = int_param(match[4])
    end
    ref = new(book_key, attrs[:from_chapter], attrs[:from_verse], 
        attrs[:to_chapter], attrs[:to_verse])
  end
  ref.parent = parent
  ref
end

Private Class Methods

int_param(param) click to toggle source
# File lib/bible_passage/reference.rb, line 81
def int_param(param)
  param ? param.to_i : nil
end
match_passage_format(passage) click to toggle source
# File lib/bible_passage/reference.rb, line 77
def match_passage_format(passage)
  passage.match(/^\s*(\d?\s*[A-Za-z\s]+)\s*(\d+)?:?(\d+)?\s*-?\s*(\d+)?:?(\d+)?\s*(,.+)?/)
end
process_multi_chapter_match(book_key, match, options) click to toggle source
# File lib/bible_passage/reference.rb, line 85
def process_multi_chapter_match(book_key, match, options)
  if match[2]
    from_chapter = match[2].to_i 
    # has from verse
    if match[3]
      from_verse = match[3].to_i
      if match[5]
        to_chapter = match[4].to_i
        to_verse = match[5].to_i
      else
        to_verse = int_param(match[4])
      end
    else
      from_verse = int_param(match[3])
      to_chapter = int_param(match[4])
    end
  end
  new(book_key, from_chapter, from_verse, to_chapter, to_verse, options)
end
process_single_chapter_match(book_key, match, options) click to toggle source
# File lib/bible_passage/reference.rb, line 105
def process_single_chapter_match(book_key, match, options)
  if match[2]
    from_verse = match[2].to_i
    to_verse = match[4].to_i if match[4]
  end
  if match[0] =~ /:/
    book_name = options[:data_store].book_name(book_key)
    msg = "#{book_name} doesn't have any chapters"
    if options[:raise_errors]
      raise InvalidReferenceError.new(msg)
    else
      return InvalidReference.new(msg)
    end
  end
  new(book_key, nil, from_verse, nil, to_verse, options)
end

Public Instance Methods

==(other) click to toggle source
# File lib/bible_passage/reference.rb, line 246
def ==(other)
  attributes == other.attributes
end
attributes() click to toggle source
# File lib/bible_passage/reference.rb, line 239
def attributes
  %w{book_key from_chapter from_verse to_chapter to_verse}.
    inject({}) do |memo, attr_key|
      memo.merge(attr_key.to_sym => send(attr_key))
  end
end
book_key=(key) click to toggle source
# File lib/bible_passage/reference.rb, line 143
def book_key=(key)
  @book = @data_store.book_name(key)
  @book_key = key
end
from_chapter() click to toggle source
# File lib/bible_passage/reference.rb, line 148
def from_chapter
  @from_chapter || 1
end
from_chapter=(val) click to toggle source
# File lib/bible_passage/reference.rb, line 152
def from_chapter=(val)
  if val
    if val < 1 || val > @data_store.number_of_chapters(book_key)
      @error = "#{book} doesn't have a chapter #{val}"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    @inherit_book_key = true
    @from_chapter = val
  end
end
from_verse() click to toggle source
# File lib/bible_passage/reference.rb, line 163
def from_verse
  @from_verse || 1
end
from_verse=(val) click to toggle source
# File lib/bible_passage/reference.rb, line 167
def from_verse=(val)
  if val && valid?
    if val > @data_store.number_of_verses(book_key, from_chapter) || val < 1
      @error = "#{book} #{from_chapter} doesn't have a verse #{val}"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    @inherit_chapter = true
    @from_verse = val
  end
end
inheritable_attributes() click to toggle source
# File lib/bible_passage/reference.rb, line 250
def inheritable_attributes
  out = {}
  out[:book_key] = book_key if @inherit_book_key
  out[:from_chapter] = to_chapter if @inherit_chapter
  out
end
parse_child(child_passage) click to toggle source
# File lib/bible_passage/reference.rb, line 139
def parse_child(child_passage)
  @child = self.class::parse_child(child_passage, self)
end
to_chapter() click to toggle source
# File lib/bible_passage/reference.rb, line 178
def to_chapter
  @to_chapter || from_chapter
end
to_chapter=(val) click to toggle source
# File lib/bible_passage/reference.rb, line 182
def to_chapter=(val)
  if val
    if val < from_chapter
      @error = "to_chapter cannot be before from_chapter"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    if val > @data_store.number_of_chapters(book_key)
      @error = "#{book} doesn't have a chapter #{val}"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    @to_chapter = val
  end
end
to_s() click to toggle source
# File lib/bible_passage/reference.rb, line 214
def to_s
  return nil if !valid?
  if @parent
    out = to_s_child
  else
    out = to_s_root
  end
  out << child.to_s if child
  out
end
to_verse() click to toggle source
# File lib/bible_passage/reference.rb, line 196
def to_verse
  @to_verse || from_verse
end
to_verse=(val) click to toggle source
# File lib/bible_passage/reference.rb, line 200
def to_verse=(val)
  if val && valid?
    if val < from_verse && single_chapter_passage?
      @error = "to_verse cannot be before from_verse"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    if val > @data_store.number_of_verses(book_key, to_chapter)
      @error = "#{book} #{to_chapter} doesn't have a verse #{val}"
      raise InvalidReferenceError.new(@error) if @raise_errors
    end
    @to_verse = val
  end
end
valid?() click to toggle source
# File lib/bible_passage/reference.rb, line 257
def valid?
  @error.nil?
end
whole_book?() click to toggle source
# File lib/bible_passage/reference.rb, line 229
def whole_book?
  from_chapter == 1 && from_verse == 1 && 
    to_chapter == @data_store.number_of_chapters(book_key) &&
    to_verse == @data_store.number_of_verses(book_key, to_chapter)
end
whole_chapter?() click to toggle source
# File lib/bible_passage/reference.rb, line 235
def whole_chapter?
  whole_chapters? && from_chapter == to_chapter
end
whole_chapters?() click to toggle source
# File lib/bible_passage/reference.rb, line 225
def whole_chapters?
  from_verse == 1 && to_verse_last_in_chapter?
end

Private Instance Methods

calculate_to_chapter(supplied_to_chapter) click to toggle source
# File lib/bible_passage/reference.rb, line 333
def calculate_to_chapter(supplied_to_chapter)
  int_param(supplied_to_chapter) || begin
    if @from_chapter
      @from_chapter
    else
      @data_store.number_of_chapters(book_key)
    end
  end
end
calculate_to_verse(supplied_to_verse) click to toggle source
# File lib/bible_passage/reference.rb, line 343
def calculate_to_verse(supplied_to_verse)
  int_param(supplied_to_verse) || 
    @from_verse ||
      @data_store.number_of_verses(book_key, self.to_chapter)
end
from_part() click to toggle source
# File lib/bible_passage/reference.rb, line 262
def from_part
  out = ''
  unless whole_book?
    out << ' '
    out << from_chapter.to_s
    out << from_verse_part
  end
  out
end
from_verse_part() click to toggle source
# File lib/bible_passage/reference.rb, line 272
def from_verse_part
  if whole_chapters?
    ''
  else
    out = single_chapter_book? ? ' ' : ':'
    "#{out}#{from_verse.to_s}"
  end
end
int_param(param) click to toggle source
# File lib/bible_passage/reference.rb, line 313
def int_param(param)
  param ? param.to_i : nil
end
single_chapter_book?() click to toggle source
# File lib/bible_passage/reference.rb, line 325
def single_chapter_book?
  @data_store.number_of_chapters(book_key) == 1
end
single_chapter_passage?() click to toggle source
# File lib/bible_passage/reference.rb, line 317
def single_chapter_passage?
  from_chapter == to_chapter
end
single_verse_passage?() click to toggle source
# File lib/bible_passage/reference.rb, line 321
def single_verse_passage?
  single_chapter_passage? && from_verse == to_verse
end
to_chapter_part() click to toggle source
# File lib/bible_passage/reference.rb, line 293
def to_chapter_part
  if single_chapter_passage?
    ''
  else
    to_chapter.to_s
  end
end
to_part() click to toggle source
# File lib/bible_passage/reference.rb, line 281
def to_part
  out = ''
  unless whole_book? || single_verse_passage? || whole_chapter?
    out << '-'
    unless single_chapter_passage?
      out << to_chapter_part 
    end
    out << to_verse_part
  end
  out
end
to_s_child() click to toggle source
# File lib/bible_passage/reference.rb, line 357
def to_s_child
  out = ','
  if book_key != @parent.book_key
    out << " #{to_s_root}"
  else
    out << "#{from_part}#{to_part}"
  end
end
to_s_root() click to toggle source
# File lib/bible_passage/reference.rb, line 349
def to_s_root
  if single_chapter_book?
    out = "#{book}#{from_verse_part}#{to_verse_part}"
  else
    out = "#{book}#{from_part}#{to_part}"
  end
end
to_verse_last_in_chapter?() click to toggle source
# File lib/bible_passage/reference.rb, line 329
def to_verse_last_in_chapter?
  to_verse == @data_store.number_of_verses(book_key, to_chapter)
end
to_verse_part() click to toggle source
# File lib/bible_passage/reference.rb, line 301
def to_verse_part
  if single_verse_passage? || whole_chapters?
    ''
  else
    out = ''
    out << '-' if single_chapter_book?
    out << ':' unless single_chapter_passage?
    out << to_verse.to_s
    out
  end
end