class Columnize::Columnizer
Constants
- ARRANGE_ARRAY_OPTS
- ATTRS
-
TODO: change colfmt to cell_format; change colsep to something else
- OLD_AND_NEW_KEYS
Attributes
Public Class Methods
Source
# File lib/columnize/columnize.rb, line 14 def initialize(list=[], opts={}) self.list = list self.opts = DEFAULT_OPTS.merge(opts) end
Public Instance Methods
Source
# File lib/columnize/columnize.rb, line 133 def arrange_by_column(list, nrows, ncols) (0...ncols).map do |i| (0..nrows-1).inject([]) do |row, j| k = i + (j * ncols) k < list.length ? row << list[k] : row end end end
Given list
, ncols
, nrows
, arrange the one-dimensional array into a 2-dimensional lists of lists organized by columns.
In either horizontal or vertical arrangement, we will need to access this for the list data or for the width information.
Here is an example: arrange_by_column
((1..5).to_a, 2, 3) =>
[[1,3,5], [2,4]]
Source
# File lib/columnize/columnize.rb, line 119 def arrange_by_row(list, nrows, ncols) (0...nrows).map {|r| list[r*ncols, ncols] }.compact end
Given list
, ncols
, nrows
, arrange the one-dimensional array into a 2-dimensional lists of lists organized by rows.
In either horizontal or vertical arrangement, we will need to access this for the list data or for the width information.
Here is an example: arrange_by_row
((1..5).to_a, 3, 2) =>
[[1,2], [3,4], [5]],
Source
# File lib/columnize/columnize.rb, line 41 def columnize return @short_circuit if @short_circuit rows, colwidths = min_rows_and_colwidths ncols = colwidths.length justify = lambda {|t, c| @ljust ? t.ljust(colwidths[c]) : t.rjust(colwidths[c]) } textify = lambda do |row| row.map!.with_index(&justify) unless ncols == 1 && @ljust "#{@line_prefix}#{row.join(@colsep)}#{@line_suffix}" end text = rows.map(&textify) text.first.sub!(/^#{@line_prefix}/, @array_prefix) unless @array_prefix.empty? text.last.sub!(/#{@line_suffix}$/, @array_suffix) unless @array_suffix.empty? text.join("\n") # + "\n" # if we want extra separation end
Source
# File lib/columnize/columnize.rb, line 19 def list=(list) @list = list if @list.is_a? Array @short_circuit = @list.empty? ? "<empty>\n" : nil else @short_circuit = '' @list = [] end end
Source
# File lib/columnize/columnize.rb, line 62 def min_rows_and_colwidths list = @list.map(&@stringify) cell_widths = list.map(&@term_adjuster).map(&:size) # Set default arrangement: one atom per row cell_width_max = cell_widths.max result = [arrange_by_row(list, list.size, 1), [cell_width_max]] # If any atom > @displaywidth, stop and use one atom per row. return result if cell_width_max > @displaywidth # For horizontal arrangement, we want to *maximize* the number # of columns. Thus the candidate number of rows (+sizes+) starts # at the minumum number of rows, 1, and increases. # For vertical arrangement, we want to *minimize* the number of # rows. So here the candidate number of columns (+sizes+) starts # at the maximum number of columns, list.length, and # decreases. Also the roles of columns and rows are reversed # from horizontal arrangement. # Loop from most compact arrangement to least compact, stopping # at the first successful packing. The below code is tricky, # but very cool. # # FIXME: In the below code could be DRY'd. (The duplication got # introduced when I revised the code - rocky) if @arrange_vertical (1..list.length).each do |size| other_size = (list.size + size - 1) / size colwidths = arrange_by_row(cell_widths, other_size, size).map(&:max) totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) return [arrange_by_column(list, other_size, size), colwidths] if totwidth <= @displaywidth end else list.length.downto(1).each do |size| other_size = (list.size + size - 1) / size colwidths = arrange_by_column(cell_widths, other_size, size).map(&:max) totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) return [arrange_by_row(list, other_size, size), colwidths] if totwidth <= @displaywidth end end result end
TODO: make this a method, rather than a function (?) compute the smallest number of rows and the max widths for each column
Source
# File lib/columnize/columnize.rb, line 30 def opts=(opts) @opts = opts OLD_AND_NEW_KEYS.each {|old, new| @opts[new] = @opts.delete(old) if @opts.keys.include?(old) and !@opts.keys.include?(new) } @opts.merge!(ARRANGE_ARRAY_OPTS) if @opts[:arrange_array] set_attrs_from_opts end
TODO: freeze @opts
Source
# File lib/columnize/columnize.rb, line 142 def set_attrs_from_opts ATTRS.each {|attr| self.instance_variable_set "@#{attr}", @opts[attr] } @ljust = !@list.all? {|datum| datum.kind_of?(Numeric)} if @ljust == :auto @displaywidth -= @line_prefix.length @displaywidth = @line_prefix.length + 4 if @displaywidth < 4 @stringify = @colfmt ? lambda {|li| @colfmt % li } : lambda {|li| li.to_s } @term_adjuster = @opts[:term_adjust] ? lambda {|c| c.gsub(/\e\[.*?m/, '') } : lambda {|c| c } end
Source
# File lib/columnize/columnize.rb, line 37 def update_opts(opts) self.opts = @opts.merge(opts) end