Skip to content

Commit

Permalink
Add support for keyword lists (Issue aerosol#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
fusillicode committed Apr 9, 2017
1 parent 3fff55a commit b841e16
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
44 changes: 26 additions & 18 deletions lib/tabula.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ defmodule Tabula do
]

@default_sheet :org_mode
@access_functions [
default: [access_functions: [get: &Map.get/3, keys: &Map.keys/1]],
keywords: [access_functions: [get: &Keyword.get/3, keys: &Keyword.keys/1]]
]

defmacro __using__(opts) do
quote do
Expand All @@ -51,27 +55,33 @@ defmodule Tabula do
|> IO.puts
end

def render_table(rows, opts \\ []) do
def render_table([h|_] = rows, opts \\ []) do
opts = set_access_functions(opts, h)
cols = extract_cols(rows, opts)
_render_table(rows, cols, opts)
|> :erlang.list_to_binary
end

def max_widths(cols, rows) do
max_index = rows
|> length
|> strlen
cols
|> map(fn k ->
defp set_access_functions(opts, a_row) do
opts
|> Keyword.merge(@access_functions[:default])
|> (fn (opts) ->
is_list(a_row) && Keyword.merge(opts, @access_functions[:keywords]) || opts
end).()
end

def max_widths(cols, rows, opts \\ @access_functions[:default]) do
extraction_function = opts[:access_functions][:get]
max_index = rows |> length |> strlen
cols |> map(fn k ->
max([
strlen(k), max_index
| map(rows, &(Map.get(&1, k) |> strlen))
strlen(k), max_index | map(rows, &(extraction_function.(&1, k, nil) |> strlen))
])
end)
end

defp _render_table(rows, [_|_]=cols, opts) do
widths = max_widths(cols, rows)
widths = max_widths(cols, rows, opts)
formatters = widths |> formatters(opts)
spacers = widths |> spacers(opts)

Expand All @@ -87,12 +97,10 @@ defmodule Tabula do

end

defp extract_cols([first|_]=_rows, opts) do
defp extract_cols([first|_] = _rows, opts) do
case opts[:only] do
nil ->
first |> Map.keys
cols when is_list(cols) ->
cols
nil -> opts[:access_functions][:keys].(first)
cols when is_list(cols) -> cols
end
end

Expand Down Expand Up @@ -142,11 +150,11 @@ defmodule Tabula do

defp strlen(x), do: render_cell(x) |> String.length()

defp values(cols, {row, index}, _opts) do
defp values(cols, {row, index}, opts) do
cols
|> map(fn (@index) -> index+1
(col) -> Map.get(row, col)
end)
(col) -> opts[:access_functions][:get].(row, col, nil)
end)
end

defp style(style, opts) do
Expand Down
15 changes: 15 additions & 0 deletions test/tabula_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,19 @@ defmodule TabulaTest do
assert table == expect
end

test "Support keyword lists and preserve ordering of columns" do
rows = [
[name: "ecto", point: %Point{x: 0, y: 0}, version: Version.parse!("2.0.4")],
[name: "phoenix", point: %Point{x: 1, y: 0}, version: Version.parse!("1.2.0")]
]
table = Tabula.render_table(rows)

expect = """
:name | :point | :version
--------+-------------------------------+---------
ecto | %TabulaTest.Point{x: 0, y: 0} | 2.0.4
phoenix | %TabulaTest.Point{x: 1, y: 0} | 1.2.0
"""
assert table == expect
end
end

0 comments on commit b841e16

Please sign in to comment.