diff options
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | mammoth/docx/styles_xml.py | 13 | ||||
| -rw-r--r-- | tests/docx/styles_xml_tests.py | 12 |
3 files changed, 28 insertions, 1 deletions
@@ -1,3 +1,7 @@ +# 1.11.0 + +* Ignore style definitions using a style ID that has already been used. + # 1.10.0 * Add "Heading" and "Body" styles, as found in documents created by Apple Pages, diff --git a/mammoth/docx/styles_xml.py b/mammoth/docx/styles_xml.py index 0b3f39d..3178553 100644 --- a/mammoth/docx/styles_xml.py +++ b/mammoth/docx/styles_xml.py @@ -67,7 +67,18 @@ def read_styles_xml_element(element): style = _read_style_element(style_element) style_set = styles.get(element_type) - if style_set is not None: + + # Per 17.7.4.17 style (Style Definition) of ECMA-376 4th edition Part 1: + # + # > If multiple style definitions each declare the same value for their + # > styleId, then the first such instance shall keep its current + # > identifier with all other instances being reassigned in any manner + # > desired. + # + # For the purpose of conversion, there's no point holding onto styles + # with reassigned style IDs, so we ignore such style definitions. + + if style_set is not None and style.style_id not in style_set: style_set[style.style_id] = style return Styles( diff --git a/tests/docx/styles_xml_tests.py b/tests/docx/styles_xml_tests.py index 165d86c..008e12f 100644 --- a/tests/docx/styles_xml_tests.py +++ b/tests/docx/styles_xml_tests.py @@ -101,6 +101,18 @@ def test_numbering_style_has_num_id_read_from_paragraph_properties(): assert_equal("42", styles.find_numbering_style_by_id("List1").num_id) +def test_when_multiple_style_elements_have_same_style_id_then_only_first_element_is_used(): + element = xml_element("w:styles", {}, [ + _table_style_element("TableNormal", "Normal Table"), + _table_style_element("TableNormal", "Table Normal"), + ]) + styles = read_styles_xml_element(element) + assert_equal( + "Normal Table", + styles.find_table_style_by_id("TableNormal").name + ) + + def _paragraph_style_element(style_id, name): return _style_element("paragraph", style_id, name) |
