-module(trellis). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([table/1, param/1, with/4, to_string/1]). -export_type([table/1, column/1, align/0]). -type table(EZQ) :: {table, list(column(EZQ)), list(EZQ)}. -type column(EZR) :: {column, binary(), align(), fun((EZR) -> binary())}. -type align() :: left | right | center. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 60). -spec table(list(EZS)) -> table(EZS). table(Rows) -> {table, [], Rows}. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 68). -spec param(fun((EZV) -> EZW)) -> fun((EZV) -> EZW). param(F) -> F. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 73). -spec with(table(EZX), binary(), align(), fun((EZX) -> binary())) -> table(EZX). with(Builder, Header, Align, Getter) -> {table, Columns, Rows} = Builder, {table, [{column, Header, Align, Getter} | Columns], Rows}. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 87). -spec calculate_widths(list(binary()), list(binary())) -> list(integer()). calculate_widths(Headers, Values) -> Lengths = gleam@list:sized_chunk(Values, erlang:length(Headers)), gleam@list:map2( Headers, gleam@list:transpose(Lengths), fun(Header, Col_values) -> Max_value_length = gleam@list:fold( Col_values, 0, fun(Acc, Val) -> gleam@int:max(Acc, string:length(Val)) end ), gleam@int:max(string:length(Header), Max_value_length) end ). -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 193). -spec pad_left(binary(), integer()) -> binary(). pad_left(Text, Width) -> Padding = Width - string:length(Text), <<(gleam@string:repeat(<<" "/utf8>>, Padding))/binary, Text/binary>>. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 199). -spec pad_right(binary(), integer()) -> binary(). pad_right(Text, Width) -> Padding = Width - string:length(Text), <>, Padding))/binary>>. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 205). -spec pad_center(binary(), integer()) -> binary(). pad_center(Text, Width) -> Padding = Width - string:length(Text), Left = Padding div 2, Right = Padding - Left, <<<<(gleam@string:repeat(<<" "/utf8>>, Left))/binary, Text/binary>>/binary, (gleam@string:repeat(<<" "/utf8>>, Right))/binary>>. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 166). -spec make_row(list(align()), list(integer()), list(binary())) -> binary(). make_row(Aligns, Widths, Values) -> Row = begin _pipe = begin gleam@list:map2( begin gleam@list:map2( Aligns, Widths, fun(Align, Width) -> {Align, Width} end ) end, Values, fun(_use0, Value) -> {Align@1, Width@1} = _use0, Padded = case Align@1 of left -> pad_right(Value, Width@1); right -> pad_left(Value, Width@1); center -> pad_center(Value, Width@1) end, <<<<" "/utf8, Padded/binary>>/binary, " "/utf8>> end ) end, gleam@string:join(_pipe, <<"│"/utf8>>) end, <<<<"│"/utf8, Row/binary>>/binary, "│"/utf8>>. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 138). -spec make_separator(list(integer()), boolean(), boolean()) -> binary(). make_separator(Columns, Is_header, Is_top) -> Start = case {Is_top, Is_header} of {true, _} -> <<"┌"/utf8>>; {false, true} -> <<"├"/utf8>>; {false, false} -> <<"└"/utf8>> end, End = case {Is_top, Is_header} of {true, _} -> <<"┐"/utf8>>; {false, true} -> <<"┤"/utf8>>; {false, false} -> <<"┘"/utf8>> end, Middle = case {Is_top, Is_header} of {true, _} -> <<"┬"/utf8>>; {false, true} -> <<"┼"/utf8>>; {false, false} -> <<"┴"/utf8>> end, Line = gleam@list:fold( Columns, Start, fun(Acc, Col) -> <<<>, Col + 2))/binary>>/binary, Middle/binary>> end ), <<(gleam@string:slice(Line, 0, string:length(Line) - 1))/binary, End/binary>>. -file("/home/ethanthoma/projects/trellis/src/trellis.gleam", 102). -spec to_string(table(any())) -> binary(). to_string(Table) -> {table, Columns, Rows} = Table, Columns@1 = lists:reverse(Columns), Headers = gleam@list:map(Columns@1, fun(Col) -> erlang:element(2, Col) end), Aligns = gleam@list:map( Columns@1, fun(Col@1) -> erlang:element(3, Col@1) end ), Values = gleam@list:flat_map( Rows, fun(Row) -> gleam@list:map( Columns@1, fun(Col@2) -> (erlang:element(4, Col@2))(Row) end ) end ), Widths = calculate_widths(Headers, Values), Separator_top = make_separator(Widths, true, true), Header_row = make_row( gleam@list:map( gleam@list:range(1, erlang:length(Columns@1)), fun(_) -> center end ), Widths, Headers ), Separator_header = make_separator(Widths, true, false), Body_rows = gleam@list:map( Rows, fun(Row@1) -> Row_values = gleam@list:map( Columns@1, fun(Col@3) -> (erlang:element(4, Col@3))(Row@1) end ), make_row(Aligns, Widths, Row_values) end ), Separator_bottom = make_separator(Widths, false, false), _pipe = [Separator_top, Header_row, Separator_header], _pipe@1 = lists:append(_pipe, Body_rows), _pipe@2 = lists:append(_pipe@1, [Separator_bottom]), gleam@string:join(_pipe@2, <<"\n"/utf8>>).