diff --git a/commonmark_extensions/tables.py b/commonmark_extensions/tables.py index d30ae89..27747b1 100644 --- a/commonmark_extensions/tables.py +++ b/commonmark_extensions/tables.py @@ -143,6 +143,8 @@ def finalize(parser=None, block=None): # Multline mode. Merge this row with the previous one. for i in range(len(row)): if i < len(table_parts[-1][-1]): + if table_parts[-1][-1][i] == "-": + continue table_parts[-1][-1][i] += "\n" + row[i] else: table_parts[-1][-1].append(row[i]) @@ -171,7 +173,7 @@ def inner_parser(cell): for part in table_parts: for row in part: for i, cell in enumerate(row): - row[i] = inner_parser(cell) + row[i] = inner_parser(cell) if cell != "-" else None # Store the parsed table on the node. block.column_properties = column_properties @@ -211,6 +213,9 @@ def table(self, node, entering): for row in part: self.lit("\n") for colidx, cell in enumerate(row): + if cell is None: + continue + if part_tag == "thead": col_tag = "th" if self.options.get("table_th_scope"): @@ -224,6 +229,15 @@ def table(self, node, entering): if colidx in node.column_properties and "align" in node.column_properties[colidx]: col_attrs += ' align=\"' + node.column_properties[colidx]["align"] + "\"" + span = 1 + for nextid in range(colidx+1, len(row)): + if row[nextid] is None: + span += 1 + else: + break + if span > 1: + col_attrs += ' colspan=\"' + str(span) + '\"' + self.lit("<" + col_tag + col_attrs + ">") import copy diff --git a/commonmark_extensions/tests.py b/commonmark_extensions/tests.py index f9df165..2667506 100644 --- a/commonmark_extensions/tests.py +++ b/commonmark_extensions/tests.py @@ -196,6 +196,69 @@ def test_no_tbody_if_empty(self): """) + def test_colspan_header(self): + self.assertRender( +"""| foo | - | +| --- | --- | +| baz | bim |""", + +""" + + + + + + + + + + + +
foo
bazbim
""" + ) + + def test_colspan_body(self): + self.assertRender( +"""| foo | bar | +| --- | --- | +| baz | - |""", + +""" + + + + + + + + + + + +
foobar
baz
""" + ) + + def test_colspan_multiple(self): + self.assertRender( +"""| foo | bar | - |- | -| +| --- | --- | --- | --- | --- | +| baz | - | bim | - |-|""", + +""" + + + + + + + + + + + + +
foobar
bazbim
""" + ) class MultilineTablesTests(unittest.TestCase): """Test the multiline cell mode.""" @@ -236,6 +299,98 @@ def test_simple(self): """ ) + def test_colspan_header(self): + self.assertRender( +"""| foo | - | +| === | === | +| baz | bim | +| baz | bim |""", + +""" + + + + + + + + + + + +
foo

baz +baz

+

bim +bim

+
""" + ) + + def test_colspan_body(self): + self.assertRender( +"""| foo | bar | +| === | === | +| baz | - |""", + +""" + + + + + + + + + + + +
foobar
baz
""" + ) + + def test_colspan_multiple(self): + self.assertRender( +"""| foo | bar | - |- | -| +| === | === | === | === | === | +| baz | - | bim | - |-|""", + +""" + + + + + + + + + + + + +
foobar
bazbim
""" + ) + + def test_colspan_multiline_body(self): + self.assertRender( +"""| foo | bar | +| === | === | +| baz | - | +| baz | |""", + +""" + + + + + + + + + + + +
foobar

baz +baz

+
""" + ) class PlainTextRendererTests(unittest.TestCase): """Test the PlainTextRenderer cell mode."""