def columnize(*args)
list, opts = parse_columnize_options(args)
return '' if not list.is_a?(Array)
return "<empty>\n" if list.empty?
l = list.map{|li| li.to_s}
return "%s%s%s\n" % [opts[:array_prefix], l[0],
opts[:array_suffix]] if 1 == l.size
nrows = ncols = 0
colwidths = []
if opts[:displaywidth] - opts[:lineprefix].length < 4
opts[:displaywidth] = opts[:lineprefix].length + 4
else
opts[:displaywidth] -= opts[:lineprefix].length
end
if opts[:arrange_vertical]
array_index = lambda {|num_rows, row, col| num_rows*col + row }
1.upto(l.size-1) do |_nrows|
nrows = _nrows
ncols = (l.size + nrows-1) / nrows
colwidths = []
totwidth = -opts[:colsep].length
0.upto(ncols-1) do |col|
colwidth = 0
0.upto(nrows-1) do |_row|
row = _row
i = array_index.call(nrows, row, col)
break if i >= l.size
colwidth = [colwidth, cell_size(l[i], opts[:term_adjust])].max
end
colwidths.push(colwidth)
totwidth += colwidth + opts[:colsep].length
if totwidth > opts[:displaywidth]
ncols = col
break
end
end
break if totwidth <= opts[:displaywidth]
end
ncols = 1 if ncols < 1
nrows = l.size if ncols == 1
s = ''
0.upto(nrows-1) do |_row|
row = _row
texts = []
0.upto(ncols-1) do |col|
i = array_index.call(nrows, row, col)
if i >= l.size
x = ''
else
x = l[i]
end
texts.push(x)
end
texts.pop while !texts.empty? and texts[-1] == ''
if texts.size > 0
0.upto(texts.size-1) do |col|
unless ncols == 1 && opts[:ljust]
if opts[:ljust]
texts[col] = texts[col].ljust(colwidths[col])
else
texts[col] = texts[col].rjust(colwidths[col])
end
end
end
s += "%s%s\n" % [opts[:lineprefix], texts.join(opts[:colsep])]
end
end
return s
else
array_index = lambda {|num_rows, row, col| ncols*(row-1) + col }
totwidth = i = rounded_size = 0
l.size.downto(1) 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 = -opts[:colsep].length
colwidth = row = 0
0.upto(ncols-1) do |col|
1.upto(nrows) do |_row|
row = _row
i = array_index.call(nrows, row, col)
break if i >= l.size
colwidth = [colwidth, cell_size(l[i], opts[:term_adjust])].max
end
colwidths.push(colwidth)
totwidth += colwidth + opts[:colsep].length
break if totwidth > opts[:displaywidth];
end
if totwidth <= opts[:displaywidth]
nrows = row
break
elsif totwidth >= opts[:displaywidth]
break
end
end
break if totwidth <= opts[:displaywidth] and i >= rounded_size-1
end
ncols = 1 if ncols < 1
nrows = l.size if ncols == 1
s = ''
prefix = if opts[:array_prefix].empty?
opts[:lineprefix]
else
opts[:array_prefix]
end
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.push(x)
end
0.upto(texts.size-1) do |col|
unless ncols == 1 && opts[:ljust]
if opts[:ljust]
texts[col] = texts[col].ljust(colwidths[col]) if ncols != 1
else
texts[col] = texts[col].rjust(colwidths[col])
end
end
end
s += "%s%s\n" % [prefix, texts.join(opts[:colsep])]
prefix = opts[:lineprefix]
end
s += opts[:array_suffix]
return s
end
end