columnize 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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