#-*- perl -*-
#
# Copyright (C) 2001,2002,2003,2004 Ken'ichi Fukamachi
#
# $FML: MH.pm,v 1.16 2003/07/21 04:51:34 fukachan Exp $
#
package Mail::Message::MH;
use strict;
=head1 NAME
Mail::Message::MH - utilities to handle MH style format
=head1 SYNOPSIS
use Mail::Message::MH;
my $mh = new Mail::Message::MH;
=head1 DESCRIPTION
=head1 METHODS
=head2 expand($str, [$min, $max])
return ARRAY_REF of numbers specified by the following format:
100
100-110
first-110
100-last
first
first:100
last
last:100
=cut
# Descriptions: constructor.
# Arguments: OBJ($self) HASH_REF($args)
# Side Effects: none
# Return Value: OBJ
sub new
{
my ($self, $args) = @_;
my ($type) = ref($self) || $self;
my $me = {};
return bless $me, $type;
}
# Descriptions: expand MH style expression to list of numbers.
# Arguments: OBJ($self) STR($str) NUM($min) NUM($max)
# Side Effects: none
# Return Value: ARRAY_REF
sub expand
{
my ($self, $str, $min, $max) = @_;
my $ra = [];
unless (defined $min) { $min = 1;}
if ($str =~ /,/o) {
for my $s (split(/,/, $str)) {
my $ra0 = $self->expand($s, $min, $max);
for my $element (@$ra0) { push(@$ra, $element);}
}
return $ra;
}
if ($str eq 'all') {
unless (defined $max) { return [];}
return _expand_range($min, $max);
}
elsif ($str =~ /^\d+$/o) {
return [ $str ];
}
elsif ($str =~ /^(\d+)\-(\d+)$/o) {
my ($first, $last) = ($1, $2);
$first = $min if ($first < $min);
$last = $max if ($last > $max);
return _expand_range($first, $last);
}
elsif ($str =~ /^(first)\-(\d+)$/) {
my ($first, $last) = ($1, $2);
$last = $max if ($last > $max);
return _expand_range($min, $last);
}
elsif ($str =~ /^(\d+)\-(last)$/) {
unless (defined $max) { return [];}
my ($first, $last) = ($1, $2);
$first = $min if ($first < $min);
return _expand_range($first, $max);
}
elsif ($str eq 'first') {
return [ $min ];
}
elsif ($str eq 'last' || $str eq 'cur') {
unless (defined $max) { return [];}
return [ $max ];
}
elsif ($str =~ /^first:(\d+)$/) {
return _expand_range($min, $min + $1 - 1);
}
elsif ($str =~ /^last:(\d+)$/) {
unless (defined $max) { return [];}
return _expand_range($max - $1 + 1, $max);
}
return [];
}
# Descriptions: make an array from $fist to $last number.
# Arguments: NUM($first) NUM($last)
# Side Effects: none
# Return Value: ARRAY_REF (as [ $first .. $last ])
sub _expand_range
{
my ($first, $last) = @_;
my (@fn) = ();
for my $n ($first .. $last) { push(@fn, $n);}
return \@fn;
}
if ($0 eq __FILE__) {
eval q{
my $mh = new Mail::Message::MH;
for (qw(1,2,3 1,10,last:20 100 100-110 first-110 190-last first
first:10 last last:10)) {
print "\n[$_] => ";
my $a = $mh->expand($_, 1, 200);
print "@$a\n";
}
};
}
=head1 CODING STYLE
See C on fml coding style guide.
=head1 AUTHOR
Ken'ichi Fukamachi
=head1 COPYRIGHT
Copyright (C) 2001,2002,2003,2004 Ken'ichi Fukamachi
All rights reserved. This program is free software; you can
redistribute it and/or modify it under the same terms as Perl itself.
=head1 HISTORY
Mail::Message::MH first appeared in fml8 mailing list driver package.
See C for more details.
=cut
1;