diff options
| author | Michael Williamson <mike@zwobble.org> | 2019-03-17 18:20:17 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2019-03-17 18:20:17 +0000 |
| commit | 6d5fe54cd6183d12c0e984d9d0d7e3204817583f (patch) | |
| tree | e7d25ad8d8307bb06b333e897488cd137dad19af /mammoth/docx | |
| parent | 20c1fea1a37ac39f3114775facad74644435253e (diff) | |
Defer resolution of abstract nums until necessary
Diffstat (limited to 'mammoth/docx')
| -rw-r--r-- | mammoth/docx/__init__.py | 26 | ||||
| -rw-r--r-- | mammoth/docx/numbering_xml.py | 27 |
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) |
