Changeset 3054


Ignore:
Timestamp:
Nov 9, 2005 6:02:56 PM (9 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.