tabulo 2.3.3 → 2.4.0

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: 6104501fe177f52639fb3e05c12c5cd53d62d1388ad85e2abecaa58f15b3d39d
4
- data.tar.gz: 35648de653973f20a5871a71bb2cd9340eb1b80196dc25f510477e7e8143a9db
3
+ metadata.gz: bbe40163f1115e0ea4b81c13b61518eee7827d4ebd8fb87047b0f5081b0ff02a
4
+ data.tar.gz: 630ab47731a06f597ca568ac2bce02ae0a92621a943b2db716ccf5ff0c25bc56
5
5
  SHA512:
6
- metadata.gz: e5c158f65f97272c637bf37fab53f542001264f3e094ea07a67b4a5e6d583cfb315a40d0a51abad2135fa84169b1edce77420dc9fded8f619f842aa5087c7262
7
- data.tar.gz: 0d0f2abb4a82098b4c4886926254f65c17c80b751509818927f8a237c2f4dce35f61d8fcdf028ba9d47640611d14349437eb767ffd2deaf92ebc5c8ee16eda8c
6
+ metadata.gz: d2d3d5ccadecf03327f4325736fe4a8caaef1304bbecf42261e77030271011d3065cb028d584705c83bb8156364a3618a71f6256e3c2b9abbe3a8d54013febb0
7
+ data.tar.gz: 3b1203c04e29e62a9d4d314b1be5e25483711f3e0d13008a60ecf1feac18a63b3374bdf0a9678f69593881a3bc96a9197b9d0b9b8b80bdb4a700d4d94115f9e6
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ### v2.4.0
4
+
5
+ * Add additional, optional `CellData` parameter to `styler` and `formatter` callbacks
6
+ * Add optional `column_index` parameter to `header_styler` callback
7
+ * Add optional `row_index` parameter to `extractor` callback
8
+ * Add `rake yard` Rake task for generating YARD documentation
9
+ * Minor documentation fixes
10
+ * Upgrade dependency version: `unicode-display_width` gem to 1.7.0
11
+
3
12
  ### v2.3.3
4
13
 
5
14
  * Fix styler option on Table initializer, which had no effect
data/README.md CHANGED
@@ -216,6 +216,29 @@ end
216
216
  +--------------+--------------+--------------+
217
217
  ```
218
218
 
219
+ The `add_column` method can be passed a single parameter callable, as shown in the above example,
220
+ with the parameter representing the member of the underyling enumerable; or it can be passed
221
+ 2-parameter callable, with the second parameter representing the (0-based) index of each row. This can be
222
+ useful if you want to display a row number in one of the columns:
223
+
224
+ ```ruby
225
+ table = Tabulo::Table.new(["a", "b", "c"]) do |t|
226
+ t.add_column("Row") { |letter, row_index| row_index }
227
+ t.add_column("Value", &:itself)
228
+ end
229
+ ```
230
+
231
+ ```
232
+ > puts table
233
+ +--------------+--------------+
234
+ | Row | Value |
235
+ +--------------+--------------+
236
+ | 0 | a |
237
+ | 1 | b |
238
+ | 2 | c |
239
+ +--------------+--------------+
240
+ ```
241
+
219
242
  <a name="labels-headers"></a>
220
243
  #### Column labels _vs_ headers
221
244
 
@@ -550,6 +573,12 @@ end
550
573
  Formatters set for individual columns on calling `#add_column` always override the default formatter for
551
574
  the table.
552
575
 
