The _sprintlist subroutine takes a list reference and returns a string
where the list is nicely formatted. You can specify the tag for the
first line, the indentation, the separator used, the line width,
and even a prefix for every line. Play with the different options
to see how they affect the output. For example, the following:
@list=('aaa'..'aax');
print _sprintlist(\@list,"Members:",undef,10,undef,60,"* ");
will produce:
* Members: aaa, aab, aac, aad, aae, aaf, aag, aah, aai,
* aaj, aak, aal, aam, aan, aao, aap, aaq, aar,
* aas, aat, aau, aav, aaw, aax
Any arguments given as "undef" (or not given) take on their
default values.
The _sprintstr function takes a string instead of a list,
and uses _sprintlist to print the string nicely formatted.
Most of the arguments are the same.
I have also included a sample Help() function to print command
summaries with their help strings. This assumes the hash
%COMMANDS is indexed by command name, and each element is a
hash ref with elements "Sum" and "Desc".
A named-argument interface is left as an exercise to the reader :-)
--ZZamboni
Updated: Added sample input and output for Help().
# Returns an indented string containing a list. Syntax is:
# _sprintlist($listref[, $firstline[, $separator[, $indent
# [, $break[, $linelen[, $lineprefix]]]]])
# All lines are indented by $indent spaces (default 0).
# If $firstline is given, that string is inserted in the
# indentation of the first line (it is truncated to $indent spaces
# unless $break is true, in which case the list is pushed to the next
# line). Normally the list elements are separated by commas and spaces
# ", ". If $separator is given, that string is used as a separator.
# Lines are wrapped to $linelen characters, unless it is specified as
# some other value. A value of 0 for $linelen makes it not do line wra
+pping.
# If $lineprefix is given, it is printed at the beginning of each line
+.
sub _sprintlist {
my $listref=shift or return;
my @list=@$listref;
my $fline=shift;
my $separator=shift || ", ";
my $indent=shift;
$indent=0 unless defined($indent);
my $space=" " x $indent;
$fline||=$space;
my $break=shift || 0;
my $linelen=shift;
$linelen=80 unless defined($linelen);
my $lp=shift||"";
$linelen-=length($lp);
if (!$break || length($fline)<=$indent) {
$fline=substr("$fline$space", 0, length($space));
}
else {
# length($fline)>$indent
$fline="$fline\n$space";
}
my $str="";
my $line="";
foreach (@list) {
$line.=$separator if $line;
if ($linelen && length($line)+length($_)+length($space)>=$linelen)
+ {
$line=~s/\s*$//;
$str.="$space$line\n";
$line="";
}
$line.="$_";
}
$str.="$space$line";
$str=~s/^$space/$fline/;
$str=~s/^/$lp/mg if $lp;
return $str;
}
# Gets a string, and returns it nicely formatted and word-wrapped. It
# uses _sprintlist as a backend. Its syntax is the same as
# _sprintlist, except that is gets a string instead of a list ref, and
# that $separator is not used because we automatically break on white
# space.
# Syntax: _sprintstr($string[, $firstline[, $indent[, $break[, $linele
+n
# [, $lineprefix]]]]]);
# See _sprintlist for the meaning of each parameter.
sub _sprintstr {
my ($str, $fl, $ind, $br, $len, $lp)=@_;
$ind||=0;
# Split string into \n-separated parts.
my @strs=($str=~/([^\n]+\n?|[^\n]*\n)/g);
# Now process each line separately
my $s;
my $result;
foreach $s (@strs) {
# Store end of lines at the end of the string
my $eols=($s=~/(\n*)$/)[0];
# Split in words.
my @words=(split(/\s+/, $s));
$result.=_sprintlist(\@words,$fl," ",$ind,$br,$len, $lp).$eols;
# The $firstline is only needed at the beginning of the first stri
+ng.
$fl=undef;
}
return $result;
}
And the sample Help() function:
# Sample %COMMANDS in the format assumed.
%COMMANDS=(
add => { Sum => 'add NAME to LIST',
Desc => 'Add the name to the mailing list.' },
all => { Sum => 'all [-a|-l]',
Desc => 'Print out all the aliases and mailing lists. '.
'With -a only prints aliases, with -l only prints '
+.
'lists.' },
delete => { Sum => 'delete LIST,...',
Desc => 'Delete mailing lists. Also deleted owner-LIST a
+nd '.
'LIST-owner if they exist.' },
list => { Sum => 'list [-1|-x|-s|-n] LIST|/regex/,...',
Desc => 'List information about the given aliases. If list
+ '.
'name starts with "/" it is assumed to be a regula
+r '.
'expression. '.
'-1 lists members one per line, '.
'-x lists members all on a single line. '.
'-s lists in Unix alias format. '.
'-n only shows list names.' },
);
# Usage message
sub Help {
print "The current commands are:\n";
my $cmd;
foreach $cmd (sort keys %COMMANDS) {
print _sprintstr($COMMANDS{$cmd}->{Desc},
$COMMANDS{$cmd}->{Sum},30,1)."\n";
}
print "Use 'quit' or '^D' to quit.\n";
}
With the given definition of %COMMANDS, Help() produces:
The current commands are:
add NAME to LIST Add the name to the mailing list.
all [-a|-l] Print out all the aliases and mailing li
+sts. With
-a only prints aliases, with -l only pri
+nts
lists.
delete LIST,... Delete mailing lists. Also deleted owner
+-LIST and
LIST-owner if they exist.
list [-1|-x|-s|-n] LIST|/regex/,...
List information about the given aliases
+. If list
name starts with "/" it is assumed to be
+ a
regular expression. -1 lists members one
+ per
line, -x lists members all on a single l
+ine. -s
lists in Unix alias format. -n only show
+s list
names.
Use 'quit' or '^D' to quit.