Class: BibleReferenceParser::ChapterReference
- Inherits:
-
Object
- Object
- BibleReferenceParser::ChapterReference
- Includes:
- TracksErrors
- Defined in:
- lib/bible_reference_parser/reference/chapter_reference.rb
Overview
This class handles the parsing of chapters in a passage or string.
Each ChapterReference object contains the chapter number and a ReferenceCollection of verses.
The main method of interest is ChapterReference.parse_chapters. This will parse a passage or string and return a ReferenceCollection of ChapterReference objects. One object for each chapter identified. Example:
chapters = ChapterReference.parse_chapters("1:1-10, 5:6")
chapters[0].number # => 1
chapters[1].number # => 5
Although less useful, parse_chapters can even parse just the chapters in a complete passage:
chapters = ChapterReference.parse_chapters("Genesis 1:1-10, Mark 5:6")
chapters[0].number # => 1
chapters[1].number # => 5
You can see if there were any errors in parsing by checking the “has_errors?” method on the returned ReferenceCollection. Without specify metadata to validate against, only simple validation is possible. If you do provide metadata, (ex. BibleMetadata), The ChapterReference will add an error message if the chapter doesn’t exist for the book.
If you want to parse chapters for a particular book, its better to use the parse_chapters_in_reference method. This method takes an existing book reference. Example:
book = BookReference.new("Genesis", "1:1000, 51:10")
chapters = ChapterReference.parse_chapters_in_reference(book)
chapters.has_errors? # => true
chapters.no_errors? # => false
chapters.errors # => ["The verse '1000' does not exist for Genesis 1",
"Chapter '51' does not exist for the book Genesis"]
You can check if an individiual ChapterReference has errors as well:
book = BookReference.new("Genesis", "1:1000, 51:10")
chapters = ChapterReference.parse_chapters_in_reference(book)
chapters.first.has_errors? # => true
chapters.first.no_errors # => false
chapters.first.errors # => ["The verse '1000' does not exist for Genesis 1"]
Instance Attribute Summary collapse
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#number ⇒ Object
readonly
Returns the value of attribute number.
-
#raw_content ⇒ Object
readonly
Returns the value of attribute raw_content.
-
#verse_references ⇒ Object
(also: #children)
readonly
Returns the value of attribute verse_references.
Class Method Summary collapse
-
.parse_chapters(passage, metadata = nil) ⇒ Object
Parse the chapters in a passage or string.
-
.parse_chapters_in_reference(book_reference) ⇒ Object
Works similar to parse_chapters, however this should be used instead if you want to associate the chapter references with a book.
Instance Method Summary collapse
-
#clean(chain = true) ⇒ Object
Cleans invalid verse references.
-
#initialize(number, raw_content = nil, metadata = nil) ⇒ ChapterReference
constructor
Initializes a new ChapterReference object.
-
#parse_contents ⇒ Object
Parse the raw_content in order to find the verses referenced for this chapter.
-
#valid_reference? ⇒ Boolean
Whether this reference itself is valid.
-
#verse_numbers ⇒ Object
TODO write specs Get an array of ints containing the verse numbers referenced.
Methods included from TracksErrors
#add_error, #clear_errors, #errors, #has_errors?, #no_errors?
Constructor Details
#initialize(number, raw_content = nil, metadata = nil) ⇒ ChapterReference
Initializes a new ChapterReference object.
Parameters: number - The chapter number. Can either be an string or integer raw_content - A string representing the verses referenced, ex. “1-10” metadata - (optional) An array of metadata information for a particular
book, ex. BibleMetadata["Genesis"]. This is used to check if
the chapter number is valid for a book.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 63 def initialize(number, raw_content = nil, = nil) super number = number.to_i # allows passing the number parameter as string # if number is less than 1 add a parsing error and stop processing if number < 1 add_error "The chapter number '#{number}' is not valid" and return end # metadata info for a particular book in the bible @metadata = # if the metadata is given, we can verify if the chapter exists for the book unless @metadata.nil? total_chapters_in_book = @metadata["chapter_info"].length if number > total_chapters_in_book add_error "Chapter '#{number}' does not exist for the book #{@metadata['name']}" and return end end # The chapter number @number = number # The string representing the verses referenced in this chapter @raw_content = raw_content parse_contents end |
Instance Attribute Details
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
48 49 50 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 48 def @metadata end |
#number ⇒ Object (readonly)
Returns the value of attribute number.
48 49 50 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 48 def number @number end |
#raw_content ⇒ Object (readonly)
Returns the value of attribute raw_content.
48 49 50 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 48 def raw_content @raw_content end |
#verse_references ⇒ Object (readonly) Also known as: children
Returns the value of attribute verse_references.
48 49 50 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 48 def verse_references @verse_references end |
Class Method Details
.parse_chapters(passage, metadata = nil) ⇒ Object
Parse the chapters in a passage or string. Returns a ReferenceCollection of ChapterReference objects.
Parameters: passage - The passage to parse, ex. “1:1-10, 2:5-7” metadata - An array of metadata information for a particular book, ex. BibleMetadata.
NOTE: if you are passing this in, you probably should
be calling parse_chapters_in_reference instead of this one.
Example:
chapters = ChapterReference.parse_chapters("1:1-10, 2:5-7")
chapters.first.number # => 1
This can also parse just the chapters in a whole passage. It will ignore the book names:
chapters = ChapterReference.parse_chapters("Genesis 1:1-10; mark 1:5-7")
chapters.first.number # => 1
More Examples:
ChapterReference.parse_chapters("1:1")
ChapterReference.parse_chapters("1:1-10")
ChapterReference.parse_chapters("1:1-10; 5-10")
ChapterReference.parse_chapters("1:5,8,11; 2:10, 5-20")
ChapterReference.parse_chapters(10)
XXX allow option to remove duplicate chapters
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 139 def self.parse_chapters(passage, = nil) passage = passage.to_s # allows for integer passage chapters = ReferenceCollection.new # ~ Do some massaging of the data before we scan it... # Replace letters with a semi-colon. We would just remove all letters, but in cases # where books are separated by just a space, it will cause errors. For example # "Genesis 1 Exodus 1" would end up as "11". passage = passage.gsub(/[a-zA-Z]+/, ";") # Next remove everything except for numbers and these punctuation marks -> -,;: # We don't care about spaces or any other characters. passage = passage.gsub(/[^0-9:;,\-]/, "") # Finally insert a semi-colon before digits that precede a colon. This is for chapters # that reference specific verses, like "15:1". Semi-colons are used to indicate # the following sequence is separate from the preceding sequence. This is important # for back-to-back chapters with verses, ex. "1:5,10,5:10". Here we want chapter 1 # verses 5 and 10, then chapter 5 verse 10. The way we know it's not chapter 1 verse # 5, 10, and 5 is if there is a semi-colon there: "1:5,10,;5:10". passage = passage.gsub(/[0-9]+:/, ';\0') # This will look for digits followed by a semi-colon. If we match that, # we know what's before the colon is the chapter, and we know every digit or dash # directly after it are the verses. match_chapter_with_verses = /([0-9]+:)([0-9,\-]+)/ # This will match a chapter range, like "1-10" match_chapter_range = /([0-9]+\-[0-9]+)/ # This will match a single chapter selection that doesn't specify any verses. # Something like "Genesis 1, 2" tells us we want chapters 1 and chapter 2. # It looks for any digits directly followed by an optional comma or semi-colon. # It's optional because it won't be there if it's the last or only chapter. match_single_chapter = /([0-9]+[,;]?)/ # First try to match the chapter with verses, then the chapter range, then finally the single chapter pattern = Regexp.union(match_chapter_with_verses, match_chapter_range, match_single_chapter) # Let's find the chapters already! passage.scan pattern do |with_verses, verses, chapter_range, without_verses| if chapter_range # get the beginning and end of the range range = chapter_range.split "-" first = range.first.to_i last = range.last.to_i # add each chapter in the range (first..last).each do |number| chapters << ChapterReference.new(number, nil, ) end else number = with_verses ? with_verses.to_i : without_verses.to_i # remove all characters from the end util we get to a number. # This basically removes any extraneous punctation at the end. verses = verses.gsub(/[^0-9]+$/, "") unless verses.nil? chapters << ChapterReference.new(number, verses, ) end end chapters end |
.parse_chapters_in_reference(book_reference) ⇒ Object
Works similar to parse_chapters, however this should be used instead if you want to associate the chapter references with a book. This will decide what chapters are referenced based on the raw_content of the book reference. If the raw_content is nil, it will assume only the first chapter is desired.
101 102 103 104 105 106 107 108 109 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 101 def self.parse_chapters_in_reference(book_reference) if book_reference.raw_content.nil? # if the raw_content is nil, assume we want just the first chapter. This is what # Bible Gateway does if you just give a book name. return self.parse_chapters(1, book_reference.) else return self.parse_chapters(book_reference.raw_content, book_reference.) end end |
Instance Method Details
#clean(chain = true) ⇒ Object
Cleans invalid verse references. After calling this, the verse_references method will only return good verse references. You can access the invalid references through verse_references.invalid_references. See ReferenceCollection.clean for more information.
If the chain parameter is true (which it is by default) it will also tell valid verses to do a clean. Since verses are leaf-nodes so to speak, they don’t contain any references to clean so it won’t do anything.
227 228 229 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 227 def clean(chain = true) verse_references.clean(chain) end |
#parse_contents ⇒ Object
Parse the raw_content in order to find the verses referenced for this chapter.
217 218 219 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 217 def parse_contents @verse_references = VerseReference.parse_verses_in_reference self end |
#valid_reference? ⇒ Boolean
Whether this reference itself is valid. Please note this does not consider the verses inside the chapter, just the chapter itself.
212 213 214 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 212 def valid_reference? !number.nil? end |
#verse_numbers ⇒ Object
TODO write specs Get an array of ints containing the verse numbers referenced
233 234 235 236 237 238 239 |
# File 'lib/bible_reference_parser/reference/chapter_reference.rb', line 233 def verse_numbers verses = [] @verse_references.each do |ref| verses << ref.number end verses end |