columnize 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/ChangeLog +13 -0
  2. data/NEWS +10 -4
  3. data/VERSION +1 -1
  4. data/lib/columnize.rb +145 -63
  5. data/test/test-columnize.rb +28 -5
  6. metadata +2 -2
data/ChangeLog CHANGED
@@ -1,3 +1,16 @@
1
+ 2009-01-08 09:27 rockyb
2
+
3
+ * ChangeLog, NEWS, VERSION, lib/columnize.rb,
4
+ test/test-columnize.rb: Fix bad bug in arranging horizontally
5
+
6
+ 2009-01-01 04:15 rockyb
7
+
8
+ * NEWS: Merge NEWS
9
+
10
+ 2009-01-01 03:59 rockyb
11
+
12
+ * NEWS, VERSION: Ooops 0.2 release done. Go for 0.2.1
13
+
1
14
  2009-01-01 03:55 rockyb
2
15
 
3
16
  * ChangeLog: Get ready for release 0.2
data/NEWS CHANGED
@@ -1,12 +1,18 @@
1
- 0.2.1
2
- 12-31-08
3
- Add ability to run columns horizontally
1
+ 0.3.0 (01-10-09) - Sam Woodward Release
2
+
3
+ - Fix bad bug in arranging horizontally
4
+
5
+ 0.2.1 (12-31-08)
6
+
7
+ - Add ability to run columns horizontally
4
8
 
5
9
  0.2
10
+
6
11
  - Minor - get rid of hacky $0 test
7
12
 
8
13
  0.1
14
+
9
15
  - Initial release of Columnize, a module to print an Array in
10
16
  column-sorted order
11
17
 
12
- $Id: NEWS 155 2009-01-01 04:15:10Z rockyb $
18
+ $Id: NEWS 160 2009-01-10 19:02:28Z rockyb $
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -1,6 +1,6 @@
1
- # $Id: columnize.rb 150 2009-01-01 03:52:54Z rockyb $
1
+ # $Id: columnize.rb 159 2009-01-08 09:27:51Z rockyb $
2
2
  #
3
- # Copyright (C) 2007, 2008 Rocky Bernstein <rockyb@rubyforge.net>
3
+ # Copyright (C) 2007, 2008, 2009 Rocky Bernstein <rockyb@rubyforge.net>
4
4
  #
5
5
  # This program is free software; you can redistribute it and/or modify
6
6
  # it under the terms of the GNU General Public License as published by
@@ -37,15 +37,26 @@
37
37
 
38
38
  module Columnize
39
39
 
40
- # Return a string with embedded newlines (\n) arranging +list+ in
41
- # column-order so that each line is no larger than +displaywidth+.
42
- # If +list+ is not an array, the empty string, '', is returned.
43
- # +colsep+ contains the string to use to separate entries. Normally,
44
- # consecutive items go down from the top to bottom from the
45
- # left-most column to the right-most. If +arrange_vertical+ is set
46
- # false, consecutive items will go across, left to right, top to
47
- # bottom.
48
- def columnize(list, displaywidth=80, colsep = ' ', arrange_vertical=true)
40
+ # Return a list of strings with embeeded newlines (\n) as a compact
41
+ # set of columns arranged horizontally or vertically.
42
+ #
43
+ # For example, for a line width of 4 characters (arranged vertically):
44
+ # ['1', '2,', '3', '4'] => '1 3\n2 4\n'
45
+
46
+ # or arranged horizontally:
47
+ # ['1', '2,', '3', '4'] => '1 2\n3 4\n'
48
+ #
49
+ # Each column is only as wide possible, no larger than
50
+ # +displaywidth'. If +list+ is not an array, the empty string, '',
51
+ # is returned. By default, columns are separated by two spaces - one
52
+ # was not legible enough. Set +colsep+ to adjust the string separate
53
+ # columns. If +arrange_vertical+ is set false, consecutive items
54
+ # will go across, left to right, top to bottom.
55
+
56
+ def columnize(list, displaywidth=80, colsep = ' ',
57
+ arrange_vertical=true, ljust=true)
58
+
59
+ # Some degenerate cases
49
60
  if not list.is_a?(Array)
50
61
  return ''
51
62
  end
@@ -56,83 +67,154 @@ module Columnize
56
67
  if 1 == l.size
57
68
  return "#{l[0]}\n"
58
69
  end
59
- # Consider arranging list in 1 rows total, then 2 rows...
60
- # Stop when at the smallest number of rows which
61
- # can be arranged less than the display width.
62
- nrows = 0; ncols = l.size
63
-
70
+
71
+ nrows = ncols = 0 # Make nrows, ncols have more global scope
72
+ colwidths = [] # Same for colwidths
64
73
  if arrange_vertical
65
74
  array_index = lambda {|nrows, row, col| nrows*col + row }
