tabulo 2.3.3 → 2.4.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/CHANGELOG.md +9 -0
- data/README.md +49 -12
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/lib/tabulo.rb +1 -0
- data/lib/tabulo/cell.rb +34 -8
- data/lib/tabulo/cell_data.rb +13 -0
- data/lib/tabulo/column.rb +30 -7
- data/lib/tabulo/row.rb +8 -5
- data/lib/tabulo/table.rb +88 -48
- data/lib/tabulo/version.rb +1 -1
- data/tabulo.gemspec +1 -1
- metadata +5 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: bbe40163f1115e0ea4b81c13b61518eee7827d4ebd8fb87047b0f5081b0ff02a
         | 
| 4 | 
            +
              data.tar.gz: 630ab47731a06f597ca568ac2bce02ae0a92621a943b2db716ccf5ff0c25bc56
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d2d3d5ccadecf03327f4325736fe4a8caaef1304bbecf42261e77030271011d3065cb028d584705c83bb8156364a3618a71f6256e3c2b9abbe3a8d54013febb0
         | 
| 7 | 
            +
              data.tar.gz: 3b1203c04e29e62a9d4d314b1be5e25483711f3e0d13008a60ecf1feac18a63b3374bdf0a9678f69593881a3bc96a9197b9d0b9b8b80bdb4a700d4d94115f9e6
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -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—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 | 
| 591 | 
            -
            the underlying value of the cell (in this case a boolean indicating whether | 
| 592 | 
            -
             | 
| 593 | 
            -
            any processing by the [formatter](#formatting-cell-values) | 
| 594 | 
            -
             | 
| 595 | 
            -
             | 
| 596 | 
            -
             | 
| 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—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’t bleed into neighbouring cells).
         | 
| 597 630 |  | 
| 598 | 
            -
            If the content of a cell has been [truncated](#overflow-handling), then whatever colours or other | 
| 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`’s behaviour. For details, see the
         | 
| 801 | 
            -
            [documentation](https://www.rubydoc.info/gems/tabulo/2. | 
| 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. | 
| 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. | 
| 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 : | 
| 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. | 
| 1 | 
            +
            2.4.0
         | 
    
        data/lib/tabulo.rb
    CHANGED
    
    
    
        data/lib/tabulo/cell.rb
    CHANGED
    
    | @@ -9,14 +9,24 @@ module Tabulo | |
| 9 9 | 
             
                attr_reader :value
         | 
| 10 10 |  | 
| 11 11 | 
             
                # @!visibility private
         | 
| 12 | 
            -
                def initialize( | 
| 13 | 
            -
                   | 
| 14 | 
            -
                   | 
| 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 | 
            -
                  @ | 
| 23 | 
            +
                  @cell_data = cell_data
         | 
| 24 | 
            +
                  @padding_character = padding_character
         | 
| 25 | 
            +
                  @formatter = formatter
         | 
| 17 26 | 
             
                  @styler = styler
         | 
| 18 27 | 
             
                  @truncation_indicator = truncation_indicator
         | 
| 19 | 
            -
                  @ | 
| 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 ||=  | 
| 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 | 
            -
                   | 
| 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}#{ | 
| 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
         | 
    
        data/lib/tabulo/column.rb
    CHANGED
    
    | @@ -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 | 
            -
                      -> (_,  | 
| 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 | 
            -
                      -> (_,  | 
| 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. | 
| 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
         | 
    
        data/lib/tabulo/row.rb
    CHANGED
    
    | @@ -7,11 +7,12 @@ module Tabulo | |
| 7 7 | 
             
                attr_reader :source
         | 
| 8 8 |  | 
| 9 9 | 
             
                # @!visibility private
         | 
| 10 | 
            -
                def initialize(table, source, divider | 
| 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. | 
| 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,  | 
| 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  | 
| 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
         | 
    
        data/lib/tabulo/table.rb
    CHANGED
    
    | @@ -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 | 
            -
                #    | 
| 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). | 
| 172 | 
            -
                #   generates a Date, then the formatter might format | 
| 173 | 
            -
                #    | 
| 174 | 
            -
                #    | 
| 175 | 
            -
                # | 
| 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  | 
| 179 | 
            -
                #    | 
| 180 | 
            -
                #    | 
| 181 | 
            -
                #    | 
| 182 | 
            -
                # | 
| 183 | 
            -
                #   then that callable will be called for each line of content within | 
| 184 | 
            -
                # | 
| 185 | 
            -
                # | 
| 186 | 
            -
                # | 
| 187 | 
            -
                # | 
| 188 | 
            -
                # | 
| 189 | 
            -
                # | 
| 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  | 
| 192 | 
            -
                #    | 
| 193 | 
            -
                #    | 
| 194 | 
            -
                #    | 
| 195 | 
            -
                # | 
| 196 | 
            -
                #    | 
| 197 | 
            -
                # | 
| 198 | 
            -
                # | 
| 199 | 
            -
                # | 
| 200 | 
            -
                # | 
| 201 | 
            -
                # | 
| 202 | 
            -
                # | 
| 203 | 
            -
                # | 
| 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 | 
            -
                #    | 
| 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 | 
            -
                #    | 
| 211 | 
            -
                #    | 
| 212 | 
            -
                # | 
| 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 | 
            -
                #  | 
| 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 | 
| 315 | 
            -
                # | 
| 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. | 
| 364 | 
            -
                    get_columns. | 
| 365 | 
            -
                       | 
| 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 { | | 
| 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
         | 
    
        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.7.1"
         | 
| 32 | 
            -
              spec.add_runtime_dependency "unicode-display_width", "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. | 
| 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- | 
| 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. | 
| 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. | 
| 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
         |