#!/usr/bin/perl -w
# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl>
# Web: http://www.xs4all.nl/~itsme/
#      http://wiki.xda-developers.com/
#
# $Id$
#
#  script that transposes a tab separated matrix

use strict;

my $ColumnSeparator= "\\s+";
my $StripLeadingSpace= 1;
my $AlignColumns;
use Getopt::Long;
Getopt::Long::Configure ("bundling");

sub usage {
    return <<__EOF__
Usage: transpose [options] [files]
   -a    align columns
   -l    don't strip leading spaces
   -t RE specify column separator
__EOF__
}
GetOptions(
    # using both 't' and 's', since i can't seem to remember whether it was -t or -s
    "t=s" => sub { $ColumnSeparator= parseColumnSeparator($_[1]); },
    "l!"   => \$StripLeadingSpace,
    "a"   => \$AlignColumns,
) or die usage();

sub parseColumnSeparator {
    my ($cs)= @_;
    if ($cs =~ /\/(.*)\//) {
        return qr($1);
    }
    else {
        return eval('"$cs"');
    }
}
my $ncols;
my @rows;
my $outputseparator;
my @maxwidth;
while(<>) {
    chomp;
    s/^\s+// if ($StripLeadingSpace);
    if (!defined $outputseparator) {
        if (/$ColumnSeparator/) {
            $outputseparator = $&;
        }
    }

    my @cols=  split($ColumnSeparator, $_);
    my $maxwidth;
    for my $c (0..$#cols) {
        $maxwidth=length($cols[$c]) if (!defined $maxwidth || $maxwidth<length($cols[$c]));
    }
    push @maxwidth, $maxwidth;
    push @rows, \@cols;
    $ncols= (!defined $ncols || $ncols<scalar @cols)?scalar @cols:$ncols;
}
my $nrows= scalar @rows;

if (!defined $outputseparator) {
    $outputseparator= "";
}
for my $col (0..$ncols-1) {
    for my $row (0..$nrows-1) {
        print $outputseparator if ($row && !$AlignColumns);
        if (defined $rows[$row] && defined $rows[$row][$col]) {
            if ($AlignColumns) {
                printf("%*s", $maxwidth[$row]+1, $rows[$row][$col]);
            }
            else {
                print $rows[$row][$col];
            }
        }
    }
    print "\n";
}

