def table(items, opts={}, &block)
items = items.map &block if block_given?
widths = []
items.each do |item|
item.each_with_index do |s, i|
item[i] = s.to_s
widths[i] = [widths[i] || 0, s.length].max if s.respond_to?(:length)
end
end
align = opts[:align] || []
join = opts[:join] || ' '
if opts[:header]
sep = opts[:separator] || "="
ary = Array.new(opts[:header].length)
items.unshift ary.each_with_index {|obj, idx| ary[idx] = sep.to_s * (widths[idx] || 1)}
items.unshift(opts[:header])
end
items.map do |item|
item.each_with_index.map{ |s,i| s.send((align[i] == :right ? :rjust : :ljust), widths[i], ' ') }.join(join).strip
end
end