Skip to content
Browse files

Some small doc changes and but mostly add in Martin's explanation in …

…email.

Signed-off-by: rocky <rockyb@rubyforge.org>
Signed-off-by: waslogic <waslogic@gmail.com>
  • Loading branch information...
1 parent fd4f176 commit 94e1dd088d5d6de7348fc1bacf7acbec487edafb @rocky committed with waslogic Mar 24, 2013
Showing with 30 additions and 12 deletions.
  1. +1 −1 lib/columnize.rb
  2. +27 −9 lib/columnize/columnize.rb
  3. +2 −2 test/test-columnizer.rb
View
2 lib/columnize.rb
@@ -25,7 +25,7 @@ module Columnize
require File.join %W(#{ROOT_DIR} columnize #{submod})
end
- # Add +columnize_opts+ instance variable to classes that mix in this module. The type should be a kind of hash as above.
+ # Add +columnize_opts+ instance variable to classes that mix in this module. The type should be a kind of hash in file +columnize/opts+.
attr_accessor :columnize_opts
# Columnize.columize([args]) => String
View
36 lib/columnize/columnize.rb
@@ -61,24 +61,42 @@ def compute_rows_and_colwidths
list = @list.map &@stringify
cell_widths = list.map(&@term_adjuster).map(&:size)
# default is 1 atom per row (just in case any atom > @displaywidth)
- rcw = [rows_and_cols(list, 1)[0], [cell_widths.max]]
+ rcw = [min_rows_and_cols(list, 1)[0], [cell_widths.max]]
return rcw if rcw[1][0] > @displaywidth
- # TODO: explain why
- sizes, ri, ci = (1..list.length).to_a, 1, 0
- sizes, ri, ci = sizes.reverse, 0, 1 unless @arrange_vertical
+ # 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.
+
+ # The below sets up the order of the lengths to try, +sizes+. It
+ # also sets up the row and column permutation to use, [0,1] or
+ # [1,0], which are stored in +ri+, +ci+ in accessing the values
+ # passed back by min_rows_and_cols().
+ sizes, ri, ci =
+ if @arrange_vertical
+ [(1..list.length).to_a, 1, 0]
+ else
+ [(1..list.length).to_a.reverse, 0, 1]
+ end
+
+ # Loop from most compact arrangement to least compact, stopping
+ # at the first successful packing.
sizes.each do |size|
- colwidths = rows_and_cols(cell_widths, size)[ci].map(&:max)
+ colwidths = min_rows_and_cols(cell_widths, size)[ci].map(&:max)
totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length)
- rcw = [rows_and_cols(list, size)[ri], colwidths] and break if totwidth <= @displaywidth
+ rcw = [min_rows_and_cols(list, size)[ri], colwidths] and break if totwidth <= @displaywidth
end
rcw
end
- # TODO: find a better, more descriptive name for this function
- def rows_and_cols(list, ncols)
- # given list.size and ncols, calculate minimum number of rows needed. this is very cool.
+ # Given list.size and ncols, calculate minimum number of rows needed. This is very cool.
+ def min_rows_and_cols(list, ncols)
nrows = (list.size + ncols - 1) / ncols
rows = (0...nrows).map {|r| list[r*ncols, ncols] }
cols = rows[0].zip(*rows[1..-1]).map(&:compact)
View
4 test/test-columnizer.rb
@@ -92,8 +92,8 @@ def test_columnize_applies_array_prefix_and_suffix
# NOTE: compute_rows_and_colwidths tested in test-compute_rows_and_colwidths.rb
# ROWS_AND_COLS
- def test_rows_and_cols
- rows,cols = Columnize::Columnizer.new.rows_and_cols((1..9).to_a, 3)
+ def test_min_rows_and_cols
+ rows,cols = Columnize::Columnizer.new.min_rows_and_cols((1..9).to_a, 3)
assert_equal [[1,2,3],[4,5,6],[7,8,9]], rows, 'rows'
assert_equal [[1,4,7],[2,5,8],[3,6,9]], cols, 'cols'
end

0 comments on commit 94e1dd0

Please sign in to comment.
Something went wrong with that request. Please try again.