From 03f7d77da6ce807effa5494f161aab07fdd2498c Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 26 Dec 2015 11:01:22 +0000 Subject: Always use mc:Fallback when reading mc:AlternateContent elements --- NEWS | 4 ++++ mammoth/docx/office_xml.py | 15 +++++++++++++-- mammoth/lists.py | 8 ++++++++ tests/docx/office_xml_tests.py | 26 ++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/docx/office_xml_tests.py diff --git a/NEWS b/NEWS index 1765b3a..f5fabcf 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +# 0.3.26 + +* Always use mc:Fallback when reading mc:AlternateContent elements. + # 0.3.25 * Remove duplicate messages from results. diff --git a/mammoth/docx/office_xml.py b/mammoth/docx/office_xml.py index 4dffb44..0a6a8a8 100644 --- a/mammoth/docx/office_xml.py +++ b/mammoth/docx/office_xml.py @@ -1,4 +1,5 @@ -from .xmlparser import parse_xml +from ..lists import flat_map +from .xmlparser import parse_xml, XmlElement _namespaces = [ @@ -16,5 +17,15 @@ _namespaces = [ def read(fileobj): - return parse_xml(fileobj, _namespaces) + return _collapse_alternate_content(parse_xml(fileobj, _namespaces))[0] + +def _collapse_alternate_content(node): + if isinstance(node, XmlElement): + if node.name == "mc:AlternateContent": + return node.find_child("mc:Fallback").children + else: + node.children = flat_map(_collapse_alternate_content, node.children) + return [node] + else: + return [node] diff --git a/mammoth/lists.py b/mammoth/lists.py index 6e39ae0..e8477cb 100644 --- a/mammoth/lists.py +++ b/mammoth/lists.py @@ -24,6 +24,14 @@ def unique(values): return output +def flat_map(func, values): + return [ + element + for value in values + for element in func(value) + ] + + if sys.version_info[0] == 2: map = map filter = filter diff --git a/tests/docx/office_xml_tests.py b/tests/docx/office_xml_tests.py new file mode 100644 index 0000000..5b8b1e1 --- /dev/null +++ b/tests/docx/office_xml_tests.py @@ -0,0 +1,26 @@ +from __future__ import unicode_literals + +import io + +from nose.tools import istest, assert_equal + +from mammoth.docx import xmlparser as xml, office_xml + + +@istest +def alternate_content_is_replaced_by_contents_of_fallback(): + xml_string = ( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '') + + result = office_xml.read(io.StringIO(xml_string)) + assert_equal([xml.element("fallback")], result.children) -- cgit v1.2.3