SPUG: Better way to sort POD list-items?
Tim Maher
tim at consultix-inc.com
Thu Mar 11 23:33:44 CST 2004
SPUGaholics,
I just found a need to dash off the following script, in order to
sort the glossary entries of the book I'm working on into
alphabetical order.
Seems like there should be an easier way!
Anybody got a cleaner technique for associating the item labels
with their associated data? I think I used to know a trick with
split() to do that, but if so I sure can't remember it now ...
For those who don't know POD, the list format is:
=item 1.
This is item 1
=item 2.
This is item 2
and so forth.
The script below assumes its input starts with the first "=item label" and
ends with the data for the last item. That's easily arranged in vim with a
line like:
:33,47! sort_pod_items
*--------------------------------------------------------------------------*
| Tim Maher, CEO (206) 781-UNIX (866) DOC-PERL (866) DOC-UNIX |
| tim(AT)Consultix-Inc.Com http://TeachMePerl.Com http://TeachMeUnix.Com |
*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*
| Classes: Perl Prog. plus Perl Modules, 4/5-4/8 ; Template Toolkit: TBA |
| Watch for my Manning book: "Minimal Perl for Shell Users & Programmers" |
*--------------------------------------------------------------------------*
#! /usr/bin/perl -wl
# sort_pod_items
# Tim Maher, tim at teachmeperl.com
# Thu Mar 11 21:13:40 PST 2004
# Quick and dirty program to sort POD list items into ASCIIbetical order
# Doesn't handle nested lists yet, and is in dire need of a more elegant way
# to get item-labels hooked together with their contents
$/=undef;
# Runs in file-slurping mode, so all data presented at once to implicit loop
$_=<DATA>;
# First, split lines into '=item' labels for POD-list items,
# followed by associated contents
@fields= split /(^=item[^\n]*?\n)/m, $_;
# Now join labels with following contents, so each such pair is in one chunk
# Input array of 10 items reduced to output array of 5, etc.
for ( $i=0; $i < @fields; $i++ ) {
( $fields[$i] =~ /^=item\b/ ) and
push @fields2, "$fields[$i]$fields[$i++ + 1]";
}
# Now use Schwartzian Transform to sort by labels of list items and print
print map { $_->[1] }
sort { $a->[0] cmp $b->[0] }
map {
if ( $_ =~ /^=item\s+([^\n]+)\n/ ) { # $1 is label for list item
[ $1 , $_ ]
} else {
die "Bad data: records must start with =item\n";
}
} @fields2 ;
__DATA__
=item This
and stuff was written
=item What
more drivel here
=item Other
getting the idea?
=item That's all
the end
More information about the spug-list
mailing list