# -*- shell-script -*-
# Copyright (C) 2008, 2010, 2011 Rocky Bernstein rocky@gnu.org
#
# 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, 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place, Suite 330, Boston,
# MA 02111 USA.
#
# Code ported from my Ruby code which is in turn ported from a routine
# from Python.
# columnize a blank-delmited string $1 with maximum column width $2,
# separate columns with $3. The column width defaults to 80 and the
# column separator is two spaces. However if we are using ksh93t or
# greater, then $1 is where the return value is to go and the other
# parameters are shifted by 1: $2 contains the list to columnize and
# $3 the maximum width, etc.
columnize() {
typeset -i displaywidth=${1:-80}
(($# < 2)) && typeset colsep=' ' || typeset colsep="$2"
typeset -i list_size=${#list[@]}
if ((list_size == 0)) ; then
columnized=('<empty>')
return
fi
if ((1 == list_size)); then
columnized=("${list[0]}")
return
fi
# Consider arranging list in 1 rows total, then 2 rows...
# Stop when at the smallest number of rows which
# can be arranged less than the display width.
typeset -i nrows=0
typeset -i ncols=0
typeset -a colwidths=()
typeset -i i=0
for (( i=0; i<list_size; i++ )) ; do
typeset -a colwidths=()
((nrows++))
((ncols=(list_size + nrows-1) / nrows))
typeset -i totwidth=-${#colsep}
typeset -i col
for (( col=0; col<=(ncols-1); col++ )); do
# get max column width for this column
colwidth=0
typeset -i row
for (( row=0; row<=(nrows-1); row++ )); do
typeset -i j
((j=row + nrows*col)) # [rows, cols]
if ((j >= list_size)); then
break
fi
typeset item="${list[j]}"
((colwidth < ${#item})) && colwidth=${#item}
done
colwidths+=($colwidth)
((totwidth+=colwidth + ${#colsep}))
if ((totwidth > displaywidth)); then
break
fi
done
if ((totwidth <= displaywidth)); then
break
fi
done
# The smallest number of rows computed and the
# max widths for each column has been obtained.
# Now we just have to format each of the
# rows.
for (( row=0; row<nrows; row++ )); do
typeset -i text_size=0
typeset -a texts=()
for ((col=0; col<ncols; col++)); do
((i=row + nrows*col))
if ((i >= list_size)); then
item=''
else
item="${list[i]}"
fi
texts[$text_size]="$item"
((text_size++))
done
while (( text_size > 0 )) && [[ ${texts[text_size-1]} == '' ]] ; do
((text_size--))
unset texts[$text_size]
done
text_row=''
text_cell=''
for (( col=0; col<text_size; col++ )); do
fmt="%-${colwidths[col]}s"
text_cell=$(printf $fmt "${texts[col]}")
text_row+="${text_cell}"
((col != text_size-1)) && text_row+="${colsep}"
done
columnized+=("$text_row")
done
}
if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
#
print_columns() {
unset columnized
typeset -a columnized
typeset -a list
list=($1)
columnize $2 $3
typeset -i i
echo '==============='
for ((i=0; i<${#columnized[@]}; i++)) ; do
printf "${columnized[$i]}\n"
done
}
print_columns
print_columns ''
print_columns oneitem
print_columns 'a 2 c' 10 ', '
print_columns \
' one two three
4ne 5wo 6hree
7ne 8wo 9hree
10e 11o 12ree' 18
print_columns \
' 1 two three
for 5 six
7 8' 12
print_columns \
' 1 two 3
for 5 six
7 8' 12
fi