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
EmptyTitleError
}
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.
-
EmptyTitleError
Returned when attempting to build a table with an empty string as the title.
Why is this an error? It is somewhat unclear how to render this, and is likely the result of a bug in your app.
pub type HorizontalRules {
HeaderOnlyHorizontalRules
EveryRowHasHorizontalRules
NoHorizontalRules
}
Constructors
-
HeaderOnlyHorizontalRules
Renders the table with only the header having a horizontal rule beneath it. This is the default setting.
+---------+--------------+ | | Output | +---------+--------------+ | Stage 1 | Wibble | | Stage 2 | Wobble | | Stage 3 | WibbleWobble | +---------+--------------+
-
EveryRowHasHorizontalRules
Renders the table with every row the header having a horizontal rule beneath it.
+---------+--------------+ | | Output | +---------+--------------+ | Stage 1 | Wibble | +---------+--------------+ | Stage 2 | Wobble | +---------+--------------+ | Stage 3 | WibbleWobble | +---------+--------------+
-
NoHorizontalRules
Renders the table without any horizontal rules interleaved with the table’s rows.
+---------+--------------+ | | Output | | Stage 1 | Wibble | | Stage 2 | Wobble | | Stage 3 | WibbleWobble | +---------+--------------+
pub type RenderLineType {
BoxDrawingCharsLineType
BoxDrawingCharsWithRoundedCornersLineType
ASCIILineType
BlankLineType
}
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 | +---------+--------------+
-
BlankLineType
Renders the table with spaces for the borders. Note that this does not strip trailing spaces, the borders that you see in other line types are simply replaced with spaces. It will, however, remove the top and bottom borders for you.
Output Stage 1 Wibble Stage 2 Wobble Stage 3 WibbleWobble
pub type RenderOption {
TableWidthRenderOption(width: Int)
ColumnWidthRenderOption(width: Int)
LineTypeRenderOption(line_type: RenderLineType)
HorizontalRulesRenderOption(horizontal_rules: HorizontalRules)
TitlePositionRenderOption(position: TitlePosition)
HideTitleRenderOption
}
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. -
HorizontalRulesRenderOption(horizontal_rules: HorizontalRules)
Changes the way the table renders horizontal rules. See
HorizontalRules
for more details. By default, only the first row has a horizontal rule. -
TitlePositionRenderOption(position: TitlePosition)
Render a title for the table at the given position. If the table does not have a title set, this option is ignored. By default, the title will render at the top.
-
HideTitleRenderOption
Render a table that has a title set, but without its title.
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
pub type TitlePosition {
TopTitlePosition
BottomTitlePosition
}
Constructors
-
TopTitlePosition
Place the title above the table
-
BottomTitlePosition
Place the title below the 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(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 |
+---------+--------------+
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 set_title(
to builder: Builder,
title title: String,
) -> Builder
Set a title for a table that is being built. The title must be a non-empty
string or a TitleEmptyError
will be returned when build
is called.
Example
let assert Ok(table) =
tobble.builder()
|> tobble.set_title("Setup")
|> 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))
Setup
+---------+--------------+
| | Output |
+---------+--------------+
| Stage 1 | Wibble |
| Stage 2 | Wobble |
| Stage 3 | WibbleWobble |
+---------+--------------+
pub fn title(table: Table) -> Option(String)
Get the title of a table, if there is one.
Example
let assert Ok(table) =
tobble.builder()
|> tobble.set_title("Setup")
|> 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.title(table))
Some("Setup")
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"]
]