#!/usr/bin/perl # align - filter to align columns of text # Steve Kinzler, kinzler@cs.indiana.edu, Jun 00/Oct 01/Dec 01 # see website http://www.cs.indiana.edu/~kinzler/align/ # http://www.cs.indiana.edu/~kinzler/home.html#unix $version = '1.7.1'; require 5.000; $usage = < $@"), $eexpr = '' if $@; $numpatt = '^([-+]?)(?:(\d+)(\.?\d*)|(\.\d+))$'; ############################################################################### chomp(@in = <>); @do = ($eexpr eq '') ? @in : grep(eval $eexpr, @in); $opt_s = grep(/ \t|\t /, @do) ? '\s+' : grep(/\t\t/, @do) ? '\t+' : grep(/\t/, @do) ? '\t' : grep(/ /, @do) ? ' +' : ' ' if $opt_s eq 'DeFaUlT'; $opt_j = ($opt_s =~ /^(\\t|\t)/) ? 't' : ($opt_s =~ /^(\\s|\/)/) ? 's' : '_' if $opt_j eq 'DeFaUlT'; $opt_s =~ s/^\///; while (@do) { @cols = split(/$opt_s/, shift @do); @a = @aligns; @aligns = (); @nI = @numwI; @numwI = (); @w = @widths; @widths = (); @nF = @numwF; @numwF = (); foreach (@cols) { @isnum = /$numpatt/o; push(@aligns, (($a = shift @a) =~ /[^n]/) ? $a : (@isnum) ? 'n' : 'l'); push(@widths, &max(shift @w, length($_))); push(@numwI, &max(shift @nI, length($isnum[0] . $isnum[1]))); push(@numwF, &max(shift @nF, length($isnum[2] . $isnum[3]))); } push(@aligns, @a); push(@numwI, @nI); push(@widths, @w); push(@numwF, @nF); } $a = join('', @aligns); substr($opt_a, $d, 1) = substr($a, $d, 1) || 'l' while ($d = index($opt_a, 'd')) >= 0; $opt_a = $a || 'l' unless $opt_a; $opt_j = 's' if $opt_a =~ /[^l]/ && $opt_j eq 't'; $opt_j .= ':FlAg' unless $opt_j =~ s/^\///; ($tab, $tlen) = ($opt_j =~ /^[ts_]:FlAg$/) ? ("\t", $opt_t) : ($opt_j, length($opt_j)); @a = split(//, $opt_a); @nI = @numwI; @nF = @numwF; foreach (@widths) { $_ = &max($_, shift(@nI) + shift(@nF)) if (($#a) ? shift @a : $a[0]) =~ /^[nN]$/; } foreach (@in) { $opt_e ne '' && print($_, $/), next if $eexpr ne '' && ! eval $eexpr; @cols = split(/$opt_s/); $llen = $hold = 0; @a = split(//, $opt_a); @w = @widths; @nF = @numwF; while (@cols) { $a = ($#a) ? shift @a : $a[0]; $_ = shift @cols; $nF = shift @nF; @isnum = /$numpatt/o if $a =~ /^[nN]$/; if ($a eq 'N' && @isnum) { s/$/./ if $nF && ! /\./; ($F) = /(\.\d*)$/, s/$/'0' x ($nF - length($F))/e; @isnum = /$numpatt/o; } $l = length($_); $G = shift(@w) - $l; $g = $og = ($a eq 'l') ? 0 : ($a eq 'r') ? $G : ($a eq 'c') ? int($G / 2) : ($a eq 'k') ? ($G = 0) : (! @isnum) ? $G : $G - ($nF - length($isnum[2] . $isnum[3])); $g += $hold + $opt_g if $#w < $#widths - 1; if ($opt_j eq 't:FlAg') { $ns = &min($g, $ex = ($llen + $g) % $tlen); $nt = int(($g - $ns + $tlen - .000001) / $tlen); $g += $tlen - $ex if $ns; $j = $tab x $nt . (($ns) ? $tab : ''); } elsif ($opt_j eq 's:FlAg') { $ns = &min($g, ($llen + $g) % $tlen); $nt = int(($g - $ns + $tlen - .000001) / $tlen); $j = $tab x $nt . ' ' x $ns; } elsif ($opt_j eq '_:FlAg') { $j = ' ' x $g; } else { $ns = $hold % $tlen; $nt = int($hold / $tlen); $j = substr($tab, $tlen - $ns) . $tab x $nt; $ns = ($g - $hold) % $tlen; $nt = int(($g - $hold) / $tlen); $j .= $tab x $nt . substr($tab, 0, $ns); } print $j, $_; $llen += $l + $g; $hold = $G - $og; } print $/; } ############################################################################### sub max { ($_[0] >= $_[1]) ? $_[0] : $_[1] } sub min { ($_[0] <= $_[1]) ? $_[0] : $_[1] }