Как создать дерево <ul><li> без рекурсии, используя python или другой язык? - PullRequest
4 голосов
/ 14 мая 2010
class tree:
    def __init__(self, name='a', childs=[]):
        self.name = name
        self.childs = childs

выход:

<ul>
    <li>
    Introduction
    <ul>
        <li>Sub Intro</li>
    </ul>
    </li>

    <li>Module 1</li>
</ul>

Ответы [ 2 ]

2 голосов
/ 14 мая 2010

Чтобы создать вложенные списки без рекурсии, вы просто должны отслеживать свой уровень вложенности, увеличивая его при переходе к более глубоким уровням вложенности и уменьшая при переходе обратно вверх.

Естественный подход для обработки таких вещей, как закрытие тегов, заключается в том, чтобы поддерживать простой стек (список Python) и помещать на него закрывающие теги при вставке их соответствующих открывающих тегов в выходной поток. Затем вы вытолкаете их, когда переходите из любого уровня вложенности.

Вы ничего не говорите о своем формате ввода ... так что давайте представим, что он выглядит примерно так:

= Introduction
== Sub Intro
= Module 1

Тогда что-то вроде:

 def pref_txt_to_ul(txt):
    nesting = 0
    closing_tags = list()
    for x in txt:
        if len(x.split()) < 2:
            continue
        prefix, content = x.split(None,1)
        nd = len(prefix)           ## new depth
        assert prefix == "=" * nd  ## First "word" is all = characters

        if nd > nesting:
            print "\n", " " * nesting * 4, "<ul>" * (nd - nesting), ## Push new opening tags into output
            closing_tags.append('</ul>' * (nd - nesting))  ## push closing tags for later
        elif nd < nesting:
            for x in range(nesting - nd):
                if closing_tags:
                    print " " * nesting * 4, closing_tags.pop(),  ## Pop closing tags
        nesting = nd
        print "\n", " " * nesting * 4, "<li>%s</li>" % content,  # push out this item (at new depth)
    ## After all text is done:
    while closing_tags:
        print closing_tags.pop(),   # Pop off remaining cloing tags

... должен сделать свое дело (хотя и довольно грубо).

Обратите внимание, что на самом деле я не соблюдаю правило, согласно которому уровень вложенности следует увеличивать только с шагом в 1. Вырожденный ввод, переходящий от = к ====== за один шаг, будет генерировать посторонние теги и помещать посторонние теги в закрывающий стек.

Примечание: я отвечаю только на явный вопрос о том, как обрабатывать вложение без рекурсии. Из вашего примера можно сделать вывод (используя теги неупорядоченного списка HTML), что ваша реальная цель - создать правильный HTML. В этом случае есть множество инструментов Python, которые гораздо лучше подходят для этой задачи, чем любой грубый текст, который я делаю в этом примере. Поиск Yahoo или Google по: Python "генерирует HTML" вернет многие тысячи страниц о способах сделать это и о многих доступных инструментах для этого.

(Я помню, что я использовал HTMLgen несколько лет назад, и я вижу, что он все еще доступен в виде пакета Debian, но, похоже, он упал с PyPI ... индекса пакетов Python. Несомненно, есть гораздо более недавно обновленные пакеты Кажется, что большинство людей используют шаблоны, такие как Genshi или Mako, например).

0 голосов
/ 14 мая 2010

Может быть, что-то вроде этого:

NEW=object()
END=object()

class tree:
    def __init__(self, name='a', childs=[]):
        self.name = name
        self.childs = childs

    def __str__(self):
        indent=0
        result=[]
        for i in self.childs:
            if i is NEW:
                result.append('%s<ul>\n'%('    '*indent))
                indent+=1
            elif i is END:                
                indent-=1
                result.append('%s</ul>\n'%('    '*indent))
            else:
                result.append('%s<li>%s</li>\n'%('    '*indent, i))
        return ''.join(result)



print tree('test', [NEW, 'Introduction', NEW, 'Sub Intro', END, 'Module 1', END])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...