Current section

Files

Jump to
scribe lib formatter.ex
Raw

lib/formatter.ex

defmodule Scribe.Formatter.Index do
@moduledoc false
defstruct row: 0, row_max: 0, col: 0, col_max: 0
end
defmodule Scribe.Formatter.Line do
@moduledoc ~S"""
Formats rows and row separators for printing.
"""
defstruct data: [], widths: [], style: nil, opts: [], index: nil
alias Scribe.Formatter.{Index, Line}
def format(%Line{index: %Index{row: 0}} = line) do
top(line)
<> data(line)
<> bottom(line)
end
def format(%Line{} = line) do
data(line)
<> bottom(line)
end
def data(%Line{data: row, widths: widths, style: style, opts: opts, index: index}) do
left_edge = style.border_at(index.row, 0, index.row_max, index.col_max).left_edge
line =
Enum.reduce(0..index.col_max - 1, "", fn(x, acc) ->
b = style.border_at(index.row, x, index.row_max, index.col_max)
width = Enum.at(widths, x)
value = Enum.at(row, x)
cell_value =
case opts[:colorize] do
false -> value |> cell(width)
_ -> value |> cell(width) |> colorize(style.color(value))
end
acc
<> cell_value
<> b.right_edge
end)
left_edge <> line <> "\n"
end
def cell(x, width) do
len = min(String.length(" #{inspect(x)} "), width)
padding = String.duplicate(" ", width - len)
truncate(" #{inspect(x)}#{padding}", width - 2) <> " "
end
def cell_value(x, padding, max_width) when padding >= 0 do
truncate(" #{inspect(x)}#{String.duplicate(" ", padding)} ", max_width)
end
def cell_value(x, _padding, max_width), do: " #{x |> inspect() |> truncate(max_width)} "
defp truncate(elem, width) do
String.slice(elem, 0..width)
end
def colorize(string, color) do
"#{color}#{string}#{IO.ANSI.reset}"
end
def top(%Line{widths: widths, style: style, index: index}) do
top_left = style.border_at(index.row, 0, index.row_max, index.col_max).top_left_corner
line =
Enum.reduce(0..index.col_max - 1, "", fn(x, acc) ->
b = style.border_at(index.row, x, index.row_max, index.col_max)
width = Enum.at(widths, x)
acc
<> String.duplicate(b.top_edge, width)
<> b.top_right_corner
end)
top_left <> add_newline(line)
end
def bottom(%Line{widths: widths, style: style, index: index}) do
bottom_left = style.border_at(index.row, 0, index.row_max, index.col_max).bottom_left_corner
line =
Enum.reduce(0..index.col_max - 1, "", fn(x, acc) ->
b = style.border_at(index.row, x, index.row_max, index.col_max)
width = Enum.at(widths, x)
acc
<> String.duplicate(b.bottom_edge, width)
<> b.bottom_right_corner
end)
bottom_left <> add_newline(line)
end
def add_newline(""), do: ""
def add_newline(line), do: line <> "\n"
end