Packages
io_ansi_table
1.0.21
1.0.40
1.0.39
1.0.38
1.0.37
1.0.36
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.4.32
0.4.31
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.29
0.3.28
0.3.27
0.3.26
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Writes data to "stdio" in a table with borders and colors. Can choose a table style to change the look of the table.
Current section
Files
Jump to
Current section
Files
lib/io/ansi/table/column.ex
defmodule IO.ANSI.Table.Column do
@moduledoc """
Functions related to the columns of a table.
"""
use PersistConfig
alias IO.ANSI.Table.{Header, Line}
@ansi_escape "\e"
# "\e[1;31mHello" => bold with red foreground
# "\e[2;37;41mWorld => dimmed white foreground with red background
@ansi_escape_codes ~r/\e\[([0-9]{1,3}(;[0-9]{1,3})*)?[m|K]/
@typedoc """
A list of 3 contiguous widths: left width, inner width and right width
"""
@type spread :: [width]
@typedoc "Table column"
@type t :: [String.t()]
@typedoc "Column width"
@type width :: non_neg_integer
@doc ~S'''
Returns a list of column widths capped by `maximum width`.
## Examples
iex> alias IO.ANSI.Table.Column
iex> columns = [["cat", "wombat", "elk"], ["mongoose", "ant", "gnu"]]
iex> Column.widths(columns, 99)
[6, 8]
iex> alias IO.ANSI.Table.Column
iex> columns = [["cat", "wombat", "elk"], ["mongoose", "ant", "gnu"]]
iex> Column.widths(columns, 7)
[6, 7]
iex> alias IO.ANSI.Table.Column
iex> columns = [["\e[32m\e[42mCHEETAH\e[0m", "elk"], ["mongoose", "ant"]]
iex> Column.widths(columns, 99)
[7, 8]
iex> alias IO.ANSI.Table.Column
iex> columns = [["\e[32m\e[42mCHEETAH\e[0m", "elk"], ["mongoose", "ant"]]
iex> Column.widths(columns, 6)
[6, 6]
'''
@spec widths([t], width) :: [width]
def widths(columns, max_width) do
for column <- columns do
Enum.map(column, &width/1) |> Enum.max() |> min(max_width)
end
end
@doc ~S'''
Spreads a `width` given an `element` and its `align attribute`.
## Examples
iex> alias IO.ANSI.Table.Column
iex> {
...> Column.spread(7, "name", :left ),
...> Column.spread(7, "name", :center),
...> Column.spread(7, "name", :right )
...> }
{[0, 4, 3], [1, 4, 2], [3, 4, 0]}
iex> alias IO.ANSI.Table.Column
iex> {
...> Column.spread(3, "name", :left ),
...> Column.spread(3, "name", :center),
...> Column.spread(3, "name", :right )
...> }
{[0, 3, 0], [0, 3, 0], [0, 3, 0]}
iex> alias IO.ANSI.Table.Column
iex> {
...> Column.spread(10, "\e[32m\e[42mCHEETAH\e[0m", :left ),
...> Column.spread(10, "\e[32m\e[42mCHEETAH\e[0m", :center),
...> Column.spread(10, "\e[32m\e[42mCHEETAH\e[0m", :right )
...> }
{[0, 21, 3], [1, 21, 2], [3, 21, 0]}
iex> alias IO.ANSI.Table.Column
iex> {
...> Column.spread(7, "\e[32m\e[42mCHEETAH\e[0m", :left ),
...> Column.spread(7, "\e[32m\e[42mCHEETAH\e[0m", :center),
...> Column.spread(7, "\e[32m\e[42mCHEETAH\e[0m", :right )
...> }
{[0, 21, 0], [0, 21, 0], [0, 21, 0]}
'''
@spec spread(width, Line.elem(), Header.align_attr()) :: spread
def spread(width, elem, _align_attr = :left) do
elem_width = width(elem) |> min(width)
[0, io_width(elem, elem_width), width - elem_width]
end
def spread(width, elem, _align_attr = :right) do
elem_width = width(elem) |> min(width)
[width - elem_width, io_width(elem, elem_width), 0]
end
def spread(width, elem, _align_attr = :center) do
elem_width = width(elem) |> min(width)
left_width = div(width - elem_width, 2)
right_width = width - left_width - elem_width
[left_width, io_width(elem, elem_width), right_width]
end
def spread(width, elem, _align_attr), do: spread(width, elem, :left)
## Private functions
# The "visible" width of an element (ignoring embedded ANSI escape codes)...
# See function `Islands.Grid.to_maps/2` for an example of such elements.
@spec width(String.t()) :: non_neg_integer
defp width(@ansi_escape <> _rest = elem) do
String.replace(elem, @ansi_escape_codes, "") |> String.length()
end
defp width(elem), do: String.length(elem)
# The field width to be used in an Erlang io format...
@spec io_width(String.t(), non_neg_integer) :: non_neg_integer
defp io_width(@ansi_escape <> _rest = elem, _elem_width) do
# We do not cap the width of an element with embedded ANSI escape codes...
String.length(elem)
end
defp io_width(_elem, elem_width), do: elem_width
end