From 6e449db1f143ac198e820610a40765071163d87a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 4 Feb 2016 08:42:19 +0000 Subject: Handle missing run styles in the source document --- mammoth/docx/body_xml.py | 30 +++++++++++++++++++----------- tests/docx/body_xml_tests.py | 17 ++++++++++++----- 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): -- cgit v1.2.3