From f986f8b21d0a727eae00f5df2a05f921c837c2b5 Mon Sep 17 00:00:00 2001 From: Evan Read Date: Tue, 5 Sep 2023 13:31:31 +1000 Subject: [PATCH] Add support for variable last column widths in Markdown tables --- MarkdownTableFormatter.sublime-settings | 6 +++++- README.md | 8 ++++++-- markdown_table_formatter.py | 6 ++++-- simple_markdown/table.py | 8 +++++++- tests/test.py | 13 +++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/MarkdownTableFormatter.sublime-settings b/MarkdownTableFormatter.sublime-settings index 5afe4fa..ff85e0e 100644 --- a/MarkdownTableFormatter.sublime-settings +++ b/MarkdownTableFormatter.sublime-settings @@ -12,5 +12,9 @@ "padding": 0, // how text should be justified when not specified [LEFT, RIGHT, CENTER] - "default_justification": "LEFT" + "default_justification": "LEFT", + + // Whether the last column in tables must fit the widest content (set to + // "fixed") or can be variable width (set to "variable") + "last_column_width": "fixed" } diff --git a/README.md b/README.md index c058257..a85b94c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ There are two basic ways of using this plugin. Select what you want to format an ## Configuration -``` +```json { // make plugin verbose in debug console "verbose": false, @@ -31,7 +31,11 @@ There are two basic ways of using this plugin. Select what you want to format an "padding": 0, // how text should be justified when not specified [LEFT, RIGHT, CENTER] - "default_justification": "LEFT" + "default_justification": "LEFT", + + // Whether the last column in tables must fit the widest content (set to + // "fixed") or can be variable width (set to "variable") + "last_column_width": "fixed" } ``` diff --git a/markdown_table_formatter.py b/markdown_table_formatter.py index 3262668..90bce0e 100644 --- a/markdown_table_formatter.py +++ b/markdown_table_formatter.py @@ -21,6 +21,7 @@ def run(self, edit, format_all=False): padding = settings.get("padding") justify = settings.get("default_justification") justify = markdown.table.Justify.from_string[justify] + last_column_width = settings.get("last_column_width") if verbose: log.setLevel(logging.DEBUG) @@ -43,8 +44,9 @@ def run(self, edit, format_all=False): for start, end in positions: prev_table = text[start:end] log.debug("table found:\n" + prev_table) - new_table = markdown.table.format(prev_table, margin, padding, - justify) + new_table = markdown.table.format(prev_table, + margin, padding, justify, + last_column_width) log.debug("formatted output:\n" + new_table) # absolute original table position after some insertion/removal diff --git a/simple_markdown/table.py b/simple_markdown/table.py index e3e2c39..b2f65f8 100644 --- a/simple_markdown/table.py +++ b/simple_markdown/table.py @@ -25,7 +25,8 @@ def find_all(text): return tables -def format(raw_table, margin=1, padding=0, default_justify=Justify.LEFT): +def format(raw_table, margin=1, padding=0, default_justify=Justify.LEFT, + last_column_width="fixed"): rows = raw_table.splitlines() # normalize markdown table, add missing leading/trailing '|' for idx, row in enumerate(rows): @@ -52,6 +53,11 @@ def format(raw_table, margin=1, padding=0, default_justify=Justify.LEFT): text_width = [[len(col) for col in row] for row in matrix] # determine column width (including space padding/margin) col_width = [max(size) + margin*2 + padding for size in zip(*text_width)] + if last_column_width == "variable": + # modify the column width setting of last column to use use size of + # heading text of the last column instead of the size of the widest + # text of the last column + col_width[col_cnt-1] = text_width[0][-1] + margin*2 + padding # get each column justification or apply default justify = [] diff --git a/tests/test.py b/tests/test.py index c0fe02f..86de3ea 100755 --- a/tests/test.py +++ b/tests/test.py @@ -66,6 +66,19 @@ def test_format(self): table = Table.format(small, margin=1, padding=0) self.assertEqual(table, expected_small) + expected_table_variable = """\ +| Tables | Are | Cool | +|:--------------|:-------------|-----:| +| col 1 is | left-aligned | $1600 | +| col 2 is | centered | $12 | +| zebra stripes | | are neat $1 | +| | | $hello | +| $2 | | |""" + + table = Table.format(raw_table, margin=1, padding=0, + last_column_width="variable") + self.assertEqual(table, expected_table_variable) + def test_find_all(self): junk_tables = """ | Tables | Are | Cool #1 |