diff --git a/pretty.lua b/pretty.lua index b8bc2b1..d9d6db0 100644 --- a/pretty.lua +++ b/pretty.lua @@ -282,8 +282,8 @@ local function align_into_columns (l, start_i, stop_i) local start_i, stop_i = start_i or 1, stop_i or #l - assert(type(start_i) == 'number') - assert(type(start_i) == 'number') + assert(type(start_i) == 'number') + assert(type(stop_i) == 'number') -- Find columns local columns = nil @@ -328,6 +328,46 @@ local function align_into_columns (l, start_i, stop_i) end end +local function align_into_tabular_style (l, start_i, stop_i) + -- Adds alignment after seperators, to create nicely aligned tabular-format. + + -- Argument fixing and Error Checking + local start_i, stop_i = start_i or 1, stop_i or #l + + assert(type(l) == 'table') + assert(type(start_i) == 'number') + assert(type(stop_i) == 'number') + assert(type(l[start_i]) == 'table' and l[start_i][1] == 'indent') + assert(type(l[stop_i]) == 'table' and l[stop_i][1] == 'unindent') + + -- Calculate where to insert new alignment. + local indent, key_nr, index_of_last_meta, insert_later = 0, 0, 1, {} + for i = start_i + 1, stop_i - 1 do + if type(l[i]) ~= 'table' then + -- Do nothing + elseif l[i][1] == 'indent' then + indent = indent + 1 + if indent == 1 then key_nr = 1 end + index_of_last_meta = i + elseif l[i][1] == 'unindent' then + insert_later[#insert_later+1] = {'align', 'end_subtable_'..key_nr, width_of_strings_in_l(l, index_of_last_meta+1, i), i} + index_of_last_meta, key_nr = i, key_nr + 1 + indent = indent - 1 + elseif l[i][1] == 'seperator' and indent ~= 0 then + insert_later[#insert_later+1] = {'align', 'key_'..key_nr, width_of_strings_in_l(l, index_of_last_meta+1, i), i+1} + index_of_last_meta, key_nr = i, key_nr + 1 + end + end + -- Insert new alignment. + for i = #insert_later, 1, -1 do + local dat = insert_later[i] + table.insert(l, dat[#dat], dat) + dat[#dat] = nil + end + -- Fix that alignemnt + return fix_alignment(l, start_i) +end + local function fix_seperator_info (l, indent_char, max_depth) -- Error Checking @@ -440,7 +480,7 @@ local function format_table (t, depth, l) -- Decide for short or long table formatting. local table_width = width_of_strings_in_l(l, start_of_table_i) if table_width <= MAX_WIDTH_FOR_SINGLE_LINE_TABLE then - -- Is short table: Ignore the "width of key"-shit + -- Is short table: Ignore "width of key". l[start_of_table_i][3] = 'inline' ignore_alignment_info(l, start_of_table_i) elseif table_info.is_leaf_node then @@ -448,14 +488,15 @@ local function format_table (t, depth, l) -- NOTE: Currently we only allow leaf-nodes to format into columns, due -- to issues with table alignment. align_into_columns(l, start_of_table_i) + elseif table_info.is_tabular then + align_into_tabular_style(l, start_of_table_i, #l) else -- Is long table: Fix whitespace alignment fix_alignment(l, start_of_table_i) end end --- Formatting Strings - +-- Formatting coroutine local function format_coroutine (value, depth, l) -- Formats a coroutine. Unfortunantly we cannot gather a lot of information @@ -471,6 +512,8 @@ local function format_coroutine (value, depth, l) l[#l+1] = tostring(value):sub(9) end +-- Formatting primitive + local function format_primitive (value, depth, l) -- Error check assert(type(depth) == 'number' and type(l) == 'table') diff --git a/test/test_pretty.lua b/test/test_pretty.lua index f070747..32c0a5f 100644 --- a/test/test_pretty.lua +++ b/test/test_pretty.lua @@ -227,12 +227,6 @@ format_test { expect = '{ [1] = 1, [\'whatever\'] = false }', } -format_test { - -- Table view, with indent. - input = { { a = 'hello', b = 'hi' }, { a = 'hi', b = 'hello' } }, - expect = '{\n { a = \'hello\', b = \'hi\' },\n { a = \'hi\', b = \'hello\' }\n}', -} - format_test { name = 'Proper alignment when using unicode characters as keys', input = { @@ -243,18 +237,87 @@ format_test { expect = '{\n djævle = \'dyr?\',\n europa = \'måne\',\n øå = \'en å på en ø?\'\n}', } +-------------------------------------------------------------------------------- +-- Pattern specific table display. + format_test { - name = 'Format table into columns, if leaf node', + name = 'Column style', input = { - 'hello', 'world', 'how', - 'is', 'it', 'going?', - 'Im', 'doing great', 'thanks', - 'that', 'was', 'what', - 'I', 'were', 'expecting' + 'hello', 'world', 'how', + 'is', 'it', 'going?', + 'Im', 'doing great', 'thanks', + 'that', 'was', 'what', + 'I', 'were', 'expecting' }, expect = '{\n \'hello\', \'world\', \'how\',\n \'is\', \'it\', \'going?\',\n \'Im\', \'doing great\', \'thanks\',\n \'that\', \'was\', \'what\',\n \'I\', \'were\', \'expecting\'\n}', } +format_test { + name = 'Column style with trailing last row', + input = { + 'hello', 'world', 'how', + 'is', 'it', 'going?', + 'Im', 'doing great', 'thanks', + 'that', 'was', 'what', + 'I' + }, + expect = '{\n \'hello\', \'world\', \'how\',\n \'is\', \'it\', \'going?\',\n \'Im\', \'doing great\', \'thanks\',\n \'that\', \'was\', \'what\',\n \'I\'\n}', +} + +format_test { + name = 'Tabular style with strings left aligned', + input = { + { a = 'hello', b = 'hi' }, + { a = 'hi', b = 'hello' } + }, + expect = '{\n { a = \'hello\', b = \'hi\' },\n { a = \'hi\', b = \'hello\' }\n}', +} + +format_test { + name = 'Tabular style with subtables in keys', + input = { + [false] = { a = 'hi', b = 'hello' }, + [true] = { a = 'hello', b = 'hi' } + }, + expect = '{\n [false] = { a = \'hi\', b = \'hello\' },\n [true] = { a = \'hello\', b = \'hi\' }\n}', +} + +format_test { + name = 'Tabular style also works with strange keys', + input = { + { [false] = 'hi', [true] = 'hello', }, + { [false] = 'hello', [true] = 'hi', } + }, + expect = '{\n { [false] = \'hi\', [true] = \'hello\' },\n { [false] = \'hello\', [true] = \'hi\' }\n}', +} + +format_test { + name = 'Tabular style also works with lists', + input = { + { 'hello', 'world', 'how is things?' }, + { 'hi', 'planetdroid', 'sup?' } + }, + expect = '{\n { \'hello\', \'world\', \'how is things?\' },\n { \'hi\', \'planetdroid\', \'sup?\' }\n}', +} + +format_test { + name = 'Tabular style with numbers right aligned', + input = { + { x = 140, y = 72, z = 31 }, + { x = 5010, y = 1, z = 314 } + }, + expect = '{\n { x = 140, y = 72, z = 31 },\n { x = 5010, y = 1, z = 314 }\n}', +} + +format_test { + name = 'Tabular style with small subtables', + input = { + { a = 'hel', x = {b = 'abc', c = 'yo' } }, + { a = 'hi', x = {b = 'yo', c = 'abc' } } + }, + expect = '{\n { a = \'hel\', x = { b = \'abc\', c = \'yo\' } },\n { a = \'hi\', x = { b = \'yo\', c = \'abc\' } }\n}', +} + -------------------------------------------------------------------------------- -- Table recursion