From 24a09a3046fe4f86d6d50220e048cad1fb3bcf8a Mon Sep 17 00:00:00 2001 From: Matthew Kobs Date: Wed, 20 Nov 2019 09:02:01 -0600 Subject: [PATCH] [fix] Reset default chapter and verse at semicolons when parsing references (20m) This could likely be considered a breaking change in how parsing works. Before, the only way to "reset" the default chapter was to encounter a reference with a colon in it. For example, "Genesis 2; 3:15" would parse correctly, but "Genesis 2; 3" would not, since the latter reference had no colon to mark it clearly as indicating a chapter. However, in common usage, the semicolon is what signals to the human reader that what is meant is not verse 3 of chapter 2, but chapters 2 and 3; this updates Pericope to behave the same way. --- lib/pericope/parsing.rb | 7 ++++++- test/pericope_test.rb | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pericope/parsing.rb b/lib/pericope/parsing.rb index 5ccf358..d2792c4 100644 --- a/lib/pericope/parsing.rb +++ b/lib/pericope/parsing.rb @@ -80,7 +80,8 @@ def match_all(text) end def parse_reference(book, reference) - parse_ranges(book, normalize_reference(reference).split(/[,;]/)) + # Use positive lookahead to keep delimiter with the fragment that follows + parse_ranges(book, normalize_reference(reference).split(/(?=[,;])/)) end def normalize_reference(reference) @@ -93,8 +94,12 @@ def parse_ranges(book, ranges) default_verse = nil ranges.map do |range| + range_delimiter, range = range[0], range[1..-1] if range =~ /^[,;]/ range_begin_string, range_end_string = range.split("-") + # semicolon is used between chapters, even if it doesn't otherwise look it, e.g., Psalm 1; 3 + default_chapter = default_verse = nil if range_delimiter == ";" && book_has_chapters?(book) + # treat 12:4 as 12:4-12:4 range_end_string ||= range_begin_string diff --git a/test/pericope_test.rb b/test/pericope_test.rb index b30adb6..d16677e 100644 --- a/test/pericope_test.rb +++ b/test/pericope_test.rb @@ -145,6 +145,10 @@ def setup assert_equal [r(1001001, 1001031)], Pericope.parse_reference(1, "1") # Genesis 1 end + should "parse multiple chapters into ranges of verses in that chapter" do + assert_equal [r(1001001, 1001031), r(1003001, 1003024)], Pericope.parse_reference(1, "1; 3") # Genesis 1; 3 + end + should "parse multiple ranges into an array of ranges" do expected_ranges = [ r(40003001), @@ -155,7 +159,7 @@ def setup tests = [ "3:1,3,4-5,7; 4:19", - "3:1, 3 ,4-5; 7,4:19" + "3:1, 3 ,4-5, 7;4:19" ] tests.each do |input|