How to generate a <ul> <li> tree without recursive use with python or another language?

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

exit:

 <ul> <li> Introduction <ul> <li>Sub Intro</li> </ul> </li> <li>Module 1</li> </ul> 
+4
source share
2 answers

To create nested lists without recursion, you simply track your level of nesting, increasing it when you go to deeper levels of nesting and decreasing it as you move backward.

A natural approach to handling things like closing tags would be to maintain a simple stack (Python list) and push the closing tags on it when you insert their respective opening tags into the output stream. Then you push them when you cross any level of nesting.

You are not saying anything about your input format ... so let it pretend it looks something like this:

 = Introduction == Sub Intro = Module 1 

Then something like:

  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 

... should do the trick (albeit rather rudely).

Please note that I do not actually apply the rule that you only need to increase the level of nesting in steps of one. A degenerate input that goes from = to ====== in one step generates extraneous tags and pops extraneous tags onto the close stack.

Note. I answer only the explicit question of how to handle nesting without recursion. One could conclude from your example (using HTML unordered list tags) that your real goal is to generate valid HTML. In this case, there are many Python tools that are much better suited for this task than any crude text manipulations I do in this example. A Yahoo or Google search in: Python "generates HTML" will return many thousands of pages about how to do this and the many tools available for this.

(I remember that I used HTMLgen a few years ago, and I see that it is still available as a Debian package, but it seems to have fallen from PyPI ... Python package index. Undoubtedly, much more recent updates Most people seem to use template engines like Genshi or Mako for example).

+2
source

Maybe something like this:

 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]) 
-1
source

Source: https://habr.com/ru/post/1309730/


All Articles