diff options
| -rw-r--r-- | mammoth/docx/document_xml.py | 50 | ||||
| -rw-r--r-- | mammoth/results.py | 32 | ||||
| -rw-r--r-- | tests/docx/document_xml_tests.py | 10 |
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)) |
