Class: TTY::Table

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Comparable, Enumerable, Validatable
Defined in:
lib/tty/table.rb,
lib/tty/table/row.rb,
lib/tty/table/empty.rb,
lib/tty/table/error.rb,
lib/tty/table/field.rb,
lib/tty/table/border.rb,
lib/tty/table/header.rb,
lib/tty/table/columns.rb,
lib/tty/table/options.rb,
lib/tty/table/version.rb,
lib/tty/table/renderer.rb,
lib/tty/table/border_dsl.rb,
lib/tty/table/operations.rb,
lib/tty/table/border/null.rb,
lib/tty/table/indentation.rb,
lib/tty/table/orientation.rb,
lib/tty/table/validatable.rb,
lib/tty/table/border/ascii.rb,
lib/tty/table/alignment_set.rb,
lib/tty/table/border/unicode.rb,
lib/tty/table/border_options.rb,
lib/tty/table/renderer/ascii.rb,
lib/tty/table/renderer/basic.rb,
lib/tty/table/transformation.rb,
lib/tty/table/border/row_line.rb,
lib/tty/table/operation/escape.rb,
lib/tty/table/operation/filter.rb,
lib/tty/table/renderer/unicode.rb,
lib/tty/table/column_constraint.rb,
lib/tty/table/operation/padding.rb,
lib/tty/table/operation/wrapped.rb,
lib/tty/table/operation/alignment.rb,
lib/tty/table/operation/truncation.rb,
lib/tty/table/orientation/vertical.rb,
lib/tty/table/orientation/horizontal.rb

Overview

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.

Direct Known Subclasses

Empty

Defined Under Namespace

Modules: Columns, Indentation, Operation, Renderer, Validatable Classes: AlignmentSet, ArgumentRequired, Border, BorderDSL, BorderOptions, ColumnConstraint, DimensionMismatchError, Empty, Field, Header, InvalidArgument, InvalidOrientationError, NoImplementationError, Operations, Options, Orientation, ResizeError, Row, Transformation, TupleMissing, TypeError, UnknownAttributeError

Constant Summary collapse

VERSION =
"0.12.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Validatable

#assert_row_size, #assert_row_sizes, #assert_table_type, #validate_options!

Constructor Details

#initialize(options = {}, &block) ⇒ TTY::Table

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a Table

Parameters:

  • options (Hash) (defaults to: {})

    the options to create the table with

Options Hash (options):

  • :header (String)

    column names to be displayed

  • :rows (String)

    Array of Arrays expressing the rows

  • :orientation (Symbol)

    used to transform table orientation



114
115
116
117
118
119
120
121
122
123
124
125
# 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

Instance Attribute Details

#headerEnumerable (readonly)

The table header

Returns:

  • (Enumerable)


27
28
29
# File 'lib/tty/table.rb', line 27

def header
  @header
end

#orientationTTY::Table::Orientation

The table orientation out of :horizontal and :vertical



42
43
44
# File 'lib/tty/table.rb', line 42

def orientation
  @orientation
end

#original_columnsInteger (readonly)

The table original column count

Returns:

  • (Integer)


56
57
58
# File 'lib/tty/table.rb', line 56

def original_columns
  @original_columns
end

#original_rowsInteger (readonly)

The table original row count

Returns:

  • (Integer)


49
50
51
# File 'lib/tty/table.rb', line 49

def original_rows
  @original_rows
end

#rowsEnumerable (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The table rows

Returns:

  • (Enumerable)


34
35
36
# File 'lib/tty/table.rb', line 34

def rows
  @rows
end

Class Method Details

.[](*rows) ⇒ Object

Create a new Table where each argument is a row

Examples:

table = TTY::Table[["a1", "a2"], ["b1", "b2"]]


68
69
70
# File 'lib/tty/table.rb', line 68

def self.[](*rows)
  new(rows: rows)
end

.new(*args, &block) ⇒ Object

Instantiate a new Table

Examples:

of no header

table = Table.new [["a1", "a2"], ["b1", "b2"]]

