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/header.ex
defmodule IO.ANSI.Table.Header do
@moduledoc """
Finds the align or sort attribute of a header.
Also converts a header into a "heading".
"""
alias IO.ANSI.Table.Spec
@typedoc "Align atribute"
@type align_attr :: :left | :center | :right
@typedoc "Align spec"
@type align_spec :: t | {align_attr, t}
@typedoc "Sort atribute"
@type sort_attr :: MapSorter.SortSpec.sort_dir()
@typedoc "Sort spec"
@type sort_spec :: MapSorter.SortSpec.t()
@typedoc "Sort symbol"
@type sort_symbol :: {sort_attr, String.t()} | {:pos, sym_pos | [sym_pos]}
@typedoc "Symbol position"
@type sym_pos :: :leading | :trailing
@typedoc "Header"
@type t :: Map.key()
@doc """
Finds the align or sort attribute of a `header`.
## Examples
iex> alias IO.ANSI.Table.Header
iex> sort_specs = ["dept", desc: "hired"]
iex> {
...> Header.find_attr("dept" , sort_specs, :asc),
...> Header.find_attr("hired", sort_specs, :asc),
...> Header.find_attr("job" , sort_specs, :asc)
...> }
{:asc, :desc, nil}
iex> alias IO.ANSI.Table.Header
iex> sort_specs = ["dept", desc: {"hired", Date}]
iex> {
...> Header.find_attr("dept" , sort_specs, :asc),
...> Header.find_attr("hired", sort_specs, :asc),
...> Header.find_attr("job" , sort_specs, :asc)
...> }
{:asc, :desc, nil}
iex> alias IO.ANSI.Table.Header
iex> sort_specs = [{"hired", Date}, "job", {:desc, "dept"}]
iex> {
...> Header.find_attr("dept" , sort_specs, :asc),
...> Header.find_attr("hired", sort_specs, :asc),
...> Header.find_attr("job" , sort_specs, :asc)
...> }
{:desc, :asc, :asc}
iex> alias IO.ANSI.Table.Header
iex> sort_specs = [{"hired", Date}, desc: "dept"]
iex> {
...> Header.find_attr("dept" , sort_specs, :asc),
...> Header.find_attr("hired", sort_specs, :asc),
...> Header.find_attr("job" , sort_specs, :asc)
...> }
{:desc, :asc, nil}
iex> alias IO.ANSI.Table.Header
iex> align_specs = ["dept", right: "hired"]
iex> {
...> Header.find_attr("dept" , align_specs, :left),
...> Header.find_attr("hired", align_specs, :left),
...> Header.find_attr("job" , align_specs, :left)
...> }
{:left, :right, nil}
"""
@spec find_attr(t, [align_spec | sort_spec], :left | :asc) ::
align_attr | sort_attr | nil
def find_attr(header, specs, default_attr) do
Enum.find_value(specs, fn
# {:center, :dob} or {:desc, :dob}
{attr, key} when key == header -> attr
# {:dob, Date}
{key, mod} when is_atom(mod) and key == header -> default_attr
# {:desc, {:dob, Date}}
{attr, {key, mod}} when is_atom(mod) and key == header -> attr
# :dob
key when key == header -> default_attr
_ -> false
end)
end
@doc """
Converts a `header` into a "heading".
## Examples
iex> alias IO.ANSI.Table.{Header, Spec}
iex> spec = Spec.new([:col_4, :col_1, :col_2], sort_specs: [asc: :col_2])
iex> Header.to_heading(:col_2, spec)
"Col 2↑"
"""
@spec to_heading(t, Spec.t()) :: String.t()
def to_heading(header, spec) do
sort_symbol(header, spec, :leading) <>
titlecase(header, spec) <>
sort_symbol(header, spec, :trailing)
end
## Private functions
@spec sort_symbol(t, Spec.t(), sym_pos) :: String.t()
defp sort_symbol(header, spec, sym_pos) do
pos_list = [spec.sort_symbols[:pos]] |> List.flatten()
sort_dir = find_attr(header, spec.sort_specs, :asc)
(sym_pos in pos_list && spec.sort_symbols[sort_dir]) || ""
end
@spec titlecase(t, Spec.t()) :: String.t()
defp titlecase(header, spec)
# string, atom or charlist
when is_binary(header) or is_atom(header) or is_list(header) do
title =
header
|> to_string()
|> String.split(~r/(_| )+/, trim: true)
|> Enum.map_join(" ", &:string.titlecase/1)
Enum.reduce(spec.header_fixes, title, &fix/2)
end
defp titlecase(header, _spec), do: inspect(header)
# fix({" Of ", " of "}, "Nbr Of Yrs") => "Nbr of Yrs"
@spec fix(tuple, String.t()) :: String.t()
defp fix({key, value}, title), do: String.replace(title, key, value)
end