tabulo 2.3.0 → 2.3.1
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/CHANGELOG.md +7 -0
- data/README.md +142 -96
- data/VERSION +1 -1
- data/lib/tabulo/table.rb +76 -92
- data/lib/tabulo/version.rb +1 -1
- data/tabulo.gemspec +4 -4
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1aa563982fa70661534282898690138b6ee57a9aacf74edec622e148d4c3cfdb
|
4
|
+
data.tar.gz: 5d4265a55ba3add10cdcef1408a81446fb4a9aa8a48da6997ac6f193eeba0f05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8737456dfe272f6b7cf3714ee17dede09be428101ea05ba7f8eef3fdd3bb7e4e9d19c121d499c40374b48ae6b92ceda341ce39c05884f624c19bfa0309f307c
|
7
|
+
data.tar.gz: 3222d37f42ea2568d6d3e6f9901fbfcf0cae94eeb10440051186f2caab375ab1effb6eafe95ba7dc43c4810fbfc905cbe5095befa264d612e4f0ef20f31ac61e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -43,7 +43,7 @@ end
|
|
43
43
|
|
44
44
|
## Features
|
45
45
|
|
46
|
-
* Presents a [DRY initialization interface](#
|
46
|
+
* Presents a [DRY initialization interface](#adding-columns): by being “column based” rather than
|
47
47
|
“row based”, it spares the developer the burden of syncing the ordering within the header row
|
48
48
|
with that of the body rows.
|
49
49
|
* Lets you set [fixed column widths](#fixed-column-widths), then either [wrap](#overflow-handling)
|
@@ -75,12 +75,18 @@ Tabulo has also been ported to Crystal (with some modifications): see [Tablo](ht
|
|
75
75
|
* [Installation](#installation)
|
76
76
|
* [Detailed usage](#detailed-usage)
|
77
77
|
* [Requiring the gem](#requiring-the-gem)
|
78
|
-
* [
|
78
|
+
* [Creating a table](#table-initialization)
|
79
|
+
* [Adding columns](#adding-columns)
|
80
|
+
* [Quick API](#quick-api)
|
81
|
+
* [Full API](#quick-api)
|
82
|
+
* [Column labels _vs_ headers](#labels-headers)
|
83
|
+
* [Positioning columns](#column-positioning)
|
84
|
+
* [Removing columns](#removing-columns)
|
79
85
|
* [Cell alignment](#cell-alignment)
|
80
86
|
* [Column width, wrapping and truncation](#column-width-wrapping-and-truncation)
|
81
87
|
* [Configuring fixed widths](#configuring-fixed-widths)
|
82
|
-
* [Configuring padding](#configuring-padding)
|
83
88
|
* [Automating column widths](#automating-column-widths)
|
89
|
+
* [Configuring padding](#configuring-padding)
|
84
90
|
* [Overflow handling](#overflow-handling)
|
85
91
|
* [Formatting cell values](#formatting-cell-values)
|
86
92
|
* [Colours and other styling](#colours-and-styling)
|
@@ -124,33 +130,30 @@ Or install it yourself:
|
|
124
130
|
require 'tabulo'
|
125
131
|
```
|
126
132
|
|
127
|
-
|
128
|
-
|
129
|
-
You instantiate a `Tabulo::Table` by passing it an underlying `Enumerable` and then telling it
|
130
|
-
the columns you want to generate.
|
133
|
+
<a name="table-initialization"></a>
|
134
|
+
### Creating a table
|
131
135
|
|
132
|
-
|
133
|
-
|
136
|
+
You instantiate a `Tabulo::Table` by passing it an underlying `Enumerable`, being the collection of
|
137
|
+
things that you want to tabulate. Each member of this collection will end up
|
138
|
+
corresponding to a row of the table. The collection can be any `Enumerable`, for example a Ruby
|
139
|
+
`Array`, or an ActiveRecord relation:
|
134
140
|
|
135
141
|
```ruby
|
136
142
|
table = Tabulo::Table.new([1, 2, 5])
|
137
|
-
|
138
|
-
table.add_column(:even?)
|
139
|
-
table.add_column(:odd?)
|
143
|
+
other_table = Tabulo::Table.new(User.all)
|
140
144
|
```
|
141
145
|
|
142
|
-
|
146
|
+
For the table to be useful, however, it must also contain columns…
|
143
147
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
150
|
-
```
|
148
|
+
<a name="adding-columns"></a>
|
149
|
+
### Adding columns
|
150
|
+
|
151
|
+
<a name="quick-api"></a>
|
152
|
+
#### Quick API
|
151
153
|
|
152
|
-
When the columns correspond to methods
|
153
|
-
directly to `new` for each column
|
154
|
+
When the columns correspond to methods on members of the underlying enumerable, you can use
|
155
|
+
the “quick API”, by passing a symbol directly to `Tabulo::Table.new` for each column.
|
156
|
+
This symbol also provides the column header:
|
154
157
|
|
155
158
|
```ruby
|
156
159
|
table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?)
|
@@ -167,9 +170,32 @@ table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?)
|
|
167
170
|
+--------------+--------------+--------------+
|
168
171
|
```
|
169
172
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
+
<a name="full-api"></a>
|
174
|
+
#### Full API
|
175
|
+
|
176
|
+
Columns can also be added to the table one-by-one using `add_column`. This “full API” is
|
177
|
+
more verbose, but provides greater configurability:
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
table = Tabulo::Table.new([1, 2, 5])
|
181
|
+
table.add_column(:itself)
|
182
|
+
table.add_column(:even?)
|
183
|
+
table.add_column(:odd?)
|
184
|
+
```
|
185
|
+
|
186
|
+
Alternatively, you can pass an initialization block to `new`:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
table = Tabulo::Table.new([1, 2, 5]) do |t|
|
190
|
+
t.add_column(:itself)
|
191
|
+
t.add_column(:even?)
|
192
|
+
t.add_column(:odd?)
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
With the full API, columns can also be initialized using a callable to which each object will be
|
197
|
+
passed to determine the value to be displayed in the table. In this case, the first argument to
|
198
|
+
`add_column` provides the header text:
|
173
199
|
|
174
200
|
```ruby
|
175
201
|
table = Tabulo::Table.new([1, 2, 5]) do |t|
|
@@ -190,6 +216,23 @@ end
|
|
190
216
|
+--------------+--------------+--------------+
|
191
217
|
```
|
192
218
|
|
219
|
+
<a name="labels-headers"></a>
|
220
|
+
#### Column labels _vs_ headers
|
221
|
+
|
222
|
+
The first argument to `add_column` is the called the _label_ for that column. It serves as the
|
223
|
+
column’s unique identifier: only one column may have a given label per table.
|
224
|
+
(`String`s and `Symbol`s are interchangeable for this purpose.) The label also forms the header shown
|
225
|
+
at the top of the column, unless a separate `header:` argument is explicitly passed:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
table.add_column(:itself, header: "N")
|
229
|
+
table.add_column(:itself2, header: "N", &:itself) # header need not be unique
|
230
|
+
# table.add_column(:itself) # would raise Tabulo::InvalidColumnLabelError, as label must be unique
|
231
|
+
```
|
232
|
+
|
233
|
+
<a name="column-positioning"></a>
|
234
|
+
#### Positioning columns
|
235
|
+
|
193
236
|
By default, each new column is added to the right of all the other columns so far added to the
|
194
237
|
table. However, if you want to insert a new column into some other position, you can use the
|
195
238
|
`before` option, passing the label of the column to the left of which you want the new column to be added:
|
@@ -210,9 +253,15 @@ table.add_column(:even?, before: :odd?)
|
|
210
253
|
+--------------+--------------+--------------+
|
211
254
|
```
|
212
255
|
|
213
|
-
|
214
|
-
|
215
|
-
|
256
|
+
<a name="removing-columns"></a>
|
257
|
+
### Removing columns
|
258
|
+
|
259
|
+
There is also a `#remove_column` method, for deleting an existing column from a table. Pass it
|
260
|
+
the label of the column you want to remove:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
table.remove_column(:even?)
|
264
|
+
```
|
216
265
|
|
217
266
|
<a name="cell-alignment"></a>
|
218
267
|
### Cell alignment
|
@@ -279,92 +328,49 @@ table = Tabulo::Table.new([1, 2], :itself, :even?, column_width: 6)
|
|
279
328
|
|
280
329
|
Widths set for individual columns always override the default column width for the table.
|
281
330
|
|
282
|
-
<a name="configuring-padding"></a>
|
283
|
-
#### Configuring padding
|
284
|
-
|
285
|
-
The single character of padding either side of each column is not counted in the column width.
|
286
|
-
The amount of this extra padding can be configured for the table as a whole, using the `column_padding`
|
287
|
-
option passed to `Table.new`—the default value of this option being `1`.
|
288
|
-
|
289
|
-
Passing a single integer to this option causes the given amount of padding to be applied to each
|
290
|
-
side of each column. For example:
|
291
|
-
|
292
|
-
```ruby
|
293
|
-
table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?, column_padding: 0)
|
294
|
-
```
|
295
|
-
|
296
|
-
```
|
297
|
-
> puts table
|
298
|
-
+------------+------------+------------+
|
299
|
-
| itself | even? | odd? |
|
300
|
-
+------------+------------+------------+
|
301
|
-
| 1| false | true |
|
302
|
-
| 2| true | false |
|
303
|
-
| 5| false | true |
|
304
|
-
+------------+------------+------------+
|
305
|
-
```
|
306
|
-
|
307
|
-
Passing an array of _two_ integers to this option configures the left and right padding for each
|
308
|
-
column, according to the first and second element of the array, respectively. For example:
|
309
|
-
|
310
|
-
```ruby
|
311
|
-
table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?, column_padding: [0, 2])
|
312
|
-
```
|
313
|
-
|
314
|
-
```
|
315
|
-
> puts table
|
316
|
-
+--------------+--------------+--------------+
|
317
|
-
| itself | even? | odd? |
|
318
|
-
+--------------+--------------+--------------+
|
319
|
-
| 1 | false | true |
|
320
|
-
| 2 | true | false |
|
321
|
-
| 5 | false | true |
|
322
|
-
+--------------+--------------+--------------+
|
323
|
-
```
|
324
|
-
|
325
331
|
<a name="pack"></a>
|
326
332
|
#### Automating column widths
|
327
333
|
|
328
334
|
Instead of setting column widths “manually”, you can tell the table to sort out the widths
|
329
335
|
itself, so that each column is just wide enough for its header and contents (plus a character
|
330
|
-
of padding):
|
336
|
+
of padding on either side):
|
331
337
|
|
332
338
|
```ruby
|
333
|
-
table = Tabulo::Table.new([
|
339
|
+
table = Tabulo::Table.new(["short", "here is a longer phrase"], :itself, :size)
|
334
340
|
table.pack
|
335
341
|
```
|
336
342
|
|
337
343
|
```
|
338
344
|
> puts table
|
339
|
-
|
340
|
-
|
|
341
|
-
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
345
|
+
+-------------------------+------+
|
346
|
+
| itself | size |
|
347
|
+
+-------------------------+------+
|
348
|
+
| short | 5 |
|
349
|
+
| here is a longer phrase | 23 |
|
350
|
+
+-------------------------+------+
|
345
351
|
```
|
346
352
|
|
347
353
|
The `pack` method returns the table itself, so you can “pack-and-print” in one go:
|
348
354
|
|
349
355
|
```ruby
|
350
|
-
puts Tabulo::Table.new([
|
356
|
+
puts Tabulo::Table.new(["short", "here is a longer phrase"], :itself, :size).pack
|
351
357
|
```
|
352
358
|
|
353
359
|
<a name="max-table-width"></a>
|
354
360
|
You can manually place an upper limit on the total width of the table when packing:
|
355
361
|
|
356
362
|
```ruby
|
357
|
-
puts Tabulo::Table.new([
|
363
|
+
puts Tabulo::Table.new(["short", "here is a longer phrase"], :itself, :size).pack(max_table_width: 24)
|
358
364
|
```
|
359
365
|
|
360
366
|
```
|
361
|
-
|
362
|
-
|
|
363
|
-
|
364
|
-
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
367
|
+
+---------------+------+
|
368
|
+
| itself | size |
|
369
|
+
+---------------+------+
|
370
|
+
| short | 5 |
|
371
|
+
| here is a lon | 23 |
|
372
|
+
| ger phrase | |
|
373
|
+
+---------------+------+
|
368
374
|
```
|
369
375
|
|
370
376
|
Or if you simply call `pack` with no arguments (or if you explicitly call
|
@@ -391,6 +397,49 @@ resized yet again on printing. This is a consequence of the table always being e
|
|
391
397
|
table itself. There are [ways around this](#freezing-a-table), however, if this is not the desired
|
392
398
|
behaviour—see [below](#freezing-a-table).
|
393
399
|
|
400
|
+
<a name="configuring-padding"></a>
|
401
|
+
#### Configuring padding
|
402
|
+
|
403
|
+
The single character of padding either side of each column is not counted in the column width.
|
404
|
+
The amount of this extra padding can be configured for the table as a whole, using the `column_padding`
|
405
|
+
option passed to `Table.new`—the default value of this option being `1`.
|
406
|
+
|
407
|
+
Passing a single integer to this option causes the given amount of padding to be applied to each
|
408
|
+
side of each column. For example:
|
409
|
+
|
410
|
+
```ruby
|
411
|
+
table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?, column_padding: 0)
|
412
|
+
```
|
413
|
+
|
414
|
+
```
|
415
|
+
> puts table
|
416
|
+
+------------+------------+------------+
|
417
|
+
| itself | even? | odd? |
|
418
|
+
+------------+------------+------------+
|
419
|
+
| 1| false | true |
|
420
|
+
| 2| true | false |
|
421
|
+
| 5| false | true |
|
422
|
+
+------------+------------+------------+
|
423
|
+
```
|
424
|
+
|
425
|
+
Passing an array of _two_ integers to this option configures the left and right padding for each
|
426
|
+
column, according to the first and second element of the array, respectively. For example:
|
427
|
+
|
428
|
+
```ruby
|
429
|
+
table = Tabulo::Table.new([1, 2, 5], :itself, :even?, :odd?, column_padding: [0, 2])
|
430
|
+
```
|
431
|
+
|
432
|
+
```
|
433
|
+
> puts table
|
434
|
+
+--------------+--------------+--------------+
|
435
|
+
| itself | even? | odd? |
|
436
|
+
+--------------+--------------+--------------+
|
437
|
+
| 1 | false | true |
|
438
|
+
| 2 | true | false |
|
439
|
+
| 5 | false | true |
|
440
|
+
+--------------+--------------+--------------+
|
441
|
+
```
|
442
|
+
|
394
443
|
<a name="overflow-handling"></a>
|
395
444
|
#### Overflow handling
|
396
445
|
|
@@ -669,11 +718,8 @@ table.each do |row|
|
|
669
718
|
end
|
670
719
|
```
|
671
720
|
|
672
|
-
The
|
673
|
-
|
674
|
-
`Symbol` for purposes of accessing this `Hash`.) This key serves as a sort of “logical label”
|
675
|
-
for the column; and it need not be the same as the column header. If we want the header to be different
|
676
|
-
to the label, we can achieve this using the `header` option to `add_column`:
|
721
|
+
The column label (being the first argument that was passed to `add_column`, converted if necessary
|
722
|
+
to a `Symbol`), always forms the key for the purposes of this `Hash`:
|
677
723
|
|
678
724
|
```ruby
|
679
725
|
table = Tabulo::Table.new(1..3) do |t|
|
@@ -752,7 +798,7 @@ a new table in which the rows and columns are swapped:
|
|
752
798
|
By default, a header row is added to the new table, showing the string value of the element
|
753
799
|
represented in that column. This can be configured, however, along with other aspects of
|
754
800
|
`transpose`’s behaviour. For details, see the
|
755
|
-
[documentation](https://www.rubydoc.info/gems/tabulo/2.3.
|
801
|
+
[documentation](https://www.rubydoc.info/gems/tabulo/2.3.1/Tabulo/Table#transpose-instance_method).
|
756
802
|
|
757
803
|
<a name="borders"></a>
|
758
804
|
### Configuring borders
|
@@ -1061,14 +1107,14 @@ The gem is available as open source under the terms of the [MIT
|
|
1061
1107
|
License](http://opensource.org/licenses/MIT).
|
1062
1108
|
|
1063
1109
|
[Gem Version]: https://rubygems.org/gems/tabulo
|
1064
|
-
[Documentation]: http://www.rubydoc.info/gems/tabulo/2.3.
|
1110
|
+
[Documentation]: http://www.rubydoc.info/gems/tabulo/2.3.1
|
1065
1111
|
[Build Status]: https://travis-ci.org/matt-harvey/tabulo
|
1066
1112
|
[Coverage Status]: https://coveralls.io/r/matt-harvey/tabulo
|
1067
1113
|
[Code Climate]: https://codeclimate.com/github/matt-harvey/tabulo
|
1068
1114
|
[Awesome Ruby]: https://github.com/markets/awesome-ruby#cli-utilities
|
1069
1115
|
|
1070
1116
|
[GV img]: https://img.shields.io/gem/v/tabulo.svg
|
1071
|
-
[DC img]: https://img.shields.io/badge/documentation-v2.3.
|
1117
|
+
[DC img]: https://img.shields.io/badge/documentation-v2.3.1-blue.svg
|
1072
1118
|
[BS img]: https://img.shields.io/travis/matt-harvey/tabulo.svg
|
1073
1119
|
[CS img]: https://img.shields.io/coveralls/matt-harvey/tabulo.svg
|
1074
1120
|
[CC img]: https://codeclimate.com/github/matt-harvey/tabulo/badges/gpa.svg
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.1
|
data/lib/tabulo/table.rb
CHANGED
@@ -107,23 +107,10 @@ module Tabulo
|
|
107
107
|
# @return [Table] a new {Table}
|
108
108
|
# @raise [InvalidColumnLabelError] if non-unique Symbols are provided to columns.
|
109
109
|
# @raise [InvalidBorderError] if invalid option passed to `border` parameter.
|
110
|
-
def initialize(
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
align_header: :center,
|
115
|
-
border: nil,
|
116
|
-
border_styler: nil,
|
117
|
-
column_padding: nil,
|
118
|
-
column_width: nil,
|
119
|
-
formatter: :to_s.to_proc,
|
120
|
-
header_frequency: :start,
|
121
|
-
header_styler: nil,
|
122
|
-
row_divider_frequency: nil,
|
123
|
-
styler: nil,
|
124
|
-
truncation_indicator: nil,
|
125
|
-
wrap_body_cells_to: nil,
|
126
|
-
wrap_header_cells_to: nil)
|
110
|
+
def initialize(sources, *columns, align_body: :auto, align_header: :center, border: nil,
|
111
|
+
border_styler: nil, column_padding: nil, column_width: nil, formatter: :to_s.to_proc,
|
112
|
+
header_frequency: :start, header_styler: nil, row_divider_frequency: nil, styler: nil,
|
113
|
+
truncation_indicator: nil, wrap_body_cells_to: nil, wrap_header_cells_to: nil)
|
127
114
|
|
128
115
|
@sources = sources
|
129
116
|
|
@@ -135,12 +122,7 @@ module Tabulo
|
|
135
122
|
@column_padding = (column_padding || DEFAULT_COLUMN_PADDING)
|
136
123
|
|
137
124
|
@left_column_padding, @right_column_padding =
|
138
|
-
|
139
|
-
when Array
|
140
|
-
@column_padding
|
141
|
-
else
|
142
|
-
[@column_padding, @column_padding]
|
143
|
-
end
|
125
|
+
Array === @column_padding ? @column_padding : [@column_padding, @column_padding]
|
144
126
|
|
145
127
|
@column_width = (column_width || DEFAULT_COLUMN_WIDTH)
|
146
128
|
@formatter = formatter
|
@@ -230,25 +212,10 @@ module Tabulo
|
|
230
212
|
# @raise [InvalidColumnLabelError] if label has already been used for another column in this
|
231
213
|
# Table. (This is case-sensitive, but is insensitive to whether a String or Symbol is passed
|
232
214
|
# to the label parameter.)
|
233
|
-
def add_column(
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
before: nil,
|
238
|
-
formatter: nil,
|
239
|
-
header: nil,
|
240
|
-
header_styler: nil,
|
241
|
-
styler: nil,
|
242
|
-
width: nil,
|
243
|
-
&extractor)
|
244
|
-
|
245
|
-
column_label =
|
246
|
-
case label
|
247
|
-
when Integer, Symbol
|
248
|
-
label
|
249
|
-
when String
|
250
|
-
label.to_sym
|
251
|
-
end
|
215
|
+
def add_column(label, align_body: nil, align_header: nil, before: nil, formatter: nil,
|
216
|
+
header: nil, header_styler: nil, styler: nil, width: nil, &extractor)
|
217
|
+
|
218
|
+
column_label = normalize_column_label(label)
|
252
219
|
|
253
220
|
if column_registry.include?(column_label)
|
254
221
|
raise InvalidColumnLabelError, "Column label already used in this table."
|
@@ -267,7 +234,11 @@ module Tabulo
|
|
267
234
|
width: width || @column_width,
|
268
235
|
)
|
269
236
|
|
270
|
-
|
237
|
+
if before == nil
|
238
|
+
add_column_final(column, column_label)
|
239
|
+
else
|
240
|
+
add_column_before(column, column_label, before)
|
241
|
+
end
|
271
242
|
end
|
272
243
|
|
273
244
|
# Removes the column identifed by the passed label.
|
@@ -315,22 +286,17 @@ module Tabulo
|
|
315
286
|
# Note that when printed, the first row will visually include the headers (assuming these
|
316
287
|
# were not disabled when the Table was initialized).
|
317
288
|
def each
|
289
|
+
header_frequency_is_integer = (Integer === @header_frequency)
|
318
290
|
@sources.each_with_index do |source, index|
|
291
|
+
is_first_row = (index == 0)
|
319
292
|
header =
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
if index == 0
|
325
|
-
:top
|
326
|
-
elsif index % @header_frequency == 0
|
327
|
-
:middle
|
328
|
-
end
|
329
|
-
else
|
330
|
-
@header_frequency
|
293
|
+
if is_first_row && (@header_frequency == :start || header_frequency_is_integer)
|
294
|
+
:top
|
295
|
+
elsif header_frequency_is_integer && (index % @header_frequency == 0)
|
296
|
+
:middle
|
331
297
|
end
|
332
298
|
|
333
|
-
show_divider = @row_divider_frequency &&
|
299
|
+
show_divider = @row_divider_frequency && !is_first_row && (index % @row_divider_frequency == 0)
|
334
300
|
|
335
301
|
yield Row.new(self, source, header: header, divider: show_divider)
|
336
302
|
end
|
@@ -338,7 +304,7 @@ module Tabulo
|
|
338
304
|
|
339
305
|
# @return [String] an "ASCII" graphical representation of the Table column headers.
|
340
306
|
def formatted_header
|
341
|
-
cells =
|
307
|
+
cells = get_columns.map(&:header_cell)
|
342
308
|
format_row(cells, @wrap_header_cells_to)
|
343
309
|
end
|
344
310
|
|
@@ -360,7 +326,7 @@ module Tabulo
|
|
360
326
|
# It may be that `:top`, `:middle` and `:bottom` all look the same. Whether
|
361
327
|
# this is the case depends on the characters used for the table border.
|
362
328
|
def horizontal_rule(position = :bottom)
|
363
|
-
column_widths =
|
329
|
+
column_widths = get_columns.map { |column| column.width + total_column_padding }
|
364
330
|
@border_instance.horizontal_rule(column_widths, position)
|
365
331
|
end
|
366
332
|
|
@@ -393,15 +359,12 @@ module Tabulo
|
|
393
359
|
# Table will refuse to shrink itself.
|
394
360
|
# @return [Table] the Table itself
|
395
361
|
def pack(max_table_width: :auto)
|
396
|
-
|
397
|
-
columns = column_registry.values
|
398
|
-
|
399
|
-
columns.each { |column| column.width = wrapped_width(column.header) }
|
362
|
+
get_columns.each { |column| column.width = wrapped_width(column.header) }
|
400
363
|
|
401
364
|
@sources.each do |source|
|
402
|
-
|
365
|
+
get_columns.each do |column|
|
403
366
|
width = wrapped_width(column.body_cell(source).formatted_content)
|
404
|
-
column.width = width
|
367
|
+
column.width = [width, column.width].max
|
405
368
|
end
|
406
369
|
end
|
407
370
|
|
@@ -492,20 +455,27 @@ module Tabulo
|
|
492
455
|
|
493
456
|
# @!visibility private
|
494
457
|
def formatted_body_row(source, header:, divider:)
|
495
|
-
cells =
|
458
|
+
cells = get_columns.map { |column| column.body_cell(source) }
|
496
459
|
inner = format_row(cells, @wrap_body_cells_to)
|
497
460
|
|
498
|
-
if header
|
461
|
+
if header == :top
|
462
|
+
join_lines([
|
463
|
+
horizontal_rule(:top),
|
464
|
+
formatted_header,
|
465
|
+
horizontal_rule(:middle),
|
466
|
+
inner
|
467
|
+
].reject(&:empty?))
|
468
|
+
elsif header
|
499
469
|
join_lines([
|
500
|
-
horizontal_rule(
|
470
|
+
horizontal_rule(:middle),
|
501
471
|
formatted_header,
|
502
472
|
horizontal_rule(:middle),
|
503
|
-
inner
|
473
|
+
inner
|
504
474
|
].reject(&:empty?))
|
505
475
|
elsif divider
|
506
476
|
join_lines([
|
507
477
|
horizontal_rule(:middle),
|
508
|
-
inner
|
478
|
+
inner
|
509
479
|
].reject(&:empty?))
|
510
480
|
else
|
511
481
|
inner
|
@@ -514,39 +484,49 @@ module Tabulo
|
|
514
484
|
|
515
485
|
private
|
516
486
|
|
487
|
+
# @!visibility private
|
488
|
+
def get_columns
|
489
|
+
column_registry.values
|
490
|
+
end
|
491
|
+
|
517
492
|
# @!visibility private
|
518
493
|
def add_column_before(column, label, before)
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
new_column_entries
|
524
|
-
|
525
|
-
old_column_entries.each do |entry|
|
526
|
-
if entry[0] == before
|
527
|
-
found = true
|
528
|
-
new_column_entries << [label, column]
|
529
|
-
end
|
530
|
-
new_column_entries << entry
|
531
|
-
end
|
532
|
-
unless found
|
533
|
-
raise InvalidColumnLabelError, "There is no column with label #{before}"
|
534
|
-
end
|
535
|
-
@column_registry = new_column_entries.to_h
|
494
|
+
old_column_entries = @column_registry.to_a
|
495
|
+
new_column_entries = []
|
496
|
+
|
497
|
+
old_column_entries.each do |entry|
|
498
|
+
new_column_entries << [label, column] if entry[0] == before
|
499
|
+
new_column_entries << entry
|
536
500
|
end
|
501
|
+
|
502
|
+
found = (new_column_entries.size == old_column_entries.size + 1)
|
503
|
+
raise InvalidColumnLabelError, "There is no column with label #{before}" unless found
|
504
|
+
|
505
|
+
@column_registry = new_column_entries.to_h
|
537
506
|
end
|
538
507
|
|
539
508
|
# @!visibility private
|
540
|
-
def
|
541
|
-
@
|
509
|
+
def add_column_final(column, label)
|
510
|
+
@column_registry[label] = column
|
511
|
+
end
|
512
|
+
|
513
|
+
# @!visibility private
|
514
|
+
def normalize_column_label(label)
|
515
|
+
case label
|
516
|
+
when Integer, Symbol
|
517
|
+
label
|
518
|
+
when String
|
519
|
+
label.to_sym
|
520
|
+
end
|
542
521
|
end
|
543
522
|
|
544
523
|
# @!visibility private
|
545
524
|
def shrink_to(max_table_width)
|
546
|
-
columns =
|
525
|
+
columns = get_columns
|
526
|
+
num_columns = columns.count
|
547
527
|
total_columns_width = columns.inject(0) { |sum, column| sum + column.width }
|
548
|
-
total_padding =
|
549
|
-
total_borders =
|
528
|
+
total_padding = num_columns * total_column_padding
|
529
|
+
total_borders = num_columns + 1
|
550
530
|
unadjusted_table_width = total_columns_width + total_padding + total_borders
|
551
531
|
|
552
532
|
# Ensure max table width is at least wide enough to accommodate table borders and padding
|
@@ -564,6 +544,11 @@ module Tabulo
|
|
564
544
|
end
|
565
545
|
end
|
566
546
|
|
547
|
+
# @!visibility private
|
548
|
+
def total_column_padding
|
549
|
+
@left_column_padding + @right_column_padding
|
550
|
+
end
|
551
|
+
|
567
552
|
# @!visibility private
|
568
553
|
#
|
569
554
|
# Formats a single header row or body row as a String.
|
@@ -615,8 +600,7 @@ module Tabulo
|
|
615
600
|
def wrapped_width(str)
|
616
601
|
segments = str.split($/)
|
617
602
|
segments.inject(1) do |longest_length_so_far, segment|
|
618
|
-
|
619
|
-
longest_length_so_far > length ? longest_length_so_far : length
|
603
|
+
[longest_length_so_far, Unicode::DisplayWidth.of(segment)].max
|
620
604
|
end
|
621
605
|
end
|
622
606
|
end
|
data/lib/tabulo/version.rb
CHANGED
data/tabulo.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Matthew Harvey"]
|
10
10
|
spec.email = ["software@matthewharvey.net"]
|
11
11
|
|
12
|
-
spec.summary = "
|
13
|
-
spec.description = "
|
12
|
+
spec.summary = "Terminal table generator"
|
13
|
+
spec.description = "Plain text table generator with a column-based API"
|
14
14
|
spec.homepage = "https://github.com/matt-harvey/tabulo"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
@@ -28,8 +28,8 @@ Gem::Specification.new do |spec|
|
|
28
28
|
"changelog_uri" => "https://raw.githubusercontent.com/matt-harvey/tabulo/master/CHANGELOG.md"
|
29
29
|
}
|
30
30
|
|
31
|
-
spec.add_runtime_dependency "tty-screen", "0.7.
|
32
|
-
spec.add_runtime_dependency "unicode-display_width", "1.6.
|
31
|
+
spec.add_runtime_dependency "tty-screen", "0.7.1"
|
32
|
+
spec.add_runtime_dependency "unicode-display_width", "1.6.1"
|
33
33
|
|
34
34
|
spec.add_development_dependency "bundler"
|
35
35
|
spec.add_development_dependency "rake", "~> 11.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabulo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Harvey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-screen
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.7.
|
19
|
+
version: 0.7.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.7.
|
26
|
+
version: 0.7.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: unicode-display_width
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.6.
|
33
|
+
version: 1.6.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.6.
|
40
|
+
version: 1.6.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +164,7 @@ dependencies:
|
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '1.0'
|
167
|
-
description:
|
167
|
+
description: Plain text table generator with a column-based API
|
168
168
|
email:
|
169
169
|
- software@matthewharvey.net
|
170
170
|
executables: []
|
@@ -222,5 +222,5 @@ rubyforge_project:
|
|
222
222
|
rubygems_version: 2.7.6
|
223
223
|
signing_key:
|
224
224
|
specification_version: 4
|
225
|
-
summary:
|
225
|
+
summary: Terminal table generator
|
226
226
|
test_files: []
|