aboutsummaryrefslogtreecommitdiff
path: root/mammoth/docx/document_xml.py
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2013-12-01 11:51:38 +0000
committerMichael Williamson <mike@zwobble.org>2013-12-01 11:51:38 +0000
commitd5acaf1071564a9997a330315ea99cdc1017bae7 (patch)
treeffaee2557ff0fd4a2c69c19855293faa29b1277f /mammoth/docx/document_xml.py
parentf8d72dbba832db282a3ec04a5108fbd090f49a4f (diff)
Move document.xml parsing to separate module
Diffstat (limited to 'mammoth/docx/document_xml.py')
-rw-r--r--mammoth/docx/document_xml.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/mammoth/docx/document_xml.py b/mammoth/docx/document_xml.py
new file mode 100644
index 0000000..c83c28c
--- /dev/null
+++ b/mammoth/docx/document_xml.py
@@ -0,0 +1,76 @@
+import zipfile
+
+from .. import documents
+from ..results import Result
+from .xmlparser import parse_xml, node_types
+
+
+_handlers = {}
+
+
+def handler(name):
+ def add(func):
+ _handlers[name] = func
+
+ return add
+
+
+def read_document_xml_element(element):
+ handler = _handlers.get(element.name)
+ if handler is None:
+ return None
+ else:
+ return handler(element)
+
+
+@handler("w:t")
+def text(element):
+ return documents.Text(_inner_text(element))
+
+
+@handler("w:r")
+def run(element):
+ return documents.Run(_read_xml_elements(element.children))
+
+
+@handler("w:p")
+def paragraph(element):
+ properties = element.find_child_or_null("w:pPr")
+ style_name = properties \
+ .find_child_or_null("w:pStyle") \
+ .attributes.get("w:val")
+
+ children = _read_xml_elements(element.children)
+ return documents.paragraph(children, style_name)
+
+
+@handler("w:body")
+def body(element):
+ return _read_xml_elements(element.children)
+
+
+@handler("w:document")
+def document(element):
+ body_element = _find_child(element, "w:body")
+ return documents.Document(_read_xml_elements(body_element.children))
+
+
+def _find(predicate, iterable):
+ for item in iterable:
+ if predicate(item):
+ return item
+
+
+def _find_child(element, name):
+ return _find(lambda child: child.name == name, element.children)
+
+
+def _read_xml_elements(elements):
+ return filter(None, map(read_document_xml_element, elements))
+
+
+def _inner_text(node):
+ if node.node_type == node_types.text:
+ return node.value
+ else:
+ return "".join(_inner_text(child) for child in node.children)