TTY::Table

repository·master·Indexed 42 days ago

https://github.com/piotrmurach/tty-table

A flexible Ruby component for formatting data into tables for terminal output. Part of the TTY toolkit, it supports ASCII and Unicode rendering, custom border styles via BorderDSL, cell alignment, multiline content wrapping, and field filtering.

Tokens
7.1K
Snippets
37
Records
40
Agent score
52%

What's inside TTY::Table

  1. Use built-in renderers: Basic, ASCII, and Unicode

    master

    TTY::Table provides three primary built-in renderers that can be used either by calling table.render(type) or by instantiating the renderer class directly.

    • Basic Renderer (TTY::Table::Renderer::Basic): Formats data with whitespace and no borders. Equivalent to table.render(:basic) or just table.render.
    • ASCII Renderer (TTY::Table::Renderer::ASCII): Formats data with ASCII characters for borders. Equivalent to table.render(:ascii).
    • Unicode Renderer (TTY::Table::Renderer::Unicode): Formats data with Unicode characters for borders. Equivalent to table.render(:unicode).

    To use a renderer instance directly:

    renderer = TTY::Table::Renderer::ASCII.new(table)
    renderer.render
    table = TTY::Table.new(["header1","header2"], [["a1", "a2"], ["b1", "b2"]])
    
    # ASCII example
    table.render(:ascii)
    
    # Unicode example
    table.render(:unicode)
  2. Quickstart: Create and render a table

    master

    To create a table, provide headers and rows to TTY::Table.new. To display the table in the console, use the render method and specify a border type (e.g., :ascii).

    table = TTY::Table.new(["header1","header2"], [["a1", "a2"], ["b1", "b2"]])
    puts table.render(:ascii)
  3. Align table columns and individual fields

    master

    You can control text alignment in three ways:

    1. Per column via options: Pass an array of alignments to the alignments option. table.render(:ascii, alignments: [:center, :right])

    2. Global alignment: Use the alignment option to set all columns to the same alignment. table.render(:ascii, alignment: [:center])

    3. Granular field-level alignment: When adding rows, you can pass a hash for specific fields to define their alignment individually.

    table = TTY::Table.new(header: ["header1", "header2"])
    table << [{value: "a1", alignment: :right}, "a2"]
    table = TTY::Table.new(header: ["header1", "header2"])
    table << [{value: "a1", alignment: :right}, "a2"]
    table << ["b1", {value: "b2", alignment: :center}]
    
    table.render(:ascii)
  4. Handle multiline content and padding

    master

    Multiline Text

    • multiline: true: Enables text wrapping at natural line breaks or specified column widths.
    • multiline: false: Escapes special characters (like \n) and truncates content if column widths are set.

    Padding

    The padding option accepts an array of integers (similar to CSS) to set field padding:

    • [2, 2, 2, 2]: 2 chars left/right, 2 lines top/bottom.
    • [1, 2]: 2 chars left/right, 1 line top/bottom.
    • 1: 1 char left/right, 1 line top/bottom.

    Note: When using top/bottom padding with line breaks, multiline must be set to true to allow rows to span multiple lines correctly.

    # Applying padding and multiline together
    table.render(:ascii, multiline: true, padding: [1, 2, 1, 2])
  5. Install TTY::Table

    master

    To use tty-table in your Ruby application, add it to your Gemfile or install it directly via the gem command.

    # Add to Gemfile
    gem "tty-table"

    Or install via terminal

    $ gem install tty-table

    Then run bundle if using Gemfile

    $ bundle

  6. Customize table borders and separators

    master

    Customizing Border Characters

    You can use the border helper within a render block to override specific border parts (e.g., top, mid, left, bottom, etc.).

    table.render do |renderer|
      renderer.border do
        mid          "="
        mid_mid      " "
      end
    end

    Custom Border Classes

    Subclass TTY::Table::Border and implement def_border using the internal DSL to create entirely new border styles. Use table.render_with MyBorder to apply it.

    Row Separators

    You can force separator lines between rows using the separator option on the border object:

    • :each_row: Adds a separator after every row.
    • Array: An array of row indices after which a separator is added (e.g., [0, 2]).
    • Proc: A callable that returns true when a separator should be inserted.
    • :separator symbol: You can insert a separator directly into the table data using the :separator symbol.
    table << :separator << ["c1", "c2"]
    # Using a Proc for separators
    table.render do |renderer|
      renderer.border.separator = ->(row) { row == 0 || (row+1) % 2 == 0 }
    end
    
    # Inserting a separator into data
    table = TTY::Table.new ["h1", "h2"], [:separator, ["a1", "a2"], ["b1", "b2"]]
  7. Control table width and resizing

    master

    By default, TTY::Table calculates column widths based on content. If the table exceeds the terminal width, it is automatically rotated vertically.

    • :width: Sets a constraint on the total table width. It does not force resizing but enforces vertical rotation if the content overspills.
    • :resize: When set to true, forces the table to expand or shrink to match the terminal width or the specified :width value.
    # Force the table to match 80 columns width
    table.render(width: 80, resize: true)
    table.render(width: 80, resize: true)
  8. Configure border separator modes

    master

    The TTY::Table::Border class defines two primary modes for how separators are treated in a table:

    • EACH_ROW (:each_row): Represents a separator that appears on each row.
    • SEPARATOR (:separator): Specifies a separator to be treated as a distinct row.
    # Constants available in TTY::Table::Border
    TTY::Table::Border::EACH_ROW
    TTY::Table::Border::SEPARATOR
  9. Change table orientation

    master

    A table can be oriented as :horizontal (default) or :vertical. Changing the orientation transforms how the data is structured internally.

    table = TTY::Table.new(header: ['A', 'B'], rows: [['1', '2']])
    table.orientation = :vertical
    table.orientation = :vertical
  10. Iterate over TTY::Table rows

    master

    Since TTY::Table behaves like an Array, you can use standard iteration methods like each and each_with_index to loop through the rows.

    table.each { |row| ... }                       # iterate over rows
    table.each_with_index  { |row, index| ... }    # iterate over rows with an index
  11. Initialize a TTY::Table

    master

    You can initialize a TTY::Table using several patterns: passing a 2D array, using keyword arguments (rows: and header:), or using a block to append rows manually. You can also initialize a table with a hash where keys represent headers and values represent row data.

    # Using a 2D array
    table = TTY::Table.new([["a1", "a2"], ["b1", "b2"]])
    
    # Using keyword arguments
    table = TTY::Table.new(rows: [["a1", "a2"], ["b1", "b2"]])
    table = TTY::Table.new(header: ["h1", "h2"], rows: [["a1", "a2"], ["b1", "b2"]])
    
    # Using a block
    table = TTY::Table.new do |t|
      t << ["a1", "a2"]
      t << ["b1", "b2"]
    end
    
    # Appending rows after initialization
    table = TTY::Table.new
    table << ["a1", "a2"]
    
    # Using a hash (keys are headers)
    table = TTY::Table.new([{"h1" => ["a1", "a2"], "h2" => ["b1", "b2"]}])