aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-12-26 11:01:22 +0000
committerMichael Williamson <mike@zwobble.org>2015-12-26 11:08:18 +0000
commit03f7d77da6ce807effa5494f161aab07fdd2498c (patch)
tree631d62cfc647e139a9ca27097c250af834d1ff59
parent5a5112f8c0286da6875e54b2e61a32288135d1e8 (diff)
Always use mc:Fallback when reading mc:AlternateContent elements
-rw-r--r--NEWS4
-rw-r--r--mammoth/docx/office_xml.py15
-rw-r--r--mammoth/lists.py8
-rw-r--r--tests/docx/office_xml_tests.py26
4 files changed, 51 insertions, 2 deletions
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 = (
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
+ '<numbering xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">' +
+ '<mc:AlternateContent>' +
+ '<mc:Choice Requires="w14">' +
+ '<choice/>' +
+ '</mc:Choice>' +
+ '<mc:Fallback>' +
+ '<fallback/>' +
+ '</mc:Fallback>' +
+ '</mc:AlternateContent>' +
+ '</numbering>')
+
+ result = office_xml.read(io.StringIO(xml_string))
+ assert_equal([xml.element("fallback")], result.children)