aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2013-12-01 13:56:31 +0000
committerMichael Williamson <mike@zwobble.org>2013-12-01 13:56:31 +0000
commite1c20f1facebc5bf3e56f6aa6f2d1ac9ff8dc7d8 (patch)
tree16114ff0fb50875a9ac852e5355fabfae2236d61
parentb160de0cdd0ec662a64718ab796a51cd12924e13 (diff)
Emit warnings on unrecognised elements
-rw-r--r--mammoth/docx/document_xml.py50
-rw-r--r--mammoth/results.py32
-rw-r--r--tests/docx/document_xml_tests.py10
3 files changed, 77 insertions, 15 deletions
diff --git a/mammoth/docx/document_xml.py b/mammoth/docx/document_xml.py
index dd018de..f8fb962 100644
--- a/mammoth/docx/document_xml.py
+++ b/mammoth/docx/document_xml.py
@@ -5,10 +5,21 @@ from .xmlparser import node_types
def read_document_xml_element(element, numbering=None):
reader = _create_reader(numbering)
- return results.Result(reader(element), [])
+ return reader(element)
def _create_reader(numbering):
_handlers = {}
+ _ignored_elements = set([
+ "w:bookmarkStart",
+ "w:bookmarkEnd",
+ "w:sectPr",
+ "w:proofErr",
+ "w:lastRenderedPageBreak",
+ "w:commentRangeStart",
+ "w:commentRangeEnd",
+ "w:commentReference",
+ "w:del"
+ ])
def handler(name):
def add(func):
@@ -18,7 +29,7 @@ def _create_reader(numbering):
@handler("w:t")
def text(element):
- return documents.Text(_inner_text(element))
+ return results.success(documents.Text(_inner_text(element)))
@handler("w:r")
@@ -30,12 +41,13 @@ def _create_reader(numbering):
is_bold = properties.find_child("w:b")
is_italic = properties.find_child("w:i")
- return documents.run(
- children=_read_xml_elements(element.children),
- style_name=style_name,
- is_bold=is_bold,
- is_italic=is_italic,
- )
+ return _read_xml_elements(element.children) \
+ .map(lambda children: documents.run(
+ children=children,
+ style_name=style_name,
+ is_bold=is_bold,
+ is_italic=is_italic,
+ ))
@handler("w:p")
@@ -50,8 +62,12 @@ def _create_reader(numbering):
else:
numbering = _read_numbering_properties(numbering_properties)
- children = _read_xml_elements(element.children)
- return documents.paragraph(children, style_name, numbering)
+ return _read_xml_elements(element.children) \
+ .map(lambda children: documents.paragraph(
+ children=children,
+ style_name=style_name,
+ numbering=numbering,
+ ))
def _read_numbering_properties(element):
num_id = element.find_child("w:numId").attributes["w:val"]
@@ -67,23 +83,29 @@ def _create_reader(numbering):
@handler("w:document")
def document(element):
body_element = _find_child(element, "w:body")
- return documents.document(_read_xml_elements(body_element.children))
+ return _read_xml_elements(body_element.children) \
+ .map(documents.document)
@handler("w:tab")
def tab(element):
- return documents.tab()
+ return results.success(documents.tab())
def read(element):
handler = _handlers.get(element.name)
if handler is None:
- return None
+ if element.name not in _ignored_elements:
+ warning = results.warning("An unrecognised element was ignored: {0}".format(element.name))
+ return results.Result(None, [warning])
+ else:
+ return results.success(None)
else:
return handler(element)
def _read_xml_elements(elements):
- return filter(None, map(read, elements))
+ return results.combine(map(read, elements)) \
+ .map(lambda values: filter(None, values))
return read
diff --git a/mammoth/results.py b/mammoth/results.py
index f735df7..ab29b25 100644
--- a/mammoth/results.py
+++ b/mammoth/results.py
@@ -1,4 +1,36 @@
+import collections
+
+
class Result(object):
def __init__(self, value, messages):
self.value = value
self.messages = messages
+
+ def map(self, func):
+ return Result(func(self.value), self.messages)
+
+ #~ def bind(self, func):
+ #~ result = func(self.value)
+ #~ return Result(result.value, self.messages + result.messages)
+
+
+Message = collections.namedtuple("Message", ["type", "message"])
+
+
+def warning(message):
+ return Message("warning", message)
+
+
+def success(value):
+ return Result(value, [])
+
+
+def combine(results):
+ values = []
+ messages = []
+ for result in results:
+ values.append(result.value)
+ for message in result.messages:
+ messages.append(message)
+
+ return Result(values, messages)
diff --git a/tests/docx/document_xml_tests.py b/tests/docx/document_xml_tests.py
index 232bb34..e643efb 100644
--- a/tests/docx/document_xml_tests.py
+++ b/tests/docx/document_xml_tests.py
@@ -1,6 +1,6 @@
from nose.tools import istest, assert_equal
-from mammoth import documents
+from mammoth import documents, results
from mammoth.docx.xmlparser import element as xml_element, text as xml_text
from mammoth.docx.document_xml import read_document_xml_element
from mammoth.docx.numbering_xml import Numbering, NumberingLevel
@@ -117,9 +117,17 @@ class ReadXmlElementTests(object):
def ignored_elements_are_ignored_without_message(self):
element = xml_element("w:bookmarkStart")
result = read_document_xml_element(element)
+ assert_equal(None, result.value)
assert_equal([], result.messages)
@istest
+ def unrecognised_elements_emit_warning(self):
+ element = xml_element("w:huh", {}, [])
+ result = read_document_xml_element(element)
+ expected_warning = results.warning("An unrecognised element was ignored: w:huh")
+ assert_equal([expected_warning], result.messages)
+
+ @istest
def unrecognised_elements_are_ignored(self):
element = xml_element("w:huh", {}, [])
assert_equal(None, _read_and_get_document_xml_element(element))