Remind-Parser
view release on metacpan or search on metacpan
lib/Remind/Parser.pm view on Meta::CPAN
}, $cls;
return $self->_init;
}
sub _init {
my ($self) = @_;
# Nothing to do
return $self;
}
# --- Accessors
sub reminders { scalar(@_) > 1 ? $_[0]->{'reminders'} = $_[1] : $_[0]->{'reminders'} }
sub strict { scalar(@_) > 1 ? $_[0]->{'strict'} = $_[1] : $_[0]->{'strict'} }
sub strip_times { scalar(@_) > 1 ? $_[0]->{'strip_times'} = $_[1] : $_[0]->{'strip_times'} }
sub fill_gaps { scalar(@_) > 1 ? $_[0]->{'fill_gaps'} = $_[1] : $_[0]->{'fill_gaps'} }
# --- Other public methods
sub parse {
my ($self, $fh) = @_;
delete $self->{'days'}; # We'll regenerate later if asked
my ($file, $line, $loc, %file);
my ($past_header, $all_done);
my @reminders;
my %loc2event;
my %loc2count;
my $next_event = 1;
my $start = <$fh>;
return [] unless defined $start;
if ($start !~ /^# rem2ps begin$/) {
die "First line of input is not the proper header: $_"
if $self->strict;
}
while (<$fh>) {
chomp;
if ($all_done) {
if ($_ !~ /^# rem2ps begin$/ ) {
die "Spurious input at end of input: $_"
if $self->strict;
last;
}
else { $past_header = 0 ; $all_done = 0 }
}
if (/^# fileinfo (\d+) (.+)/) {
($line, $file) = ($1, $2);
$loc = "$file:$line";
$past_header = 1;
}
elsif ($past_header) {
# We've skipped past the header
if (/^# rem2ps end$/) {
# All done
$all_done = 1;
}
else {
unless (defined $loc) {
die "Input does not contain file and line offsets; you must use option -p with remind";
}
my ($date, $special, $tag, $duration, $offset, $description) = split / +/, $_, 6;
my ($year, $month, $day) = split m{[-/]}, $date;
if ($self->strip_times && $description =~ s/^((\d\d?):(\d\d)([ap]m) )//) {
# Strip the time -- but then restore it if it doesn't match
# the offset in minutes
my ($stripped, $H, $M, $pm) = ($1, $2, $3, $4 eq 'pm');
$description = $stripped . $description
unless $offset == _HMpm2min($H, $M, $pm);
}
my $event = $loc2event{$loc} ||= $next_event++;
my $instance = ++$loc2count{$loc};
my %reminder = (
'event' => $event,
'instance' => $instance,
'file' => $file,
'line' => $line,
'year' => $year + 0,
'month' => $month + 0,
'day' => $day + 0,
'description' => $description,
$tag eq '*' ? () : ('tag' => $tag),
$special eq '*' ? () : ('special' => $special),
);
$reminder{'date'} = _format_date(@reminder{qw(year month day)});
my ($begin, $end);
if ($offset eq '*') {
# Untimed (whole day) reminder
$reminder{'all_day'} = 1;
}
else {
# Timed reminder
my $H = $reminder{'hour'} = int($offset / 60);
my $M = $reminder{'minute'} = $offset % 60;
my $S = $reminder{'second'} = 0;
if ($duration ne '*') {
$reminder{'duration'} = {
'hours' => int($duration / 60),
'minutes' => $duration % 60,
'seconds' => 0,
};
}
}
push @reminders, _normalize_date(\%reminder);
}
}
}
return $self->{'reminders'} = \@reminders;
}
sub days {
my ($self, %args) = @_;
return $self->{'days'} if $self->{'days'};
my ($begin_date, $end_date) = @args{qw(begin end)};
my $reminders = $self->reminders;
my %date_info;
_consolidate_reminders($reminders, \%date_info);
_sort_date_reminders(\%date_info);
if (exists $args{'fill_gaps'}) {
_fill_gaps(\%date_info) if $args{'fill_gaps'};
}
elsif ($self->fill_gaps) {
_fill_gaps(\%date_info);
( run in 1.770 second using v1.01-cache-2.11-cpan-71847e10f99 )