http://qs321.pair.com?node_id=101673
Category: Text Processing
Author/Contact Info Kingsley Gordon kingman@ncf.ca
Description: This module reformats paragraphs (delimited by \n\n) into equal-width or varied-width columns by interpreting a format string. See the synopsis for a couple of examples.

I just read yesterday that formats will be a module in perl 6 so I guess there's already something like this out there?

package New_Format;

# See the bottom of this file for the POD documentation.  Search for t
+he
# string '=head'.

use strict;
use diagnostics;
use vars qw(@ISA @EXPORT $VERSION);
use subs qw(analyze pad_paragraphs_array create_format print_it);
use Exporter;
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(new_format);

my ($format_block, $columns, @paragraphs, $str, $number_of_paragraphs,
+  $number_of_cells_in_last_row, $number_of_cells_up_to_last_row, $num
+ber_of_full_rows, $padding);

sub new_format {
    local $/ = "\n\n";
    @paragraphs = <>;
    ($format_block, $columns)= @_;    
    $str = &_get_main_format_vars;
    analyze;
    pad_paragraphs_array;
    analyze;
    eval create_format;
    print_it(sub {write});
    #sanity_check;
}

sub create_format {
    # Create the format block; note the spaces at the end.
    my $format = "format STDOUT =\n";
    my $cnt = $format_block =~ tr/^/^/;
    if ($cnt == 1) { $format .= $format_block x $columns . "\n" }
    else { $format .= $format_block . "\n" } 
    $format .= $str;
    $format .= "\n\n.\n";
    return $format;
}

sub analyze {
    $number_of_paragraphs = $#paragraphs+1;
    $number_of_cells_in_last_row = ($number_of_paragraphs % $columns);
    $number_of_cells_up_to_last_row = $number_of_paragraphs - ($number
+_of_paragraphs % $columns);
    $number_of_full_rows = $number_of_cells_up_to_last_row / $columns;
    $padding = $columns - $number_of_cells_in_last_row;
}

sub pad_paragraphs_array {
    # push empty elements to @paragraphs
    for (my $x = 1; $x <= $padding; $x++) {
    push @paragraphs, "\n";
    }
}

sub sanity_check {
    print <<EOQ;
    number of columns: $columns
    number of paragraphs: $number_of_paragraphs
    number of cells up to last row: $number_of_cells_up_to_last_row
    number of cells to pad: $padding
    number of cells in last row: $number_of_cells_in_last_row
    number_of_full_rows: $number_of_full_rows
EOQ
}

sub _get_main_format_vars {
    my $format_vars;
    # Zero indexed
    for (my $i = 0; $i <= $columns-1; $i++) {
        $format_vars .=    '$_[' . "$i" . '], ';
    }
    $format_vars =~ s/, $//;
    return $format_vars;
}

sub print_it {
    my $sub = $_[0];
    for (my $y = 1; $y <= $number_of_full_rows; $y++) {
        &$sub(splice(@paragraphs, 0, $columns));
    }
}

1;

### POD ###

=head1 NAME

New_Format - turn paragraphs into columns via a format.

=head1 SYNOPSIS

    #!/usr/bin/perl -w

    use strict;
    use New_Format;
    

    # To create a format with equal-width columns specify one field an
+d the number
    # of times you'd like it repeated (the number of columns).

    # five columns
    # new_format('^<<<<<<<<<<<<<<<<<<~~  ', 5);

    # three columns
    # new_format('^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~  ', 3);

    # To create a format with varied-width columns specify the entire 
