easytables.nvim/lua/easytables/tablebuilder.lua
2023-10-04 21:40:29 +02:00

160 lines
5.1 KiB
Lua

local table = {};
function table.create_new_table(width, height)
local table = {}
for i = 1, height do
table[i] = {}
for j = 1, width do
table[i][j] = ""
end
end
return table
end
local function edit_cell(table, x, y, value)
table[y][x] = value
end
DEFAULT_DRAW_REPRESENTATION_OPTIONS = {
min_width = 3,
filler = " ",
top_left = "",
top_right = "",
bottom_left = "",
bottom_right = "",
horizontal = "",
vertical = "",
left_t = "",
right_t = "",
top_t = "",
bottom_t = "",
cross = ""
}
local function find_largest_value_length(table)
local largest_value_length = #table[1][1]
for i = 1, #table do
for j = 1, #table[i] do
local cell_width = #table[i][j]
if cell_width > largest_value_length then
largest_value_length = cell_width
end
end
end
return largest_value_length
end
function create_horizontal_line(width, cell_width, left, middle, right, middle_t)
local string = ""
for i = 1, width do
if i == 1 then
string = string .. left
elseif i == width then
string = string .. right
elseif (i - 1) % (cell_width + 1) == 0 then
string = string .. middle_t
else
string = string .. middle
end
end
return string
end
-- Creates a horizontal divider like this:
-- `create_horizontal_divider(5, 5, {variant = "top"})`:
-- ┌─────┬─────┬─────┬─────┬─────┐
-- `create_horizontal_divider(5, 5, {variant = "between"})`:
-- ├─────┼─────┼─────┼─────┼─────┤
-- `create_horizontal_divider(5, 5, {variant = "bottom"})`:
-- └─────┴─────┴─────┴─────┴─────┘
function create_horizontal_divider(table_width, cell_width, options)
local options = options or {}
local top_left = options.top_left or DEFAULT_DRAW_REPRESENTATION_OPTIONS.top_left
local top_right = options.top_right or DEFAULT_DRAW_REPRESENTATION_OPTIONS.top_right
local bottom_left = options.bottom_left or DEFAULT_DRAW_REPRESENTATION_OPTIONS.bottom_left
local bottom_right = options.bottom_right or DEFAULT_DRAW_REPRESENTATION_OPTIONS.bottom_right
local horizontal = options.horizontal or DEFAULT_DRAW_REPRESENTATION_OPTIONS.horizontal
local left_t = options.left_t or DEFAULT_DRAW_REPRESENTATION_OPTIONS.left_t
local right_t = options.right_t or DEFAULT_DRAW_REPRESENTATION_OPTIONS.right_t
local top_t = options.top_t or DEFAULT_DRAW_REPRESENTATION_OPTIONS.top_t
local bottom_t = options.bottom_t or DEFAULT_DRAW_REPRESENTATION_OPTIONS.bottom_t
local cross = options.cross or DEFAULT_DRAW_REPRESENTATION_OPTIONS.cross
local variant = options.variant or "between"
local full_width = table_width * cell_width + table_width + 1
if variant == "top" then
return create_horizontal_line(full_width, cell_width, top_left, horizontal, top_right, top_t)
elseif variant == "between" then
return create_horizontal_line(full_width, cell_width, left_t, horizontal, right_t, cross)
elseif variant == "bottom" then
return create_horizontal_line(full_width, cell_width, bottom_left, horizontal, bottom_right, bottom_t)
end
end
function table.draw_representation(table, options)
local options = options or {}
local min_width = options.min_width or DEFAULT_DRAW_REPRESENTATION_OPTIONS.min_width
local filler = options.filler or DEFAULT_DRAW_REPRESENTATION_OPTIONS.filler
local vertical = options.vertical or DEFAULT_DRAW_REPRESENTATION_OPTIONS.vertical
local representation = {}
local largest_length = find_largest_value_length(table)
-- If length is shorter than min_width, then add filler to the end of the string
local length = largest_length < min_width and min_width or largest_length
local horizontal_divider = create_horizontal_divider(#table[1], length, options)
representation[#representation + 1] = create_horizontal_divider(#table[1], length, { variant = "top" })
for i = 1, #table do
local line = ""
for j = 1, #table[i] do
local cell = table[i][j]
local cell_width = #cell
if cell_width < min_width then
cell = cell .. string.rep(filler, length - cell_width)
end
cell = vertical .. cell
if j == #table[i] then
cell = cell .. vertical
end
line = line .. cell
end
representation[#representation + 1] = line
if i ~= #table then
representation[#representation + 1] = horizontal_divider
end
end
representation[#representation + 1] = create_horizontal_divider(#table[1], length, { variant = "bottom" })
return representation
end
function table.from_representation(representation, options)
local opts = options or {}
local table = {}
for i = 1, #representation do
local character = representation[i]
end
end
return table