Это своего рода проблема стека / проблема графа. Давайте назовем это деревом. (или документ или что-то в этом роде.)
Я думаю, ваш первоначальный кортеж может быть улучшен. (текст, глубина, тип)
stack = []
depth = 0
broken_value = -1
current = {"title":"root", "contents":[]}
for item in list_of_tuples:
if item[1]>depth:
#deeper
next = { "title":item[0], "contents":[] }
current["contents"].append(next)
stack.append(current)
current=next
depth = item[1]
elif item[1]<depth:
#shallower closes current gets previous level
while depth>item[1]:
prev = stack.pop()
depth = depth-1
current = {"title":item[0], "content":[]}
stack[-1].append(current)
depth=item[1]
else:
#same depth
if item[2]==broken_value:
#<p> element gets added to current level.
current['contents'].append(item[0])
else:
#<h> element gets added to parent of current.
current = {"title":item[0], "content":[]}
stack[-1]["contents"].append(current)
broken_value = item[2]
Это создаст произвольный график глубины, который предполагает, что глубина увеличивается на 1, но может уменьшаться на произвольное число.
Вероятно, было бы лучше отслеживать глубину в словаре, чтобы вы могли перемещать более одной глубины за раз. Вместо просто «заголовок» и «контент» может быть «заголовок», «глубина» и «контент»
Пояснение
Стек отслеживает открытые элементы и наш текущий Элемент - это элемент, который мы строим.
Если мы находим глубину>, чем наша текущая глубина, то мы помещаем текущий элемент в стек (он все еще открыт) и начинаем работать со следующим элементом уровня.
Если глубина меньше текущего элемента, мы закроем текущий элемент и родительские элементы на одну глубину.
Наконец, если это та же самая глубина, мы решаем, является ли это только что добавленным элементом 'p', или другим 'h', который закрывает ток и начинает новый ток.