of direct parameters

rows  = [["a1", "a2"], ["b1", "b2"]]
table = Table.new ["Header 1", "Header 2"], rows

of parameters passed as options

rows  = [["a1", "a2"], ["b1", "b2"]]
table = Table.new header: ["Header 1", "Header 2"], rows: rows

of parameters passed as hash

Table.new [{"Header1" => ["a1","a2"], "Header2" => ["b1", "b2"] }]}

Parameters:

  • args (Array[Symbol], Hash)


91
92
93
94
95
96
97
98
# 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

Instance Method Details

#<<(row) ⇒ self

Add row to table

Parameters:

  • row (Array)

Returns:

  • (self)


294
295
296
297
298
299
300
301
302
# 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

#==(other) ⇒ Boolean

Compare table for equivalence of header and rows attributes

Returns:

  • (Boolean)


504
505
506
507
# File 'lib/tty/table.rb', line 504

def ==(other)
  other.is_a?(self.class) &&
    header == other.header && rows == other.rows
end

#[](row_index, column_index = false) ⇒ Object Also known as: at, element, component

Lookup element of the table given a row(i) and column(j)

Examples:

table = TTY::Table.new [["a1","a2"], ["b1","b2"]]
table[0]    # => ["a1","a2"]
table[0,0]  # => "a1"
table[-1]   # => ["b1","b2"]

Parameters:

  • row_index (Integer)
  • column_index (Integer) (defaults to: false)


210
211
212
213
214
215
216
217
# 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

#[]=(row_index, column_index, val) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Set table value at row(i) and column(j)



225
226
227
# File 'lib/tty/table.rb', line 225

def []=(row_index, column_index, val)
  @rows[row_index][column_index] = val
end

#coerce(rows) ⇒ Array

Coerce an Enumerable into a Table This coercion mechanism is used by Table to handle Enumerable types and force them into array type.

Parameters:

  • rows (Enumerable)

    the object to coerce

Returns:

  • (Array)


477
478
479
480
481
482
483
484
485
486
487
# 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

#column(index) { ... } ⇒ self

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.

Examples:

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| ... }

Parameters:

  • index (Integer, String, Symbol)

Yields:

  • optional block to execute in the iteration operation

Returns:

  • (self)


276
277
278
279
280
281
282
283
284
285
# 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

#columns_sizeInteger Also known as: columns_count

Return the number of columns

Examples:

table.columns_size # => 5

Returns:

  • (Integer)


349
350
351
# File 'lib/tty/table.rb', line 349

def columns_size
  rows.size > 0 ? rows[0].size : 0
end

#dataArray

Provides access to all table data

Returns:

  • (Array)


141
142
143
# File 'lib/tty/table.rb', line 141

def data
  (header && !header.empty?) ? [header] + rows : rows
end

#each {|Array[Array]| ... } ⇒ self

Iterate over each tuple in the set

Examples:

table = TTY::Table.new(header, tuples)
table.each { |row| ... }

Yields:

  • (Array[Array])

Returns:

  • (self)


315
316
317
318
319
# File 'lib/tty/table.rb', line 315

def each
  return to_enum unless block_given?
  data.each { |row| yield row }
  self
end

#each_with_indexObject

Same as #each but passes the index of the row with the row itself

Examples:

table = TTY::Table.new(header, tuples)
table.each_with_index { |row, index|
  puts "#{row} at #{index}"
}

Returns:

  • self



332
333
334
335
336
337
338
339
# 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

#empty?Boolean

Return true if this is an empty table, i.e. if the number of rows or the number of columns is 0

Returns:

  • (Boolean)


393
394
395
# File 'lib/tty/table.rb', line 393

def empty?
  columns_size == 0 || rows_size == 0
end

#eql?(other) ⇒ Boolean

Compare table for equality of header and rows attributes

Returns:

  • (Boolean)


494
495
496
497
# File 'lib/tty/table.rb', line 494

