A set of routines to align text within columns. Suitable to build ascii-text based table. (include demo rountine)

I dunno how to make CPAN modules (with POD). sorry. welcome any input/comment/feedback etc. Hopefully someone might find it useful ;)

update : Data (especially text) will be aligned (smartly) in column.
# # 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, bu +t WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY o +r 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 f +unction) sub alignRows($$$@); # same, but extended for multiple rows +, no numbering features sub numberedAlignRows($$$@); # same, but extended with numbered row +s #-------------- # FUNCTION: # SAMPLE PROGRAM - demonstrate the capability of aligner functions # # IN: # none # OUT: # none #-------------- sub main { print "Not auto numbered\n"; alignRows("", # output handle (default STD +OUT) [ALIGN_LEFT, ALIGN_LEFT], # column alignment [5, 50], # list of columns width ["Id", "Residue"], # list of data ["-----", "----------"], ["123.12", "AAABACACCA ". "AAABACACCACAGGATCCACACTCAAGTTT ". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAG +GATCCACACTAGGATCCACACTGGATCCACACT" ], ["A342", "AGGATCCACAGGA"], ["B652", "AGGATCCACACTAGGATCCACACTAGGATCCACACT" ]); print "\n\n"; print "auto Numbered\n"; numberedAlignRows("", # output handle (default STD +OUT) [ALIGN_LEFT, ALIGN_LEFT], # column alignment [5, 50], # list of columns width ["Id", "Residue"], # list of data ["-----", "----------"], ["123.12", "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTA +AAGGATCCACACTAGGATCCACACTGGATCCACACT". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAG +GATCCACACTAGGATCCACACTGGATCCACACT". "AAABACACCACAGGATCCACACTCAAGTTTGGTAGGATCCACACTTTAAAG +GATCCACACTAGGATCCACACTGGATCCACACT" ], ["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], $inli +ne; } elsif($justifies->[$colNum] == ALIGN_LEFT) { printf $fileHandle "%-*s", $colsWidth->[$colNum], $inl +ine; } else { # centered #-------------- my $lenSpc = ($colsWidth->[$colNum] - length($inline)) + / 2; my $space = ""; $space = sprintf("%*s", $lenSpc, " ") if $lenSpc > 0; printf $fileHandle "%-*s", $colsWidth->[$colNum], $spa +ce.$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 dimensi +onal 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 dimensi +onal 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 r +ow $count++; } unshift(@$justifies, ALIGN_RIGHT); # add new column's justifi +cation code unshift(@$colsWidth, 5); # add new column's width # call alignment's function #-------------- alignRows($fileHandle, $justifies, $colsWidth, @rows); }

Replies are listed 'Best First'.
Re: Text aligner (in table)
by Anonymous Monk on Jul 12, 2006 at 03:27 UTC