tobble

Tobble is a table library for Gleam, which makes it as easy as possible to render tables from simple output. It does provide some customization options, but they are not very expansive, as Tobble does not aim to be a full layout library. Rather, it aims to make it simple to make beautiful output for your programs.

import gleam/io
import tobble

pub fn main() {
  let assert Ok(table) =
    tobble.builder()
    |> tobble.add_row(["", "Output"])
    |> tobble.add_row(["Stage 1", "Wibble"])
    |> tobble.add_row(["Stage 2", "Wobble"])
    |> tobble.add_row(["Stage 3", "WibbleWobble"])
    |> tobble.build()

  io.println(tobble.render(table))
}
+---------+--------------+
|         | Output       |
+---------+--------------+
| Stage 1 | Wibble       |
| Stage 2 | Wobble       |
| Stage 3 | WibbleWobble |
+---------+--------------+

Types

Builder is a type used to help you build tables. See builder() for more details.

pub opaque type Builder
pub type BuilderError {
  InconsistentColumnCountError(expected: Int, got: Int)
  EmptyTableError
}

Constructors

  • InconsistentColumnCountError(expected: Int, got: Int)

    Returned when not all rows have the same number of columns.

    Why is this an error? It is not possible to render a rectangular table if any row has a different number of columns than another.

  • EmptyTableError

    Returned when attempting to build a table with no rows.

    Why is this an error? It is somewhat unclear how to render this, and is left as an error so callers can handle it however is best for their application.

pub type RenderLineType {
  BoxDrawingCharsLineType
  BoxDrawingCharsWithRoundedCornersLineType
  ASCIILineType
}

Constructors

  • BoxDrawingCharsLineType

    Renders the table with box drawing characters for the borders.

    ┌─────────┬──────────────┐
    │         │ Output       │
    ├─────────┼──────────────┤
    │ Stage 1 │ Wibble       │
    │ Stage 2 │ Wobble       │
    │ Stage 3 │ WibbleWobble │
    └─────────┴──────────────┘
  • BoxDrawingCharsWithRoundedCornersLineType

    Renders the table with box drawing characters for the borders, but with rounded corners.

    ╭─────────┬──────────────╮
    │         │ Output       │
    ├─────────┼──────────────┤
    │ Stage 1 │ Wibble       │
    │ Stage 2 │ Wobble       │
    │ Stage 3 │ WibbleWobble │
    ╰─────────┴──────────────╯
  • ASCIILineType

    Render the table with ASCII characters for the borders. This is the default setting.

    +---------+--------------+
    |         | Output       |
    +---------+--------------+
    | Stage 1 | Wibble       |
    | Stage 2 | Wobble       |
    | Stage 3 | WibbleWobble |
    +---------+--------------+
    
pub type RenderOption {
  TableWidthRenderOption(width: Int)
  ColumnWidthRenderOption(width: Int)
  LineTypeRenderOption(line_type: RenderLineType)
}

Constructors

  • TableWidthRenderOption(width: Int)

    Render the table with a width of, at most, the given width. Note that this is best effort, and there are pathological cases where Tobble will decide to render your tables slightly wider than requested (e.g. requesting a width too small to even fit the table borders). By default, the table width is unconstrained.

  • ColumnWidthRenderOption(width: Int)

    Render the table where each column’s text has the given width. If a width less than 1 is given, this will default to 1. By default, columns are as wide as the longest row within them.

  • LineTypeRenderOption(line_type: RenderLineType)

    Render the table with a different style of border By default, ASCIILineType is used.

Table is the central type of Tobble. It holds the data you wish to display, without regard for how you render it. These can be built using builder/build.

pub opaque type Table

Functions

pub fn add_row(
  to builder: Builder,
  columns columns: List(String),
) -> Builder

Add a row to a table that is being built. Every call to add_row for a given Builder must have the same number of columns, or an InconsistentColumnCountError will be returned when build is called.

pub fn build(
  with builder: Builder,
) -> Result(Table, BuilderError)

Build a Table from the given Builder. If an invalid operation was performed when constructing the Builder, an error will be returned.

pub fn builder() -> Builder

Create a new Builder for table generation. Once you have completed adding your rows to this with add_row, you should call build to generate a Table.

pub fn render(table table: Table) -> String

Render the given table to a String, with the default options. The output can be customized by using render_with_options.

Example

let assert Ok(ttable) =
    tobble.builder()
    |> tobble.add_row(["", "Output"])
    |> tobble.add_row(["Stage 1", "Wibble"])
    |> tobble.add_row(["Stage 2", "Wobble"])
    |> tobble.add_row(["Stage 3", "WibbleWobble"])
    |> tobble.build()

  io.println(tobble.render(table))
+---------+--------------+
|         | Output       |
+---------+--------------+
| Stage 1 | Wibble       |
| Stage 2 | Wobble       |
| Stage 3 | WibbleWobble |
+---------+--------------+
pub fn render_iter(
  table table: Table,
  options options: List(RenderOption),
) -> Yielder(String)

Render the given table to a Yielder. Each element of the Yielder will produce a single line of output, without a trailing newline. Note that options are applied in order, so if duplicate or conflicting options are given, the last one will win.

Example

let assert Ok(table) =
tobble.builder()
|> tobble.add_row(["", "Output"])
|> tobble.add_row(["Stage 1", "Wibble"])
|> tobble.add_row(["Stage 2", "Wobble"])
|> tobble.add_row(["Stage 3", "WibbleWobble"])
|> tobble.build()


table
|> tobble.render_iter(options: [])
|> yielder.each(io.println)
+---------+--------------+
|         | Output       |
+---------+--------------+
| Stage 1 | Wibble       |
| Stage 2 | Wobble       |
| Stage 3 | WibbleWobble |
+---------+--------------+
pub fn render_with_options(
  table table: Table,
  options options: List(RenderOption),
) -> String

Render the given table to a String, with extra options. Note that options are applied in order, so if duplicate or conflicting options are given, the last one will win.

let assert Ok(table) =
  tobble.builder()
  |> tobble.add_row(["", "Output"])
  |> tobble.add_row(["Stage 1", "Wibble"])
  |> tobble.add_row(["Stage 2", "Wobble"])
  |> tobble.add_row(["Stage 3", "WibbleWobble"])
  |> tobble.build()

io.println(
  tobble.render_with_options(table, options: [
    tobble.ColumnWidthRenderOption(6),
  ]),
)
+--------+--------+
|        | Output |
+--------+--------+
| Stage  | Wibble |
| 1      |        |
| Stage  | Wobble |
| 2      |        |
| Stage  | Wibble |
| 3      | Wobble |
+--------+--------+
pub fn to_list(table: Table) -> List(List(String))

Convert an existing table to a list of its rows.

Example

let assert Ok(table) =
  tobble.builder()
  |> tobble.add_row(["", "Output"])
  |> tobble.add_row(["Stage 1", "Wibble"])
  |> tobble.add_row(["Stage 2", "Wobble"])
  |> tobble.add_row(["Stage 3", "WibbleWobble"])
  |> tobble.build()

io.debug(tobble.to_list(table))
[
  ["", "Output"],
  ["Stage 1", "Wibble"],
  ["Stage 2", "Wobble"],
  ["Stage 3", "WibbleWobble"]
]
Search Document