66
- else
67
- array_index = lambda {|nrows, row, col| nrows*row + col }
68
- end
75
+ # Try every row count from 1 upwards
76
+ 1.upto(l.size-1) do |nrows|
77
+ ncols = (l.size + nrows-1) / nrows
78
+ colwidths = []
79
+ totwidth = -colsep.length
69
80
 
70
- colwidths = []
71
- 1.upto(l.size) do
72
- colwidths = []
73
- nrows += 1
74
- totwidth = -colsep.length
75
- col = 0
76
- 0.upto(ncols-1) do |col|
77
- # get max column width for this column
78
- colwidth = 0
79
- 0.upto(nrows-1) do |row|
80
- i = array_index.call(nrows, row, col)
81
- if i >= l.size
81
+ 0.upto(ncols-1) do |col|
82
+ # get max column width for this column
83
+ colwidth = 0
84
+ 0.upto(nrows-1) do |row|
85
+ i = array_index.call(nrows, row, col)
86
+ if i >= l.size
87
+ break
88
+ end
89
+ colwidth = [colwidth, l[i].size].max
90
+ end
91
+ colwidths << colwidth
92
+ totwidth += colwidth + colsep.length
93
+ if totwidth > displaywidth
94
+ ncols = col
82
95
  break
83
96
  end
84
- colwidth = [colwidth, l[i].size].max
85
97
  end
86
- colwidths << colwidth
87
- totwidth += colwidth + colsep.length
88
- if totwidth > displaywidth
89
- ncols = col
98
+ if totwidth <= displaywidth
90
99
  break
91
100
  end
92
101
  end
93
- if totwidth <= displaywidth
94
- break
102
+ # The smallest number of rows computed and the
103
+ # max widths for each column has been obtained.
104
+ # Now we just have to format each of the
105
+ # rows.
106
+ s = ''
107
+ 0.upto(nrows-1) do |row|
108
+ texts = []
109
+ 0.upto(ncols-1) do |col|
110
+ i = array_index.call(nrows, row, col)
111
+ if i >= l.size
112
+ x = ""
113
+ else
114
+ x = l[i]
115
+ end
116
+ texts << x
117
+ end
118
+ while texts and texts[-1] == ''
119
+ texts = texts[0..-2]
120
+ end
121
+ if texts.size > 0
122
+ 0.upto(texts.size-1) do |col|
123
+ if ljust
124
+ texts[col] = texts[col].ljust(colwidths[col])
125
+ else
126
+ texts[col] = texts[col].rjust(colwidths[col])
127
+ end
128
+ end
129
+ s += "%s\n" % texts.join(colsep)
130
+ end
95
131
  end
96
- end
97
- # The smallest number of rows computed and the
98
- # max widths for each column has been obtained.
99
- # Now we just have to format each of the
100
- # rows.
101
- s = ''
102
- 0.upto(nrows-1) do |row|
103
- texts = []
104
- 0.upto(ncols-1) do |col|
105
- i = array_index.call(nrows, row, col)
106
- if i >= l.size
107
- if arrange_vertical:
108
- x = ""
109
- else
132
+ return s
133
+ else
134
+ array_index = lambda {|nrows, row, col| ncols*(row-1) + col }
135
+ # Try every column count from size downwards
136
+ # Assign to make enlarge scope of loop variables
137
+ totwidth = i = rounded_size = 0
138
+ l.size.downto(0) do |ncols|
139
+ # Try every row count from 1 upwards
140
+ min_rows = (l.size+ncols-1) / ncols
141
+ min_rows.upto(l.size) do |nrows|
142
+ rounded_size = nrows * ncols
143
+ colwidths = []
144
+ totwidth = -colsep.length
145
+ colwidth = row = 0
146
+ 0.upto(ncols-1) do |col|
147
+ # get max column width for this column
148
+ 1.upto(nrows) do |row|
149
+ i = array_index.call(nrows, row, col)
150
+ if i >= rounded_size
151
+ break
152
+ elsif i < l.size
153
+ colwidth = [colwidth, l[i].size].max
154
+ end
155
+ end
156
+ colwidths << colwidth
157
+ totwidth += colwidth + colsep.length
158
+ if totwidth > displaywidth
159
+ break
160
+ end
161
+ end
162
+ if totwidth <= displaywidth
163
+ # Found the right nrows and ncols
164
+ nrows = row
165
+ break
166
+ elsif totwidth >= displaywidth
167
+ # Need to reduce ncols
110
168
  break
111
169
  end
112
- else
113
- x = l[i]
114
170
  end
115
- texts << x
116
- end
117
- while texts and texts[-1] == ''
118
- texts = texts[0..-2]
171
+ if totwidth <= displaywidth and i >= rounded_size-1
172
+ break
173
+ end
119
174
  end
