These three routines (given inside a simple utility program) perform full justification of text by expanding the spaces between words until the line meets the specified width.

Each routine uses a different method, which basically means they use a different starting point within the line and work out from there. I think that middle_out() looks the best, followed closely by right_to_left(). Your call, though.

These routines are simple. They do not do any reflowing and if the lines start out longer than the width given, they just pass it through unmodified. Update: If you want reflowing, just pass the text through Text::Wrap first.

Significate Update: I posted a new version as a reply below. It simplifies the code in the method somewhat and fixes a few bugs related to getting the options. More info below. :-)

#!/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 (de +fault) --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/(?<!\. ) {2,}/ /g; } if(defined $last_line) { if($last_line !~ /^$/ and $_ !~ /^$/) { $last_line = $METHOD->($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 mid +dle 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 the +re 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; }

In reply to Full justification - 3 methods by bbfu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.