#!/usr/bin/perl -wn BEGIN { $LINE_WIDTH = 75; $METHOD = 'middle_out'; $CONDENSE = 1; use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( 'condense!' => \$CONDENSE, 'm|middle' => sub { $METHOD = 'middle_out' }, 'l|left' => sub { $METHOD = 'left_to_right' }, 'r|right' => sub { $METHOD = 'right_to_left' }, 'w|width=i' => \$LINE_WIDTH, 'help' => sub { my $self = $0; $self =~ s/^.*\///; die << "USAGE"; Usage: $self [OPTION]... [FILE]... Fully justifies a stream of text using one of three different methods. --condense condense multiple spaces before justifying (default) --nocondense -m, --middle use the middle-out method (default) -l, --left use the left-to-right method -r, --right use the right-to-left method -w, --width=WIDTH set the line-width to WIDTH (default is 75) --help display this help and exit The different methods describe where $self starts expanding spaces to get lines to be the appropriate width. For example, middle-out starts in the middle of the line, expanding spaces in both directions. The middle-out method usually looks best, although right-to-left is some- times better. USAGE }, ); } if($CONDENSE) { s/^ +| +$//g; s/(?($last_line, $LINE_WIDTH); } print $last_line; } $last_line = $_; END { print $last_line if defined $last_line } sub middle_out { my $line = shift; my $width = shift; while(length($line) < $width) { my $pr = my $pf = int(length($line) / 2); # Start from the middle until($pr == -1 and $pf == -1) { $pr = rindex $line, ' ', $pr; if($pr > -1) { substr $line, $pr, 1, ' '; --$pr; # Skip the space that was there. ++$pf; ++$pf; # Adjust $pf to match what's really there now last unless(length($line) < $width); } $pf = index $line, ' ', $pf; if($pf > -1) { substr $line, $pf, 1, ' '; ++$pf; ++$pf; # Skip the two spaces we just made last unless(length($line) < $width); } } } return $line; } sub right_to_left { my $line = shift; my $width = shift; while(length($line) < $width) { my $pr = rindex $line, ' '; while($pr >= 0 and length($line) < $width) { substr $line, $pr, 1, ' '; --$pr; # Skip the space that was there $pr = rindex $line, ' ', $pr; } } return $line; } sub left_to_right { my $line = shift; my $width = shift; my $width = shift; while(length($line) < $width) { my $pr = rindex $line, ' '; while($pr >= 0 and length($line) < $width) { substr $line, $pr, 1, ' '; --$pr; # Skip the space that was there $pr = rindex $line, ' ', $pr; } } return $line; } sub left_to_right { my $line = shift; my $width = shift; while(length($line) < $width) { my $pf = index $line, ' '; while($pf >= 0 and length($line) < $width) { substr $line, $pf, 1, ' '; ++$pf; # Skip the space that was there ++$pf; # Skip the extra space we just put in $pf = index $line, ' ', $pf; } } return $line; }