tabulo 2.7.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/tests.yml +4 -3
- data/.gitignore +1 -0
- data/CHANGELOG.md +32 -0
- data/README.md +103 -15
- data/VERSION +1 -1
- data/lib/tabulo/table.rb +134 -58
- data/lib/tabulo/version.rb +1 -1
- data/tabulo.gemspec +1 -1
- 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: d58a5b883e9c9685c3cff492c6ad49b88ce921c5947596c5fe9199a5818dbfab
|
4
|
+
data.tar.gz: d9e2d10ea6314b73bdc3ad5a41bf790211ad7abe1e42899c52bc8bf2b405e8e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fb526cb0ddc9d63033eb40aa81a0aa2f39a306e051074693fcc4d08c95a216d13ffa27c92a1eb7bed08d3daef431bff6d15faa839b87580f830b916409c46a7
|
7
|
+
data.tar.gz: 587ba915a07b2e6d67d58296a7147fab9017d038facf0976a628baa71f8ebdf6a08f3d25559ca372630026452d65d12f83ced616c78cd33fca9e7e31ff0ed597
|
data/.github/workflows/tests.yml
CHANGED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### v2.8.0
|
4
|
+
|
5
|
+
* Add `except:` param to `Tabulo::Table#pack` method, allowing specific
|
6
|
+
columns to be excluded from the action of `.pack`
|
7
|
+
* Provide method `Tabulo::Table#autosize_columns`, allowing columns to be auto-sized
|
8
|
+
to fit their contents' widths, without having to call `.pack` (which also has
|
9
|
+
other effects on the table). This method also has an `except:` param allowing columns
|
10
|
+
to be excluded from its action.
|
11
|
+
* Provide method `Tabulo::Table#shrink_to`, allowing the table's width to be reduced
|
12
|
+
so as not to exceed a given target number of characters (or the argument `:screen`
|
13
|
+
meaning "width of terminal"), independently of the `.pack` method.
|
14
|
+
This method also has an `except:` param allowing columns to be excluded from its action.
|
15
|
+
* Fix `max_table_width:` param to `.pack` not being respected if table title was
|
16
|
+
wider than terminal.
|
17
|
+
* Documentation improvements
|
18
|
+
* Fix broken documentation links
|
19
|
+
* Add Ruby 3.1 to CI config
|
20
|
+
|
21
|
+
### v2.7.3
|
22
|
+
|
23
|
+
* Fix malformed YARD documentation for `Tabulo::Table#initialize` method
|
24
|
+
|
25
|
+
### v2.7.2
|
26
|
+
|
27
|
+
* Minor documentation improvements and tweaks
|
28
|
+
* Upgrade Ruby patch versions in CI config
|
29
|
+
|
30
|
+
### v2.7.1
|
31
|
+
|
32
|
+
* Dependency version upgrades
|
33
|
+
* Minor documentation improvements and tweaks
|
34
|
+
|
3
35
|
### v2.7.0
|
4
36
|
|
5
37
|
* Add `wrap_preserve` option, allowing whole words to be preserved when wrapping.
|
data/README.md
CHANGED
@@ -4,11 +4,9 @@
|
|
4
4
|
[![Documentation][DC img]][Documentation]
|
5
5
|
[![Build Status][BS img]][Build Status]
|
6
6
|
[![Coverage Status][CS img]][Coverage Status]
|
7
|
-
[![Code Climate][CC img]][Code Climate]
|
8
7
|
[![Awesome][AR img]][Awesome Ruby]
|
9
8
|
|
10
|
-
Tabulo is a Ruby library for generating plain text tables
|
11
|
-
or “ASCII tables”). It is both highly configurable and very easy to use.
|
9
|
+
Tabulo is a Ruby library for generating plain text tables. It is both highly configurable and very easy to use.
|
12
10
|
|
13
11
|
<a name="overview"></a>
|
14
12
|
## Overview
|
@@ -76,15 +74,16 @@ Tabulo has also been ported to Crystal (with some modifications): see [Tablo](ht
|
|
76
74
|
|
77
75
|
* [Overview](#overview)
|
78
76
|
* [Features](#features)
|
79
|
-
* [Table of contents](#
|
77
|
+
* [Table of contents](#contents)
|
80
78
|
* [Installation](#installation)
|
81
79
|
* [Detailed usage](#detailed-usage)
|
82
80
|
* [Creating a table](#table-initialization)
|
83
81
|
* [Adding columns](#adding-columns)
|
84
82
|
* [Quick API](#quick-api)
|
85
|
-
* [Full API](#
|
83
|
+
* [Full API](#full-api)
|
86
84
|
* [Column labels _vs_ headers](#labels-headers)
|
87
85
|
* [Positioning columns](#column-positioning)
|
86
|
+
* [Extracting column content from a hash or array](#from-arrays-hashes)
|
88
87
|
* [Removing columns](#removing-columns)
|
89
88
|
* [Adding a title](#title)
|
90
89
|
* [Cell alignment](#cell-alignment)
|
@@ -93,6 +92,7 @@ Tabulo has also been ported to Crystal (with some modifications): see [Tablo](ht
|
|
93
92
|
* [Automating column widths](#automating-column-widths)
|
94
93
|
* [Configuring padding](#configuring-padding)
|
95
94
|
* [Overflow handling](#overflow-handling)
|
95
|
+
* [Wrapping at word boundaries](#preserve-words)
|
96
96
|
* [Manual cell wrapping](#manual-wrapping)
|
97
97
|
* [Formatting cell values](#formatting-cell-values)
|
98
98
|
* [Colours and other styling](#colours-and-styling)
|
@@ -102,7 +102,7 @@ Tabulo has also been ported to Crystal (with some modifications): see [Tablo](ht
|
|
102
102
|
* [Setting default styles](#default-styles)
|
103
103
|
* [Styling borders](#styling-borders)
|
104
104
|
* [Repeating headers](#repeating-headers)
|
105
|
-
* [Using a Table Enumerator](#
|
105
|
+
* [Using a Table Enumerator](#enumerator)
|
106
106
|
* [Accessing cell values](#accessing-cell-values)
|
107
107
|
* [Accessing the underlying enumerable](#accessing-sources)
|
108
108
|
* [Transposing rows and columns](#transposition)
|
@@ -113,6 +113,7 @@ Tabulo has also been ported to Crystal (with some modifications): see [Tablo](ht
|
|
113
113
|
* [Contributing](#contributing)
|
114
114
|
* [License](#license)
|
115
115
|
|
116
|
+
<a name="installation"></a>
|
116
117
|
## Installation [↑](#contents)
|
117
118
|
|
118
119
|
Add this line to your application’s Gemfile:
|
@@ -135,6 +136,7 @@ To use the gem, you need to require it in your source code as follows:
|
|
135
136
|
require 'tabulo'
|
136
137
|
```
|
137
138
|
|
139
|
+
<a name="detailed-usage"></a>
|
138
140
|
<a name="table-initialization"></a>
|
139
141
|
### Creating a table [↑](#contents)
|
140
142
|
|
@@ -281,6 +283,69 @@ table.add_column(:even?, before: :odd?)
|
|
281
283
|
+--------------+--------------+--------------+
|
282
284
|
```
|
283
285
|
|
286
|
+
<a name="from-arrays-hashes"></a>
|
287
|
+
#### Extracting column content from a hash or array [↑](#contents)
|
288
|
+
|
289
|
+
Sometimes the data source for the table may be a collection of hashes or arrays. For example:
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
data = [
|
293
|
+
{ english: "hello", portuguese: "bom dia" },
|
294
|
+
{ english: "goodbye", portuguese: "adeus" },
|
295
|
+
]
|
296
|
+
```
|
297
|
+
|
298
|
+
or
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
data = [
|
302
|
+
["hello", "bom dia"],
|
303
|
+
["goodbye", "adeus"],
|
304
|
+
]
|
305
|
+
```
|
306
|
+
|
307
|
+
To tabulate such a collection, simply use the same mechanism as described above, passing a block to
|
308
|
+
the `add_column` method to tell Tabulo how to extract the data for each column from a row. For
|
309
|
+
example, to tabulate the first example above, you could do something like this:
|
310
|
+
|
311
|
+
```ruby
|
312
|
+
table = Tabulo::Table.new(data) do |t|
|
313
|
+
t.add_column("English") { |h| h[:english] }
|
314
|
+
t.add_column("Portuguese") { |h| h[:portuguese] }
|
315
|
+
end
|
316
|
+
|
317
|
+
puts table
|
318
|
+
```
|
319
|
+
|
320
|
+
For the second example, you could do the following:
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
table = Tabulo::Table.new(data) do |t|
|
324
|
+
t.add_column("English") { |a| a[0] }
|
325
|
+
t.add_column("Portuguese") { |a| a[1] }
|
326
|
+
end
|
327
|
+
|
328
|
+
puts table
|
329
|
+
```
|
330
|
+
|
331
|
+
In both cases, the output will be as follows:
|
332
|
+
|
333
|
+
```
|
334
|
+
+--------------+--------------+
|
335
|
+
| English | Portuguese |
|
336
|
+
+--------------+--------------+
|
337
|
+
| hello | bom dia |
|
338
|
+
| goodbye | adeus |
|
339
|
+
+--------------+--------------+
|
340
|
+
```
|
341
|
+
|
342
|
+
If you have previously used other terminal tabulation libraries, you may be accustomed to being _required_
|
343
|
+
to place your data into an array of hashes or arrays before you can tabulate them. Tabulo, however,
|
344
|
+
offers an API that is more general and flexible than this; your data source can be _any_
|
345
|
+
enumerable collection (not just an array), and each item in that collection can be _any_ object (not
|
346
|
+
necessarily an array or a hash). However, as shown above, it is still straightforward to tabulate an
|
347
|
+
array of hashes or arrays, if your data source happens to take that form.
|
348
|
+
|
284
349
|
<a name="removing-columns"></a>
|
285
350
|
### Removing columns [↑](#contents)
|
286
351
|
|
@@ -345,9 +410,11 @@ If a table title is present, it is center-aligned by default. This can be change
|
|
345
410
|
table = Tabulo::Table.new([1, 2], :itself, :even?, title: "Numbers", align_title: :left)
|
346
411
|
```
|
347
412
|
|
413
|
+
<a name="column-width-wrapping-and-truncation"></a>
|
348
414
|
### Column width, wrapping and truncation [↑](#contents)
|
349
415
|
|
350
416
|
<a name="fixed-column-widths"></a>
|
417
|
+
<a name="configuring-fixed-widths"></a>
|
351
418
|
#### Configuring fixed widths [↑](#contents)
|
352
419
|
|
353
420
|
By default, column width is fixed at 12 characters, plus 1 character of padding on either side.
|
@@ -390,6 +457,7 @@ table = Tabulo::Table.new([1, 2], :itself, :even?, column_width: 6)
|
|
390
457
|
Widths set for individual columns always override the default column width for the table.
|
391
458
|
|
392
459
|
<a name="pack"></a>
|
460
|
+
<a name="automating-column-widths"></a>
|
393
461
|
#### Automating column widths [↑](#contents)
|
394
462
|
|
395
463
|
Instead of setting column widths “manually”, you can tell the table to sort out the widths
|
@@ -466,6 +534,16 @@ necessary (see [Overflow handling](#overflow-handling)). Under the hood, a chara
|
|
466
534
|
is deducted column by column—the widest column being targetted each time—until
|
467
535
|
the table will fit.
|
468
536
|
|
537
|
+
To resize only specific columns, `pack` takes an `except:` argument, which can be a single column
|
538
|
+
label or an Array of column labels. E.g. `pack(except: :id)` will exclude the `id` column from
|
539
|
+
resizing and let it keep its current width. This is useful if you want to prevent the addition of
|
540
|
+
linebreaks in your data. When using this option, other columns might be shrunk more to still make
|
541
|
+
the table fit within the `max_table_width`.
|
542
|
+
|
543
|
+
For even finer-grained control over column and table resizing, see the
|
544
|
+
for the [`#autosize_columns`](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#autosize_columns-instance_method)
|
545
|
+
and [`#shrink_to`](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#autosize_columns-instance_method) methods.
|
546
|
+
|
469
547
|
Note that `pack`ing the table necessarily involves traversing the entire collection up front as
|
470
548
|
the maximum cell width needs to be calculated for each column. You may not want to do this
|
471
549
|
if the collection is very large.
|
@@ -729,7 +807,7 @@ the table.
|
|
729
807
|
The `formatter` callback also has an alternative, 2-parameter version. If `formatter` is passed
|
730
808
|
a 2-parameter callable, the second parameter will be given a `CellData` instance,
|
731
809
|
containing additional information about the cell that may be useful in determining how to format
|
732
|
-
it—see the [documentation](https://www.rubydoc.info/gems/tabulo/2.
|
810
|
+
it—see the [documentation](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/CellData.html)
|
733
811
|
for details.
|
734
812
|
|
735
813
|
<a name="colours-and-styling"></a>
|
@@ -775,7 +853,7 @@ number is even). The second parameter represents the formatted string value of t
|
|
775
853
|
content after any processing by the [formatter](#formatting-cell-values). The third and fourth
|
776
854
|
parameters are optional, and contain further information about the cell and its contents that may be useful in
|
777
855
|
determining how to style it. See the
|
778
|
-
[documentation](https://www.rubydoc.info/gems/tabulo/2.
|
856
|
+
[documentation](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#add_column-instance_method) for details.
|
779
857
|
|
780
858
|
If the content of a cell is wrapped over multiple lines, then the `styler` will be called once
|
781
859
|
per line, so that each line of the cell will have the escape sequence applied to it separately
|
@@ -795,7 +873,7 @@ table.add_column(:even?, header_styler: -> (s) { "\033[32m#{s}\033[0m" })
|
|
795
873
|
```
|
796
874
|
|
797
875
|
The `header_styler` option accepts a 1-, 2- or 3-parameter callable. See the
|
798
|
-
[documentation](https://www.rubydoc.info/gems/tabulo/2.
|
876
|
+
[documentation](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#add_column-instance_method)
|
799
877
|
for details.
|
800
878
|
|
801
879
|
<a name="styling-title"></a>
|
@@ -809,7 +887,7 @@ table = Tabulo::Table.new(1..5, :itself, :even?, :odd?, title: "Numbers", title_
|
|
809
887
|
```
|
810
888
|
|
811
889
|
The `title_styler` option accepts a 1- or 2-parameter callable. See the
|
812
|
-
[documentation](https://www.rubydoc.info/gems/tabulo/2.
|
890
|
+
[documentation](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#initialize-instance_method)
|
813
891
|
for details.
|
814
892
|
|
815
893
|
<a name="styling-borders"></a>
|
@@ -875,6 +953,12 @@ table = Tabulo::Table.new(1..10, :itself, :even?, header_frequency: 5)
|
|
875
953
|
|
876
954
|
Note that if the table has a [title](#title), it will not be repeated; only column headers are repeated.
|
877
955
|
|
956
|
+
One can achieve even finer-grained control over printing of headers within the table body by stepping
|
957
|
+
through the table a row at a time (using `.each` or other methods of `Enumerable`) and calling the
|
958
|
+
the [`formatted_header`](https://www.rubydoc.info/gems/tabulo/Tabulo/Table#formatted_header-instance_method)
|
959
|
+
method in combination with [`horizontal_rule`](https://www.rubydoc.info/gems/tabulo/Tabulo%2FTable:horizontal_rule)
|
960
|
+
to produce headers at arbitrary points in the output.
|
961
|
+
|
878
962
|
<a name="enumerator"></a>
|
879
963
|
### Using a Table Enumerator [↑](#contents)
|
880
964
|
|
@@ -1004,7 +1088,7 @@ a new table in which the rows and columns are swapped:
|
|
1004
1088
|
By default, a header row is added to the new table, showing the string value of the element
|
1005
1089
|
represented in that column. This can be configured, however, along with other aspects of
|
1006
1090
|
`transpose`’s behaviour. For details, see the
|
1007
|
-
[documentation](https://www.rubydoc.info/gems/tabulo/2.
|
1091
|
+
[documentation](https://www.rubydoc.info/gems/tabulo/2.8.0/Tabulo/Table#transpose-instance_method).
|
1008
1092
|
|
1009
1093
|
<a name="borders"></a>
|
1010
1094
|
### Configuring borders [↑](#contents)
|
@@ -1222,6 +1306,11 @@ If you want a line before every row, pass `1` to `row_divider_frequency`. For ex
|
|
1222
1306
|
+--------------+--------------+--------------+
|
1223
1307
|
```
|
1224
1308
|
|
1309
|
+
In addition to these options, it is also possible to print horizontal dividers at any chosen
|
1310
|
+
point in the table output, by stepping through the table one row at a time
|
1311
|
+
and calling the [`horizontal_rule`](https://www.rubydoc.info/gems/tabulo/Tabulo%2FTable:horizontal_rule)
|
1312
|
+
method as required.
|
1313
|
+
|
1225
1314
|
<a name="freezing-a-table"></a>
|
1226
1315
|
### Using a table as a snapshot rather than as a dynamic view [↑](#contents)
|
1227
1316
|
|
@@ -1389,21 +1478,20 @@ install dependencies.
|
|
1389
1478
|
`bundle exec rake spec` will run the test suite. For a list of other Rake tasks that are available in
|
1390
1479
|
the development environment, run `bundle exec rake -T`.
|
1391
1480
|
|
1481
|
+
<a name="license"></a>
|
1392
1482
|
## License [↑](#contents)
|
1393
1483
|
|
1394
1484
|
The gem is available as open source under the terms of the [MIT
|
1395
1485
|
License](http://opensource.org/licenses/MIT).
|
1396
1486
|
|
1397
1487
|
[Gem Version]: https://rubygems.org/gems/tabulo
|
1398
|
-
[Documentation]: http://www.rubydoc.info/gems/tabulo
|
1488
|
+
[Documentation]: http://www.rubydoc.info/gems/tabulo
|
1399
1489
|
[Build Status]: https://github.com/matt-harvey/tabulo/actions/workflows/tests.yml
|
1400
1490
|
[Coverage Status]: https://coveralls.io/github/matt-harvey/tabulo
|
1401
|
-
[Code Climate]: https://codeclimate.com/github/matt-harvey/tabulo
|
1402
1491
|
[Awesome Ruby]: https://github.com/markets/awesome-ruby#cli-utilities
|
1403
1492
|
|
1404
1493
|
[GV img]: https://img.shields.io/gem/v/tabulo.svg
|
1405
|
-
[DC img]: https://img.shields.io/badge/documentation-v2.
|
1494
|
+
[DC img]: https://img.shields.io/badge/documentation-v2.8.0-blue.svg
|
1406
1495
|
[BS img]: https://github.com/matt-harvey/tabulo/actions/workflows/tests.yml/badge.svg
|
1407
1496
|
[CS img]: https://img.shields.io/coveralls/matt-harvey/tabulo.svg
|
1408
|
-
[CC img]: https://codeclimate.com/github/matt-harvey/tabulo/badges/gpa.svg
|
1409
1497
|
[AR img]: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.8.0
|
data/lib/tabulo/table.rb
CHANGED
@@ -125,7 +125,7 @@ module Tabulo
|
|
125
125
|
# defaults to {DEFAULT_TRUNCATION_INDICATOR}. If passed something other than <tt>nil</tt> or
|
126
126
|
# a single-character String, raises {InvalidTruncationIndicatorError}.
|
127
127
|
# @param [Symbol] wrap_preserve Specifies what unit of text the wrapping mechanism will try to
|
128
|
-
#
|
128
|
+
# preserve intact when wrapping column content when the column width is reached:
|
129
129
|
# * If passed `:rune` (the default), then it will wrap at the "character" level (approximately
|
130
130
|
# speaking, the Unicode grapheme cluster level). This means the maximum number of what
|
131
131
|
# readers usually think of as "characters" will be fit on each line, within the column's allocated
|
@@ -207,11 +207,10 @@ module Tabulo
|
|
207
207
|
# by the Table-level setting passed to the <tt>align_header</tt> (which itself defaults
|
208
208
|
# to <tt>:center</tt>). Otherwise, this option determines the alignment of the header
|
209
209
|
# content for this column.
|
210
|
-
# @param [Symbol,
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
# in either String or Symbol form for this purpose.
|
210
|
+
# @param [Symbol, Integer, nil] before The label of the column before (i.e. to the left of) which the
|
211
|
+
# new column should inserted. If <tt>nil</tt> is passed, it will be inserted after all other columns.
|
212
|
+
# If there is no column with the given label, then an {InvalidColumnLabelError} will be raised.
|
213
|
+
# A non-Integer labelled column can be identified in Symbol form for this purpose.
|
215
214
|
# @param [#to_proc] formatter A lambda or other callable object that
|
216
215
|
# will be passed the calculated value of each cell to determine how it should be displayed. This
|
217
216
|
# is distinct from the extractor and the styler (see below).
|
@@ -420,7 +419,7 @@ module Tabulo
|
|
420
419
|
end
|
421
420
|
|
422
421
|
# @return [String] a graphical representation of the Table column headers formatted with fixed
|
423
|
-
# width plain text.
|
422
|
+
# width plain text, excluding any horizontal borders above or below.
|
424
423
|
def formatted_header
|
425
424
|
cells = get_columns.map(&:header_cell)
|
426
425
|
format_row(cells, @wrap_header_cells_to)
|
@@ -453,8 +452,10 @@ module Tabulo
|
|
453
452
|
|
454
453
|
# Resets all the column widths so that each column is *just* wide enough to accommodate
|
455
454
|
# its header text as well as the formatted content of each its cells for the entire
|
456
|
-
# collection, together with
|
457
|
-
# without
|
455
|
+
# collection, together with padding (by default 1 character on either side of the column),
|
456
|
+
# without wrapping. Other adjustments may also be performed (see below).
|
457
|
+
#
|
458
|
+
# In addition, if the table has a title but is not wide enough to
|
458
459
|
# accommodate (without wrapping) the title text (with a character of padding either side),
|
459
460
|
# widens the columns roughly evenly until the table as a whole is just wide enough to
|
460
461
|
# accommodate the title text.
|
@@ -468,7 +469,7 @@ module Tabulo
|
|
468
469
|
# is called. If the source Enumerable changes between that point, and the point when
|
469
470
|
# the Table is printed, then columns will *not* be resized yet again on printing.
|
470
471
|
#
|
471
|
-
# @param [nil, Numeric] max_table_width With no args, or if passed <tt>:auto</tt>,
|
472
|
+
# @param [nil, :auto, Numeric] max_table_width With no args, or if passed <tt>:auto</tt>,
|
472
473
|
# stops the total table width (including padding and borders) from expanding beyond the
|
473
474
|
# bounds of the terminal screen.
|
474
475
|
# If passed <tt>nil</tt>, the table width will not be capped.
|
@@ -476,34 +477,104 @@ module Tabulo
|
|
476
477
|
# deducted from the width of the widest column until the target is reached. When the
|
477
478
|
# table is printed, wrapping or truncation will then occur in these columns as required
|
478
479
|
# (depending on how they were configured).
|
479
|
-
# Note that regardless of the value passed to max_table_width
|
480
|
-
# enough to accommodate at least 1 character's width of content
|
481
|
-
#
|
482
|
-
# of the table and 1 between adjacent columns). I.e. there is a certain width below width the
|
480
|
+
# Note that regardless of the value passed to `max_table_width`, the table will always be left wide
|
481
|
+
# enough to accommodate at least 1 character's width of content for each column, and the padding
|
482
|
+
# configured for each column (by default 1 character either side), together with border characters
|
483
|
+
# (1 on each side of the table and 1 between adjacent columns). I.e. there is a certain width below width the
|
483
484
|
# Table will refuse to shrink itself.
|
485
|
+
# @param [nil, Symbol, Integer, Array[Symbol|Integer]] except If passed one or multiple column labels,
|
486
|
+
# these columns will be excluded from resizing and will keep their current width.
|
487
|
+
# (Note if passing integers, these are not necessarily positional: only columns _explicitly_
|
488
|
+
# given an integer label will have these as labels.)
|
484
489
|
# @return [Table] the Table itself
|
485
|
-
def pack(max_table_width: :auto)
|
486
|
-
|
490
|
+
def pack(max_table_width: :auto, except: nil)
|
491
|
+
autosize_columns(except: except)
|
492
|
+
|
493
|
+
max_width = nil
|
494
|
+
if max_table_width
|
495
|
+
max_width = (max_table_width == :auto ? TTY::Screen.width : max_table_width)
|
496
|
+
shrink_to(max_width, except: except)
|
497
|
+
end
|
498
|
+
|
499
|
+
if @title
|
500
|
+
border_edge_width = (@border == :blank ? 0 : 2)
|
501
|
+
all_columns = get_columns
|
502
|
+
min_width =
|
503
|
+
Unicode::DisplayWidth.of(@title) +
|
504
|
+
all_columns.first.left_padding +
|
505
|
+
all_columns.last.right_padding +
|
506
|
+
border_edge_width
|
487
507
|
|
508
|
+
min_width = max_width if max_width && max_width < min_width
|
509
|
+
expand_to(min_width, except: except)
|
510
|
+
end
|
511
|
+
|
512
|
+
self
|
513
|
+
end
|
514
|
+
|
515
|
+
# Resets all the column widths so that each column is *just* wide enough to accommodate
|
516
|
+
# its header text as well as the formatted content of each its cells for the entire
|
517
|
+
# collection, together with padding (by default 1 character either side), without wrapping.
|
518
|
+
#
|
519
|
+
# @param [nil, Symbol, Integer, Array[Symbol|Integer]] except If passed one or multiple column labels,
|
520
|
+
# these columns will be excluded from resizing and will keep their current width.
|
521
|
+
# (Note if using integers, these are not necessarily positional: only columns _explicitly_
|
522
|
+
# given an integer label will have these as labels.)
|
523
|
+
# @return [Table] the Table itself
|
524
|
+
def autosize_columns(except: nil)
|
525
|
+
columns = get_columns(except: except)
|
526
|
+
columns.each { |column| column.width = Util.wrapped_width(column.header) }
|
488
527
|
@sources.each_with_index do |source, row_index|
|
489
|
-
|
528
|
+
columns.each_with_index do |column, column_index|
|
490
529
|
cell = column.body_cell(source, row_index: row_index, column_index: column_index)
|
491
530
|
cell_width = Util.wrapped_width(cell.formatted_content)
|
492
531
|
column.width = Util.max(column.width, cell_width)
|
493
532
|
end
|
494
533
|
end
|
534
|
+
self
|
535
|
+
end
|
495
536
|
|
496
|
-
|
537
|
+
# If `max_table_width` is passed an integer, then column widths will be adjusted downward so
|
538
|
+
# that the total table width is reduced to the passed target width. (If the total width of the
|
539
|
+
# table exceeds the passed `max_table_width`, then this method is a no-op.)
|
540
|
+
#
|
541
|
+
# Width is deducted from columns if required to achieve this, with one character progressively
|
542
|
+
# deducted from the width of the widest column until the target is reached. When the
|
543
|
+
# table is printed, wrapping or truncation will then occur in these columns as required
|
544
|
+
# (depending on how they were configured).
|
545
|
+
#
|
546
|
+
# Note that regardless of the value passed to `max_table_width`, the table will always be left wide
|
547
|
+
# enough to accommodate at least 1 character's width of content for each column, and the padding
|
548
|
+
# configured for each column (by default 1 character either side), together with border characters
|
549
|
+
# (1 on each side of the table and 1 between adjacent columns). I.e. there is a certain width below width the
|
550
|
+
# Table will refuse to shrink itself.
|
551
|
+
#
|
552
|
+
# If `max_table_width` is passed the symbol `:screen`, then this method will behave as if it
|
553
|
+
# were passed an integer, with that integer being the width of the terminal.
|
554
|
+
#
|
555
|
+
# @param [Integer, :screen] the desired maximum table width
|
556
|
+
# @param [nil, Symbol, Integer, Array[Symbol|Integer]] except If passed one or multiple column labels,
|
557
|
+
# these columns will be excluded from resizing and will keep their current width.
|
558
|
+
# (Note if passing integers, these are not necessarily positional: only columns _explicitly_
|
559
|
+
# given an integer label will have these as labels.)
|
560
|
+
# @return [Table] the Table itself
|
561
|
+
def shrink_to(max_table_width, except: nil)
|
562
|
+
min_content_width_per_column = 1
|
563
|
+
min_total_column_content_width = num_columns * min_content_width_per_column
|
564
|
+
min_table_width = total_padding_width + total_borders_width + min_total_column_content_width
|
497
565
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
566
|
+
max_table_width = (max_table_width == :screen ? TTY::Screen.width : max_table_width)
|
567
|
+
max_table_width = Util.max(min_table_width, max_table_width)
|
568
|
+
|
569
|
+
required_reduction = Util.max(total_table_width - max_table_width, 0)
|
570
|
+
|
571
|
+
shrinkable_columns = get_columns(except: except)
|
572
|
+
required_reduction.times do
|
573
|
+
widest_column = shrinkable_columns.inject(shrinkable_columns.first) do |widest, column|
|
574
|
+
column.width >= widest.width ? column : widest
|
575
|
+
end
|
576
|
+
|
577
|
+
widest_column.width -= 1
|
507
578
|
end
|
508
579
|
|
509
580
|
self
|
@@ -609,8 +680,13 @@ module Tabulo
|
|
609
680
|
private
|
610
681
|
|
611
682
|
# @!visibility private
|
612
|
-
def get_columns
|
613
|
-
|
683
|
+
def get_columns(except: nil)
|
684
|
+
if except
|
685
|
+
column_labels = except ? column_registry.keys - Array(except) : column_registry.keys
|
686
|
+
column_labels.map { |label| column_registry[label] }
|
687
|
+
else
|
688
|
+
column_registry.values
|
689
|
+
end
|
614
690
|
end
|
615
691
|
|
616
692
|
# @!visibility private
|
@@ -695,16 +771,35 @@ module Tabulo
|
|
695
771
|
end
|
696
772
|
|
697
773
|
# @!visibility private
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
total_borders = num_columns + 1
|
703
|
-
unadjusted_table_width = total_columns_padded_width + total_borders
|
704
|
-
required_increase = Util.max(min_table_width - unadjusted_table_width, 0)
|
774
|
+
# @return [Integer] the total combined width of padding characters
|
775
|
+
def total_padding_width
|
776
|
+
get_columns.inject(0) { |sum, column| sum + column.total_padding }
|
777
|
+
end
|
705
778
|
|
779
|
+
# @!visibility private
|
780
|
+
# @return [Integer] the total combined width of vertical border characters
|
781
|
+
def total_borders_width
|
782
|
+
num_columns + 1
|
783
|
+
end
|
784
|
+
|
785
|
+
# @!visibility private
|
786
|
+
# @return [Integer] the total combined width of column contents (excludes borders and padding)
|
787
|
+
def total_column_content_width
|
788
|
+
get_columns.inject(0) { |sum, column| sum + column.width }
|
789
|
+
end
|
790
|
+
|
791
|
+
# @!visibility private
|
792
|
+
# @return [Integer] the total actual width of the table as a whole
|
793
|
+
def total_table_width
|
794
|
+
total_column_content_width + total_padding_width + total_borders_width
|
795
|
+
end
|
796
|
+
|
797
|
+
# @!visibility private
|
798
|
+
def expand_to(min_table_width, except: nil)
|
799
|
+
required_increase = Util.max(min_table_width - total_table_width, 0)
|
800
|
+
expandable_columns = get_columns(except: except)
|
706
801
|
required_increase.times do
|
707
|
-
narrowest_column =
|
802
|
+
narrowest_column = expandable_columns.inject(expandable_columns.first) do |narrowest, column|
|
708
803
|
column.width <= narrowest.width ? column : narrowest
|
709
804
|
end
|
710
805
|
|
@@ -713,27 +808,8 @@ module Tabulo
|
|
713
808
|
end
|
714
809
|
|
715
810
|
# @!visibility private
|
716
|
-
def
|
717
|
-
|
718
|
-
num_columns = columns.count
|
719
|
-
total_columns_padded_width = columns.inject(0) { |sum, column| sum + column.padded_width }
|
720
|
-
total_padding = columns.inject(0) { |sum, column| sum + column.total_padding }
|
721
|
-
total_borders = num_columns + 1
|
722
|
-
unadjusted_table_width = total_columns_padded_width + total_borders
|
723
|
-
|
724
|
-
# Ensure max table width is at least wide enough to accommodate table borders and padding
|
725
|
-
# and one character of content.
|
726
|
-
min_table_width = total_padding + total_borders + column_registry.count
|
727
|
-
max_table_width = Util.max(min_table_width, max_table_width)
|
728
|
-
required_reduction = Util.max(unadjusted_table_width - max_table_width, 0)
|
729
|
-
|
730
|
-
required_reduction.times do
|
731
|
-
widest_column = columns.inject(columns.first) do |widest, column|
|
732
|
-
column.width >= widest.width ? column : widest
|
733
|
-
end
|
734
|
-
|
735
|
-
widest_column.width -= 1
|
736
|
-
end
|
811
|
+
def num_columns
|
812
|
+
column_registry.count
|
737
813
|
end
|
738
814
|
|
739
815
|
# @!visibility private
|
data/lib/tabulo/version.rb
CHANGED
data/tabulo.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
}
|
30
30
|
|
31
31
|
spec.add_runtime_dependency "tty-screen", "0.8.1"
|
32
|
-
spec.add_runtime_dependency "unicode-display_width", "2.
|
32
|
+
spec.add_runtime_dependency "unicode-display_width", "2.1.0"
|
33
33
|
|
34
34
|
spec.add_development_dependency "bundler"
|
35
35
|
spec.add_development_dependency "rake", "~> 12.3.3"
|
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.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Harvey
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-screen
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.1.0
|
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: 2.
|
40
|
+
version: 2.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,7 +206,7 @@ licenses:
|
|
206
206
|
metadata:
|
207
207
|
source_code_uri: https://github.com/matt-harvey/tabulo
|
208
208
|
changelog_uri: https://raw.githubusercontent.com/matt-harvey/tabulo/master/CHANGELOG.md
|
209
|
-
post_install_message:
|
209
|
+
post_install_message:
|
210
210
|
rdoc_options: []
|
211
211
|
require_paths:
|
212
212
|
- lib
|
@@ -221,8 +221,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0'
|
223
223
|
requirements: []
|
224
|
-
rubygems_version: 3.
|
225
|
-
signing_key:
|
224
|
+
rubygems_version: 3.2.3
|
225
|
+
signing_key:
|
226
226
|
specification_version: 4
|
227
227
|
summary: Terminal table generator
|
228
228
|
test_files: []
|