# # By Mohd Yunus Sharum (youknows@gmail.com) # Universiti Putra Malaysia, Malaysia. # # Copyright (C) 2006 Mohd Yunus Sharum # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details. # # http://www.gnu.org/licenses/gpl.html#SEC1 # use strict; # justification codes - used by alignColumns() #-------------- use constant ALIGN_LEFT => -1; use constant ALIGN_CENTER => 0; use constant ALIGN_RIGHT => 1; # word separator - used by alignColumns() #-------------- my $separator = '\s,.\-\+'; my $not_separator = '^'.$separator; # functions' declaration #-------------- sub alignColumns($$$@); # align data in multi columns (basic function) sub alignRows($$$@); # same, but extended for multiple rows, no numbering features sub numberedAlignRows($$$@); # same, but extended with numbered rows #-------------- # FUNCTION: # SAMPLE PROGRAM - demonstrate the capability of aligner functions # # IN: # none # OUT: # none #-------------- sub main { print "Not auto numbered\n"; alignRows("", # output handle (default STDOUT) [ALIGN_LEFT, ALIGN_LEFT], # column alignment [5, 50], # list of columns width ["Id", "Residue"], # list of data ["-----", "----------"], ["123.12", "AAABACACCA ". "AAABACACCACAGGATCCACACTCAAGTTT ". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAGGATCCACACTAGGATCCACACTGGATCCACACT" ], ["A342", "AGGATCCACAGGA"], ["B652", "AGGATCCACACTAGGATCCACACTAGGATCCACACT" ]); print "\n\n"; print "auto Numbered\n"; numberedAlignRows("", # output handle (default STDOUT) [ALIGN_LEFT, ALIGN_LEFT], # column alignment [5, 50], # list of columns width ["Id", "Residue"], # list of data ["-----", "----------"], ["123.12", "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAGGATCCACACTAGGATCCACACTGGATCCACACT". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAGGATCCACACTAGGATCCACACTGGATCCACACT". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAGGATCCACACTAGGATCCACACTGGATCCACACT" ], ["A342", "AGGATCCACAGGA"], ["B652", "AGGATCCACACTAGGATCCACACTAGGATCCACACT" ]); } main(); #-------------- # FUNCTION: # Align data in column based on column width (only for single row) # IN: # Filehandle: File handle to send output (default STDOUT) # Justifies: List of justifying codes (right,center or left) # ColsWidth: List of columns' width # Data: List of data to display (for single row) # OUT: # none #-------------- sub alignColumns($$$@) { my ($fileHandle, $justifies, $colsWidth, @data) = @_; $fileHandle = *STDOUT if !$fileHandle; my $totCols = scalar @$colsWidth; my ($inline, $strLen); my $finished = 0; while(!$finished) { $finished = 1; # check each columns #-------------- for my $colNum (0..$totCols-1) { $data[$colNum] =~ s/^\s+//; $strLen = length($data[$colNum]); $inline = ""; if($strLen > 0) { # check if data exceed column's size #-------------- if ($strLen > $colsWidth->[$colNum]) { $inline = substr($data[$colNum], 0, $colsWidth->[$colNum]); $data[$colNum] = substr($data[$colNum], $colsWidth->[$colNum]); # check if single word is splitted #-------------- if ($data[$colNum] =~ /^[$not_separator]/o and $inline =~ /[$not_separator]$/o and $inline =~ /[$separator]/o) { if ($inline =~ s/(.+[$separator]+)(.+)$/$1/) { $data[$colNum] = $2 . $data[$colNum]; } } $finished = 0; } else { $inline = substr($data[$colNum], 0); $data[$colNum] = ""; } } $inline =~ s/\s+$//; # print data, justified #-------------- print $fileHandle (" | ") if $colNum > 0; if($justifies->[$colNum] == ALIGN_RIGHT) { printf $fileHandle "%*s", $colsWidth->[$colNum], $inline; } elsif($justifies->[$colNum] == ALIGN_LEFT) { printf $fileHandle "%-*s", $colsWidth->[$colNum], $inline; } else { # centered #-------------- my $lenSpc = ($colsWidth->[$colNum] - length($inline)) / 2; my $space = ""; $space = sprintf("%*s", $lenSpc, " ") if $lenSpc > 0; printf $fileHandle "%-*s", $colsWidth->[$colNum], $space.$inline; } } print $fileHandle "\n"; } } #-------------- # FUNCTION: # Align and display data in rows. # Use function alignColumns() to align data in single row # IN: # Filehandle: File handle to send output (default STDOUT) # Justifies: List of justifying codes (right,center or left) # ColsWidth: List of columns' width # Rows: List of data to display (in mutiple rows / 2 dimensional data) # OUT: # none #-------------- sub alignRows($$$@) { my ($fileHandle, $justifies, $colsWidth, @rows) = @_; for my $row (@rows) { alignColumns($fileHandle, $justifies, $colsWidth, @$row); } } #-------------- # FUNCTION: # Display data in numbered rows # Notes - assuming first two rows of @rows are columns' headers # Use function alignRows() to align data # IN: # Filehandle: File handle to send output (default STDOUT) # Justifies: List of justifying codes (right,center or left) # ColsWidth: List of columns' width # Rows: List of data to display (in mutiple rows / 2 dimensional data) # OUT: # none #-------------- sub numberedAlignRows($$$@) { my ($fileHandle, $justifies, $colsWidth, @rows) = @_; # add new column #-------------- unshift(@{$rows[0]}, "No.") ; # add new column's header unshift(@{$rows[1]}, "-----") ; # add new column's separator my $count = 1; my $num = 1; for my $row (@rows) { unshift(@$row, $num++) if $count > 2; # add number on each row $count++; } unshift(@$justifies, ALIGN_RIGHT); # add new column's justification code unshift(@$colsWidth, 5); # add new column's width # call alignment's function #-------------- alignRows($fileHandle, $justifies, $colsWidth, @rows); }