aboutsummaryrefslogtreecommitdiff
path: root/mammoth/docx
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-07-04 13:52:28 +0100
committerMichael Williamson <mike@zwobble.org>2015-07-04 13:52:28 +0100
commit3a363314e6149361b16959d4e3c2ebb6cd97ab1f (patch)
tree1ce2159a0ccdd9d0ceac90ecbda6cdc924254f27 /mammoth/docx
parent044398430b84b73fa6fce57405254f4a63c42424 (diff)
Handle relationships in notes
Diffstat (limited to 'mammoth/docx')
-rw-r--r--mammoth/docx/__init__.py40
-rw-r--r--mammoth/docx/document_xml.py16
-rw-r--r--mammoth/docx/notes_xml.py26
3 files changed, 45 insertions, 37 deletions
diff --git a/mammoth/docx/__init__.py b/mammoth/docx/__init__.py
index 3e7c0e0..ec8d363 100644
--- a/mammoth/docx/__init__.py
+++ b/mammoth/docx/__init__.py
@@ -1,13 +1,14 @@
import zipfile
import contextlib
+from .. import results, lists
from .xmlparser import parse_xml
from .document_xml import read_document_xml_element
from .content_types_xml import read_content_types_xml_element
-from .relationships_xml import read_relationships_xml_element
+from .relationships_xml import read_relationships_xml_element, Relationships
from .numbering_xml import read_numbering_xml_element, Numbering
from .styles_xml import read_styles_xml_element
-from .notes_xml import read_footnotes_xml_element, read_endnotes_xml_element
+from .notes_xml import create_footnotes_reader, create_endnotes_reader
from . import body_xml
@@ -25,23 +26,32 @@ _namespaces = [
def read(fileobj):
zip_file = zipfile.ZipFile(fileobj)
-
body_readers = _body_readers(zip_file)
- body_reader = body_readers("document")
- footnote_elements = _try_read_entry_or_default(
- zip_file, "word/footnotes.xml", read_footnotes_xml_element, default=[])
+ return _read_notes(zip_file, body_readers).bind(lambda notes:
+ _read_document(zip_file, body_readers, notes))
+
+
+def _read_notes(zip_file, body_readers):
+ empty_result = results.success([])
+
+ read_footnotes_xml = create_footnotes_reader(body_readers("footnotes"))
+ footnotes = _try_read_entry_or_default(
+ zip_file, "word/footnotes.xml", read_footnotes_xml, default=empty_result)
+
+ read_endnotes_xml = create_endnotes_reader(body_readers("endnotes"))
+ endnotes = _try_read_entry_or_default(
+ zip_file, "word/endnotes.xml", read_endnotes_xml, default=empty_result)
- endnote_elements = _try_read_entry_or_default(
- zip_file, "word/endnotes.xml", read_endnotes_xml_element, default=[])
+ return results.combine([footnotes, endnotes]).map(lists.collect)
+def _read_document(zip_file, body_readers, notes):
with _open_entry(zip_file, "word/document.xml") as document_fileobj:
document_xml = _parse_docx_xml(document_fileobj)
return read_document_xml_element(
document_xml,
- body_reader=body_reader,
- footnote_elements=footnote_elements,
- endnote_elements=endnote_elements,
+ body_reader=body_readers("document"),
+ notes=notes,
)
@@ -56,9 +66,11 @@ def _body_readers(zip_file):
styles = read_styles_xml_element(_parse_docx_xml(styles_fileobj))
def for_name(name):
- with _open_entry(zip_file, "word/_rels/{0}.xml.rels".format(name)) as relationships_fileobj:
- relationships = read_relationships_xml_element(_parse_docx_xml(relationships_fileobj))
-
+ relationships_path = "word/_rels/{0}.xml.rels".format(name)
+ relationships = _try_read_entry_or_default(
+ zip_file, relationships_path, read_relationships_xml_element,
+ default=Relationships({}))
+
return body_xml.reader(
numbering=numbering,
content_types=content_types,
diff --git a/mammoth/docx/document_xml.py b/mammoth/docx/document_xml.py
index 3cdbec2..1c15001 100644
--- a/mammoth/docx/document_xml.py
+++ b/mammoth/docx/document_xml.py
@@ -1,19 +1,13 @@
from .. import documents
-from .. import results
def read_document_xml_element(element,
body_reader,
- footnote_elements=None,
- endnote_elements=None):
+ notes=None):
- note_elements = (footnote_elements or []) + (endnote_elements or [])
+ if notes is None:
+ notes = []
- def _read_note(element):
- return body_reader.read_all(element.body).map(
- lambda body: documents.note(element.note_type, element.id, body))
-
body_element = element.find_child("w:body")
- children_result = body_reader.read_all(body_element.children)
- notes_result = results.combine(map(_read_note, note_elements)).map(documents.notes)
- return results.map(documents.document, children_result, notes_result)
+ return body_reader.read_all(body_element.children) \
+ .map(lambda children: documents.document(children, documents.notes(notes)))
diff --git a/mammoth/docx/notes_xml.py b/mammoth/docx/notes_xml.py
index b9b0362..f1072f9 100644
--- a/mammoth/docx/notes_xml.py
+++ b/mammoth/docx/notes_xml.py
@@ -1,13 +1,17 @@
+import functools
+
from .. import lists
+from .. import documents
+from .. import results
-def create_reader(note_type):
+def create_reader(note_type, body_reader):
def read_notes_xml_element(element):
note_elements = lists.filter(
_is_note_element,
element.find_children("w:" + note_type),
)
- return lists.map(_read_note_element, note_elements)
+ return results.combine(lists.map(_read_note_element, note_elements))
def _is_note_element(element):
@@ -15,16 +19,14 @@ def create_reader(note_type):
def _read_note_element(element):
- return NoteElement(note_type, element.attributes["w:id"], element.children)
+ return body_reader.read_all(element.children).map(lambda body:
+ documents.note(
+ note_type=note_type,
+ note_id=element.attributes["w:id"],
+ body=body
+ ))
return read_notes_xml_element
-class NoteElement(object):
- def __init__(self, note_type, id, body):
- self.note_type = note_type
- self.id = id
- self.body = body
-
-
-read_footnotes_xml_element = create_reader("footnote")
-read_endnotes_xml_element = create_reader("endnote")
+create_footnotes_reader = functools.partial(create_reader, "footnote")
+create_endnotes_reader = functools.partial(create_reader, "endnote")