[alt.sources] row-major multi-column printouts

tchrist@convexe.uucp (Tom Christiansen) (10/26/89)

here's one that prints out its input in multi-column format.
hah, you say, pr already does that!  true, but pr uses a 
column-major order and this (i call it "words")  does so in 
a row-major one.  to see what i mean, compare:
	% ls
	% ls | pr -l1 -t -5
	% ls | words
note lines 1 and 3 produce the same output, but you can't massage
pr into doing this.    in other words, (`ls -1 | words`) eq (`ls -C`).

it shows a good use of indexed arrays, as well as more dynamic
code generation via sprintf and eval.  it derives your current cols 
from your termcap entry.  i could have read from the output
of stty, but that's slow, or i could have used the ioctl()
from perl3, but i that's system dependent.  this will work 
with perl2.


--tom

#!/usr/local/bin/perl -w

sub eol { ($elt+1) % $cols == 0; }	# is this the last elt on line?

$maxlen = 1;	# widest string yet seen

$cols = ($ENV{"TERMCAP"} =~ /:co#(\d+):/)  # parse termcap
	    ? $1 	# from termcap if found
	    : 80; 	# else default to 80


while (<>) { 	# read stdin into $_
    s/\s+$//;
    $maxlen = $mylen if (($mylen = length($_)) > $maxlen);
    push(list, $_);
} 

$maxlen += 1;  # spaces

$cols = int($cols / $maxlen);
$rows = int(($#list+$cols) / $cols);
$mask = sprintf("%%-%ds ", $maxlen);

for ($elt = 0; $elt < $rows * $cols; $elt++) { 
    $target =  ($elt%$cols) * $rows + int(($elt/$cols));
    $piece = sprintf($mask, $target < ($#list+1) ? $list[$target] : "");
    $piece =~ s/\s+$// if do eol();  # don't blank pad to eol of line
    print $piece;
    print "\n" if do eol();
}

print "\n" if do eol();

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"