tabulo 2.7.0 → 2.8.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/.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: []
|