576
+ The `formatter` callback has an alternative, 2-parameter version. If `formatter` is passed
577
+ a 2-parameter callable, the second parameter will be given a `CellData` instance,
578
+ containing additional information about the cell that may be useful in determining how to format
579
+ it&mdash;see the [documentation](https://www.rubydoc.info/gems/tabulo/2.4.0/Tabulo/CellData.html)
580
+ for details.
581
+
553
582
  <a name="colours-and-styling"></a>
554
583
  ### Colours and other styling
555
584
 
@@ -587,16 +616,20 @@ table.add_column(
587
616
  )
588
617
  ```
589
618
 
590
- The `styler` option should be passed a callable that takes two parameters: the first represents
591
- the underlying value of the cell (in this case a boolean indicating whether the number is even);
592
- and the second represents the formatted string value of that cell, i.e. the cell content after
593
- any processing by the [formatter](#formatting-cell-values). If the content of a cell is wrapped
594
- over multiple lines, then the `styler` will be called once per line, so that each line of the
595
- cell will have the escape sequence applied to it separately (ensuring the styling doesn&#8217;t bleed
596
- into neighbouring cells).
619
+ The `styler` option should be passed a callable that takes either two or three parameters: the
620
+ first parameter represents the underlying value of the cell (in this case a boolean indicating whether
621
+ the number is even); the second represents the formatted string value of that cell, i.e. the cell
622
+ content after any processing by the [formatter](#formatting-cell-values); and the third parameter,
623
+ if present, will be passed a `CellData` object, containing other information about the cell
624
+ that may be useful in determining how to style it&mdash;see the
625
+ [documentation](https://www.rubydoc.info/gems/tabulo/2.4.0/Tabulo/CellData.html) for details.
626
+
627
+ If the content of a cell is wrapped over multiple lines, then the `styler` will be called once
628
+ per line, so that each line of the cell will have the escape sequence applied to it separately
629
+ (ensuring the styling doesn&#8217;t bleed into neighbouring cells).
597
630
 
598
- If the content of a cell has been [truncated](#overflow-handling), then whatever colours or other styling
599
- apply to the cell content will also be applied the truncation indicator character.
631
+ If the content of a cell has been [truncated](#overflow-handling), then whatever colours or other
632
+ styling apply to the cell content will also be applied the truncation indicator character.
600
633
 
601
634
  <a name="styling-column-headers"></a>
602
635
  #### Styling column headers
@@ -608,6 +641,10 @@ to cells in the table body, use the `header_styler` option, e.g.:
608
641
  table.add_column(:even?, header_styler: -> (s) { "\033[32m#{s}\033[0m" })
609
642
  ```
610
643
 
644
+ The `header_styler` option accepts either a 1- or 2-parameter callable. See the
645
+ [documentation](https://www.rubydoc.info/gems/tabulo/2.4.0/Tabulo/Table#add_column-instance_method)
646
+ for details.
647
+
611
648
  <a name="default-styles"></a>
612
649
  #### Setting default styles
613
650
 
@@ -798,7 +835,7 @@ a new table in which the rows and columns are swapped:
798
835
  By default, a header row is added to the new table, showing the string value of the element
799
836
  represented in that column. This can be configured, however, along with other aspects of
800
837
  `transpose`&#8217;s behaviour. For details, see the
801
- [documentation](https://www.rubydoc.info/gems/tabulo/2.3.3/Tabulo/Table#transpose-instance_method).
838
+ [documentation](https://www.rubydoc.info/gems/tabulo/2.4.0/Tabulo/Table#transpose-instance_method).
802
839
 
803
840
  <a name="borders"></a>
804
841
  ### Configuring borders
@@ -1107,14 +1144,14 @@ The gem is available as open source under the terms of the [MIT
1107
1144
  License](http://opensource.org/licenses/MIT).
1108
1145
 
1109
1146
  [Gem Version]: https://rubygems.org/gems/tabulo
1110
- [Documentation]: http://www.rubydoc.info/gems/tabulo/2.3.3
1147
+ [Documentation]: http://www.rubydoc.info/gems/tabulo/2.4.0
1111
1148
  [Build Status]: https://travis-ci.org/matt-harvey/tabulo
1112
1149
  [Coverage Status]: https://coveralls.io/r/matt-harvey/tabulo
1113
1150
  [Code Climate]: https://codeclimate.com/github/matt-harvey/tabulo
1114
1151
  [Awesome Ruby]: https://github.com/markets/awesome-ruby#cli-utilities
1115
1152
 
1116
1153
  [GV img]: https://img.shields.io/gem/v/tabulo.svg
1117
- [DC img]: https://img.shields.io/badge/documentation-v2.3.3-blue.svg
1154
+ [DC img]: https://img.shields.io/badge/documentation-v2.4.0-blue.svg
1118
1155
  [BS img]: https://img.shields.io/travis/matt-harvey/tabulo.svg
1119
1156
  [CS img]: https://img.shields.io/coveralls/matt-harvey/tabulo.svg
1120
1157
  [CC img]: https://codeclimate.com/github/matt-harvey/tabulo/badges/gpa.svg
data/Rakefile CHANGED
@@ -1,12 +1,17 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
  require "rake-version"
4
+ require "yard"
4
5
 
5
6
  RSpec::Core::RakeTask.new(:spec)
6
7
 
7
- task :default => :spec
8
+ task default: :spec
8
9
 
9
10
  RakeVersion::Tasks.new do |v|
10
11
  v.copy "lib/tabulo/version.rb"
11
12
  v.copy "README.md", all: true
12
13
  end
14
+
15
+ YARD::Rake::YardocTask.new do |t|
16
+ t.options = ["--markup-provider=redcarpet", "--markup=markdown"]
17
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.3
1
+ 2.4.0
@@ -4,6 +4,7 @@ require "tabulo/util"
4
4
  require "tabulo/table"
5
5
  require "tabulo/version"
6
6
  require "tabulo/row"
7
+ require "tabulo/cell_data"
7
8
  require "tabulo/cell"
8
9
  require "tabulo/column"
9
10
  require "tabulo/border"
@@ -9,14 +9,24 @@ module Tabulo
9
9
  attr_reader :value
10
10
 
11
11
  # @!visibility private
12
- def initialize(value:, formatter:, alignment:, width:, styler:, truncation_indicator:, padding_character:)
13
- @value = value
14
- @formatter = formatter
12
+ def initialize(
13
+ alignment:,
14
+ cell_data:,
15
+ formatter:,
16
+ padding_character:,
17
+ styler:,
18
+ truncation_indicator:,
19
+ value:,
20
+ width:)
21
+
15
22
  @alignment = alignment
16
- @width = width
23
+ @cell_data = cell_data
24
+ @padding_character = padding_character
25
+ @formatter = formatter
17
26
  @styler = styler
18
27
  @truncation_indicator = truncation_indicator
19
- @padding_character = padding_character
28
+ @value = value
29
+ @width = width
20
30
  end
21
31
 
22
32
  # @!visibility private
@@ -37,11 +47,27 @@ module Tabulo
37
47
  # @return [String] the content of the Cell, after applying the formatter for this Column (but
38
48
  # without applying any wrapping or the styler).
39
49
  def formatted_content
40
- @formatted_content ||= @formatter.call(@value)
50
+ @formatted_content ||= apply_formatter
41
51
  end
42
52
 
43
53
  private
44
54
 
55
+ def apply_formatter
56
+ if @formatter.arity == 2
57
+ @formatter.call(@value, @cell_data)
58
+ else
59
+ @formatter.call(@value)
60
+ end
61
+ end
62
+
63
+ def apply_styler(content)
64
+ if @styler.arity == 3
65
+ @styler.call(@value, content, @cell_data)
66
+ else
67
+ @styler.call(@value, content)
68
+ end
69
+ end
70
+
45
71
  def subcells
46
72
  @subcells ||= calculate_subcells
47
73
  end
@@ -63,7 +89,7 @@ module Tabulo
63
89
  end
64
90
 
65
91
  def styled_truncation_indicator
66
- @styler.call(@value, @truncation_indicator)
92
+ apply_styler(@truncation_indicator)
67
93
  end
68
94
 
69
95
  def calculate_subcells
@@ -99,7 +125,7 @@ module Tabulo
99
125
  [padding, 0]
100
126
  end
101
127
 
102
- "#{' ' * left_padding}#{@styler.call(@value, content)}#{' ' * right_padding}"
128
+ "#{' ' * left_padding}#{apply_styler(content)}#{' ' * right_padding}"
103
129
  end
104
130
 
105
131
  def real_alignment
@@ -0,0 +1,13 @@
1
+ module Tabulo
2
+
3
+ # Contains information about a particular {Cell} in the {Table}.
4
+ #
5
+ # @attr source [Object] The member of this {Cell}'s {Table}'s underlying enumerable from which
6
+ # this {Cell}'s {Row} was derived.
7
+ # @attr row_index [Integer] The positional index of the {Cell}'s {Row}. The topmost {Row} of the
8
+ # {Table} has index 0, the next has index 1, etc..
9
+ # @attr column_index [Integer] The positional index of the {Cell}'s {Column}. The leftmost {Column}
10
+ # of the {Table} has index 0, the next has index 1, etc..
11
+ CellData = Struct.new(:source, :row_index, :column_index)
12
+
13
+ end
@@ -5,6 +5,7 @@ module Tabulo
5
5
 
6
6
  attr_accessor :width
7
7
  attr_reader :header
8
+ attr_reader :index
8
9
 
9
10
  def initialize(
10
11
  align_body:,
@@ -13,6 +14,7 @@ module Tabulo
13
14
  formatter:,
14
15
  header:,
15
16
  header_styler:,
17
+ index:,
16
18
  padding_character:,
17
19
  styler:,
18
20
  truncation_indicator:,
@@ -23,12 +25,15 @@ module Tabulo
23
25
  @extractor = extractor
24
26
  @formatter = formatter
25
27
  @header = header
28
+ @index = index
26
29
 
27
30
  @header_styler =
28
- if header_styler
29
- -> (_, s) { header_styler.call(s) }
31
+ if header_styler && (header_styler.arity == 2)
32
+ -> (_, str, cell_data) { header_styler.call(str, cell_data.column_index) }
33
+ elsif header_styler
34
+ -> (_, str) { header_styler.call(str) }
30
35
  else
31
- -> (_, s) { s }
36
+ -> (_, str) { str }
32
37
  end
33
38
 
34
39
  @padding_character = padding_character
@@ -38,8 +43,12 @@ module Tabulo
38
43
  end
39
44
 
40
45
  def header_cell
46
+ if @header_styler.arity == 3
47
+ cell_data = CellData.new(nil, nil, @index)
48
+ end
41
49
  Cell.new(
42
50
  alignment: @align_header,
51
+ cell_data: cell_data,
43
52
  formatter: -> (s) { s },
44
53
  padding_character: @padding_character,
45
54
  styler: @header_styler,
@@ -49,20 +58,34 @@ module Tabulo
49
58
  )
50
59
  end
51
60
 
52
- def body_cell(source)
61
+ def body_cell(source, row_index:, column_index:)
62
+ if body_cell_data_required?
63
+ cell_data = CellData.new(source, row_index, @index)
64
+ end
53
65
  Cell.new(
54
66
  alignment: @align_body,
67
+ cell_data: cell_data,
55
68
  formatter: @formatter,
56
69
  padding_character: @padding_character,
57
70
  styler: @styler,
58
71
  truncation_indicator: @truncation_indicator,
59
- value: body_cell_value(source),
72
+ value: body_cell_value(source, row_index: row_index, column_index: column_index),
60
73
  width: @width,
61
74
  )
62
75
  end
63
76
 
64
- def body_cell_value(source)
65
- @extractor.call(source)
77
+ def body_cell_value(source, row_index:, column_index:)
78
+ if @extractor.arity == 2
79
+ @extractor.call(source, row_index)
80
+ else
81
+ @extractor.call(source)
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def body_cell_data_required?
88
+ @cell_data_required ||= (@styler.arity == 3 || @formatter.arity == 2)
66
89
  end
67
90
  end
68
91
  end
@@ -7,11 +7,12 @@ module Tabulo
7
7
  attr_reader :source
8
8
 
9
9
  # @!visibility private
10
- def initialize(table, source, divider: false, header: :top)
10
+ def initialize(table, source, divider:, header:, index:)
11
11
  @table = table
12
12
  @source = source
13
13
  @divider = divider
14
14
  @header = header
15
+ @index = index
15
16
  end
16
17
 
17
18
  # Calls the given block once for each {Cell} in the {Row}, passing that {Cell} as parameter.
@@ -23,8 +24,8 @@ module Tabulo
23
24
  # puts cell.value # => 1, => false
24
25
  # end
25
26
  def each
26
- @table.column_registry.each do |_, column|
27
- yield column.body_cell(@source)
27
+ @table.column_registry.each_with_index do |(_, column), column_index|
28
+ yield column.body_cell(@source, row_index: @index, column_index: column_index)
28
29
  end
29
30
  end
30
31
 
@@ -34,7 +35,7 @@ module Tabulo
34
35
  # and divider frequency).
35
36
  def to_s
36
37
  if @table.column_registry.any?
37
- @table.formatted_body_row(@source, header: @header, divider: @divider)
38
+ @table.formatted_body_row(@source, divider: @divider, header: @header, index: @index)
38
39
  else
39
40
  ""
40
41
  end
@@ -42,7 +43,9 @@ module Tabulo
42
43
 
43
44
  # @return a Hash representation of the {Row}, with column labels acting as keys and the {Cell}s the values.
44
45
  def to_h
45
- @table.column_registry.map { |label, column| [label, column.body_cell(@source)] }.to_h
46
+ @table.column_registry.map.with_index do |(label, column), column_index|
47
+ [label, column.body_cell(@source, row_index: @index, column_index: column_index)]
48
+ end.to_h
46
49
  end
47
50
  end
48
51
  end
@@ -64,7 +64,7 @@ module Tabulo
64
64
  # If passed <tt>nil</tt>, then no additional styling will be applied to borders. If passed a
65
65
  # callable, then that callable will be called for each border section, with the
66
66
  # resulting string rendered in place of that border. The extra width of the string returned by the
67
- # {border_styler} is not taken into consideration by the internal table rendering calculations
67
+ # <tt>border_styler</tt> is not taken into consideration by the internal table rendering calculations
68
68
  # Thus it can be used to apply ANSI escape codes to border characters, to colour the borders
69
69
  # for example, without breaking the table formatting.
70
70
  # @param [nil, Integer, Array] column_padding (1) Determines the amount of blank space with which to pad
@@ -168,48 +168,85 @@ module Tabulo
168
168
  # in either String or Symbol form for this purpose.
169
169
  # @param [#to_proc] formatter (nil) A lambda or other callable object that
170
170
  # will be passed the calculated value of each cell to determine how it should be displayed. This
171
- # is distinct from the extractor (see below). For example, if the extractor for this column
172
- # generates a Date, then the formatter might format that Date in a particular way.
173
- # If no formatter is provided, then the callable that was passed to the `formatter` option
174
- # of the table itself on its creation (see {#initialize}) (which itself defaults to
175
- # `:to_s.to_proc`), will be used as the formatter for the column.
171
+ # is distinct from the extractor and the styler (see below).
172
+ # For example, if the extractor for this column generates a Date, then the formatter might format
173
+ # that Date in a particular way.
174
+ # * If <tt>nil</tt> is provided, then the callable that was passed to the `formatter` option
175
+ # of the table itself on its creation (see {#initialize}) (which itself defaults to
176
+ # `:to_s.to_proc`), will be used as the formatter for the column.
177
+ # * If a 1-parameter callable is passed, then this callable will be called with the calculated
178
+ # value of the cell; it should then return a String, and this String will be displayed as
179
+ # the formatted value of the cell.
180
+ # * If a 2-parameter callable is passed, then the first parameter represents the calculated
181
+ # value of the cell, and the second parameter is a {CellData} instance, containing
182
+ # additional information about the cell that may be relevant to what formatting should
183
+ # be applied. For example, the {CellData#row_index} attribute can be inspected to determine
184
+ # whether the {Cell} is an odd- or even-numbered {Row}, to arrange for different formatting
185
+ # to be applied to alternating rows.
186
+ # See the documentation for {CellData} for more.
176
187
  # @param [nil, #to_s] header (nil) Text to be displayed in the column header. If passed nil,
177
188
  # the column's label will also be used as its header text.
178
- # @param [nil, #to_proc] header_styler (nil) A lambda or other callable object taking
179
- # a single parameter, representing a single line of within the header content for
180
- # this column. For example, if the header cell content is wrapped over three lines, then
181
- # the {header_styler} will be called once for each line. If passed <tt>nil</tt>, then
182
- # no additional styling will be applied to the header cell content. If passed a callable,
183
- # then that callable will be called for each line of content within the header cell, and the
184
- # resulting string rendered in place of that line. The extra width of the string returned by the
185
- # {header_styler} is not taken into consideration by the internal table and
186
- # cell width calculations involved in rendering the table. Thus it can be used to apply
187
- # ANSI escape codes to header cell content, to colour the cell content for example, without
188
- # breaking the table formatting.
189
- # Note that if the header content is truncated, then any {header_styler} will be applied to the
189
+ # @param [nil, #to_proc] header_styler (nil) A lambda or other callable object that will
190
+ # determine the colors or other styling applied to the header content. Can be passed
191
+ # <tt>nil</tt>, or can be passed a callable that takes either 1 or 2 parameters:
192
+ # * If passed <tt>nil</tt>, then no additional styling will be applied to the cell content
193
+ # (other than what was already applied by the <tt>formatter</tt>).
194
+ # * If passed a callable, then that callable will be called for each line of content within
195
+ # the header cell, and the resulting string rendered in place of that line.
196
+ # The extra width of the string returned by the <tt>header_styler</tt> is not taken into
197
+ # consideration by the internal table and cell width calculations involved in rendering the
198
+ # table. Thus it can be used to apply ANSI escape codes to header cell content, to color the
199
+ # cell content for example, without breaking the table formatting.
200
+ # * If the passed callable takes 1 parameter, then the first parameter is a string
201
+ # representing a single formatted line within the header cell. For example, if the header
202
+ # cell content is wrapped over three lines, then the <tt>header_styler</tt> will be called
203
+ # three times for that header cell, once for each line of content.
204
+ # * If the passed callable takes 2 parameters, then the first parameter is as above, and the
205
+ # second parameter is an Integer representing the positional index of this header's {Column},
206
+ # with the leftmost column having index 0, the next having index 1 etc.. This can be
207
+ # used, for example, to apply different styles to alternating {Column}s.
208
+ #
209
+ # Note that if the header content is truncated, then any <tt>header_styler</tt> will be applied to the
190
210
  # truncation indicator character as well as to the truncated content.
191
- # @param [nil, #to_proc] styler (nil) A lambda or other callable object that will be passed
192
- # two arguments: the calculated value of the cell (prior to the {formatter} being applied);
193
- # and a string representing a single formatted line within the cell. For example, if the
194
- # cell content is wrapped over three lines, then for that cell, the {styler} will be called
195
- # three times, once for each line of content within the cell. If passed <tt>nil</tt>, then
196
- # no additional styling will be applied to the cell content (other than what was already
197
- # applied by the {formatter}). If passed a callable, then that callable will be called for
198
- # each line of content within the cell, and the resulting string rendered in place of that
199
- # line. The {styler} option differs from the {formatter} option in that the extra width of the
200
- # string returned by {styler} is not taken into consideration by the internal table and
201
- # cell width calculations involved in rendering the table. Thus it can be used to apply
202
- # ANSI escape codes to cell content, to colour the cell content for example, without
203
- # breaking the table formatting.
211
+ # @param [nil, #to_proc] styler (nil) A lambda or other callable object that will determine
212
+ # the colors or other styling applied to the formatted value of the cell. Can be passed
213
+ # <tt>nil</tt>, or can be passed a callable that takes either 2 or 3 parameters:
214
+ # * If passed <tt>nil</tt>, then no additional styling will be applied to the cell content
215
+ # (other than what was already applied by the <tt>formatter</tt>).
216
+ # * If passed a callable, then that callable will be called for each line of content within
217
+ # the cell, and the resulting string rendered in place of that line.
218
+ # The <tt>styler</tt> option differs from the <tt>formatter</tt> option in that the extra width of the
219
+ # string returned by <tt>styler</tt> is not taken into consideration by the internal table and
220
+ # cell width calculations involved in rendering the table. Thus it can be used to apply
221
+ # ANSI escape codes to cell content, to color the cell content for example, without
222
+ # breaking the table formatting.
223
+ # * If the passed callable takes 2 parameters, then the first parameter is the calculated
224
+ # value of the cell (prior to the <tt>formatter</tt> being applied); and the second parameter is
225
+ # a string representing a single formatted line within the cell. For example, if the cell
226
+ # content is wrapped over three lines, then for that cell, the <tt>styler</tt> will be called
227
+ # three times, once for each line of content within the cell.
228
+ # * If the passed callable takes 3 parameters, then the first two parameters are as above,
229
+ # and the third parameter is a {CellData} instance, containing additional information
230
+ # about the cell that may be relevant to what styles should be applied. For example, the
231
+ # {CellData#row_index} attribute can be inspected to determine whether the {Cell} is an
232
+ # odd- or even-numbered {Row}, to arrange for different styling to be applied to
233
+ # alternating rows. See the documentation for {CellData} for more.
234
+ #
204
235
  # Note that if the content of a cell is truncated, then the whatever styling is applied by the
205
- # {styler} to the cell content will also be applied to the truncation indicator character.
236
+ # <tt>styler</tt> to the cell content will also be applied to the truncation indicator character.
206
237
  # @param [Integer] width (nil) Specifies the width of the column, excluding padding. If
207
238
  # nil, then the column will take the width provided by the `column_width` param
208
239
  # with which the Table was initialized.
209
- # @param [#to_proc] extractor A block or other callable
210
- # that will be passed each of the Table sources to determine the value in each cell of this
211
- # column. If this is not provided, then the column label will be treated as a method to be
212
- # called on each source item to determine each cell's value.
240
+ # @param [#to_proc] extractor A block or other callable that will be passed each of the {Table}
241
+ # sources to determine the value in each cell of this column.
242
+ # * If this is not provided, then the column label will be treated as a method to be called on
243
+ # each source item to determine each cell's value.
244
+ # * If provided a single-parameter callable, then this callable will be passed each of the
245
+ # {Table} sources to determine the cell value for each row in this column.
246
+ # * If provided a 2-parameter callable, then for each of the {Table} sources, this callable
247
+ # will be passed the source, and the row index, to determine the cell value for that row.
248
+ # For this purpose, the first body row (not counting the header row) has an index of 0,
249
+ # the next an index of 1, etc..
213
250
  # @raise [InvalidColumnLabelError] if label has already been used for another column in this
214
251
  # Table. (This is case-sensitive, but is insensitive to whether a String or Symbol is passed
215
252
  # to the label parameter.)
@@ -229,6 +266,7 @@ module Tabulo
229
266
  formatter: formatter || @formatter,
230
267
  header: (header || label).to_s,
231
268
  header_styler: header_styler || @header_styler,
269
+ index: column_registry.count,
232
270
  padding_character: PADDING_CHARACTER,
233
271
  styler: styler || @styler,
234
272
  truncation_indicator: @truncation_indicator,
@@ -297,7 +335,7 @@ module Tabulo
297
335
 
298
336
  show_divider = @row_divider_frequency && (index != 0) && Util.divides?(@row_divider_frequency, index)
299
337
 
300
- yield Row.new(self, source, header: header, divider: show_divider)
338
+ yield Row.new(self, source, header: header, divider: show_divider, index: index)
301
339
  end
302
340
  end
303
341
 
@@ -307,14 +345,15 @@ module Tabulo
307
345
  format_row(cells, @wrap_header_cells_to)
308
346
  end
309
347
 
310
- # @param [:top, :middle, :bottom] align_body (:bottom) Specifies the position
348
+ # Produce a horizontal dividing line suitable for printing at the top, bottom or middle
349
+ # of the table.
350
+ #
351
+ # @param [:top, :middle, :bottom] position (:bottom) Specifies the position
311
352
  # for which the resulting horizontal dividing line is intended to be printed.
312
353
  # This determines the border characters that are used to construct the line.
313
354
  # @return [String] an "ASCII" graphical representation of a horizontal
314
- # dividing line suitable for printing at the top, bottom or middle of the
315
- # table.
316
- # @example Print a horizontal divider between each pair of rows, and again
317
- # at the bottom:
355
+ # dividing line.
356
+ # @example Print a horizontal divider between each pair of rows, and again at the bottom:
318
357
  #
319
358
  # table.each_with_index do |row, i|
320
359
  # puts table.horizontal_rule(:middle) unless i == 0
@@ -360,9 +399,10 @@ module Tabulo
360
399
  def pack(max_table_width: :auto)
361
400
  get_columns.each { |column| column.width = wrapped_width(column.header) }
362
401
 
363
- @sources.each do |source|
364
- get_columns.each do |column|
365
- cell_width = wrapped_width(column.body_cell(source).formatted_content)
402
+ @sources.each_with_index do |source, row_index|
403
+ get_columns.each_with_index do |column, column_index|
404
+ cell = column.body_cell(source, row_index: row_index, column_index: column_index)
405
+ cell_width = wrapped_width(cell.formatted_content)
366
406
  column.width = Util.max(column.width, cell_width)
367
407
  end
368
408
  end
@@ -445,15 +485,15 @@ module Tabulo
445
485
  # Add a column to the new table for each of the original table's sources
446
486
  sources.each_with_index do |source, i|
447
487
  t.add_column(i, header: extra_opts[:headers].call(source)) do |original_column|
448
- original_column.body_cell_value(source)
488
+ original_column.body_cell_value(source, row_index: i, column_index: original_column.index)
449
489
  end
450
490
  end
451
491
  end
452
492
  end
453
493
 
454
494
  # @!visibility private
455
- def formatted_body_row(source, header:, divider:)
456
- cells = get_columns.map { |column| column.body_cell(source) }
495
+ def formatted_body_row(source, header:, divider:, index:)
496
+ cells = get_columns.map.with_index { |c, i| c.body_cell(source, row_index: index, column_index: i) }
457
497
  inner = format_row(cells, @wrap_body_cells_to)
458
498
 
459
499
  if header == :top
@@ -1,3 +1,3 @@
1
1
  module Tabulo
2
- VERSION = "2.3.3"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  }
30
30
 
31
31
  spec.add_runtime_dependency "tty-screen", "0.7.1"
32
- spec.add_runtime_dependency "unicode-display_width", "1.6.1"
32
+ spec.add_runtime_dependency "unicode-display_width", "1.7.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.3.3
4
+ version: 2.4.0
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-03-13 00:00:00.000000000 Z
11
+ date: 2020-03-29 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: 1.6.1
33
+ version: 1.7.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: 1.6.1
40
+ version: 1.7.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -189,6 +189,7 @@ files:
189
189
  - lib/tabulo.rb
190
190
  - lib/tabulo/border.rb
191
191
  - lib/tabulo/cell.rb
192
+ - lib/tabulo/cell_data.rb
192
193
  - lib/tabulo/column.rb
193
194
  - lib/tabulo/deprecation.rb
194
195
  - lib/tabulo/exceptions.rb