aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mammoth/docx/__init__.py39
-rw-r--r--tests/docx/docx_tests.py36
2 files changed, 69 insertions, 6 deletions
diff --git a/mammoth/docx/__init__.py b/mammoth/docx/__init__.py
index 5b21e18..e98d4b6 100644
--- a/mammoth/docx/__init__.py
+++ b/mammoth/docx/__init__.py
@@ -50,9 +50,23 @@ def _find_part_paths(zip_file):
package_relationships = _read_relationships(zip_file, "_rels/.rels")
document_filename = _find_document_filename(zip_file, package_relationships)
+ document_relationships = _read_relationships(
+ zip_file,
+ _find_relationships_path_for(document_filename),
+ )
+
+ def find(name):
+ return _find_part_path(
+ zip_file=zip_file,
+ relationships=document_relationships,
+ relationship_type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/" + name,
+ fallback_path="word/{0}.xml".format(name),
+ base_path=zips.split_path(document_filename)[0],
+ )
+
return _PartPaths(
main_document=document_filename,
- comments="word/comments.xml",
+ comments=find("comments"),
endnotes="word/endnotes.xml",
footnotes="word/footnotes.xml",
numbering="word/numbering.xml",
@@ -61,14 +75,27 @@ def _find_part_paths(zip_file):
def _find_document_filename(zip_file, relationships):
- office_document_type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
+ path = _find_part_path(
+ zip_file,
+ relationships,
+ relationship_type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
+ base_path="",
+ fallback_path="word/document.xml",
+ )
+ if zip_file.exists(path):
+ return path
+ else:
+ raise IOError("Could not find main document part. Are you sure this is a valid .docx file?")
+
+
+def _find_part_path(zip_file, relationships, relationship_type, base_path, fallback_path):
targets = [
- target.lstrip("/")
- for target in relationships.find_targets_by_type(office_document_type)
- ] + ["word/document.xml"]
+ zips.join_path(base_path, target).lstrip("/")
+ for target in relationships.find_targets_by_type(relationship_type)
+ ]
valid_targets = list(filter(lambda target: zip_file.exists(target), targets))
if len(valid_targets) == 0:
- raise IOError("Could not find main document part. Are you sure this is a valid .docx file?")
+ return fallback_path
else:
return valid_targets[0]
diff --git a/tests/docx/docx_tests.py b/tests/docx/docx_tests.py
index a474b17..64a3b81 100644
--- a/tests/docx/docx_tests.py
+++ b/tests/docx/docx_tests.py
@@ -101,6 +101,42 @@ class TestPartPaths(object):
part_paths = self._find_part_paths(fileobj)
assert_equal("word/document.xml", part_paths.main_document)
+ @istest
+ def comments_part_is_found_using_main_document_relationships(self):
+ fileobj = _create_zip({
+ "_rels/.rels": textwrap.dedent("""\
+ <?xml version="1.0" encoding="utf-8"?>
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
+ <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/word/document.xml" Id="rId1"/>
+ </Relationships>
+ """),
+ "word/document.xml": " ",
+ "word/_rels/document.xml.rels": textwrap.dedent("""\
+ <?xml version="1.0" encoding="utf-8"?>
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
+ <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" Target="target-path.xml" Id="rId2"/>
+ </Relationships>
+ """),
+ "word/target-path.xml": " "
+ })
+ part_paths = self._find_part_paths(fileobj)
+ assert_equal("word/target-path.xml", part_paths.comments)
+
+ @istest
+ def when_relationship_for_comments_cannot_be_found_then_fallback_is_used(self):
+ fileobj = _create_zip({
+ "_rels/.rels": textwrap.dedent("""\
+ <?xml version="1.0" encoding="utf-8"?>
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
+ <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="/word/document.xml" Id="rId1"/>
+ </Relationships>
+ """),
+ "word/document.xml": " ",
+ })
+ part_paths = self._find_part_paths(fileobj)
+ assert_equal("word/comments.xml", part_paths.comments)
+
+
def _find_part_paths(self, fileobj):
return docx._find_part_paths(zips.open_zip(fileobj, "r"))