aboutsummaryrefslogtreecommitdiff
path: root/mammoth/docx/numbering_xml.py
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2025-09-11 15:21:40 +0100
committerMichael Williamson <mike@zwobble.org>2025-09-11 15:21:40 +0100
commit82bc0fe4769483196ce8cc8147fab16b38c52e8f (patch)
treee53ef888e6d880ce76a3843a479231ba36de550e /mammoth/docx/numbering_xml.py
parent8216e5ae1770955ad2400cee764c7f8ec56483bf (diff)
Handle numbering levels defined without an index
Diffstat (limited to 'mammoth/docx/numbering_xml.py')
-rw-r--r--mammoth/docx/numbering_xml.py26
1 files changed, 20 insertions, 6 deletions
diff --git a/mammoth/docx/numbering_xml.py b/mammoth/docx/numbering_xml.py
index 7f7bf0e..4614d0e 100644
--- a/mammoth/docx/numbering_xml.py
+++ b/mammoth/docx/numbering_xml.py
@@ -36,15 +36,29 @@ class _AbstractNumLevel(object):
def _read_abstract_num_levels(element):
- levels = map(_read_abstract_num_level, element.find_children("w:lvl"))
- return dict(
- (level.level_index, level)
- for level in levels
- )
+ levels = {}
+
+ # Some malformed documents define numbering levels without an index, and
+ # reference the numbering using a w:numPr element without a w:ilvl child.
+ # To handle such cases, we assume a level of 0 as a fallback.
+ level_without_index = None
+
+ for level_element in element.find_children("w:lvl"):
+ level = _read_abstract_num_level(level_element)
+ if level.level_index is None:
+ level.level_index = "0"
+ level_without_index = level
+ else:
+ levels[level.level_index] = level
+
+ if "0" not in levels and level_without_index is not None:
+ levels[level_without_index.level_index] = level_without_index
+
+ return levels
def _read_abstract_num_level(element):
- level_index = element.attributes["w:ilvl"]
+ level_index = element.attributes.get("w:ilvl")
num_fmt = element.find_child_or_null("w:numFmt").attributes.get("w:val")
is_ordered = num_fmt != "bullet"
paragraph_style_id = element.find_child_or_null("w:pStyle").attributes.get("w:val")