diff options
| -rw-r--r-- | mammoth/docx/body_xml.py | 29 | ||||
| -rw-r--r-- | tests/docx/body_xml_tests.py | 14 |
2 files changed, 31 insertions, 12 deletions
diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py index f66eeae..854ccf2 100644 --- a/mammoth/docx/body_xml.py +++ b/mammoth/docx/body_xml.py @@ -100,6 +100,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f def paragraph(element): + messages = [] properties = element.find_child_or_null("w:pPr") style_id = properties \ .find_child_or_null("w:pStyle") \ @@ -108,19 +109,29 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f if style_id is None: style_name = None else: - style_name = styles.find_paragraph_style_by_id(style_id).name + style = styles.find_paragraph_style_by_id(style_id) + if style is None: + style_name = None + messages.append(_undefined_style_warning("Paragraph", style_id)) + else: + style_name = style.name numbering = _read_numbering_properties(properties.find_child_or_null("w:numPr")) return _read_xml_elements(element.children) \ - .map(lambda children: documents.paragraph( - children=children, - style_id=style_id, - style_name=style_name, - numbering=numbering, - )) \ + .bind(lambda children: _element_result_with_messages( + documents.paragraph( + children=children, + style_id=style_id, + style_name=style_name, + numbering=numbering, + ), + messages)) \ .append_extra() + def _undefined_style_warning(style_type, style_id): + return results.warning("{0} style with ID {1} was referenced but not defined in the document".format(style_type, style_id)) + def _read_numbering_properties(element): num_id = element.find_child_or_null("w:numId").attributes.get("w:val") level_index = element.find_child_or_null("w:ilvl").attributes.get("w:val") @@ -341,6 +352,10 @@ class _ReadResult(object): result = self._result.map(lambda value: func(value[0])) return _ReadResult(result.value, self.extra, result.messages) + def bind(self, func): + result = self._result.bind(lambda value: func(value[0])) + return _ReadResult(result.value, self.extra, result.messages) + def to_extra(self): return _ReadResult(None, _concat(self.extra, self.value), self.messages) diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py index ddfa9b2..a3a7802 100644 --- a/tests/docx/body_xml_tests.py +++ b/tests/docx/body_xml_tests.py @@ -40,7 +40,7 @@ class ReadXmlElementTests(object): assert_equal(None, _read_and_get_document_xml_element(element).style_id) @istest - def paragraph_has_style_id_read_from_paragraph_properties_if_present(self): + def paragraph_has_style_id_and_name_read_from_paragraph_properties_if_present(self): style_xml = xml_element("w:pStyle", {"w:val": "Heading1"}) properties_xml = xml_element("w:pPr", {}, [style_xml]) paragraph_xml = xml_element("w:p", {}, [properties_xml]) @@ -49,17 +49,21 @@ class ReadXmlElementTests(object): paragraph = _read_and_get_document_xml_element(paragraph_xml, styles=styles) assert_equal("Heading1", paragraph.style_id) + assert_equal("Heading 1", paragraph.style_name) @istest - def paragraph_has_style_name_read_from_paragraph_properties_and_styles(self): + def warning_is_emitted_when_paragraph_style_cannot_be_found(self): style_xml = xml_element("w:pStyle", {"w:val": "Heading1"}) properties_xml = xml_element("w:pPr", {}, [style_xml]) paragraph_xml = xml_element("w:p", {}, [properties_xml]) - styles = Styles({"Heading1": Style(style_id="Heading1", name="Heading 1")}, {}) + styles = Styles({}, {}) - paragraph = _read_and_get_document_xml_element(paragraph_xml, styles=styles) - assert_equal("Heading 1", paragraph.style_name) + result = _read_document_xml_element(paragraph_xml, styles=styles) + paragraph = result.value + assert_equal("Heading1", paragraph.style_id) + assert_equal(None, paragraph.style_name) + assert_equal([results.warning("Paragraph style with ID Heading1 was referenced but not defined in the document")], result.messages) @istest def paragraph_has_no_numbering_if_it_has_no_numbering_properties(self): |