+format one
    # line and the total number of columns.

    new_format('^<<<<<<<<<<<<<<<<<~~  ^||||||||||||||||||||~~  ^>>>>>>
+>>>>>>>>>>>>~~  ^>>>>>>>>>>>>>>>>>>~~  ', 4);

    __DATA__
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr,  sed diam
+ nonumy
    eirmod tempor invidunt ut labore et dolore magna aliquyam erat, se
+d diam
    voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
+ Stet clita
    kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit 
+amet. Lorem
    ipsum dolor sit amet, consetetur sadipscing elitr,  sed diam nonum
+y eirmod
    tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
+voluptua. At
    vero eos et accusam et justo duo dolores et ea rebum. Stet clita k
+asd
    gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+ Lorem ipsum
    dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirm
+od tempor
    invidunt ut labore et dolore magna aliquyam erat, sed diam voluptu
+a. At vero
    eos et accusam et justo duo dolores et ea rebum. Stet clita kasd g
+ubergren, no
    sea takimata sanctus est Lorem ipsum dolor sit amet.

    Duis autem vel eum iriure dolor in hendrerit in vulputate velit es
+se molestie
    consequat, vel illum dolore eu feugiat nulla facilisis at vero ero
+s et accumsan
    et iusto odio dignissim qui blandit praesent luptatum zzril deleni
+t augue duis
    dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, cons
+ectetuer
    adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoree
+t dolore
    magna aliquam erat volutpat.

    Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorp
+er suscipit
    lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel e
+um iriure
    dolor in hendrerit in vulputate velit esse molestie consequat, vel
+ illum dolore
    eu feugiat nulla facilisis at vero eros et accumsan et iusto odio 
+dignissim qui
    blandit praesent luptatum zzril delenit augue duis dolore te feuga
+it nulla
    facilisi.

    Nam liber tempor cum soluta nobis eleifend option congue nihil imp
+erdiet doming
    id quod mazim placerat facer possim assum. Lorem ipsum dolor sit a
+met,
    consectetuer adipiscing elit, sed diam nonummy nibh euismod tincid
+unt ut
    laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim 
+veniam, quis
    nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliqui
+p ex ea
    commodo consequat.

    Duis autem vel eum iriure dolor in hendrerit in vulputate velit es
+se molestie
    consequat, vel illum dolore eu feugiat nulla facilisis.

    At vero eos et accusam et justo duo dolores et ea rebum. Stet clit
+a kasd
    gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+ Lorem ipsum
    dolor sit amet, consetetur sadipscing elitr,  sed diam nonumy eirm
+od tempor
    invidunt ut labore et dolore magna aliquyam erat, sed diam voluptu
+a. At vero
    eos et accusam et justo duo dolores et ea rebum. Stet clita kasd g
+ubergren, no
    sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum d
+olor sit
    amet, consetetur sadipscing elitr,  At accusam aliquyam diam diam 
+dolore
    dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt j
+usto labore
    Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed t
+akimata ut
    vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor s
+it amet,
    consetetur sadipscing elitr,  sed diam nonumy eirmod tempor invidu
+nt ut labore
    et dolore magna aliquyam erat. 

    Consetetur sadipscing elitr,  sed diam nonumy eirmod tempor invidu
+nt ut labore
    et dolore magna aliquyam erat, sed diam voluptua. At vero eos et a
+ccusam et
    justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea t
+akimata
    sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet
+, consetetur
    sadipscing elitr,  sed diam nonumy eirmod tempor invidunt ut labor
+e et dolore
    magna aliquyam erat, sed diam voluptua. At vero eos et accusam et 
+justo duo
    dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sa
+nctus est
    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
+ sadipscing
    elitr,  sed diam nonumy eirmod tempor invidunt ut labore et dolore
+ magna
    aliquyam erat, sed diam voluptua. At vero eos et accusam et justo 
+duo dolores
    et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus es
+t Lorem ipsum
    dolor sit amet.

=head1 DESCRIPTION

This module reformats paragraphs (delimited by \n\n) into equal-width 
+or
varied-width columns by interpreting a format string.  See the synopsi
+s for a
couple of examples.

=head1 AUTHOR

Kingsley Gordon E<lt>kingman@ncf.caE<gt>

 Thu Aug  2 11:00:04 EDT 2001

=cut