aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2017-11-04 11:25:51 +0000
committerMichael Williamson <mike@zwobble.org>2017-11-04 11:25:51 +0000
commitade2f7706813d785345563c57e7baf902ea2a7f4 (patch)
tree5003acc0e03415dbe3eb71e2f35cbd8285661975
parent1498397f4ede71d81ec79f380d43ec041438a047 (diff)
Add style mappings for tables
-rw-r--r--mammoth/conversion.py19
-rw-r--r--mammoth/document_matchers.py8
-rw-r--r--mammoth/styles/parser/document_matcher_parser.py11
-rw-r--r--tests/conversion_tests.py13
-rw-r--r--tests/styles/parser/document_matcher_parser_tests.py25
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(