def columnize(list, displaywidth=80, colsep = ' ',
arrange_vertical=true, ljust=true, lineprefix='')
if not list.is_a?(Array)
return ''
end
if list.size == 0
return "<empty>\n"
end
l = list.map{|li| li.to_s}
if 1 == l.size
return "#{l[0]}\n"
end
nrows = ncols = 0
colwidths = []
displaywidth = [4, displaywidth - lineprefix.length].max
if arrange_vertical
array_index = lambda {|nrows, row, col| nrows*col + row }
1.upto(l.size-1) do |_nrows|
nrows = _nrows
ncols = (l.size + nrows-1) / nrows
colwidths = []
totwidth = -colsep.length
0.upto(ncols-1) do |_col|
col = _col
colwidth = 0
0.upto(nrows-1) do |_row|
row = _row
i = array_index.call(nrows, row, col)
if i >= l.size
break
end
colwidth = [colwidth, l[i].size].max
end
colwidths << colwidth
totwidth += colwidth + colsep.length
if totwidth > displaywidth
ncols = col
break
end
end
if totwidth <= displaywidth
break
end
end
s = ''
0.upto(nrows-1) do |_row|
row = _row
texts = []
0.upto(ncols-1) do |_col|
col = _col
i = array_index.call(nrows, row, col)
if i >= l.size
x = ""
else
x = l[i]
end
texts << x
end
while texts and texts[-1] == ''
texts = texts[0..-2]
end
if texts.size > 0
0.upto(texts.size-1) do |_col|
col = _col
if ljust
texts[col] = texts[col].ljust(colwidths[col])
else
texts[col] = texts[col].rjust(colwidths[col])
end
end
s += "%s%s\n" % [lineprefix, texts.join(colsep)]
end
end
return s
else
array_index = lambda {|nrows, row, col| ncols*(row-1) + col }
totwidth = i = rounded_size = 0
l.size.downto(0) do |_ncols|
ncols = _ncols
min_rows = (l.size+ncols-1) / ncols
min_rows.upto(l.size) do |_nrows|
nrows = _nrows
rounded_size = nrows * ncols
colwidths = []
totwidth = -colsep.length
colwidth = row = 0
0.upto(ncols-1) do |_col|
col = _col
1.upto(nrows) do |_row|
row = _row
i = array_index.call(nrows, row, col)
if i >= rounded_size
break
elsif i < l.size
colwidth = [colwidth, l[i].size].max
end
end
colwidths << colwidth
totwidth += colwidth + colsep.length
if totwidth > displaywidth
break
end
end
if totwidth <= displaywidth
nrows = row
break
elsif totwidth >= displaywidth
break
end
end
if totwidth <= displaywidth and i >= rounded_size-1
break
end
end
s = ''
1.upto(nrows) do |row|
texts = []
0.upto(ncols-1) do |col|
i = array_index.call(nrows, row, col)
if i >= l.size
break
else
x = l[i]
end
texts << x
end
0.upto(texts.size-1) do |col|
if ljust
texts[col] = texts[col].ljust(colwidths[col])
else
texts[col] = texts[col].rjust(colwidths[col])
end
end
s += "%s%s\n" % [lineprefix, texts.join(colsep)]
end
return s
end
end