@@ -27,60 +27,59 @@ def order_toc_list(toc_list):
2727 [{'level': 1}, {'level': 2}]
2828 =>
2929 [{'level': 1, 'children': [{'level': 2, 'children': []}]}]
30-
30+
3131 A wrong list is also converted:
3232 [{'level': 2}, {'level': 1}]
3333 =>
3434 [{'level': 2, 'children': []}, {'level': 1, 'children': []}]
3535 """
36-
37- def build_correct (remaining_list , prev_elements = [{'level' : 1000 }]):
38-
39- if not remaining_list :
40- return [], []
41-
42- current = remaining_list .pop (0 )
43- if not 'children' in current .keys ():
44- current ['children' ] = []
45-
46- if not prev_elements :
47- # This happens for instance with [8, 1, 1], ie. when some
48- # header level is outside a scope. We treat it as a
49- # top-level
50- next_elements , children = build_correct (remaining_list , [current ])
51- current ['children' ].append (children )
52- return [current ] + next_elements , []
53-
54- prev_element = prev_elements .pop ()
55- children = []
56- next_elements = []
57- # Is current part of the child list or next list?
58- if current ['level' ] > prev_element ['level' ]:
59- #print "%d is a child of %d" % (current['level'], prev_element['level'])
60- prev_elements .append (prev_element )
61- prev_elements .append (current )
62- prev_element ['children' ].append (current )
63- next_elements2 , children2 = build_correct (remaining_list , prev_elements )
64- children += children2
65- next_elements += next_elements2
66- else :
67- #print "%d is ancestor of %d" % (current['level'], prev_element['level'])
68- if not prev_elements :
69- #print "No previous elements, so appending to the next set"
70- next_elements .append (current )
71- prev_elements = [current ]
72- next_elements2 , children2 = build_correct (remaining_list , prev_elements )
73- current ['children' ].extend (children2 )
36+
37+ ordered_list = []
38+ if len (toc_list ):
39+ # Initialize everything by processing the first entry
40+ last = toc_list .pop (0 )
41+ last ['children' ] = []
42+ levels = [last ['level' ]]
43+ ordered_list .append (last )
44+ parents = []
45+
46+ # Walk the rest nesting the entries properly
47+ while toc_list :
48+ t = toc_list .pop (0 )
49+ current_level = t ['level' ]
50+ t ['children' ] = []
51+
52+ # Reduce depth if current level < last item's level
53+ if current_level < levels [- 1 ]:
54+ # Pop last level since we know we are less than it
55+ levels .pop ()
56+
57+ # Pop parents and levels we are less than or equal to
58+ to_pop = 0
59+ for p in reversed (parents ):
60+ if current_level <= p ['level' ]:
61+ to_pop += 1
62+ else :
63+ break
64+ if to_pop :
65+ levels = levels [:- to_pop ]
66+ parents = parents [:- to_pop ]
67+
68+ # Note current level as last
69+ levels .append (current_level )
70+
71+ # Level is the same, so append to the current parent (if available)
72+ if current_level == levels [- 1 ]:
73+ (parents [- 1 ]['children' ] if parents else ordered_list ).append (t )
74+
75+ # Current level is > last item's level,
76+ # So make last item a parent and append current as child
7477 else :
75- #print "Previous elements, comparing to those first"
76- remaining_list .insert (0 , current )
77- next_elements2 , children2 = build_correct (remaining_list , prev_elements )
78- children .extend (children2 )
79- next_elements += next_elements2
80-
81- return next_elements , children
82-
83- ordered_list , __ = build_correct (toc_list )
78+ last ['children' ].append (t )
79+ parents .append (last )
80+ levels .append (current_level )
81+ last = t
82+
8483 return ordered_list
8584
8685
0 commit comments