class Athena::Console::Helper::Table
- Athena::Console::Helper::Table
- Reference
- Object
Overview
The Table helper can be used to display tabular data rendered to any ACON::Output::Interface
.
+---------------+--------------------------+------------------+
| ISBN | Title | Author |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
+---------------+--------------------------+------------------+
Usage
Most commonly, a table will consist of a header row followed by one or more data rows:
@[ACONA::AsCommand("table")]
class TableCommand < ACON::Command
protected def execute(input : ACON::Input::Interface, output : ACON::Output::Interface) : ACON::Command::Status
ACON::Helper::Table.new(output)
.headers("ISBN", "Title", "Author")
.rows([
["99921-58-10-7", "Divine Comedy", "Dante Alighieri"],
["9971-5-0210-0", "A Tale of Two Cities", "Charles Dickens"],
["960-425-059-0", "The Lord of the Rings", "J. R. R. Tolkien"],
["80-902734-1-6", "And Then There Were None", "Agatha Christie"],
])
.render
ACON::Command::Status::SUCCESS
end
end
Separating Rows
Row separators can be added anywhere in the output by passing an ACON::Helper::Table::Separator
as a row.
table
.rows([
["99921-58-10-7", "Divine Comedy", "Dante Alighieri"],
["9971-5-0210-0", "A Tale of Two Cities", "Charles Dickens"],
ACON::Helper::Table::Separator.new,
["960-425-059-0", "The Lord of the Rings", "J. R. R. Tolkien"],
["80-902734-1-6", "And Then There Were None", "Agatha Christie"],
])
+---------------+--------------------------+------------------+
| ISBN | Title | Author |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+--------------------------+------------------+
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
+---------------+--------------------------+------------------+
Header/Footer Titles
Header and/or footer titles can optionally be added via the #header_title
and/or #footer_title
methods.
table
.header_title("Books")
.footer_title("Page 1/2")
+---------------+----------- Books --------+------------------+
| ISBN | Title | Author |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+--------------------------+------------------+
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
+---------------+--------- Page 1/2 -------+------------------+
Column Sizing
By default, the width of each column is calculated automatically based on their contents.
The #column_widths
method can be used to set the column widths explicitly.
table
.column_widths(10, 0, 30)
.render
In this example, the first column's width will be 10
, the last column's width will be 30
, and the second column's width will be calculated automatically since it is zero.
If you only want to set the width of a specific column, the #column_width
method can be used.
table
.column_width(0, 10)
.column_width(2, 30)
.render
The resulting table would be:
+---------------+------------------ Books -+--------------------------------+
| ISBN | Title | Author |
+---------------+--------------------------+--------------------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+--------------------------+--------------------------------+
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
+---------------+--------------------------+--------------------------------+
Notice that the width of the first column is greater than 10 characters wide. This is because column widths are always considered as the minimum width. If the content doesn't fit, it will be automatically increased to the longest content length.
Max Width
If you would rather wrap the contents in multiple rows, the #column_max_width
method can be used.
table
.column_max_width(0, 5)
.column_max_width(1, 10)
.render
This would cause the table to now be:
+-------+------------+-- Books -----------------------+
| ISBN | Title | Author |
+-------+------------+--------------------------------+
| 99921 | Divine Com | Dante Alighieri |
| -58-1 | edy | |
| 0-7 | | |
| (the rest of the rows...) |
+-------+------------+--------------------------------+
Orientation
By default, the table contents are displayed as a normal table with the data being in rows, the first being the header row(s).
The table can also be rendered vertically or horizontally via the #vertical
and #horizontal
methods respectively.
For example, the same contents rendered vertically would be:
+----------------------------------+
| ISBN: 99921-58-10-7 |
| Title: Divine Comedy |
| Author: Dante Alighieri |
|----------------------------------|
| ISBN: 9971-5-0210-0 |
| Title: A Tale of Two Cities |
| Author: Charles Dickens |
|----------------------------------|
| ISBN: 960-425-059-0 |
| Title: The Lord of the Rings |
| Author: J. R. R. Tolkien |
|----------------------------------|
| ISBN: 80-902734-1-6 |
| Title: And Then There Were None |
| Author: Agatha Christie |
+----------------------------------+
While horizontally, it would be:
+--------+-----------------+----------------------+-----------------------+--------------------------+
| ISBN | 99921-58-10-7 | 9971-5-0210-0 | 960-425-059-0 | 80-902734-1-6 |
| Title | Divine Comedy | A Tale of Two Cities | The Lord of the Rings | And Then There Were None |
| Author | Dante Alighieri | Charles Dickens | J. R. R. Tolkien | Agatha Christie |
+--------+-----------------+----------------------+-----------------------+--------------------------+
Styles
Up until now, all the tables have been rendered using the default
style.
The table helper comes with a few additional built in styles, including:
- borderless
- compact
- box
- double-box
The desired can be set via the #style
method.
table
.style("default") # Same as not calling the method
.render
borderless
=============== ========================== ==================
ISBN Title Author
=============== ========================== ==================
99921-58-10-7 Divine Comedy Dante Alighieri
9971-5-0210-0 A Tale of Two Cities Charles Dickens
=============== ========================== ==================
960-425-059-0 The Lord of the Rings J. R. R. Tolkien
80-902734-1-6 And Then There Were None Agatha Christie
=============== ========================== ==================
compact
ISBN Title Author
99921-58-10-7 Divine Comedy Dante Alighieri
9971-5-0210-0 A Tale of Two Cities Charles Dickens
960-425-059-0 The Lord of the Rings J. R. R. Tolkien
80-902734-1-6 And Then There Were None Agatha Christie
box
┌───────────────┬──────────────────────────┬──────────────────┐
│ ISBN │ Title │ Author │
├───────────────┼──────────────────────────┼──────────────────┤
│ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri │
│ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens │
├───────────────┼──────────────────────────┼──────────────────┤
│ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien │
│ 80-902734-1-6 │ And Then There Were None │ Agatha Christie │
└───────────────┴──────────────────────────┴──────────────────┘
double-box
╔═══════════════╤══════════════════════════╤══════════════════╗
║ ISBN │ Title │ Author ║
╠═══════════════╪══════════════════════════╪══════════════════╣
║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║
║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║
╟───────────────┼──────────────────────────┼──────────────────╢
║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║
║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║
╚═══════════════╧══════════════════════════╧══════════════════╝
Custom Styles
If you would rather something more personal, custom styles can also be defined by providing #style
with an ACON::Helper::Table::Style
instance.
table_style = ACON::Helper::Table::Style.new
.horizontal_border_chars("<fg=magenta>|</>")
.vertical_border_chars("<info>-</>")
.default_crossing_char(' ')
table
.style(table_style)
.render
Notice you can use the same style tags as you can with ACON::Formatter::OutputStyleInterface
s.
This is used by default to give some color to headers when allowed.
TIP: Custom styles can also be registered globally:
ACON::Helper::Table.set_style_definition "colorful", table_style
# ...
table.style("colorful")
This method can also be used to override the built-in styles.
See ACON::Helper::Table::Style
for more information.
Table Cells
The ACON::Helper::Table::Cell
type can be used to style a specific cell.
Such as customizing the fore/background color, the alignment of the text, or the overall format of the cell.
See the related type for more information/examples.
Spanning Multiple Columns and Rows
The ACON::Helper::Table::Cell
type can also be used to add colspan and/or rowspan to a cell;
which would make it span more than one column/row.
ACON::Helper::Table.new(output)
.headers("ISBN", "Title", "Author")
.rows([
["99921-58-10-7", "Divine Comedy", "Dante Alighieri"],
ACON::Helper::Table::Separator.new,
[ACON::Helper::Table::Cell.new("This value spans 3 columns.", colspan: 3)],
])
.render
This would result in:
+---------------+---------------+-----------------+
| ISBN | Title | Author |
+---------------+---------------+-----------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+---------------+---------------+-----------------+
| This value spans 3 columns. |
+---------------+---------------+-----------------+
TIP: This table cells with colspan and center
alignment can be used to create header cells that span the entire table width:
table
.headers([
[ACON::Helper::Table::Cell.new(
"Main table title",
colspan: 3,
style: ACON::Helper::Table::CellStyle.new(
align: :center
)
)],
%w(ISBN Title Author),
])
Would generate:
+--------+--------+--------+
| Main table title |
+--------+--------+--------+
| ISBN | Title | Author |
+--------+--------+--------+
In a similar way, rowspan can be used to have a column span multiple rows. This is especially helpful for columns with line breaks.
ACON::Helper::Table.new(output)
.headers("ISBN", "Title", "Author")
.rows([
[
"978-0521567817",
"De Monarchia",
ACON::Helper::Table::Cell.new("Dante Alighieri\nspans multiple rows", rowspan: 2),
],
["978-0804169127", "Divine Comedy"],
])
.render
This would result in:
+----------------+---------------+---------------------+
| ISBN | Title | Author |
+----------------+---------------+---------------------+
| 978-0521567817 | De Monarchia | Dante Alighieri |
| 978-0804169127 | Divine Comedy | spans multiple rows |
+----------------+---------------+---------------------+
colspan and rowspan may also be used together to create any layout you can think of.
Modifying Rendered Tables
The #render
method requires providing the entire table's content in order to fully render the table.
In some cases, that may not be possible if the data is generated dynamically.
In such cases, the #append_row
method can be used which functions similarly to #add_row
, but will append the rows to an already rendered table.
INFO: This feature is only available when the table is rendered in an ACON::Output::Section
.
@[ACONA::AsCommand("table")]
class TableCommand < ACON::Command
protected def execute(input : ACON::Input::Interface, output : ACON::Output::Interface) : ACON::Command::Status
section = output.section
table = ACON::Helper::Table.new(section)
.add_row("Foo")
table.render
table.append_row "Bar"
ACON::Command::Status::SUCCESS
end
end
This ultimately results in:
+-----+
| Foo |
| Bar |
+-----+
Defined in:
helper/table.crConstructors
Class Method Summary
-
.set_style_definition(name : String, style : ACON::Helper::Table::Style) : Nil
Registers the provided style with the provided name.
-
.style_definition(name : String) : ACON::Helper::Table::Style
Returns the
ACON::Helper::Table::Style
style with the provided name, raising anACON::Exceptions::InvalidArgument
if no style with that name is defined.
Instance Method Summary
-
#add_row(row : RowType) : self
Adds a single new row to this table.
-
#add_row(*columns : CellType) : self
Adds the provided columns as a single row to this table.
-
#add_rows(rows : Enumerable(RowType)) : self
Similar to
#rows(rows : Enumerable(RowType))
, but appends the provided rows to this table. -
#append_row(row : RowType) : self
Appends row to an already rendered table.
-
#append_row(*columns : CellType) : self
Appends the provided columns as a single row to an already rendered table.
-
#column_max_width(index : Int32, width : Int32) : self
Sets the maximum width for the column at the provided index.
-
#column_style(index : Int32, style : ACON::Helper::Table::Style | String) : self
Sets the style of the column at the provided index.
-
#column_style(index : Int32) : ACON::Helper::Table::Style
Returns the
ACON::Helper::Table::Style
the column at the provided index is using, falling back on#style
. -
#column_width(index : Int32, width : Int32) : self
Sets the minimum width for the column at the provided index.
-
#column_widths(widths : Enumerable(Int32)) : self
Sets the minimum column widths to the provided widths.
-
#column_widths(*widths : Int32) : self
Sets the minimum column widths to the provided widths.
-
#footer_title(footer_title : String | Nil) : self
Sets the table [footer title][Athena::Console::Helper::Table--headerfooter-titles].
-
#header_title(header_title : String | Nil) : self
Sets the table [header title][Athena::Console::Helper::Table--headerfooter-titles].
- #headers(headers : RowType) : self
- #headers(headers : Enumerable(RowType)) : self
- #headers(*names : CellType) : self
-
#horizontal : self
Changes this table's [orientation][Athena::Console::Helper::Table--orientation] to horizontal.
-
#render
Renders this table to the
ACON::Output::Interface
it was instantiated with. -
#row(index : Int32, row : RowType) : self
Manually sets the provided row to the provided index.
-
#rows(rows : RowType) : self
Overrides the rows of this table to those provided in rows.
-
#rows(rows : Enumerable(RowType)) : self
Overrides the rows of this table to those provided in rows.
-
#style(style : String | ACON::Helper::Table::Style) : self
Sets the style of this table.
-
#style : ACON::Helper::Table::Style
Returns the
ACON::Helper::Table::Style
used by this table. -
#vertical : self
Changes this table's [orientation][Athena::Console::Helper::Table--orientation] to vertical.
Constructor Detail
Class Method Detail
Registers the provided style with the provided name.
See [custom styles][Athena::Console::Helper::Table--custom-styles].
Returns the ACON::Helper::Table::Style
style with the provided name,
raising an ACON::Exceptions::InvalidArgument
if no style with that name is defined.
Instance Method Detail
Adds a single new row to this table.
# Existing rows are not removed.
table
.add_row(%w(One Two Three))
.add_row(%w(Foo Bar Baz))
.render
Adds the provided columns as a single row to this table.
# Existing rows are not removed.
table
.add_row("One", "Two", "Three")
.add_row("Foo", "Bar", "Baz")
.render
Similar to #rows(rows : Enumerable(RowType))
, but appends the provided rows to this table.
# Existing rows are not removed.
table
.add_rows([
%w(One Two Three),
%w(Foo Bar Baz),
])
.render
Appends row to an already rendered table.
See [modifying rendered tables][Athena::Console::Helper::Table--modifying-rendered-tables]
Appends the provided columns as a single row to an already rendered table.
See [modifying rendered tables][Athena::Console::Helper::Table--modifying-rendered-tables]
Sets the maximum width for the column at the provided index.
See [column sizing][Athena::Console::Helper::Table--column-sizing].
Sets the style of the column at the provided index.
style may either be an explicit ACON::Helper::Table::Style
,
or the name of the style to use if it is built-in, or was registered via .set_style_definition
.
Returns the ACON::Helper::Table::Style
the column at the provided index is using, falling back on #style
.
Sets the minimum width for the column at the provided index.
See [column sizing][Athena::Console::Helper::Table--column-sizing].
Sets the minimum column widths to the provided widths.
See [column sizing][Athena::Console::Helper::Table--column-sizing].
Sets the minimum column widths to the provided widths.
See [column sizing][Athena::Console::Helper::Table--column-sizing].
Sets the table [header title][Athena::Console::Helper::Table--headerfooter-titles].
Changes this table's [orientation][Athena::Console::Helper::Table--orientation] to horizontal.
Renders this table to the ACON::Output::Interface
it was instantiated with.
ameba:disable Metrics/CyclomaticComplexity
Manually sets the provided row to the provided index.
# Existing rows are not removed.
table
.add_row(%w(One Two Three))
.row(0, %w(Foo Bar Baz)) # Overrides row 0 to this row
.render
Overrides the rows of this table to those provided in rows.
table
.rows(%w(Foo Bar Baz))
.render
Overrides the rows of this table to those provided in rows.
table
.rows([
%w(One Two Three),
%w(Foo Bar Baz),
])
.render
Sets the style of this table.
style may either be an explicit ACON::Helper::Table::Style
,
or the name of the style to use if it is built-in, or was registered via .set_style_definition
.
See [styles][Athena::Console::Helper::Table--styles] and [custom styles][Athena::Console::Helper::Table--custom-styles].
Changes this table's [orientation][Athena::Console::Helper::Table--orientation] to vertical.