class TTY::Table
A core class intended for storing data in a structured, tabular form. Once the data is stored in a TTY::Table
various operations can be performed before the information is dumped into a stdout.
Constants
- VERSION
Attributes
The table header
@return [Enumerable]
@api public
The table orientation out of :horizontal and :vertical
@return [TTY::Table::Orientation]
@api public
The table original column count
@return [Integer]
@api public
The table original row count
@return [Integer]
@api public
The table rows
@return [Enumerable]
@api private
Public Class Methods
Create a new Table
where each argument is a row
@example
table = TTY::Table[["a1", "a2"], ["b1", "b2"]]
@api public
# File lib/tty/table.rb, line 68 def self.[](*rows) new(rows: rows) end
Instantiate a new Table
@example of no header
table = Table.new [["a1", "a2"], ["b1", "b2"]]
@example of direct parameters
rows = [["a1", "a2"], ["b1", "b2"]] table = Table.new ["Header 1", "Header 2"], rows
@example of parameters passed as options
rows = [["a1", "a2"], ["b1", "b2"]] table = Table.new header: ["Header 1", "Header 2"], rows: rows
@example of parameters passed as hash
Table.new [{"Header1" => ["a1","a2"], "Header2" => ["b1", "b2"] }]}
@param [Array, Hash] args
@api public
# File lib/tty/table.rb, line 91 def self.new(*args, &block) options = args.last.respond_to?(:to_hash) ? args.pop : {} if args.size.nonzero? super(Transformation.extract_tuples(args).merge(options), &block) else super(options, &block) end end
Initialize a Table
@param [Hash] options
the options to create the table with
@option options [String] :header
column names to be displayed
@option options [String] :rows
Array of Arrays expressing the rows
@option options [Symbol] :orientation
used to transform table orientation
@return [TTY::Table]
@api private
# File lib/tty/table.rb, line 114 def initialize(options = {}, &block) validate_options! options @header = (value = options[:header]) ? Header.new(value) : nil @rows = coerce(options.fetch(:rows) { Row.new([]) }) @rotated = false self.orientation = options.fetch(:orientation) { :horizontal } assert_row_sizes @rows orientation.transform(self) yield_or_eval(&block) if block_given? end
Public Instance Methods
Add row to table
@param [Array] row
@return [self]
@api public
# File lib/tty/table.rb, line 294 def <<(row) if row == Border::SEPARATOR separators << columns_size - (header ? 0 : 2) else assert_row_size(row, rows) rows << to_row(row) end self end
Compare table for equivalence of header and rows attributes
@return [Boolean]
@api public
# File lib/tty/table.rb, line 504 def ==(other) other.is_a?(self.class) && header == other.header && rows == other.rows end
Lookup element of the table given a row(i) and column(j)
@param [Integer] row_index @param [Integer] column_index
@example
table = TTY::Table.new [["a1","a2"], ["b1","b2"]] table[0] # => ["a1","a2"] table[0,0] # => "a1" table[-1] # => ["b1","b2"]
@api public
# File lib/tty/table.rb, line 210 def [](row_index, column_index = false) return row(row_index) unless column_index if row_index >= 0 && column_index >= 0 rows.fetch(row_index) { return nil }[column_index] else raise TTY::Table::TupleMissing.new(row_index, column_index) end end
Coerce an Enumerable into a Table
This coercion mechanism is used by Table
to handle Enumerable types and force them into array type.
@param [Enumerable] rows
the object to coerce
@return [Array]
@api public
# File lib/tty/table.rb, line 477 def coerce(rows) coerced_rows = [] Array(rows).each do |row| if row == Border::SEPARATOR separators << coerced_rows.length - (header ? 0 : 1) else coerced_rows << to_row(row, header) end end coerced_rows end
Return a column number at the index of the table as an Array. If the table has a header then column can be searched by header name. When a block is given, the elements of that Array are iterated over.
@example
header = [:h1, :h2] rows = [ ["a1", "a2"], ["b1", "b2"] ] table = TTY::Table.new :rows => rows, :header => header table.column(1) table.column(1) { |element| ... } table.column(:h1) table.column(:h1) { |element| ... }
@param [Integer, String, Symbol] index
@yield []
optional block to execute in the iteration operation
@return [self]
@api public
# File lib/tty/table.rb, line 276 def column(index) index_unknown = index.is_a?(Integer) && (index >= columns_size || index < 0) if block_given? return self if index_unknown rows.map { |row| yield row[index] } else return nil if index_unknown rows.map { |row| row[index] }.compact end end
Return the number of columns
@example
table.columns_size # => 5
@return [Integer]
@api public
# File lib/tty/table.rb, line 349 def columns_size rows.size > 0 ? rows[0].size : 0 end
Provides access to all table data
@return [Array]
@api public
# File lib/tty/table.rb, line 141 def data (header && !header.empty?) ? [header] + rows : rows end
Iterate over each tuple in the set
@example
table = TTY::Table.new(header, tuples) table.each { |row| ... }
@yield [Array]
@return [self]
@api public
# File lib/tty/table.rb, line 315 def each return to_enum unless block_given? data.each { |row| yield row } self end
Same as each
but passes the index of the row with the row itself
@example
table = TTY::Table.new(header, tuples) table.each_with_index { |row, index| puts "#{row} at #{index}" }
@return self
@api public
# File lib/tty/table.rb, line 332 def each_with_index return to_enum unless block_given? start_index = -1 data.each do |row| yield row.to_a, start_index += 1 end self end
Return true if this is an empty table, i.e. if the number of rows or the number of columns is 0
@return [Boolean]
@api public
# File lib/tty/table.rb, line 393 def empty? columns_size == 0 || rows_size == 0 end
Compare table for equality of header and rows attributes
@return [Boolean]
@api public
# File lib/tty/table.rb, line 494 def eql?(other) instance_of?(other.class) && header.eql?(other.header) && rows.eql?(other.rows) end
Hash for this instance and its attributes
@return [Numeric]
@api public
# File lib/tty/table.rb, line 525 def hash [self.class, header, rows].hash end
Inspect this instance attributes
@return [String]
@api public
# File lib/tty/table.rb, line 514 def inspect "#<#{self.class.name} header=#{header.inspect} rows=#{rows.inspect} " \ "original_rows=#{original_rows.inspect} " \ "original_columns=#{original_columns.inspect}>" end
Sets table orientation
@param [String,Symbol] value
@api public
# File lib/tty/table.rb, line 150 def orientation=(value) @orientation = Orientation.coerce(value) end
Render a given table. This method takes options which will be passed to the renderer prior to rendering, which allows the caller to set any table rendering variables.
@param [Symbol] renderer_type
the renderer to be used
@param [Hash] options
@yield [renderer]
@yieldparam [TTY::Table::Renderer] renderer
the renderer for the table
@return [String]
@api public
# File lib/tty/table.rb, line 435 def render(*args, &block) render_with(nil, *args, &block) end
Render a given table using custom border class.
@param [TTY::Table::Border] border_class
@param [Symbol] renderer_type
@param [Hash] options
@yield [renderer]
@yieldparam [TTY::Table::Renderer] renderer
the renderer for the table
@return [String]
@api public
# File lib/tty/table.rb, line 455 def render_with(border_class, renderer_type=(not_set=true), options={}, &block) unless not_set if renderer_type.respond_to?(:to_hash) options = renderer_type else options[:renderer] = renderer_type end end Renderer.render_with(border_class, self, options, &block) end
Return renderer for this table
@param [Symbol] type
the renderer type
@param [Hash] options
the renderer options
# File lib/tty/table.rb, line 414 def renderer(type = :basic, options = {}) @renderer ||= Renderer.select(type).new(self, options) end
Rotate the table between vertical and horizontal orientation
@return [self]
@api private
# File lib/tty/table.rb, line 168 def rotate orientation.transform(self) self end
Rotate the table horizontally
@api private
# File lib/tty/table.rb, line 187 def rotate_horizontal return unless rotated? head, body = orientation.slice(self) if header && header.empty? @header = head[0] @rows = body.map { |row| to_row(row, @header) } else @rows = body.map { |row| to_row(row) } end end
Rotate the table vertically
@api private
# File lib/tty/table.rb, line 176 def rotate_vertical @original_columns = columns_size @original_rows = rows_size @rows = orientation.slice(self) @header = [] if header @rotated = true end
Marks this table as rotated
@return [Boolean]
@api public
# File lib/tty/table.rb, line 159 def rotated? @rotated end
Return a row number at the index of the table as an Array. When a block is given, the elements of that Array are iterated over.
@example
rows = [["a1", "a2"], ["b1", "b2"]] table = TTY::Table.new rows: rows table.row(1) { |row| ... }
@param [Integer] index
@yield []
optional block to execute in the iteration operation
@return [self]
@api public
# File lib/tty/table.rb, line 246 def row(index, &block) if block_given? rows.fetch(index) { return self }.each(&block) self else rows.fetch(index) { return nil } end end
Return the number of rows
@example
table.row_size # => 5
@return [Integer]
@api public
# File lib/tty/table.rb, line 362 def rows_size rows.size end
Provides a list of rows to have separations applied
@return [Array]
@api public
# File lib/tty/table.rb, line 132 def separators @separators ||= [] end
Return the number of rows and columns
@example
table.size # => [3,5]
@return [Array] row x columns
@api public
# File lib/tty/table.rb, line 374 def size [rows_size, columns_size] end
Convert an Array row into Header
@return [TTY::Table::Header]
@api private
# File lib/tty/table/header.rb, line 15 def to_header(row) Header.new(row) end
Convert an Array row into Row
@return [TTY::Table::Row]
@api private
# File lib/tty/table/row.rb, line 15 def to_row(row, header = nil) Row.new(row, header) end
Return string representation of table using basic renderer.
@return [String]
@api public
# File lib/tty/table.rb, line 402 def to_s render(:basic) end
Check table width
@return [Integer] width
@api public
# File lib/tty/table.rb, line 383 def width Columns.total_width(data) end
Private Instance Methods
Set table value at row(i) and column(j)
@api private
# File lib/tty/table.rb, line 225 def []=(row_index, column_index, val) @rows[row_index][column_index] = val end
Evaluate block
@return [Table]
@api private
# File lib/tty/table.rb, line 536 def yield_or_eval(&block) return unless block block.arity > 0 ? yield(self) : instance_eval(&block) end