Skip to content
This repository has been archived by the owner on Aug 1, 2021. It is now read-only.

update the vendorized TableRex and namespace it with Licensir #23

Merged
merged 1 commit into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/mix/tasks/licenses.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defmodule Mix.Tasks.Licenses do
_ = Mix.Shell.IO.info([:yellow, "Notice: This is not a legal advice. Use the information below at your own risk."])

rows
|> TableRex.quick_render!(["Package", "Version", "License"])
|> Licensir.TableRex.quick_render!(["Package", "Version", "License"])
|> IO.puts()
end

Expand Down
6 changes: 3 additions & 3 deletions lib/table_rex.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
defmodule TableRex do
defmodule Licensir.TableRex do
@moduledoc """
TableRex generates configurable, text-based tables for display
"""
alias TableRex.Renderer
alias TableRex.Table
alias Licensir.TableRex.Renderer
alias Licensir.TableRex.Table

@doc """
A shortcut function to render with a one-liner.
Expand Down
48 changes: 41 additions & 7 deletions lib/table_rex/cell.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule TableRex.Cell do
defmodule Licensir.TableRex.Cell do
@moduledoc """
Defines a struct that represents a single table cell, and helper functions.

Expand All @@ -14,6 +14,9 @@ defmodule TableRex.Cell do

* `rendered_value`: The stringified value for rendering

* `wrapped_lines`: A list of 1 or more string values representing
the line(s) within the cell to be rendered

* `align`:
* `:left`: left align text in the cell.
* `:center`: center text in the cell.
Expand All @@ -26,9 +29,9 @@ defmodule TableRex.Cell do
enable that Cell to work well with the rest of TableRex. It should
be set to a piece of data that can be rendered to string.
"""
alias TableRex.Cell
alias Licensir.TableRex.Cell

defstruct raw_value: nil, rendered_value: "", align: nil, color: nil
defstruct raw_value: nil, rendered_value: "", align: nil, color: nil, wrapped_lines: [""]

@type t :: %__MODULE__{}

Expand All @@ -51,17 +54,48 @@ defmodule TableRex.Cell do
hindered.
"""
@spec to_cell(Cell.t()) :: Cell.t()
def to_cell(%Cell{rendered_value: rendered_value} = cell) when rendered_value != "", do: cell
def to_cell(%Cell{rendered_value: rendered_value} = cell)
when is_binary(rendered_value) and rendered_value != "" do
%Cell{cell | wrapped_lines: wrapped_lines(rendered_value)}
end

def to_cell(%Cell{raw_value: raw_value} = cell) do
%Cell{cell | rendered_value: to_string(raw_value)}
rendered_value = to_string(raw_value)
%Cell{cell | rendered_value: rendered_value, wrapped_lines: wrapped_lines(rendered_value)}
end

@spec to_cell(any, list) :: Cell.t()
def to_cell(value, opts \\ []) do
def to_cell(value, opts \\ [])

def to_cell(list, opts) when is_list(list) do
if List.improper?(list) do
list
|> to_string()
|> to_cell(opts)
else
list
|> Enum.join("\n")
|> to_cell(opts)
end
end

def to_cell(value, opts) do
opts = Enum.into(opts, %{})

%Cell{rendered_value: to_string(value), raw_value: value}
rendered_value = to_string(value)

%Cell{
raw_value: value,
rendered_value: rendered_value,
wrapped_lines: wrapped_lines(rendered_value)
}
|> Map.merge(opts)
end

@spec height(Cell.t()) :: integer
def height(%Cell{wrapped_lines: lines}), do: length(lines)

defp wrapped_lines(value) when is_binary(value) do
String.split(value, "\n")
end
end
2 changes: 1 addition & 1 deletion lib/table_rex/column.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule TableRex.Column do
defmodule Licensir.TableRex.Column do
@moduledoc """
Defines a struct that represents a column's metadata

Expand Down
4 changes: 2 additions & 2 deletions lib/table_rex/renderer.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule TableRex.Renderer do
defmodule Licensir.TableRex.Renderer do
@moduledoc """
An Elixir behaviour that defines the API Renderers should conform to, allowing
for display output in a variety of formats.
Expand All @@ -11,5 +11,5 @@ defmodule TableRex.Renderer do
@callback default_options() :: map

