TableTennis Ruby Library

repository·main·Indexed 41 days ago

https://github.com/gurgeous/table_tennis

A Ruby library for printing stylish, highly customizable tables in the terminal. It features automatic theme detection, auto-layout for terminal fitting, and advanced visualization tools such as color scales for numeric columns and row highlighting. TableTennis supports various input formats including arrays of hashes, ActiveRecord objects, and structs, and provides multiple rendering strategies including memory-efficient streaming for large datasets.

Tokens
6.9K
Snippets
22
Records
26
Agent score
53%

What's inside TableTennis

  1. Customize themes

    main

    TableTennis automatically detects your terminal's background color to choose between a :dark or :light theme.

    Manual options for the theme: key:

    • :dark: Use the dark theme.
    • :light: Use the light theme.
    • :ansi: Use your terminal's default colors.

    Note: If ANSI colors are disabled (e.g., via color: false), the theme setting has no effect.

  2. How rows and data types work in TableTennis

    main

    TableTennis constructs tables from an array of rows. It is highly flexible regarding the input data format:

    • Hashes/Objects: An array of hashes, ActiveRecord objects, structs, or Data records (anything responding to to_h).
    • Single Hash: You can pass a single hash to represent one row.
    • Arrays: An array of arrays (e.g., [[1,2],[3,4]]) works as a collection of rows.

    If you provide a single hash, it will be treated as a single row.

    puts TableTennis.new([{a: "hello", b: "world"}, {a: "foo", b: "bar"}])
    puts TableTennis.new(Recipe.all.to_a)  # activerecord
    puts TableTennis.new(array_of_structs) # these use to_h
    puts TableTennis.new([[1,2],[3,4]])    # array of arrays
    puts TableTennis.new(authors[0])       # single hash
  3. Quickstart: Print a stylish table

    main

    To print a table, require the library, initialize TableTennis.new with your data and an optional configuration hash, and then print the result. TableTennis works best when you pass it an array of objects that respond to to_h (like Hashes, ActiveRecord objects, Structs, or Data records).

    require "table_tennis"
    
    options = { title: "Star Wars People", zebra: true, color_scale: :height }
    puts TableTennis.new(Starwars.all, options)
  4. Install TableTennis

    main

    You can install the table_tennis gem directly via the command line or add it to your Gemfile for project-based dependency management.

    # install gem
    $ gem install table_tennis
    
    # or add to your Gemfile
    gem "table_tennis"
  5. Format Hash arguments in the TableTennis CLI

    main

    The TableTennis CLI supports a custom hash syntax for flags like --color-scales and --headers.

    Syntax: key=value,key2=value2 or key=:symbol.

    • Values can be strings or integers.
    • To pass a symbol, append a colon to the value (e.g., color=:blue).
    • Use commas to separate pairs.
    # Custom headers: column 'a' becomes 'Alpha', column 'b' becomes 'Beta'
    --headers a=Alpha,b=Beta
    
    # Color scales: 'score' uses the 'blue' symbol scale, 'rank' uses 'red' symbol scale
    --color-scales score=:blue,rank=:red
  6. Initialize and use TableTennis

    main

    To create a table, use TableTennis.new by passing an array of hashes (representing rows) and an optional options hash. You can also pass a block to configure the table.

    Common usage patterns:

    • puts TableTennis.new(array_of_hashes): Renders the table to $stdout.
    • puts TableTennis.new(array_of_hashes, options): Renders the table with specific configurations.
    • TableTennis.new(rows, options) { |config| ... }: Uses a block for configuration.
    puts TableTennis.new(array_of_hashes, options = {})
  7. Render tables to different outputs

    main

    While most users simply puts the table to $stdout, TableTennis supports different rendering strategies:

    • to_s (via puts): Best for small tables. It converts the whole table to a string first.
    • .render: Writes rows to $stdout one at a time. This is significantly more memory-efficient and is preferred for very large tables (e.g., > 10,000 rows).
    • .render(io): Renders the table to any IO stream, such as $stderr, an open file, or a StringIO object.
    # Uses `to_s`, so there can be a pause before output shows up. Best for small tables.
    puts TableTennis.new(rows)
    
    # Write to `$stdout` one row at a time. Prefer this for tables over 10,000 rows.
    TableTennis.new(rows).render
    
    # Render to any I/O stream ($stdout/$stderr, an open file, StringIO...)
    TableTennis.new(rows).render(io)
  8. Configure TableTennis options

    main

    TableTennis provides a wide range of options to customize the appearance and behavior of your tables. You can pass these as a hash to .new, set them via a block, or set global defaults.

    # Using a hash
    TableTennis.new(rows, title: "Employees", zebra: true)
    
    # Using a block
    TableTennis.new(rows) do |t|
      t.title = "Yet Another Way To Set Things Up"
    end
    
    # Setting global defaults
    TableTennis.defaults = { title: "All Tables Have This Name" }
  9. Use color scales to visualize numeric columns

    main

    The color_scales option allows you to apply a color gradient to a column of floats, similar to conditional formatting in spreadsheets.

    • You can pass a single symbol (the column name), an array of column names, or a hash mapping column names to specific color scales.
    • The default scale is :b (blue) if a single column is provided.
    • Supported color scale abbreviations: %i[g y r b gw yw rw bw rg gr gyr] (e.g., :gyr transitions from green to yellow to red).
    puts TableTennis.new(rows, color_scales: :price)
    puts TableTennis.new(rows, color_scales: [ :price, :quantity ])
    puts TableTennis.new(rows, color_scales: { price: :b, quantity: :r })
  10. Configure Column headers and titleization

    main

    When a TableTennis::Column is initialized, it determines its @header based on the table's configuration.

    1. Custom Headers: If the table configuration contains a headers hash, the column will use the value associated with its name: config.headers.dig(name).
    2. Default Header: If no specific header is provided, it defaults to the column's name converted to a string.
    3. Titleization: If the table configuration has titleize? set to true, the header will be processed via Util::Strings.titleize.
  11. Reference: Popular TableTennis options

    main

    Commonly used configuration keys for TableTennis.new:

    | option | default | details |
    | -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `color_scales` | ─ | Color code a column of floats, similar to the "conditional formatting" feature in Google Sheets. See [docs below](#color-scales). |
    | `columns` | ─ | Manually set which columns to include. Leave unset to show all columns. |
    | `headers` | ─ | Specify some or all column headers. For example, `{user_id: "Customer"}`. When unset, headers are inferred. |
    | `mark` | ─ | `mark` is a way to highlight specific columns with a nice color. For example, use `mark: ->(row) { row[:planet] == "tatooine" }` to highlight those rows. Your lambda can also return a specific bg color or Paint color array. |
    | `row_numbers` | `false` | Show row numbers in the table. |
    | `search` | ─ | String/regex to highlight in output. |
    | `separators` | `true` | Include column and header separators in output. |
    | `title` | ─ | Add a title line to the table. |
    | `titleize` | ─ | Titleize column headers, so `person_id` becomes `Person`. |
    | `zebra` | `false` | Turn on zebra stripes. |
  12. Apply theme colors to strings with `paint`

    main

    The paint(str, value) method applies color styling to a string based on a theme symbol or a specific color.

    The value parameter can be:

    1. A theme symbol (e.g., :title, :header1, :zebra).
    2. A color string or symbol compatible with Colors.get (e.g., #fff, :bold, `