Ignore:
Timestamp:
11/09/05 18:02:56 (8 years ago)
Author:
moschny
Message:

Rewrite the TOC structure parser, using a recursive algorithm instead
of an explicit stack.

The new method accepts table-of-contents with varying amounts of
indentation characters (unlike the current version of Trac itself,
where deeper levels must be indented by exactly two white spaces).

Furthermore, it "repairs" malformed TOCs by inserting dummy
nodes. Trac does this, too, but may insert more dummy nodes than our
method (because of the fixed amount of whitespace expected per level).

In any case, there shouldn't be any differences between Trac's and our
interpretation of the structure for most "well-formed" TOCs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trac/trunk/wiki-macros/TracNav.py

    r3053 r3054  
    114114 
    115115 
     116def getTocEntryAndNextIndent(g): 
     117    indent, link, label = g.next() 
     118    yield indent 
     119 
     120    ready = False 
     121    while not ready: 
     122        yield link, label 
     123        try: 
     124            indent, link, label = g.next() 
     125        except StopIteration: 
     126            indent, ready = -1, True 
     127        yield indent 
     128 
     129 
     130def _parseToc(g, nextIndent, level = 0): 
     131    list = [] 
     132    if nextIndent > level: 
     133        subList, nextIndent = _parseToc(g, nextIndent, level + 1) 
     134        if nextIndent < level: 
     135            # level is empty 
     136            return subList, nextIndent 
     137        else: 
     138            # broken indentation structure 
     139            list.append((None, None, subList)) 
     140    while 1: 
     141        if nextIndent == level: 
     142            (link, label), nextIndent = g.next(), g.next() 
     143            if nextIndent > level: 
     144                subList, nextIndent = _parseToc(g, nextIndent, level + 1) 
     145                list.append((link, label, subList)) 
     146            else: 
     147                list.append((link, label, None)) 
     148        else: 
     149            assert nextIndent < level 
     150            return list, nextIndent 
     151 
     152 
    116153def parseToc(tocText): 
    117     stack = [] 
    118     for indent, link, label in getTocEntry(tocText): 
    119  
    120         if len(stack) == 0: 
    121             stack.append((indent, [])) 
    122  
    123         (lastIndent, list) = stack[len(stack) - 1] 
    124  
    125         if indent > lastIndent: 
    126             stack.append((indent, [(link, label, None)])) 
    127         elif indent == lastIndent: 
    128             list.append((link, label, None)) 
    129         else: 
    130             while indent < lastIndent: 
    131                 (_, list) = stack.pop() 
    132                 (lastIndent, topList) = stack[len(stack) - 1] 
    133                 (topLink, topLabel, _) = topList[len(topList) - 1] 
    134                 topList[len(topList) - 1] = (topLink, topLabel, list) 
    135  
    136             (lastIndent, list) = stack[len(stack) - 1] 
    137             list.append((link, label, None)) 
    138                  
    139     while len(stack) > 1: 
    140         (_, list) = stack.pop() 
    141         (_, topList) = stack[len(stack) - 1] 
    142         (topLink, topLabel, _) = topList[len(topList) - 1] 
    143         topList[len(topList) - 1] = (topLink, topLabel, list) 
    144  
    145     (_, list) = stack.pop() 
     154    g = getTocEntryAndNextIndent(getTocEntry(tocText)) 
     155    list, _ = _parseToc(g, g.next()) 
    146156    return list 
    147  
     157    
    148158 
    149159def execute(hdf, args, env): 
Note: See TracChangeset for help on using the changeset viewer.