diff --git a/tabular.lua b/tabular.lua index d6b4e4f..15a75ac 100644 --- a/tabular.lua +++ b/tabular.lua @@ -1,6 +1,10 @@ -local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local math = _tl_compat and _tl_compat.math or math; local os = _tl_compat and _tl_compat.os or os; local pairs = _tl_compat and _tl_compat.pairs or pairs; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table; local utf8 = _tl_compat and _tl_compat.utf8 or utf8; local tabular = {} +local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local math = _tl_compat and _tl_compat.math or math; local os = _tl_compat and _tl_compat.os or os; local pairs = _tl_compat and _tl_compat.pairs or pairs; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table; local utf8 = _tl_compat and _tl_compat.utf8 or utf8 + + + +local tabular = {} + -local AnsiColors = {} @@ -63,7 +67,7 @@ if (os.getenv("LANG") or ""):upper():match("UTF%-?8") then end -local Output = {} + @@ -80,7 +84,7 @@ local function escape_chars(c) return "\\" .. string.byte(c) end -local Pair = {} + local function show_as_list(t, color, seen, ids, skip_array) local tt = {} @@ -136,7 +140,7 @@ local function show_primitive(t) return out end -local Row = {} + @@ -194,7 +198,7 @@ show_as_columns = function(t, bgcolor, seen, ids, column_order, skip_header) elseif bgcolor then table.insert(line, bgcolor) end - table.insert(line, text .. (" "):rep(w - strlen(text))) + table.insert(line, text .. (" "):rep((w - strlen(text)))) if color then table.insert(line, bgcolor) end @@ -236,7 +240,7 @@ show_as_columns = function(t, bgcolor, seen, ids, column_order, skip_header) local line = { draw.V } for _, cname in ipairs(column_names) do local row = columns[cname][i] - output_cell(line, cname, row and row[h] or "", bgcolor and colors[(i % #colors) + 1]) + output_cell(line, cname, row and row[math.floor(h)] or "", bgcolor and colors[(i % #colors) + 1]) end output_line(out, table.concat(line)) end @@ -266,7 +270,7 @@ show = function(t, color, seen, ids, column_order) if type(t) == "table" then local tt = t - if #tt > 0 and type(tt[1]) == "table" then + if #(tt) > 0 and type(tt[1]) == "table" then return show_as_columns(tt, color, seen, ids, column_order) else return show_as_list(tt, color, seen, ids) @@ -302,4 +306,8 @@ if arg and arg[0]:match("tabular%..*$") then os.exit(0) end -return setmetatable(tabular, { __call = function(_, ...) return tabular.show(...) end }) +return setmetatable(tabular, { + __call = function(_, ...) + return tabular.show(...) + end, +}) diff --git a/tabular.tl b/tabular.tl index 4b7321e..e465afa 100644 --- a/tabular.tl +++ b/tabular.tl @@ -1,4 +1,8 @@ -local tabular = {} +local record Tabular + show: function(t: any, column_order?: {string}, color?: boolean): string +end + +local tabular: Tabular = {} local record AnsiColors noReset: function(string):string @@ -26,7 +30,7 @@ local colors: {string} = { ansicolors.noReset("%{white}"), } -local function strlen(s: string): number +local function strlen(s: string): integer s = s:gsub("\27[^m]*m", "") return #s end @@ -48,17 +52,17 @@ if (os.getenv("LANG") or ""):upper():match("UTF%-?8") then X = "┼", } - strlen = function(s: string): number + strlen = function(s: string): integer s = s:gsub("\27[^m]*m", "") - return utf8.len(s) or #s + return utf8.len(s) as integer or #s end strsub = function(s: string, i: number, j: number): string - local uj = utf8.offset(s, j + 1) + local uj: number = utf8.offset(s, j + 1) if uj then uj = uj - 1 end - return s:sub(utf8.offset(s, i), uj) + return s:sub(utf8.offset(s, i) as integer, uj as integer) end end @@ -68,8 +72,8 @@ local record Output width: number end -local show: function(any, string, {any:boolean}, {any:number}, {string}):Output -local show_as_columns: function({{any:any}}, string, {any:boolean}, {any:number}, {string}, boolean): Output +local show: function(any, string, {any:boolean}, {any:number}, ?{string}):Output +local show_as_columns: function({{any:any}}, string, {any:boolean}, {any:number}, {string}, ?boolean): Output local function output_line(out: Output, line: string) table.insert(out, line) @@ -82,7 +86,7 @@ end local type Pair = {string, any} -local function show_as_list(t: {any:any}, color: string, seen: {any:boolean}, ids: {any:number}, skip_array: boolean): Output +local function show_as_list(t: {any:any}, color: string, seen: {any:boolean}, ids: {any:number}, skip_array?: boolean): Output local tt: {Pair} = {} local width = 0 local keys = {} @@ -186,7 +190,7 @@ show_as_columns = function(t: {{any:any}}, bgcolor: string, seen: {any:boolean}, table.sort(column_names) end - local function output_cell(line: {string}, cname: string, text: string, color: string) + local function output_cell(line: {string}, cname: string, text: string, color?: string) local w = columns[cname].width text = text or "" if color then @@ -194,7 +198,7 @@ show_as_columns = function(t: {{any:any}}, bgcolor: string, seen: {any:boolean}, elseif bgcolor then table.insert(line, bgcolor) end - table.insert(line, text .. (" "):rep(w - strlen(text))) + table.insert(line, text .. (" "):rep((w - strlen(text)) as integer)) if color then table.insert(line, bgcolor) end @@ -207,8 +211,8 @@ show_as_columns = function(t: {{any:any}}, bgcolor: string, seen: {any:boolean}, local border_bot = {} for i, cname in ipairs(column_names) do local w = columns[cname].width - table.insert(border_top, draw.H:rep(w)) - table.insert(border_bot, draw.H:rep(w)) + table.insert(border_top, draw.H:rep(w as integer)) + table.insert(border_bot, draw.H:rep(w as integer)) if i < #column_names then table.insert(border_top, draw.N) table.insert(border_bot, draw.S) @@ -236,7 +240,7 @@ show_as_columns = function(t: {{any:any}}, bgcolor: string, seen: {any:boolean}, local line = { draw.V } for _, cname in ipairs(column_names) do local row = columns[cname][i] - output_cell(line, cname, row and row[h] or "", bgcolor and colors[(i % #colors) + 1]) + output_cell(line, cname, row and row[math.floor(h)] or "", bgcolor and colors[(i % #colors) + 1]) end output_line(out, table.concat(line)) end @@ -266,7 +270,7 @@ show = function(t: any, color: string, seen: {any:boolean}, ids: {any:number}, c if type(t) == "table" then local tt = t as {any:any} - if #tt > 0 and type(tt[1]) == "table" then + if #(tt as {any}) > 0 and type(tt[1]) == "table" then return show_as_columns(tt as {{any:any}}, color, seen, ids, column_order) else return show_as_list(tt, color, seen, ids) @@ -276,7 +280,7 @@ show = function(t: any, color: string, seen: {any:boolean}, ids: {any:number}, c end end -local function detect_cycles(t: any, n: number, seen: {any:number}): {any:number}, number +local function detect_cycles(t: any, n?: number, seen?: {any:number}): {any:number}, number n = n or 0 seen = seen or {} if type(t) == "table" then @@ -292,7 +296,7 @@ local function detect_cycles(t: any, n: number, seen: {any:number}): {any:number return seen, n end -function tabular.show(t: any, column_order: {string}, color: boolean): string +function tabular.show(t: any, column_order?: {string}, color?: boolean): string local ids = detect_cycles(t) return table.concat(show(t, color and colors and ansicolors.noReset("%{reset}"), {}, ids, column_order), "\n") end @@ -302,4 +306,8 @@ if arg and arg[0]:match("tabular%..*$") then os.exit(0) end -return setmetatable( tabular, { __call = function(_, ...): string return tabular.show(...) end } ) +return setmetatable( tabular, { + __call = function(_: Tabular, ...:any): string + return tabular.show(... as {string}) + end +} )