Religion-Bible-Reference

 view release on metacpan or  search on metacpan

lib/Religion/Bible/Reference.pm  view on Meta::CPAN

#pod This module converts simple text descriptions of bible references and ranges
#pod into objects that stringify into a canonical form.
#pod
#pod B<WARNING!>  This module is mostly an idea and not so much a guaranteed
#pod interface or well-tested implementation.  If you're interested in either of
#pod those existing, you should let me know.
#pod
#pod =func bibref
#pod
#pod   my $ref = bibref($ref_string)
#pod
#pod This function is exported by default, and constructs a new
#pod Religion::Bible::Reference
#pod
#pod Reference strings must be a book followed by a list of chapters, verses, or
#pod ranges.  The following are all valid ranges:
#pod
#pod   Pro 23:12, 23:15-17
#pod   st.jn8:32
#pod   Song of Solomon 8:7-8
#pod   2 John 1
#pod
#pod =cut

sub bibref { __PACKAGE__->new(@_); }

#pod =method new
#pod
#pod   my $ref = Religion::Bible::Reference->new($ref_string)
#pod
#pod This method acts just like the exported C<bibref> function.
#pod
#pod =cut

# ok:
# jn8
# jn8:32
# jn8:30-32
# jn8:25-28,30-32
# jn8:1,3-4,6

sub _parse_ref {
  my ($class, $ref_string) = @_;
  my $range_regex  = qr/\d+(?::(?:\d[-,]?)+)?/;

  (my $book  = $ref_string) =~ s/\s*($range_regex)\z//;
  my $ranges = $1;

  return (book => $book, ranges => $ranges);
}

sub new {
  my ($class, $ref_string) = @_;

  my %bibref = $class->_parse_ref($ref_string);

  my $self;

  return unless $self->{book}  = $class->canonicalize_book($bibref{book});

  bless $self => $class;

  return unless my $range = $self->_parse_ranges($bibref{ranges});

  $self->{chapter} = $range->{chapter};
  $self->{ranges}  = $range->{ranges};

  return unless $class->_validate_ranges(
    $self->{book},
    $self->{chapter},
    $self->{ranges},
  );

  return $self;
}

sub _validate_ranges {
  my ($class, $book, $chapter, $ranges) = @_;

  foreach my $range (@$ranges) {
    return unless $class->validate_verse($book, $chapter, $range->[0]);
    return unless $class->validate_verse($book, $chapter, $range->[1]);
  }
  return 1;
}

sub _parse_ranges {
  my ($self, $string) = @_;

  my ($chapter, $rest) = $string =~ /\A(\d+)(?::(.+))?\z/;

  return unless $chapter;
  return { chapter => $string,
           ranges => [[ 1, $book_chapters{$self->{book}}[$chapter - 1] ]] }
           unless $rest;

  my @range_strings = split /,\s?/, $rest;

  my @range;

  for my $rs (@range_strings) {
    my ($start, $end) = $rs =~ /\A(\d+)(?:-(\d+))?\z/;
    return unless $start;
    push @range, [ $start, (defined $end ? $end : $start) ];
  }

  return { chapter => $chapter, ranges => \@range };
}

#pod =method stringify
#pod
#pod   $self->stringify
#pod
#pod This method returns a string representing the reference, using the canonical
#pod book name.
#pod
#pod =cut

sub stringify {
  my ($self) = @_;
  my $string = $self->{book}



( run in 2.048 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )