console_table 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +28 -0
- data/console_table.gemspec +1 -1
- data/lib/console_table.rb +49 -2
- data/test/test_console_table.rb +174 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 53523d0566e09dc3e87c3957c4c34380109d1e4e23d939e37737491028f48b44
|
|
4
|
+
data.tar.gz: bfd6f961dcace666cf928610aa5c27a744677d6f7cc2143b297c68283c103206
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ca15f89a5284c001383cadede2f99d27aa06a4a7f65caab961ba7453d7dd825bdd15004fc95bd7b486266c13c6ea82fe8e28224ef2d7a2c70bd5350255e7e12
|
|
7
|
+
data.tar.gz: a3a48e2f7165b8858ff37f4f09a4c3d6d8db2bcf18110804cdb93697cd7a2009d9475775d05cb5e2f4889352d562b6283294a97a7079353d491f6cdbb1ac30c5
|
data/README.md
CHANGED
|
@@ -106,6 +106,34 @@ Rod 04-14-80 Chainsaw It works on my machine
|
|
|
106
106
|
===============================================================================
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
By default, line breaks in cell values are treated as whitespace to preserve the historical behavior. If you pass `:multiline=>true` when defining the table, values can contain line breaks, and ConsoleTable will keep the following lines in the correct columns. Each line is still padded, justified, truncated, or ellipsized according to the column settings.
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
table_config = [
|
|
113
|
+
{:title=>"Test", :size=>6},
|
|
114
|
+
{:title=>"This", :size=>8},
|
|
115
|
+
{:title=>"Thing", :size=>"*", :ellipsize=>true},
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
ConsoleTable.define(table_config, :title=>"Test Table", :width=>60, :multiline=>true) do |table|
|
|
119
|
+
table << ["short", "longer", "longer text\nwith line wraps"]
|
|
120
|
+
table << ["short", "longer", "longer text without line wraps but with enough text to kinda need them"]
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
which yields:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
============================================================
|
|
128
|
+
Test Table
|
|
129
|
+
Test This Thing
|
|
130
|
+
------------------------------------------------------------
|
|
131
|
+
short longer longer text
|
|
132
|
+
with line wraps
|
|
133
|
+
short longer longer text without line wraps but with e...
|
|
134
|
+
============================================================
|
|
135
|
+
```
|
|
136
|
+
|
|
109
137
|
We can specify justification options for columns as well, and even overwrite them when we supply row data, simply by using `Hash`es instead of `String`s for the values. For example:
|
|
110
138
|
|
|
111
139
|
```ruby
|
data/console_table.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "console_table"
|
|
7
|
-
spec.version = "0.
|
|
7
|
+
spec.version = "0.4.0"
|
|
8
8
|
spec.authors = ["Rod Hilton"]
|
|
9
9
|
spec.email = ["consoletable@rodhilton.com"]
|
|
10
10
|
spec.summary = %q{Simplifies printing tables of information to commandline consoles}
|
data/lib/console_table.rb
CHANGED
|
@@ -67,6 +67,7 @@ module ConsoleTable
|
|
|
67
67
|
@right_margin = options[:right_margin] || 0
|
|
68
68
|
@headings = options[:headings].nil? ? true : options[:headings]
|
|
69
69
|
@ellipse = options[:ellipse] || "..."
|
|
70
|
+
@multiline = options[:multiline] || false
|
|
70
71
|
|
|
71
72
|
#Set outline, just the upper and lower lines
|
|
72
73
|
if @borders
|
|
@@ -207,6 +208,18 @@ module ConsoleTable
|
|
|
207
208
|
|
|
208
209
|
print_line if @borders unless not @headings and @count == 0
|
|
209
210
|
|
|
211
|
+
if @multiline
|
|
212
|
+
multiline_rows(options).each do |row|
|
|
213
|
+
print_cells(row)
|
|
214
|
+
end
|
|
215
|
+
else
|
|
216
|
+
print_cells(options)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
@count = @count + 1
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def print_cells(options)
|
|
210
223
|
@out.print " "*@left_margin
|
|
211
224
|
if @borders
|
|
212
225
|
@out.print "|"
|
|
@@ -245,8 +258,42 @@ module ConsoleTable
|
|
|
245
258
|
end
|
|
246
259
|
end
|
|
247
260
|
@out.print "\n"
|
|
261
|
+
end
|
|
248
262
|
|
|
249
|
-
|
|
263
|
+
def multiline_rows(options)
|
|
264
|
+
lines_by_key = {}
|
|
265
|
+
@column_widths.each do |column|
|
|
266
|
+
lines_by_key[column[:key]] = cell_lines(options[column[:key]] || "")
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
row_height = lines_by_key.values.collect { |lines| lines.length }.max || 1
|
|
270
|
+
|
|
271
|
+
(0...row_height).collect do |line_index|
|
|
272
|
+
row = {}
|
|
273
|
+
@column_widths.each do |column|
|
|
274
|
+
row[column[:key]] = lines_by_key[column[:key]][line_index] || ""
|
|
275
|
+
end
|
|
276
|
+
row
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def cell_lines(to_print)
|
|
281
|
+
if to_print.is_a? Hash
|
|
282
|
+
split_lines(to_print[:text]).collect do |line|
|
|
283
|
+
to_print.merge({:text => line})
|
|
284
|
+
end
|
|
285
|
+
else
|
|
286
|
+
split_lines(to_print)
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def split_lines(string)
|
|
291
|
+
return [""] if string.nil?
|
|
292
|
+
|
|
293
|
+
string = string.to_s
|
|
294
|
+
return [""] if string == ""
|
|
295
|
+
|
|
296
|
+
string.split("\n", -1)
|
|
250
297
|
end
|
|
251
298
|
|
|
252
299
|
def infer_justify_from_string(to_print, justify)
|
|
@@ -402,4 +449,4 @@ module ConsoleTable
|
|
|
402
449
|
@out.print "\n"
|
|
403
450
|
end
|
|
404
451
|
end
|
|
405
|
-
end
|
|
452
|
+
end
|
data/test/test_console_table.rb
CHANGED
|
@@ -116,7 +116,7 @@ Column 1 Column 2 Column 3
|
|
|
116
116
|
assert_output_equal expected, @mock_out.string
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
def
|
|
119
|
+
def test_newlines_converted_to_spaces_in_middle_stripped_at_ends_by_default
|
|
120
120
|
table_config = [
|
|
121
121
|
{:key => :col1, :size => 20, :title => "Column 1"},
|
|
122
122
|
{:key => :col2, :size => 20, :title => "Column 2"},
|
|
@@ -142,6 +142,118 @@ Bl ah Stuff Junk
|
|
|
142
142
|
assert_output_equal expected, @mock_out.string
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
+
def test_newlines_render_as_multiple_cell_lines_when_multiline_is_enabled
|
|
146
|
+
table_config = [
|
|
147
|
+
{:key => :col1, :size => 20, :title => "Column 1"},
|
|
148
|
+
{:key => :col2, :size => 20, :title => "Column 2"},
|
|
149
|
+
{:key => :col3, :size => 20, :title => "Column 3"},
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
ConsoleTable.define(table_config, :width => 62, :multiline => true, :output => @mock_out) do |table|
|
|
153
|
+
table << [
|
|
154
|
+
{:text => "Bl\nah", :justify => :left},
|
|
155
|
+
{:text => "\nStuff", :justify => :left},
|
|
156
|
+
{:text => "Junk\n", :justify => :right}
|
|
157
|
+
]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
expected=<<-END
|
|
161
|
+
==============================================================
|
|
162
|
+
Column 1 Column 2 Column 3
|
|
163
|
+
--------------------------------------------------------------
|
|
164
|
+
Bl Junk
|
|
165
|
+
ah Stuff
|
|
166
|
+
==============================================================
|
|
167
|
+
END
|
|
168
|
+
|
|
169
|
+
assert_output_equal expected, @mock_out.string
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_multiline_cells_in_multiple_columns_share_continuation_lines
|
|
173
|
+
table_config = [
|
|
174
|
+
{:key => :first, :size => 10, :title => "First"},
|
|
175
|
+
{:key => :second, :size => 10, :title => "Second"},
|
|
176
|
+
{:key => :third, :size => 10, :title => "Third"},
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
ConsoleTable.define(table_config, :width => 40, :multiline => true, :output => @mock_out) do |table|
|
|
180
|
+
table << {
|
|
181
|
+
:first => "A1\nA2",
|
|
182
|
+
:second => "B1\nB2",
|
|
183
|
+
:third => "C1"
|
|
184
|
+
}
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
expected=<<-END
|
|
188
|
+
================================
|
|
189
|
+
First Second Third
|
|
190
|
+
--------------------------------
|
|
191
|
+
A1 B1 C1
|
|
192
|
+
A2 B2
|
|
193
|
+
================================
|
|
194
|
+
END
|
|
195
|
+
|
|
196
|
+
assert_output_equal expected, @mock_out.string
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def test_explicit_newlines_render_as_continuation_lines
|
|
200
|
+
table_config = [
|
|
201
|
+
{:title => "Test", :size => 6},
|
|
202
|
+
{:title => "This", :size => 8},
|
|
203
|
+
{:title => "Thing", :size => "*"},
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
ConsoleTable.define(table_config, :title => "Test Table", :width => 60, :multiline => true, :output => @mock_out) do |table|
|
|
207
|
+
table << ["short", "longer", "longer text\nwith line wraps"]
|
|
208
|
+
table << ["short", "longer", "longer text without line wraps but with enough text to kinda need them"]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
expected=<<-END
|
|
212
|
+
============================================================
|
|
213
|
+
Test Table
|
|
214
|
+
Test This Thing
|
|
215
|
+
------------------------------------------------------------
|
|
216
|
+
short longer longer text
|
|
217
|
+
with line wraps
|
|
218
|
+
short longer longer text without line wraps but with enou
|
|
219
|
+
============================================================
|
|
220
|
+
END
|
|
221
|
+
|
|
222
|
+
assert_output_equal expected, @mock_out.string
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_multiline_cells_ellipsize_each_line_independently
|
|
226
|
+
table_config = [
|
|
227
|
+
{:key => :first, :size => 10, :title => "First", :ellipsize => true},
|
|
228
|
+
{:key => :second, :size => 10, :title => "Second", :ellipsize => true},
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
ConsoleTable.define(table_config, :width => 40, :multiline => true, :output => @mock_out) do |table|
|
|
232
|
+
table << {
|
|
233
|
+
:first => "short\nthis line is very long",
|
|
234
|
+
:second => "this line is very long\nshort"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
table << {
|
|
238
|
+
:first => {:text => "tiny\nanother line is too long", :ellipsize => true},
|
|
239
|
+
:second => {:text => "another line is too long\ntiny", :ellipsize => true}
|
|
240
|
+
}
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
expected=<<-END
|
|
244
|
+
=====================
|
|
245
|
+
First Second
|
|
246
|
+
---------------------
|
|
247
|
+
short this li...
|
|
248
|
+
this li... short
|
|
249
|
+
tiny another...
|
|
250
|
+
another... tiny
|
|
251
|
+
=====================
|
|
252
|
+
END
|
|
253
|
+
|
|
254
|
+
assert_output_equal expected, @mock_out.string
|
|
255
|
+
end
|
|
256
|
+
|
|
145
257
|
def test_linebreak_inside_colorcode_still_resets
|
|
146
258
|
table_config = [
|
|
147
259
|
{:key => :col1, :size => 20, :title => "Column 1"},
|
|
@@ -1160,6 +1272,66 @@ Row 2, Column 1 Row 2, Column 1
|
|
|
1160
1272
|
assert_output_equal expected, @mock_out.string
|
|
1161
1273
|
end
|
|
1162
1274
|
|
|
1275
|
+
def test_newlines_render_inside_bordered_table_cells
|
|
1276
|
+
table_config = [
|
|
1277
|
+
{:key => :col1, :size => 6, :title => "Column 1"},
|
|
1278
|
+
{:key => :col2, :size => 8, :title => "Column 2"},
|
|
1279
|
+
]
|
|
1280
|
+
|
|
1281
|
+
ConsoleTable.define(table_config, :width => 100, :headings => false, :borders => true, :multiline => true, :output => @mock_out) do |table|
|
|
1282
|
+
table << ["A\nB", "C"]
|
|
1283
|
+
table << ["D", "E\nF"]
|
|
1284
|
+
end
|
|
1285
|
+
|
|
1286
|
+
expected=<<-END
|
|
1287
|
+
*======*========*
|
|
1288
|
+
|A |C |
|
|
1289
|
+
|B | |
|
|
1290
|
+
+------+--------+
|
|
1291
|
+
|D |E |
|
|
1292
|
+
| |F |
|
|
1293
|
+
*======*========*
|
|
1294
|
+
END
|
|
1295
|
+
|
|
1296
|
+
assert_output_equal expected, @mock_out.string
|
|
1297
|
+
end
|
|
1298
|
+
|
|
1299
|
+
def test_multiline_bordered_cells_mix_padding_justification_and_ellipses
|
|
1300
|
+
table_config = [
|
|
1301
|
+
{:key => :left, :size => 10, :title => "Left", :ellipsize => true},
|
|
1302
|
+
{:key => :center, :size => 12, :title => "Center", :justify => :center, :ellipsize => true},
|
|
1303
|
+
{:key => :right, :size => 10, :title => "Right", :justify => :right, :ellipsize => true},
|
|
1304
|
+
]
|
|
1305
|
+
|
|
1306
|
+
ConsoleTable.define(table_config, :width => 80, :borders => true, :multiline => true, :output => @mock_out) do |table|
|
|
1307
|
+
table << {
|
|
1308
|
+
:left => "Short\nThis line is too long",
|
|
1309
|
+
:center => "This center line is too long\nMid",
|
|
1310
|
+
:right => "Tiny"
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
table << {
|
|
1314
|
+
:left => "This starts too long\nOK",
|
|
1315
|
+
:center => {:text => "Small\nThis override line is too long", :justify => :left, :ellipsize => true},
|
|
1316
|
+
:right => "This right line is too long\nEnd"
|
|
1317
|
+
}
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
expected=<<-END
|
|
1321
|
+
*==========*============*==========*
|
|
1322
|
+
|Left | Center | Right|
|
|
1323
|
+
+----------+------------+----------+
|
|
1324
|
+
|Short |This cent...| Tiny|
|
|
1325
|
+
|This li...| Mid | |
|
|
1326
|
+
+----------+------------+----------+
|
|
1327
|
+
|This st...|Small |This ri...|
|
|
1328
|
+
|OK |This over...| End|
|
|
1329
|
+
*==========*============*==========*
|
|
1330
|
+
END
|
|
1331
|
+
|
|
1332
|
+
assert_output_equal expected, @mock_out.string
|
|
1333
|
+
end
|
|
1334
|
+
|
|
1163
1335
|
def test_can_define_a_table_with_just_numbers_for_size
|
|
1164
1336
|
table_config = [
|
|
1165
1337
|
{:key => :col1, :size => 20, :title => "Column 1"},
|
|
@@ -1608,4 +1780,4 @@ Row 2, Col Row 2, Col
|
|
|
1608
1780
|
end
|
|
1609
1781
|
|
|
1610
1782
|
end
|
|
1611
|
-
end
|
|
1783
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: console_table
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rod Hilton
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: simplecov
|