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);
}