aboutsummaryrefslogtreecommitdiff
path: root/mammoth/docx
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2019-03-17 18:20:17 +0000
committerMichael Williamson <mike@zwobble.org>2019-03-17 18:20:17 +0000
commit6d5fe54cd6183d12c0e984d9d0d7e3204817583f (patch)
treee7d25ad8d8307bb06b333e897488cd137dad19af /mammoth/docx
parent20c1fea1a37ac39f3114775facad74644435253e (diff)
Defer resolution of abstract nums until necessary
Diffstat (limited to 'mammoth/docx')
-rw-r--r--mammoth/docx/__init__.py26
-rw-r--r--mammoth/docx/numbering_xml.py27
2 files changed, 31 insertions, 22 deletions
diff --git a/mammoth/docx/__init__.py b/mammoth/docx/__init__.py
index 75511d2..517683d 100644
--- a/mammoth/docx/__init__.py
+++ b/mammoth/docx/__init__.py
@@ -1,7 +1,7 @@
from functools import partial
import os
-import cobble
+import cobble
from .. import results, lists, zips
from .document_xml import read_document_xml_element
@@ -27,7 +27,7 @@ def read(fileobj):
zip_file,
part_paths=part_paths,
)
-
+
return results.combine([
_read_notes(read_part_with_body, part_paths),
_read_comments(read_part_with_body, part_paths),
@@ -49,12 +49,12 @@ class _PartPaths(object):
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,
@@ -63,7 +63,7 @@ def _find_part_paths(zip_file):
fallback_path="word/{0}.xml".format(name),
base_path=zips.split_path(document_filename)[0],
)
-
+
return _PartPaths(
main_document=document_filename,
comments=find("comments"),
@@ -111,7 +111,7 @@ def _read_notes(read_part_with_body, part_paths):
lambda root, body_reader: read_endnotes_xml_element(root, body_reader=body_reader),
default=_empty_result,
)
-
+
return results.combine([footnotes, endnotes]).map(lists.flatten)
@@ -122,7 +122,7 @@ def _read_comments(read_part_with_body, part_paths):
default=_empty_result,
)
-
+
def _read_document(zip_file, read_part_with_body, notes, comments, part_paths):
return read_part_with_body(
part_paths.main_document,
@@ -146,19 +146,19 @@ def _part_with_body_reader(document_path, zip_file, part_paths):
zip_file,
part_paths.numbering,
read_numbering_xml_element,
- default=Numbering({}),
+ default=Numbering(abstract_nums={}, nums={}),
)
-
+
styles = _try_read_entry_or_default(
zip_file,
part_paths.styles,
read_styles_xml_element,
Styles.EMPTY,
)
-
+
def read_part(name, reader, default=_undefined):
relationships = _read_relationships(zip_file, _find_relationships_path_for(name))
-
+
body_reader = body_xml.reader(
numbering=numbering,
content_types=content_types,
@@ -172,7 +172,7 @@ def _part_with_body_reader(document_path, zip_file, part_paths):
return _read_entry(zip_file, name, partial(reader, body_reader=body_reader))
else:
return _try_read_entry_or_default(zip_file, name, partial(reader, body_reader=body_reader), default=default)
-
+
return read_part
@@ -180,7 +180,7 @@ def _part_with_body_reader(document_path, zip_file, part_paths):
def _find_relationships_path_for(name):
dirname, basename = zips.split_path(name)
return zips.join_path(dirname, "_rels", basename + ".rels")
-
+
def _read_relationships(zip_file, name):
return _try_read_entry_or_default(
diff --git a/mammoth/docx/numbering_xml.py b/mammoth/docx/numbering_xml.py
index f7f98e0..31a0d3c 100644
--- a/mammoth/docx/numbering_xml.py
+++ b/mammoth/docx/numbering_xml.py
@@ -1,10 +1,12 @@
+import cobble
+
from ..documents import numbering_level
def read_numbering_xml_element(element):
abstract_nums = _read_abstract_nums(element)
- nums = _read_nums(element, abstract_nums)
- return Numbering(nums)
+ nums = _read_nums(element)
+ return Numbering(abstract_nums=abstract_nums, nums=nums)
def _read_abstract_nums(element):
@@ -33,27 +35,34 @@ def _read_abstract_num_level(element):
return numbering_level(level_index, is_ordered)
-def _read_nums(element, abstract_nums):
+def _read_nums(element):
num_elements = element.find_children("w:num")
return dict(
- _read_num(num_element, abstract_nums)
+ _read_num(num_element)
for num_element in num_elements
)
-def _read_num(element, abstract_nums):
+def _read_num(element):
num_id = element.attributes.get("w:numId")
abstract_num_id = element.find_child_or_null("w:abstractNumId").attributes["w:val"]
- return num_id, abstract_nums[abstract_num_id]
+ return num_id, _Num(abstract_num_id=abstract_num_id)
+
+
+@cobble.data
+class _Num(object):
+ abstract_num_id = cobble.field()
class Numbering(object):
- def __init__(self, nums):
+ def __init__(self, abstract_nums, nums):
+ self._abstract_nums = abstract_nums
self._nums = nums
-
+
def find_level(self, num_id, level):
num = self._nums.get(num_id)
if num is None:
return None
else:
- return num.get(level)
+ abstract_num = self._abstract_nums[num.abstract_num_id]
+ return abstract_num.get(level)