Packages
io_ansi_table
0.2.4
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/style.ex
defmodule IO.ANSI.Table.Style do
@moduledoc """
Defines functions to retrieve properties of predefined table styles.
"""
@type attr :: [atom] | atom
# {left_border, inner_border, right_border}
@type borders :: {String.t, String.t, String.t}
@type border_widths :: {
# [left_border_width, filler_width]
[non_neg_integer],
# [filler_width, inner_border_width, filler_width]
[non_neg_integer],
# [filler_width, right_border_width]
[non_neg_integer]
}
@type line_type :: :top | :header | :separator | :bottom
@type row_type :: :row | :even_row | :odd_row | :row_1 | :row_2 | :row_3
@type t :: atom
Mix.Project.config[:config_path] |> Mix.Config.read! |> Mix.Config.persist
@external_resource Path.expand Mix.Project.config[:config_path]
@app Mix.Project.config[:app]
@styles Application.get_env @app, :table_styles
Module.register_attribute __MODULE__, :style_lengths, accumulate: true
@doc """
Retrieves the table style for a given table style `tag`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.style_for("light")
{:ok, :light}
iex> alias IO.ANSI.Table.Style
iex> Style.style_for("green-alt")
{:ok, :green_alt}
"""
@spec style_for(String.t) :: {:ok, t} | :error
def style_for(tag)
@doc """
Retrieves the table style tag for a given table `style`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.tag_for(:light)
"light"
iex> alias IO.ANSI.Table.Style
iex> Style.tag_for(:green_alt)
"green-alt"
"""
@spec tag_for(t) :: String.t | nil
def tag_for(style)
for {style, %{}} <- @styles do
@style_lengths String.length(inspect style)
tag = String.replace to_string(style), "_", "-"
def style_for(unquote tag), do: {:ok, unquote style}
def tag_for(unquote style), do: unquote(tag)
end
def style_for(_tag), do: :error
def tag_for(_style), do: nil
@max_length Enum.max @style_lengths
@doc """
Retrieves the line types of a given table `style`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.line_types(:light)
[:top, :header, :separator, [:row], :bottom]
iex> alias IO.ANSI.Table.Style
iex> Style.line_types(:green_alt)
[:top, :header, :separator, [:even_row, :odd_row]]
"""
@spec line_types(t) :: [line_type | [row_type]] | nil
def line_types(style)
for {style, %{line_types: line_types}} <- @styles do
def line_types(unquote style), do: unquote(line_types)
end
def line_types(_style), do: nil
@doc """
Retrieves the dash of a given table `style` and line/row `type`.
## Examples
iex> IO.ANSI.Table.Style
iex> Style.dash(:dark, :top)
"═"
iex> IO.ANSI.Table.Style
iex> Style.dash(:dark, :row)
nil
"""
@spec dash(t, line_type | row_type) :: String.t | nil
def dash(style, type)
@doc """
Retrieves the borders of a given table `style` and line/row `type`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.borders(:cyan, :bottom)
{"╚═", "═╩═", "═╝"}
iex> alias IO.ANSI.Table.Style
iex> Style.borders(:cyan, :row)
{"║", "║", "║"}
"""
@spec borders(t, line_type | row_type) :: borders | nil
def borders(style, type)
for {style, %{borders: borders}} <- @styles do
for {type, {left, inner, right, dash}} <- borders do
def dash(unquote(style), unquote(type)), do: unquote(dash)
def borders(unquote(style), unquote(type)) do
{unquote(left), unquote(inner), unquote(right)}
end
end
end
def dash(_style, _type), do: nil
def borders(_style, _type), do: nil
@doc """
Retrieves the 3 multipart border widths (left, inner and right)
of a given table `style` and line/row `type`. The widths are multipart to
account for the "fillers" preceding/following the borders.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.border_widths(:plain, :bottom) # borders: "└─", "─┴─", "─┘"
{[2, 0], [0, 3, 0], [0, 2]}
iex> alias IO.ANSI.Table.Style
iex> Style.border_widths(:plain, :header) # borders: "│" , "│" , "│"
{[1, 1], [1, 1, 1], [1, 1]}
"""
@spec border_widths(t, line_type | row_type) :: border_widths | nil
def border_widths(style, type)
for {style, %{border_widths: border_widths}} <- @styles do
for {type, {left, inner, right}} <- border_widths do
def border_widths(unquote(style), unquote(type)) do
{unquote(left), unquote(inner), unquote(right)}
end
end
end
def border_widths(_style, _type), do: nil
@doc """
Retrieves the border attribute of a given table `style` and line/row `type`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.border_attr(:green, :top)
[:light_yellow, :light_green_background]
"""
@spec border_attr(t, line_type | row_type) :: attr | nil
def border_attr(style, type)
for {style, %{border_attrs: border_attrs}} <- @styles do
for {type, border_attr} <- border_attrs do
def border_attr(unquote(style), unquote(type)), do: unquote(border_attr)
end
end
def border_attr(_style, _type), do: nil
@doc """
Retrieves the filler attribute of a given table `style` and line/row `type`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.filler_attr(:mixed, :row)
:light_green_background
"""
@spec filler_attr(t, line_type | row_type) :: attr | nil
def filler_attr(style, type)
for {style, %{filler_attrs: filler_attrs}} <- @styles do
for {type, filler_attr} <- filler_attrs do
def filler_attr(unquote(style), unquote(type)), do: unquote(filler_attr)
end
end
def filler_attr(_style, _type), do: nil
@doc """
Retrieves the key attribute of a given table `style` and line/row `type`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.key_attr(:light, :row)
:light_cyan
iex> alias IO.ANSI.Table.Style
iex> Style.key_attr(:light, :header)
[:light_yellow, :underline]
"""
@spec key_attr(t, line_type | row_type) :: attr | nil
def key_attr(style, type)
for {style, %{key_attrs: key_attrs}} <- @styles do
for {type, key_attr} <- key_attrs do
def key_attr(unquote(style), unquote(type)), do: unquote(key_attr)
end
end
def key_attr(_style, _type), do: nil
@doc """
Retrieves the non key attribute of a given table `style` and line/row `type`.
## Examples
iex> alias IO.ANSI.Table.Style
iex> Style.non_key_attr(:cyan, :row)
[:black, :light_cyan_background]
"""
@spec non_key_attr(t, line_type | row_type) :: attr | nil
def non_key_attr(style, type)
for {style, %{non_key_attrs: non_key_attrs}} <- @styles do
for {type, non_key_attr} <- non_key_attrs do
def non_key_attr(unquote(style), unquote(type)) do
unquote(non_key_attr)
end
end
end
def non_key_attr(_style, _type), do: nil
@doc ~S"""
Retrieves a list of interpolated texts (one per table style)
and optionally passes each interpolated text to a function.
## Examples
alias IO.ANSI.Table.Style
Style.texts " - `&style`&filler - ¬e\n"
alias IO.ANSI.Table.Style
Style.texts " - `&style`&filler - ¬e", &IO.puts/1
## Interpolation placeholders
- `&style` - table style (e.g. ":light")
- `&tag` - table style tag (e.g. "light")
- `&filler` - padding after &style or &tag
- `¬e` - table style note
- `&rank` - table style rank (3 digits)
"""
@spec texts(String.t, (String.t -> any)) :: [any]
def texts(template, fun \\ & &1) when is_function(fun, 1) do
@styles
|> Enum.sort(& elem(&1, 1).rank <= elem(&2, 1).rank)
|> Stream.map(&interpolate &1, template)
|> Enum.map(&fun.(&1))
end
@spec interpolate({t, map}, String.t) :: String.t
defp interpolate({style, %{note: note, rank: rank}}, template) do
import String, only: [duplicate: 2, replace: 3, slice: 2]
{style, tag} = {inspect(style), tag_for(style)}
filler = duplicate " ", @max_length - String.length(style)
template
|> replace("&style", style)
|> replace("&tag", tag)
|> replace("&filler", filler)
|> replace("¬e", note)
|> replace("&rank", slice("0#{rank}", -3..-1)) # last 3 digits
|> replace(~r/ +. *$/u, "") # e.g. erase trailing " - "
|> replace(~r/ +\(\) *$/, "") # erase trailing " () "
end
end