@doc "Renders a passed %TableRex.Table{} struct into a string."
@callback render(table :: %TableRex.Table{}, opts :: list) :: render_return
@callback render(table :: %Licensir.TableRex.Table{}, opts :: list) :: render_return
end
56 changes: 33 additions & 23 deletions lib/table_rex/renderer/text.ex
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
defmodule TableRex.Renderer.Text do
defmodule Licensir.TableRex.Renderer.Text do
@moduledoc """
Renderer module which handles outputting ASCII-style tables for display.
"""
alias TableRex.Cell
alias TableRex.Table
alias TableRex.Renderer.Text.Meta
alias Licensir.TableRex.Cell
alias Licensir.TableRex.Table
alias Licensir.TableRex.Renderer.Text.Meta

@behaviour TableRex.Renderer
@behaviour Licensir.TableRex.Renderer

# horizontal_styles: [:all, :header, :frame:, :off]
# vertical_styles: [:all, :frame, :off]
Expand Down Expand Up @@ -174,14 +174,7 @@ defmodule TableRex.Renderer.Text do

defp render_header({%Table{header_row: header_row} = table, meta, opts, rendered}) do
separator = if meta.render_column_separators?, do: opts[:vertical_symbol], else: " "
line = render_cell_row(table, meta, header_row, separator)

line =
if meta.render_vertical_frame? do
line |> frame_with(opts[:vertical_symbol])
else
line
end
line = render_cell_row(table, meta, header_row, separator, opts[:vertical_symbol])

{table, meta, opts, [line | rendered]}
end
Expand Down Expand Up @@ -219,15 +212,10 @@ defmodule TableRex.Renderer.Text do
end

defp render_rows({%Table{rows: rows} = table, meta, opts, rendered}) do
separator = if meta.render_column_separators?, do: opts[:vertical_symbol], else: " "
lines = Enum.map(rows, &render_cell_row(table, meta, &1, separator))
cell_separator = if meta.render_column_separators?, do: opts[:vertical_symbol], else: " "

lines =
if meta.render_vertical_frame? do
Enum.map(lines, &frame_with(&1, opts[:vertical_symbol]))
else
lines
end
Enum.map(rows, &render_cell_row(table, meta, &1, cell_separator, opts[:vertical_symbol]))

lines =
if meta.render_row_separators? do
Expand All @@ -248,6 +236,12 @@ defmodule TableRex.Renderer.Text do
{table, meta, opts, rendered}
end

defp vertically_framed(lines, %{render_vertical_frame?: true}, symbol) do
Enum.map(lines, &frame_with(&1, symbol))
end

defp vertically_framed(lines, _, _), do: lines

defp render_bottom_frame({table, %Meta{render_horizontal_frame?: false} = meta, opts, rendered}) do
{table, meta, opts, rendered}
end
Expand All @@ -271,8 +265,24 @@ defmodule TableRex.Renderer.Text do
|> Enum.join()
end

defp render_cell_row(%Table{} = table, %Meta{} = meta, row, separator) do
defp render_cell_row(%Table{} = table, %Meta{} = meta, row, cell_separator, frame_symbol) do
row_height =
row
|> Enum.map(&Cell.height/1)
|> Enum.max()

1..row_height
|> Enum.map(&render_cell_row_line(table, meta, row, cell_separator, &1))
|> vertically_framed(meta, frame_symbol)
|> Enum.join("\n")
end

defp render_cell_row_line(%Table{} = table, %Meta{} = meta, row, separator, line_index) do
row
|> Enum.map(fn %Cell{wrapped_lines: lines} = cell ->
line_value = Enum.at(lines, line_index - 1) || ""
%Cell{cell | rendered_value: line_value}
end)
|> Enum.with_index()
|> Enum.map(&render_cell(table, meta, &1))
|> Enum.intersperse(separator)
Expand Down Expand Up @@ -341,7 +351,7 @@ defmodule TableRex.Renderer.Text do
|> Enum.with_index()
|> Enum.reduce({%{}, %{}}, &reduce_row_maximums(table, &1, &2))

num_columns = Map.size(col_widths)
num_columns = map_size(col_widths)

# Infer padding on left and right of title
title_padding =
Expand Down Expand Up @@ -392,7 +402,7 @@ defmodule TableRex.Renderer.Text do
|> String.split("\n")

