summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-04 08:42:19 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-04 13:34:29 +0000
commit6e449db1f143ac198e820610a40765071163d87a (patch)
tree29195292abb67fc33ae389dda630865f34aacb4c
parent2fcc877a3513b79b9217a7575136e7711a2a3875 (diff)
Handle missing run styles in the source document
-rw-r--r--mammoth/docx/body_xml.py30
-rw-r--r--tests/docx/body_xml_tests.py17
2 files changed, 31 insertions, 16 deletions
diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py
index 854ccf2..ae33191 100644
--- a/mammoth/docx/body_xml.py
+++ b/mammoth/docx/body_xml.py
@@ -67,6 +67,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f
def run(element):
+ messages = []
properties = element.find_child_or_null("w:rPr")
style_id = properties \
.find_child_or_null("w:rStyle") \
@@ -75,7 +76,12 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f
if style_id is None:
style_name = None
else:
- style_name = styles.find_character_style_by_id(style_id).name
+ style = styles.find_character_style_by_id(style_id)
+ if style is None:
+ style_name = None
+ messages.append(_undefined_style_warning("Run", style_id))
+ else:
+ style_name = style.name
vertical_alignment = properties \
.find_child_or_null("w:vertAlign") \
@@ -87,16 +93,18 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f
is_strikethrough = properties.find_child("w:strike")
return _read_xml_elements(element.children) \
- .map(lambda children: documents.run(
- children=children,
- style_id=style_id,
- style_name=style_name,
- is_bold=is_bold,
- is_italic=is_italic,
- is_underline=is_underline,
- is_strikethrough=is_strikethrough,
- vertical_alignment=vertical_alignment,
- ))
+ .bind(lambda children: _element_result_with_messages(
+ documents.run(
+ children=children,
+ style_id=style_id,
+ style_name=style_name,
+ is_bold=is_bold,
+ is_italic=is_italic,
+ is_underline=is_underline,
+ is_strikethrough=is_strikethrough,
+ vertical_alignment=vertical_alignment,
+ ),
+ messages))
def paragraph(element):
diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py
index a3a7802..2d6644c 100644
--- a/tests/docx/body_xml_tests.py
+++ b/tests/docx/body_xml_tests.py
@@ -116,22 +116,29 @@ class ReadXmlElementTests(object):
assert_equal(None, _read_and_get_document_xml_element(element).style_id)
@istest
- def run_has_style_id_read_from_run_properties_if_present(self):
+ def run_has_style_id_and_name_read_from_run_properties_if_present(self):
style_xml = xml_element("w:rStyle", {"w:val": "Heading1Char"})
styles = Styles({}, {"Heading1Char": Style(style_id="Heading1Char", name="Heading 1 Char")})
run = self._read_run_with_properties([style_xml], styles=styles)
assert_equal("Heading1Char", run.style_id)
+ assert_equal("Heading 1 Char", run.style_name)
@istest
- def run_has_style_name_read_from_run_properties_and_styles(self):
+ def warning_is_emitted_when_run_style_cannot_be_found(self):
style_xml = xml_element("w:rStyle", {"w:val": "Heading1Char"})
+ properties_xml = xml_element("w:rPr", {}, [style_xml])
+ run_xml = xml_element("w:r", {}, [properties_xml])
- styles = Styles({}, {"Heading1Char": Style(style_id="Heading1Char", name="Heading 1 Char")})
+ styles = Styles({}, {})
+
+ result = _read_document_xml_element(run_xml, styles=styles)
+ run = result.value
+ assert_equal("Heading1Char", run.style_id)
+ assert_equal(None, run.style_name)
+ assert_equal([results.warning("Run style with ID Heading1Char was referenced but not defined in the document")], result.messages)
- run = self._read_run_with_properties([style_xml], styles=styles)
- assert_equal("Heading 1 Char", run.style_name)
@istest
def run_is_not_bold_if_bold_element_is_not_present(self):