120
- if texts.size > 0
175
+ # The smallest number of rows computed and the
176
+ # max widths for each column has been obtained.
177
+ # Now we just have to format each of the
178
+ # rows.
179
+ s = ''
180
+ 1.upto(nrows) do |row|
181
+ texts = []
182
+ 0.upto(ncols-1) do |col|
183
+ i = array_index.call(nrows, row, col)
184
+ if i >= l.size
185
+ break
186
+ else
187
+ x = l[i]
188
+ end
189
+ texts << x
190
+ end
121
191
  0.upto(texts.size-1) do |col|
122
- texts[col] = texts[col].ljust(colwidths[col]) if
123
- colwidths[col]
192
+ if ljust
193
+ texts[col] = texts[col].ljust(colwidths[col])
194
+ else
195
+ texts[col] = texts[col].rjust(colwidths[col])
196
+ end
124
197
  end
125
198
  s += "%s\n" % texts.join(colsep)
126
199
  end
200
+ return s
127
201
  end
128
- return s
129
202
  end
130
203
  module_function :columnize
131
204
  end
132
205
  if __FILE__ == $0
133
206
  #
134
- puts Columnize::columnize(5)
135
207
  include Columnize
208
+
209
+ [[4, 4], [4, 7], [100, 80]].each do |width, num|
210
+ data = (1..num).map{|i| i.to_s}
211
+ [[false, 'horizontal'], [true, 'vertical']].each do |bool, dir|
212
+ puts "Width: #{width}, direction: #{dir}"
213
+ print columnize(data, width, ' ', arrange_vertical=bool)
214
+ end
215
+ end
216
+
217
+ puts Columnize::columnize(5)
136
218
  puts columnize([])
137
219
  puts columnize(["a", 2, "c"], 10, ', ')
138
220
  puts columnize(["oneitem"])
@@ -19,7 +19,30 @@ class TestColumnize < Test::Unit::TestCase
19
19
  assert_equal("1 2\n3 4\n",
20
20
  columnize(['1', '2', '3', '4'], 4, ' ', false))
21
21
  assert_equal("<empty>\n", columnize([]))
22
+
23
+
22
24
  assert_equal("oneitem\n", columnize(["oneitem"]))
25
+
26
+ data = (0..54).map{|i| i.to_s}
27
+ assert_equal(
28
+ "0, 6, 12, 18, 24, 30, 36, 42, 48, 54\n" +
29
+ "1, 7, 13, 19, 25, 31, 37, 43, 49\n" +
30
+ "2, 8, 14, 20, 26, 32, 38, 44, 50\n" +
31
+ "3, 9, 15, 21, 27, 33, 39, 45, 51\n" +
32
+ "4, 10, 16, 22, 28, 34, 40, 46, 52\n" +
33
+ "5, 11, 17, 23, 29, 35, 41, 47, 53\n",
34
+ columnize(data, 39, ', ', true, false))
35
+
36
+ assert_equal(
37
+ " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n" +
38
+ "10, 11, 12, 13, 14, 15, 16, 17, 18, 19\n" +
39
+ "20, 21, 22, 23, 24, 25, 26, 27, 28, 29\n" +
40
+ "30, 31, 32, 33, 34, 35, 36, 37, 38, 39\n" +
41
+ "40, 41, 42, 43, 44, 45, 46, 47, 48, 49\n" +
42
+ "50, 51, 52, 53, 54\n",
43
+ columnize(data, 39, ', ', false, false))
44
+
45
+
23
46
  data = ["one", "two", "three",
24
47
  "for", "five", "six",
25
48
  "seven", "eight", "nine",
@@ -31,11 +54,11 @@ class TestColumnize < Test::Unit::TestCase
31
54
  "twentyfive","twentysix", "twentyseven"]
32
55
 
33
56
  assert_equal(
34
- "one two three for five six \n" +
35
- "seven eight nine ten eleven twelve \n" +
36
- "thirteen fourteen fifteen sixteen seventeen eightteen \n" +
37
- "nineteen twenty twentyone twentytwo twentythree twentyfour\n" +
38
- "twentyfive twentysix twentyseven\n", columnize(data, 80, ' ', false))
57
+ "one two three for five six \n" +
58
+ "seven eight nine ten eleven twelve \n" +
59
+ "thirteen fourteen fifteen sixteen seventeen eightteen \n" +
60
+ "nineteen twenty twentyone twentytwo twentythree twentyfour \n" +
61
+ "twentyfive twentysix twentyseven\n", columnize(data, 80, ' ', false))
39
62
 
40
63
  assert_equal(
41
64
  "one five nine thirteen seventeen twentyone twentyfive \n" +
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: columnize
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.1
7
- date: 2008-12-31 00:00:00 -05:00
6
+ version: 0.3.0
7
+ date: 2009-01-10 00:00:00 -05:00
8
8
  summary: Read file with caching
9
9
  require_paths:
10
10
  - lib