height = Enum.count(lines)
width = Enum.max(lines) |> String.length()
width = lines |> Enum.map(&String.length/1) |> Enum.max()
{width + padding * 2, height}
end

Expand Down
10 changes: 5 additions & 5 deletions lib/table_rex/renderer/text/meta.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
defmodule TableRex.Renderer.Text.Meta do
defmodule Licensir.TableRex.Renderer.Text.Meta do
@moduledoc """
The data structure for the `TableRex.Renderer.Text` rendering module, it holds results
of style & dimension calculations to be passed down the render pipeline.
"""
alias TableRex.Renderer.Text.Meta
alias Licensir.TableRex.Renderer.Text.Meta

defstruct col_widths: %{},
row_heights: %{},
Expand All @@ -15,7 +15,7 @@ defmodule TableRex.Renderer.Text.Meta do
render_row_separators?: false

@doc """
Retreives the "inner width" of the table, which is the full width minus any frame.
Retrieves the "inner width" of the table, which is the full width minus any frame.
"""
def inner_width(%Meta{table_width: table_width, render_vertical_frame?: true}) do
table_width - 2
Expand All @@ -26,14 +26,14 @@ defmodule TableRex.Renderer.Text.Meta do
end

@doc """
Retreives the column width at the given column index.
Retrieves the column width at the given column index.
"""
def col_width(meta, col_index) do
Map.get(meta.col_widths, col_index)
end

@doc """
Retreives the row width at the given row index.
Retrieves the row width at the given row index.
"""
def row_height(meta, row_index) do
Map.get(meta.row_heights, row_index)
Expand Down
22 changes: 11 additions & 11 deletions lib/table_rex/table.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
defmodule TableRex.Table do
defmodule Licensir.TableRex.Table do
@moduledoc """
A set of functions for working with tables.

The `Table` is represented internally as a struct though the
fields are private and must not be accessed directly. Instead,
use the functions in this module.
"""
alias TableRex.Cell
alias TableRex.Column
alias TableRex.Renderer
alias TableRex.Table
alias Licensir.TableRex.Cell
alias Licensir.TableRex.Column
alias Licensir.TableRex.Renderer
alias Licensir.TableRex.Table

defstruct title: nil, header_row: [], rows: [], columns: %{}, default_column: %Column{}

Expand All @@ -25,7 +25,7 @@ defmodule TableRex.Table do
## Examples

iex> Table.new
%TableRex.Table{}
%Licensir.TableRex.Table{}

"""
@spec new() :: Table.t()
Expand All @@ -34,7 +34,7 @@ defmodule TableRex.Table do
@doc """
Creates a new table with an initial set of rows and an optional header and title.
"""
@spec new(list, list, String.t()) :: Table.t()
@spec new(list, list, String.t() | nil) :: Table.t()
def new(rows, header_row \\ [], title \\ nil) when is_list(rows) and is_list(header_row) do
new()
|> put_title(title)
Expand Down Expand Up @@ -197,7 +197,7 @@ defmodule TableRex.Table do

def sort(%Table{rows: [first_row | _]}, column_index, _order)
when length(first_row) <= column_index do
raise TableRex.Error,
raise Licensir.TableRex.Error,
message:
"You cannot sort by column #{column_index}, as the table only has #{length(first_row)} column(s)"
end
Expand All @@ -220,7 +220,7 @@ defmodule TableRex.Table do
end

defp build_sort_function(_column_index, order) do
raise TableRex.Error,
raise Licensir.TableRex.Error,
message: "Invalid sort order parameter: #{order}. Must be an atom, either :desc or :asc."
end

Expand All @@ -233,7 +233,7 @@ defmodule TableRex.Table do
end

@doc """
Retreives the value of a column meta option at the specified col_index.
Retrieves the value of a column meta option at the specified col_index.
If no value has been set, default values are returned.
"""
@spec get_column_meta(Table.t(), integer, atom) :: any
Expand Down Expand Up @@ -291,7 +291,7 @@ defmodule TableRex.Table do
def render!(%Table{} = table, opts \\ []) when is_list(opts) do
case render(table, opts) do
{:ok, rendered_string} -> rendered_string
{:error, reason} -> raise TableRex.Error, message: reason
{:error, reason} -> raise Licensir.TableRex.Error, message: reason
end
end
end