Skip to content

Commit 389aba6

Browse files
committed
Skip parsing bullet items for parent/child map
1 parent b4a2131 commit 389aba6

File tree

2 files changed

+109
-6
lines changed

2 files changed

+109
-6
lines changed

pydocx/export/numbering_span.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ def _get_component_item(self, component, to_tuple=False):
253253

254254
return item
255255

256-
def detect_parent_child_map_for_items(self):
256+
def detect_parent_child_map_for_items(self, skip_bullets=True):
257257
"""
258258
There are cases when we have span inside an item and this span is different from
259259
the parent one.
@@ -302,6 +302,19 @@ def detect_parent_child_map_for_items(self):
302302

303303
components_reversed_list = list(reversed(components))
304304
for i, component in enumerate(components[:-1]):
305+
# TODO@geo This is a hack so solve a issue with one document.
306+
# To properly implement lists I think we should not use ul/ol at all and instead
307+
# mimic lists using tags like <p>, like:
308+
# <p>1. Item 1</p>
309+
# <p>2. Item 1</p>
310+
311+
# We only require to find the parent/child hierarchy for lists that have incremented numbers/letters
312+
# such as: decimal, letter, roman
313+
# For bullet we can skip this
314+
if skip_bullets:
315+
level = component.get_numbering_level()
316+
if level and level.is_bullet_format():
317+
continue
305318
parent_item = self._get_component_item(component)
306319
nums = []
307320
outer_item_found = False

tests/export/test_numbering_span.py

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ def assertDictEqual(self, d1, d2, msg=None):
391391
if d1 != d2:
392392
raise AssertionError("Dicts do not match: %s" % msg)
393393

394-
def create_container(self):
395-
xml = '''
394+
def create_container(self, xml=None):
395+
default_xml = '''
396396
<numbering>
397397
<abstractNum abstractNumId="1">
398398
<lvl ilvl="0"></lvl>
@@ -437,6 +437,7 @@ def create_container(self):
437437
</numbering>
438438
'''
439439

440+
xml = xml or default_xml
440441
numbering = self._load_from_xml(xml)
441442

442443
container = type(
@@ -450,7 +451,7 @@ def create_container(self):
450451

451452
return container
452453

453-
def create_numbering_paragraph(self, num_id, level_id='0', container=True):
454+
def create_numbering_paragraph(self, num_id, level_id='0', container=None, ):
454455
paragraph_params = {
455456
'properties': ParagraphProperties(
456457
numbering_properties=NumberingProperties(
@@ -460,8 +461,10 @@ def create_numbering_paragraph(self, num_id, level_id='0', container=True):
460461
)
461462
}
462463

463-
if container:
464-
paragraph_params['container'] = self.create_container()
464+
if container is None:
465+
container = self.create_container()
466+
467+
paragraph_params['container'] = container
465468

466469
return Paragraph(**paragraph_params)
467470

@@ -756,3 +759,90 @@ def test_nested_sublist_parent_contains_child_and_child_parent(self):
756759
self.assertDictEqual(builder.parent_child_num_map, parent_items)
757760
self.assertDictEqual(builder.child_parent_num_map, child_item)
758761
self.assertTrue(result)
762+
763+
def test_skip_bullets_listing_items(self):
764+
xml = '''
765+
<numbering>
766+
<abstractNum abstractNumId="1">
767+
<lvl ilvl="0">
768+
<numFmt val="decimal"/>
769+
</lvl>
770+
</abstractNum>
771+
<num numId="1">
772+
<abstractNumId val="1" />
773+
</num>
774+
<abstractNum abstractNumId="2">
775+
<lvl ilvl="0">
776+
<numFmt val="decimal"/>
777+
</lvl>
778+
</abstractNum>
779+
<num numId="2">
780+
<abstractNumId val="2" />
781+
</num>
782+
<abstractNum abstractNumId="3">
783+
<lvl ilvl="0">
784+
<numFmt val="bullet"/>
785+
</lvl>
786+
<lvl ilvl="1">
787+
<numFmt val="bullet"/>
788+
</lvl>
789+
</abstractNum>
790+
<num numId="3">
791+
<abstractNumId val="3" />
792+
</num>
793+
<abstractNum abstractNumId="4">
794+
<lvl ilvl="0">
795+
<numFmt val="bullet"/>
796+
</lvl>
797+
</abstractNum>
798+
<num numId="4">
799+
<abstractNumId val="4" />
800+
</num>
801+
<abstractNum abstractNumId="5">
802+
<lvl ilvl="0">
803+
<numFmt val="bullet"/>
804+
</lvl>
805+
</abstractNum>
806+
<num numId="5">
807+
<abstractNumId val="5" />
808+
</num>
809+
</numbering>
810+
'''
811+
812+
container = self.create_container(xml)
813+
components = [
814+
self.create_numbering_paragraph('1', '0', container=container),
815+
self.create_numbering_paragraph('3', '0', container=container),
816+
self.create_numbering_paragraph('3', '1', container=container),
817+
self.create_numbering_paragraph('4', '0', container=container),
818+
self.create_numbering_paragraph('3', '0', container=container),
819+
self.create_numbering_paragraph('1', '0', container=container),
820+
self.create_numbering_paragraph('2', '0', container=container),
821+
self.create_numbering_paragraph('5', '0', container=container),
822+
self.create_numbering_paragraph('2', '0', container=container),
823+
]
824+
825+
builder = NumberingSpanBuilder(components)
826+
result = builder.detect_parent_child_map_for_items()
827+
828+
parent_items = {
829+
('1', '0'):
830+
[
831+
{'num_id': '3', 'level': '0'},
832+
{'num_id': '3', 'level': '1'},
833+
{'num_id': '4', 'level': '0'},
834+
],
835+
('2', '0'):
836+
[
837+
{'num_id': '5', 'level': '0'},
838+
]
839+
}
840+
child_item = {
841+
'3': {'num_id': '1', 'level': '0'},
842+
'4': {'num_id': '1', 'level': '0'},
843+
'5': {'num_id': '2', 'level': '0'},
844+
}
845+
846+
self.assertDictEqual(builder.parent_child_num_map, parent_items)
847+
self.assertDictEqual(builder.child_parent_num_map, child_item)
848+
self.assertTrue(result)

0 commit comments

Comments
 (0)