tabulo 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87e2e8bb108886b594c80a32396ab586c90792ae6e5efeb5769e457b13d6c96d
4
- data.tar.gz: 03c93ac0d5419fb654244ab574d9e7aa43263f40ca71e008f6d43772a76ffece
3
+ metadata.gz: 1aa563982fa70661534282898690138b6ee57a9aacf74edec622e148d4c3cfdb
4
+ data.tar.gz: 5d4265a55ba3add10cdcef1408a81446fb4a9aa8a48da6997ac6f193eeba0f05
5
5
  SHA512:
6
- metadata.gz: ae04026433b44638cd777f483fb0e8b0494370cc71fb84c5bc91cc38c65c92aa4e68183b48db1e92e53b3e3ede6b680975190d2626510f0ad31b6f651bb9538d
7
- data.tar.gz: 5a543577d7d678ccee445789d588147a778fa45899876872749ad1ced9119e99369b43b1e7b642d2f9eae27c41d2e904de9d7765513b9b813824deac5e8d958c
6
+ metadata.gz: b8737456dfe272f6b7cf3714ee17dede09be428101ea05ba7f8eef3fdd3bb7e4e9d19c121d499c40374b48ae6b92ceda341ce39c05884f624c19bfa0309f307c
7
+ data.tar.gz: 3222d37f42ea2568d6d3e6f9901fbfcf0cae94eeb10440051186f2caab375ab1effb6eafe95ba7dc43c4810fbfc905cbe5095befa264d612e4f0ef20f31ac61e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ### v2.3.1
4
+
5
+ * Documentation improvements
6
+ * Update dependency versions
7
+ * Minor refactoring
8
+ * Update Ruby gem description and summary
9
+
3
10
  ### v2.3.0
4
11
 
5
12
  * Provide `#remove_column` method.
data/README.md CHANGED
@@ -43,7 +43,7 @@ end
43
43
 
44
44
  ## Features
45
45
 
46
- * Presents a [DRY initialization interface](#configuring-columns): by being “column based” rather than
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
- * [Configuring columns](#configuring-columns)
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
- ### Configuring columns
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
- A simple case involves initializing columns from symbols corresponding to methods on members of the
133
- underlying `Enumerable`. In this case the symbol also provides the header for each column:
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
- table.add_column(:itself)
138
- table.add_column(:even?)
139
- table.add_column(:odd?)
143
+ other_table = Tabulo::Table.new(User.all)
140
144
  ```
141
145
 
142
- Alternatively, you can pass an initialization block to `new`:
146
+ For the table to be useful, however, it must also contain columns&hellip;
143
147
 
144
- ```ruby
145
- table = Tabulo::Table.new([1, 2, 5]) do |t|
146
- t.add_column(:itself)
147
- t.add_column(:even?)
148
- t.add_column(:odd?)
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, you can also use the &ldquo;quick API&rdquo;, by passing a symbol
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 &ldquo;quick API&rdquo;, 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
- Columns can also be initialized using a callable to which each object will be passed to determine
171
- the value to be displayed in the table. In this case, the first argument to `add_column` provides
172
- the header text:
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 &ldquo;full API&rdquo; 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&#8217;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
- There is also a `#remove_column` method, for deleting an existing column from a table; see the
214
- [documentation](https://www.rubydoc.info/gems/tabulo/2.3.0/Tabulo/Table#remove_column-instance_method)
215
- for details.
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`&mdash;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 &ldquo;manually&rdquo;, 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([1, 2], :itself, :even?)
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
- | itself | even? |
341
- +--------+-------+
342
- | 1 | false |
343
- | 2 | true |
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 &ldquo;pack-and-print&rdquo; in one go:
348
354
 
349
355
  ```ruby
350
- puts Tabulo::Table.new([1, 2], :itself, :even?).pack
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([1, 2], :itself, :even?).pack(max_table_width: 17)
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
- | itsel | even? |
363
- | f | |
364
- +-------+-------+
365
- | 1 | false |
366
- | 2 | true |
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&mdash;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`&mdash;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 first argument to `add_column` always provides the key for the purpose of accessing the `Hash`
673
- form of a `Tabulo::Row`. (If the provided argument was a `String`, it will be converted to a
674
- `Symbol` for purposes of accessing this `Hash`.) This key serves as a sort of &ldquo;logical label&rdquo;
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`&#8217;s behaviour. For details, see the
755
- [documentation](https://www.rubydoc.info/gems/tabulo/2.3.0/Tabulo/Table#transpose-instance_method).
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.0
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.0-blue.svg
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.0
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
- sources,
112
- *columns,
113
- align_body: :auto,
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
- case @column_padding
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
- label,
235
- align_body: nil,
236
- align_header: nil,
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
- add_column_before(column, column_label, before)
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
- case @header_frequency
321
- when :start
322
- :top if index == 0
323
- when Integer
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 && (index != 0) && (index % @row_divider_frequency == 0)
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 = column_registry.map { |_, column| column.header_cell }
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 = column_registry.map { |_, column| column.width + total_column_padding }
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
- return self if column_registry.none?
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
- columns.each do |column|
365
+ get_columns.each do |column|
403
366
  width = wrapped_width(column.body_cell(source).formatted_content)
404
- column.width = width if width > column.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 = column_registry.map { |_, column| column.body_cell(source) }
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(header == :top ? :top : :middle),
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
- if before == nil
520
- @column_registry[label] = column
521
- else
522
- old_column_entries = @column_registry.to_a
523
- new_column_entries = []
524
- found = false
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 total_column_padding
541
- @left_column_padding + @right_column_padding
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 = column_registry.values
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 = column_registry.count * total_column_padding
549
- total_borders = column_registry.count + 1
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
- length = Unicode::DisplayWidth.of(segment)
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
@@ -1,3 +1,3 @@
1
1
  module Tabulo
2
- VERSION = "2.3.0"
2
+ VERSION = "2.3.1"
3
3
  end
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 = "Enumerable ASCII terminal table"
13
- spec.description = "Enumerable ASCII terminal table"
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.0"
32
- spec.add_runtime_dependency "unicode-display_width", "1.6.0"
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.0
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-02-03 00:00:00.000000000 Z
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.0
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.0
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.0
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.0
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: Enumerable ASCII terminal table
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: Enumerable ASCII terminal table
225
+ summary: Terminal table generator
226
226
  test_files: []