def eql?(other)
  instance_of?(other.class) &&
    header.eql?(other.header) && rows.eql?(other.rows)
end

#hashNumeric

Hash for this instance and its attributes

Returns:

  • (Numeric)


525
526
527
# File 'lib/tty/table.rb', line 525

def hash
  [self.class, header, rows].hash
end

#inspectString

Inspect this instance attributes

Returns:

  • (String)


514
515
516
517
518
# 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

#render(*args) {|renderer| ... } ⇒ String

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.

Parameters:

  • renderer_type (Symbol)

    the renderer to be used

  • options (Hash)

Yields:

Yield Parameters:

Returns:

  • (String)


435
436
437
# File 'lib/tty/table.rb', line 435

def render(*args, &block)
  render_with(nil, *args, &block)
end

#render_with(border_class, renderer_type = (not_set=true), options = {}) {|renderer| ... } ⇒ String

Render a given table using custom border class.

Parameters:

  • border_class (TTY::Table::Border)
  • renderer_type (Symbol) (defaults to: (not_set=true))
  • options (Hash) (defaults to: {})

Yields:

Yield Parameters:

Returns:

  • (String)


455
456
457
458
459
460
461
462
463
464
465
# 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

#renderer(type = :basic, options = {}) ⇒ Object

Return renderer for this table

Parameters:

  • type (Symbol) (defaults to: :basic)

    the renderer type

  • options (Hash) (defaults to: {})

    the renderer options



414
415
416
# File 'lib/tty/table.rb', line 414

def renderer(type = :basic, options = {})
  @renderer ||= Renderer.select(type).new(self, options)
end

#rotateself

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Rotate the table between vertical and horizontal orientation

Returns:

  • (self)


168
169
170
171
# File 'lib/tty/table.rb', line 168

def rotate
  orientation.transform(self)
  self
end

#rotate_horizontalObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Rotate the table horizontally



187
188
189
190
191
192
193
194
195
196
# 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_verticalObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Rotate the table vertically



176
177
178
179
180
181
182
# 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

#rotated?Boolean

Marks this table as rotated

Returns:

  • (Boolean)


159
160
161
# File 'lib/tty/table.rb', line 159

def rotated?
  @rotated
end

#row(index) { ... } ⇒ self

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.

Examples:

rows  = [["a1", "a2"], ["b1", "b2"]]
table = TTY::Table.new rows: rows
table.row(1) { |row| ... }

Parameters:

  • index (Integer)

Yields:

  • optional block to execute in the iteration operation

Returns:

  • (self)


246
247
248
249
250
251
252
253
# 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

#rows_sizeInteger

Return the number of rows

Examples:

table.row_size # => 5

Returns:

  • (Integer)


362
363
364
# File 'lib/tty/table.rb', line 362

def rows_size
  rows.size
end

#separatorsArray

Provides a list of rows to have separations applied

Returns:

  • (Array)


132
133
134
# File 'lib/tty/table.rb', line 132

def separators
  @separators ||= []
end

#sizeArray

Return the number of rows and columns

Examples:

table.size # => [3,5]

Returns:

  • (Array)

    row x columns



374
375
376
# File 'lib/tty/table.rb', line 374

def size
  [rows_size, columns_size]
end

#to_header(row) ⇒ TTY::Table::Header

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert an Array row into Header

Returns:



15
16
17
# File 'lib/tty/table/header.rb', line 15

def to_header(row)
  Header.new(row)
end

#to_row(row, header = nil) ⇒ TTY::Table::Row

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert an Array row into Row

Returns:



15
16
17
# File 'lib/tty/table/row.rb', line 15

def to_row(row, header = nil)
  Row.new(row, header)
end

#to_sString

Return string representation of table using basic renderer.

Returns:

  • (String)


402
403
404
# File 'lib/tty/table.rb', line 402

def to_s
  render(:basic)
end

#widthInteger

Check table width

Returns:

  • (Integer)

    width



383
384
385
# File 'lib/tty/table.rb', line 383

def width
  Columns.total_width(data)
end