#!/usr/bin/perl -t
use 5.001 ; use strict ; use warnings ; # 5.011 で動作確認
use Getopt::Std ; getopts './:svM:', \my%o ;
use Term::ANSIColor qw[ :constants ] ; $Term::ANSIColor::AUTORESET = 1 ;


my $sep = $o{'/'} // "\t"  ; # 区切り文字 現状、入力区切りの正規表現として扱われ、出力の区切りとしても使われる。
my $emp0 = $o{'.'} ? '='  : '' ; # 凹んでいた箇所に新たなセルを入れる場合に割り当てられる文字列
my $emp1 = $o{'.'} ? '.' : '' ; # 空文字列のセルに入れる文字列

my @mat ; # 入力の行列を格納する。
my $maxind = 0 ; #入力の横幅の最大値 ; 出力の縦幅

while (<>) {
    chomp ;
    if ( $o{s} ) { 
        s/\s*$//  ; # -s 指定で末尾の空白文字を取り除く。
        if (/^$/) { 
            $. -- ; 
            next ;
        } ; 
    }
    my @F = split /$sep/ , $_ , -1 ;
    #no warnings ;
    eval { do { @F = map eval "$o{M}",  @F } if defined $o{M} } ; # <-- - Taintを検出するモード(-T) の時でも実行できるようにしたつもり。
    @{ $mat[ $. - 1 ] } = @F  ;
    $maxind = $#F if $#F > $maxind  ;
}

for my $i ( 0 .. $maxind ) {
    my @each  ;
    push @each ,  $mat[ $_ ][ $i ] for  0 .. $#mat  ; # 早い
    print join ( "$sep" , map{ m/^$/ ? $emp1 : $_ } map { $_ // $emp0 } @each ) , "\n" ;
}

$0 =~ s|.*/|| ;
my $ocols = $. ; 
my $orows = $maxind + 1 ; 
print STDERR CYAN "$ocols x $orows -> $orows x $ocols (rows x columns) matrix transformation ($0).\n"  if $o{v} ;


## ヘルプの扱い
sub VERSION_MESSAGE {}
sub HELP_MESSAGE {
    use FindBin qw[ $Script $Bin ] ;
    sub EnvJ ( ) { $ENV{LANG} =~ m/^ja_JP/ ? 1 : 0 } ; # # ja_JP.UTF-8 
    sub en( ) { grep ( /^en(g(l(i(sh?)?)?)?)?/i , @ARGV ) ? 1 : 0 } # English という文字列を先頭から2文字以上を含むか 
    sub ja( ) { grep ( /^jp$|^ja(p(a(n?)?)?)?/i , @ARGV ) ? 1 : 0 } # jp または japan という文字列を先頭から2文字以上を含むか 
    sub opt( ) { grep (/^opt(i(o(ns?)?)?)?$/i, @ARGV ) ? 1 : 0 } # options という文字列を先頭から3文字以上含むから
    sub noPOD ( ) { grep (/^no-?p(od?)?\b/i, @ARGV) ? 1 : 0 } # POD を使わないと言う指定がされているかどうか
    my $jd = "JapaneseManual" ;
    my $flagE = ! ja && ( en || ! EnvJ ) ; # 英語にするかどうかのフラグ

    exec "perldoc $0" if $flagE &&  ! opt && ! noPOD   ; 
    $ARGV[1] //= '' ;
    open my $FH , '<' , $0 ;
    while(<$FH>){
        s/\Q'=script='\E/$Script/gi ;
        s/\Q'=bin='\E/$Bin/gi ;
        if ( s/^=head1\b\s*// .. s/^=cut\b\s*// ) { 
            if ( s/^=begin\s+$jd\b\s*// .. s/^=end\s+$jd\b\s*// xor $flagE ) {
                print $_ if ! opt || m/^\s+\-/  ; 
            }
        } 
        #print $_ if /^=head1/ .. /^=cut\b/ and opt ? m/^\s+\-/ : 1 and ( EnvJ && ! en xor s/^=begin $jd\b// .. s/^=end $jd\b// ) ;
    }
    close $FH ;
    exit 0 ;

}


=encoding utf8
=pod
=head1

   transpose -- Transforms the input in the matrix transpose way.

   Program Name : transpose    ('=Bin=')
    
     The whole input is assumed to be seperated by line ending charcter vertically
     and each line of the input is assumed to be separated by tab characters.
     You can specify other characters instead of tab by the specification "-s char".

   Usage Example : 
     
     printf -v "1\t2\n3\t4" | $0   # A matrix (1,2;3,4) will be transposed into (1,3;2,4)
     saikoro -g 3x5 | $0   # Random Matrix will be transposed.

   Options : 
      -/ str ; respecify the separator instead of a tab character.
      -s ; removing the redundant space characters. Useful when you copy the SQL output and pasting into this program.
      -v ; Verbose output such as telling the input and output dimensions.

      -.  ; 入力において空文字列を . に変換し、出力に凹みを埋めたセルには = で埋める。
      -S 'cmd' ; cmd に Perlのコマンドを書くことで、各セルに対する変換ができる。'$_*2' や 's/ab/AB/g; $_ ' などが可能。

 # This program has been made since 2016-02-03(Wed) by Toshiyuki Shimono, as a part of TSV hacking toolset for table data.


=begin JapaneseManual
  プログラム名 : '=SCRIPT='    ('=Bin=')

 入力TSVファイルを転置する。縦方向と横方向が、逆転する。

 使用例 : 
   printf -v "1\t2\n3\t4" | $0   # 行列(1,2;3,4) の転置行列を出力する。
   saikoro -g 3x5 | $0   # 乱数行列の転置行列を出力する。

 オプション: 
   -/ str : 入力と出力の両方の区切り文字を str に変更する。
   -s  : 行の末尾の空白文字を取り除く。そしてその結果空行になった場合も取り除く。入力に余計な空白文字が末尾につく場合に便利。
   -v  : 何行何列の行列を出力をしたかを標準エラー出力に出力する。(Verbose)

   -.  ; 入力において空文字列を . に変換し、出力に凹みを埋めたセルには = で埋める。
   -M 'cmd' ; cmd に Perlのコマンドを書くことで、各セルに対する変換ができる。'$_*2' や 's/ab/AB/g; $_ ' などが可能。
 
 開発メモ : 
   * 空文字列のセルが入力にふくれていたり、列数が入力で異なっていたり、空行が存在した場合には警告を表示する様にしたい。

   # このブログラム transpose は 2016年2月3日(水)から表形式データに対する道具作りの一環として、下野寿之が作成したものである。
   # このプログラムに最後に手を入れたのは、2018年6月4日(月)である。
=end JapaneseManual
=cut