diff options
| -rw-r--r-- | mammoth/conversion.py | 19 | ||||
| -rw-r--r-- | mammoth/document_matchers.py | 8 | ||||
| -rw-r--r-- | mammoth/styles/parser/document_matcher_parser.py | 11 | ||||
| -rw-r--r-- | tests/conversion_tests.py | 13 | ||||
| -rw-r--r-- | tests/styles/parser/document_matcher_parser_tests.py | 25 |
5 files changed, 68 insertions, 8 deletions
diff --git a/mammoth/conversion.py b/mammoth/conversion.py index 066544e..eb514ec 100644 --- a/mammoth/conversion.py +++ b/mammoth/conversion.py @@ -169,9 +169,14 @@ class _DocumentConverter(documents.element_visitor(args=1)): def visit_tab(self, tab, context): return [html.text("\t")] - - + + _default_table_path = html_paths.path([html_paths.element(["table"], fresh=True)]) + def visit_table(self, table, context): + return self._find_html_path(table, "table", self._default_table_path) \ + .wrap(lambda: self._convert_table_children(table, context)) + + def _convert_table_children(self, table, context): body_index = find_index( lambda child: not isinstance(child, documents.TableRow) or not child.is_header, table.children, @@ -189,7 +194,7 @@ class _DocumentConverter(documents.element_visitor(args=1)): html.element("tbody", {}, body_rows), ] - return [html.element("table", {}, children)] + return [html.force_write] + children def visit_table_row(self, table_row, context): @@ -306,18 +311,18 @@ class _DocumentConverter(documents.element_visitor(args=1)): def _find_html_path_for_paragraph(self, paragraph): default = html_paths.path([html_paths.element("p", fresh=True)]) - return self._find_html_path(paragraph, "paragraph", default) + return self._find_html_path(paragraph, "paragraph", default, warn_unrecognised=True) def _find_html_path_for_run(self, run): - return self._find_html_path(run, "run", default=html_paths.empty) + return self._find_html_path(run, "run", default=html_paths.empty, warn_unrecognised=True) - def _find_html_path(self, element, element_type, default): + def _find_html_path(self, element, element_type, default, warn_unrecognised=False): style = self._find_style(element, element_type) if style is not None: return style.html_path - if getattr(element, "style_id", None) is not None: + if warn_unrecognised and getattr(element, "style_id", None) is not None: self._messages.append(results.warning( "Unrecognised {0} style: {1} (Style ID: {2})".format( element_type, element.style_name, element.style_id) diff --git a/mammoth/document_matchers.py b/mammoth/document_matchers.py index 6429911..91adf3f 100644 --- a/mammoth/document_matchers.py +++ b/mammoth/document_matchers.py @@ -19,6 +19,14 @@ RunMatcher = collections.namedtuple("RunMatcher", ["style_id", "style_name"]) RunMatcher.element_type = "run" +def table(style_id=None, style_name=None): + return TableMatcher(style_id, style_name) + + +TableMatcher = collections.namedtuple("TableMatcher", ["style_id", "style_name"]) +TableMatcher.element_type = "table" + + class bold(object): element_type = "bold" diff --git a/mammoth/styles/parser/document_matcher_parser.py b/mammoth/styles/parser/document_matcher_parser.py index 034c59c..b9e09f3 100644 --- a/mammoth/styles/parser/document_matcher_parser.py +++ b/mammoth/styles/parser/document_matcher_parser.py @@ -24,7 +24,16 @@ def parse_document_matcher(tokens): style_id=style_id, style_name=style_name, ) - + + elif tokens.try_skip(TokenType.IDENTIFIER, "table"): + style_id = try_parse_class_name(tokens) + style_name = _parse_style_name(tokens) + + return document_matchers.table( + style_id=style_id, + style_name=style_name, + ) + elif tokens.try_skip(TokenType.IDENTIFIER, "b"): return document_matchers.bold diff --git a/tests/conversion_tests.py b/tests/conversion_tests.py index 38aa1a8..a2b1a0b 100644 --- a/tests/conversion_tests.py +++ b/tests/conversion_tests.py @@ -348,6 +348,19 @@ def docx_table_is_converted_to_table_in_html(): @istest +def table_style_mappings_can_be_used_to_map_tables(): + table = documents.table([], style_name="Normal Table") + result = convert_document_element_to_html( + table, + style_map=[ + _style_mapping("table[style-name='Normal Table'] => table.normal-table:fresh"), + ], + ) + expected_html = '<table class="normal-table"></table>' + assert_equal(expected_html, result.value) + + +@istest def header_rows_are_wrapped_in_thead(): table = documents.table([ documents.table_row([documents.table_cell([])], is_header=True), diff --git a/tests/styles/parser/document_matcher_parser_tests.py b/tests/styles/parser/document_matcher_parser_tests.py index 62f3181..dc93941 100644 --- a/tests/styles/parser/document_matcher_parser_tests.py +++ b/tests/styles/parser/document_matcher_parser_tests.py @@ -97,6 +97,31 @@ def reads_run_with_style_name(): read_document_matcher("r[style-name='Emphasis']") ) + +@istest +def reads_plain_table(): + assert_equal( + document_matchers.table(), + read_document_matcher("table") + ) + + +@istest +def reads_table_with_style_id(): + assert_equal( + document_matchers.table(style_id="TableNormal"), + read_document_matcher("table.TableNormal") + ) + + +@istest +def reads_table_with_style_name(): + assert_equal( + document_matchers.table(style_name=document_matchers.equal_to("Normal Table")), + read_document_matcher("table[style-name='Normal Table']") + ) + + @istest def reads_bold(): assert_equal( |
