diff options
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | mammoth/docx/body_xml.py | 15 | ||||
| -rw-r--r-- | tests/docx/body_xml_tests.py | 31 |
3 files changed, 39 insertions, 11 deletions
@@ -1,3 +1,7 @@ +# 0.3.21 + +* Ignore w:numPr elements without w:numId or w:ilvl children. + # 0.3.20 * Add support for linked images. diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py index 54f9dd3..9588bfe 100644 --- a/mammoth/docx/body_xml.py +++ b/mammoth/docx/body_xml.py @@ -118,11 +118,7 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f else: style_name = styles.find_paragraph_style_by_id(style_id).name - numbering_properties = properties.find_child("w:numPr") - if numbering_properties is None: - numbering = None - else: - numbering = _read_numbering_properties(numbering_properties) + numbering = _read_numbering_properties(properties.find_child_or_null("w:numPr")) return _read_xml_elements(element.children) \ .map(lambda children: documents.paragraph( @@ -134,9 +130,12 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f .append_extra() def _read_numbering_properties(element): - num_id = element.find_child("w:numId").attributes["w:val"] - level_index = element.find_child("w:ilvl").attributes["w:val"] - return numbering.find_level(num_id, level_index) + 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") + if num_id is None or level_index is None: + return None + else: + return numbering.find_level(num_id, level_index) @handler("w:tab") diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py index d3b552b..6122706 100644 --- a/tests/docx/body_xml_tests.py +++ b/tests/docx/body_xml_tests.py @@ -68,18 +68,43 @@ class ReadXmlElementTests(object): @istest def paragraph_has_numbering_properties_from_paragraph_properties_if_present(self): - numbering_properties_xml = xml_element("w:numPr", {}, [ + paragraph_xml = self._paragraph_with_numbering_properties([ xml_element("w:ilvl", {"w:val": "1"}), xml_element("w:numId", {"w:val": "42"}), ]) - properties_xml = xml_element("w:pPr", {}, [numbering_properties_xml]) - paragraph_xml = xml_element("w:p", {}, [properties_xml]) numbering = Numbering({"42": {"1": documents.numbering_level("1", True)}}) paragraph = _read_and_get_document_xml_element(paragraph_xml, numbering=numbering) assert_equal("1", paragraph.numbering.level_index) assert_equal(True, paragraph.numbering.is_ordered) + + @istest + def numbering_properties_are_ignored_if_lvl_is_missing(self): + paragraph_xml = self._paragraph_with_numbering_properties([ + xml_element("w:numId", {"w:val": "42"}), + ]) + + numbering = Numbering({"42": {"1": documents.numbering_level("1", True)}}) + paragraph = _read_and_get_document_xml_element(paragraph_xml, numbering=numbering) + + assert_equal(None, paragraph.numbering) + + @istest + def numbering_properties_are_ignored_if_num_id_is_missing(self): + paragraph_xml = self._paragraph_with_numbering_properties([ + xml_element("w:ilvl", {"w:val": "1"}), + ]) + + numbering = Numbering({"42": {"1": documents.numbering_level("1", True)}}) + paragraph = _read_and_get_document_xml_element(paragraph_xml, numbering=numbering) + + assert_equal(None, paragraph.numbering) + + def _paragraph_with_numbering_properties(self, children): + numbering_properties_xml = xml_element("w:numPr", {}, children) + properties_xml = xml_element("w:pPr", {}, [numbering_properties_xml]) + return xml_element("w:p", {}, [properties_xml]) @istest def run_has_no_style_if_it_has_no_properties(self): |
