From 27b44158b3e97b61b77843ec0e004c79e1f88735 Mon Sep 17 00:00:00 2001 From: Roman Joost Date: Mon, 21 Mar 2016 16:54:48 +1000 Subject: [PATCH 1/4] Rudimentary table support Add basic support for tables. The conversion discards any styling information given by markdown. It renders the table with a fixed style. This fix is related to #26 Ceaveats: * one table per slide * no header styling * no support for links in table cells --- CHANGES | 3 +++ demo/demo-advanced.md | 7 +++++++ odpdown.py | 27 +++++++++++++++++++++++---- test.py | 17 +++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 77e00ce..6ba9094 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +v0.4.2 + - basic support for markdown tables + v0.4.1 - Update specfile from downstream project. - Fix code-block ODF space misparsing bug. diff --git a/demo/demo-advanced.md b/demo/demo-advanced.md index 4aafbf6..063dd3b 100644 --- a/demo/demo-advanced.md +++ b/demo/demo-advanced.md @@ -1,5 +1,12 @@ # Advanced Markup +## Basic Support for Tables + +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 + ## Embedded Image Markup ~~~ diff --git a/odpdown.py b/odpdown.py index eec4ed9..c077ee8 100755 --- a/odpdown.py +++ b/odpdown.py @@ -51,9 +51,10 @@ from lpod import ODF_MANIFEST, ODF_STYLES from lpod.document import odf_get_document -from lpod.frame import odf_create_text_frame, odf_create_image_frame, odf_frame +from lpod.frame import odf_create_text_frame, odf_create_image_frame, odf_frame, odf_create_frame from lpod.draw_page import odf_create_draw_page, odf_draw_page from lpod.list import odf_create_list_item, odf_create_list +from lpod.table import odf_create_table, odf_create_cell, odf_create_row from lpod.style import odf_create_style from lpod.paragraph import odf_create_paragraph, odf_span from lpod.paragraph import odf_create_line_break, odf_create_spaces @@ -627,13 +628,31 @@ def paragraph(self, text): return ODFPartialTree.from_metrics_provider([span], self) def table(self, header, body): - pass + tbl = odf_create_table(name=u'Table') + tbl.extend_rows(header.get()) + tbl.extend_rows(body.get()) + + # TODO frame positioning, table size, style etc + frame = odf_create_frame( + style=u'md2odp-ImageStyle', + size=self.outline_size, + position=self.outline_position + ) + frame.append(tbl) + return ODFPartialTree.from_metrics_provider([frame], self) def table_row(self, content): - pass + row = odf_create_row() + row.set_cells(content.get()) + return ODFPartialTree.from_metrics_provider([row], self) def table_cell(self, content, **flags): - pass + text = content.get()[0].get_text() + cell = odf_create_cell(text=text, value=text) + # TODO header style + # if flags.get('header'): + # cell.set_style('md2odp-TextDoubleEmphasisStyle') + return ODFPartialTree.from_metrics_provider([cell], self) def autolink(self, link, is_email=False): text = link diff --git a/test.py b/test.py index b1f70a6..a70fc5a 100644 --- a/test.py +++ b/test.py @@ -274,3 +274,20 @@ def test_multiline_bold(): 'text:style-name') == 'md2odp-TextDoubleEmphasisStyle') assert (odf.get()[0].get_elements('descendant::text:span')[3].get_text() == 'bold text\nnext line bold') + +@with_setup(setup) +def test_basic_table(): + markdown = ''' +|A |B +|-------|------- +|Cell 1 | 2 +|[Link](http://www.odpdown.test)| Cell 4 +'''.strip() + odf = mkdown.render(markdown) + assert len(odf.get()) == 1 + frame = odf.get()[0] + tbl = frame.get_table() + assert len(tbl.get_rows()) == 3 + assert tbl.get_row_values(0) == ['A', 'B'] + assert tbl.get_row_values(1) == ['Cell 1', '2'] + assert tbl.get_row_values(2) == ['Link', 'Cell 4'] From 088fb4d552f5e1ce5ab22f259f2b2d03c7cd33e5 Mon Sep 17 00:00:00 2001 From: Roman Joost Date: Tue, 22 Mar 2016 15:56:48 +1000 Subject: [PATCH 2/4] Fixes PEP8 error introduced by previous patch --- odpdown.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/odpdown.py b/odpdown.py index c077ee8..b9719dd 100755 --- a/odpdown.py +++ b/odpdown.py @@ -51,7 +51,8 @@ from lpod import ODF_MANIFEST, ODF_STYLES from lpod.document import odf_get_document -from lpod.frame import odf_create_text_frame, odf_create_image_frame, odf_frame, odf_create_frame +from lpod.frame import odf_create_text_frame, odf_create_image_frame, odf_frame +from lpod.frame import odf_create_frame from lpod.draw_page import odf_create_draw_page, odf_draw_page from lpod.list import odf_create_list_item, odf_create_list from lpod.table import odf_create_table, odf_create_cell, odf_create_row From 388bcbeb2202a5fd4ba13e305b85d5372dd15b2e Mon Sep 17 00:00:00 2001 From: Roman Joost Date: Wed, 30 Mar 2016 14:41:16 +1000 Subject: [PATCH 3/4] Treat table values as text content only Presentations might contain links and other markup content. This patch does not use the table API, but rather assumes that cell content is text only. --- demo/demo-advanced.md | 8 ++++---- odpdown.py | 11 +++++++++-- test.py | 9 ++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/demo/demo-advanced.md b/demo/demo-advanced.md index 063dd3b..71d4a69 100644 --- a/demo/demo-advanced.md +++ b/demo/demo-advanced.md @@ -2,10 +2,10 @@ ## Basic Support for Tables -| Heading 1 | Heading 2 -| --------- | --------- -| Cell 1 | Cell 2 -| Cell 3 | Cell 4 +| Heading 1 | Heading 2 +| ----------------------------- | --------- +| Cell 1 | Cell 2 +| [Cell 3](http://www.foo.test) | Cell 4 ## Embedded Image Markup diff --git a/odpdown.py b/odpdown.py index b9719dd..b3c97d6 100755 --- a/odpdown.py +++ b/odpdown.py @@ -648,8 +648,15 @@ def table_row(self, content): return ODFPartialTree.from_metrics_provider([row], self) def table_cell(self, content, **flags): - text = content.get()[0].get_text() - cell = odf_create_cell(text=text, value=text) + cell_content = content.get()[0] + # For presentations it seems we're dealing with text content anyway. So + # we just grab what is inside the cell, wrap it in a paragraph and show + # it. + para = odf_create_element('text:p') + para.append(cell_content) + + cell = odf_create_cell() + cell.append(para) # TODO header style # if flags.get('header'): # cell.set_style('md2odp-TextDoubleEmphasisStyle') diff --git a/test.py b/test.py index a70fc5a..2e220ee 100644 --- a/test.py +++ b/test.py @@ -288,6 +288,9 @@ def test_basic_table(): frame = odf.get()[0] tbl = frame.get_table() assert len(tbl.get_rows()) == 3 - assert tbl.get_row_values(0) == ['A', 'B'] - assert tbl.get_row_values(1) == ['Cell 1', '2'] - assert tbl.get_row_values(2) == ['Link', 'Cell 4'] + + assert tbl.get_row(0).get_text_content() == u'A\nB' + assert tbl.get_row(1).get_text_content() == u'Cell 1\n2' + assert tbl.get_row(2).get_text_content() == u'Link\nCell 4' + + assert len(tbl.xpath('//text:p/text:a')) == 1 From deb0324fd30252f3703b6d4ca2b7614b7028c7ee Mon Sep 17 00:00:00 2001 From: Roman Joost Date: Wed, 30 Mar 2016 16:30:09 +1000 Subject: [PATCH 4/4] Insert complete cell content Grabbing only the first parsed cell content discards information. This patch changes the former behaviour to use the complete parsed markup content for the table cell. --- odpdown.py | 4 ++-- test.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/odpdown.py b/odpdown.py index b3c97d6..ba2e4a9 100755 --- a/odpdown.py +++ b/odpdown.py @@ -648,12 +648,12 @@ def table_row(self, content): return ODFPartialTree.from_metrics_provider([row], self) def table_cell(self, content, **flags): - cell_content = content.get()[0] + cell_content = content.get() # For presentations it seems we're dealing with text content anyway. So # we just grab what is inside the cell, wrap it in a paragraph and show # it. para = odf_create_element('text:p') - para.append(cell_content) + para.extend(cell_content) cell = odf_create_cell() cell.append(para) diff --git a/test.py b/test.py index 2e220ee..ace3907 100644 --- a/test.py +++ b/test.py @@ -281,7 +281,7 @@ def test_basic_table(): |A |B |-------|------- |Cell 1 | 2 -|[Link](http://www.odpdown.test)| Cell 4 +|[Link](http://www.odpdown.test) Foo | Cell 4 '''.strip() odf = mkdown.render(markdown) assert len(odf.get()) == 1 @@ -291,6 +291,6 @@ def test_basic_table(): assert tbl.get_row(0).get_text_content() == u'A\nB' assert tbl.get_row(1).get_text_content() == u'Cell 1\n2' - assert tbl.get_row(2).get_text_content() == u'Link\nCell 4' + assert tbl.get_row(2).get_text_content() == u'Link Foo\nCell 4' assert len(tbl.xpath('//text:p/text:a')) == 1