Changeset 3057


Ignore:
Timestamp:
Nov 24, 2005 11:13:47 AM (11 years ago)
Author:
moschny
Message:

Use the OneLineFormatter of Trac's wiki system instead of our own
parsing routine. This has the advantage that the toc entries can
contain any wiki syntax element recognized by the OneLineFormatter.

This should close #247 and #252, although the collapse/expand
mechanism currently doesn't work for pages referenced indirectly
through references to any of their paragraphs.

File:
1 edited

Legend:

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

    r3056 r3057  
    7373from trac.wiki.api import WikiSystem
    7474from trac.wiki.model import WikiPage
    75 
    76 LISTRULE = re.compile(r"""^(?P<indent> *)\* +"""
    77                       r"""(?:(?P<wikilink>\[wiki:"""
    78                       r"""(?P<link>(&#34;([^&#34;]*)&#34;|"""
    79                       r"""'([^']*)')|([^ \]]+))"""
    80                       r"""+(?P<label>[^\]]*)\])|(?P<text>.*))""",
    81                       re.M)
     75from trac.wiki.formatter import OneLinerFormatter
     76from StringIO import StringIO
    8277
    8378TRACNAVHOME = "http://svn.ipd.uka.de/trac/javaparty/wiki/TracNav"
     79LISTRULE = re.compile(r"^(?P<indent> +)\* +(?P<rest>.*)$", re.M)
    8480
    8581def get_toc(hdf, env, curpage, name):
    86     """Fetch the wiki page containing the toc, if available."""
    87    
    88     toc_text = "* Table of contents"
     82    """
     83    Fetch the wiki page containing the toc, if available.
     84    """
     85    toc_text = " * Table of contents"
    8986
    9087    preview = hdf.getValue('args.preview', "")
    9188    if preview and (name == curpage):
    9289        toc_text = hdf.getValue('wiki.page_source', toc_text);
    93     else:
    94         if WikiSystem(env).has_page(name):
    95             toc_text = WikiPage(env, name).text
    96 
    97     # env.log.debug(tocText)
     90    elif WikiSystem(env).has_page(name):
     91        toc_text = WikiPage(env, name).text
    9892    return toc_text
    9993
    10094
    101 def get_toc_entry(toc_text):
    102     """Generator: returns the next toc entry. Each toc entry consists
    103     of it's indentation level, label and link."""
    104     next_pos = 0
    105     while 1:
    106         match = LISTRULE.search(toc_text, next_pos)
    107         if not match:
    108             # env.log.debug("No more matches")
    109             return
    110 
     95class TocFormatter(OneLinerFormatter):
     96    """
     97    Basically the OneLinerFormatter, but additionally remembers the
     98    last wiki link.
     99    """
     100
     101    def format_toc(self, wikitext, out):
     102        OneLinerFormatter.format(self, wikitext, out)
     103        return self.link
     104
     105    def __init__(self, env):
     106        OneLinerFormatter.__init__(self, env)
     107        self.link = None
     108        self.myenv = env
     109
     110    def _make_link(self, namespace, target, match, label):
     111        if namespace == 'wiki':
     112            self.link = target
     113        return OneLinerFormatter._make_link(
     114            self, namespace, target, match, label)
     115
     116    # FIXME: what about _make_relative_link() ?
     117    # FIXME: CamelCase links are special and not handled by the Formatter...
     118
     119def format_toc_entry(wikitext, env):
     120    out = StringIO()
     121    link = TocFormatter(env).format_toc(wikitext, out)
     122    return out.getvalue(), link
     123
     124
     125def get_toc_entry(toc_text, env):
     126    """
     127    Filter the toc_text for toc entries.
     128    """
     129    for match in LISTRULE.finditer(toc_text):
    111130        indent = len(match.group('indent'))
    112         if match.group('wikilink'):
    113             link = match.group('link')
    114             label = match.group('label')
    115         else:
    116             link = None
    117             label = match.group('text')
    118 
    119         # if link == None:
    120         #     env.log.debug(label + " ---")
    121         # else:
    122         #     env.log.debug(label + ": " + link)
    123    
     131        label, link = format_toc_entry(match.group('rest'), env)
     132        # env.log.debug("link is '%s'" % link)
    124133        yield indent, link, label
    125         next_pos = match.end()
    126134
    127135
    128136def get_toc_entry_and_indent(gen):
    129     """Generator, to be used as a filter for get_toc_entry().  Returns
    130     link and label of the current toc entry and the indentation level
    131     of the next entry or -1 if there are no more entries. The first
    132     call to next() returns the indentation of the first entry."""
    133    
     137    """
     138    Filter for get_toc_entry().  Returns link and label of the current
     139    toc entry and the indentation level of the next entry or -1 if
     140    there are no more entries. The first call to next() returns the
     141    indentation of the first entry.
     142    """
    134143    try:
    135144        indent, link, label = gen.next()
     
    152161    if next_indent > level:
    153162        sublist, next_indent = _parse_toc(gen, next_indent, level + 1)
    154         if next_indent < level:
    155             # level is empty
     163        if next_indent < level: # level is empty
    156164            return sublist, next_indent
    157         else:
    158             # broken indentation structure
     165        else:                   # broken indentation structure
    159166            toclist.append((None, None, sublist))
    160167    while 1:
     
    171178
    172179
    173 def parse_toc(toc_text):
    174     gen = get_toc_entry_and_indent(get_toc_entry(toc_text))
     180def parse_toc(toc_text, env):
     181    gen = get_toc_entry_and_indent(get_toc_entry(toc_text, env))
    175182    toclist, _ = _parse_toc(gen, gen.next())
    176183    return toclist
     
    184191        name = 'TOC'
    185192
    186     toc = parse_toc(get_toc(hdf, env, curpage, name))
     193    toc = parse_toc(get_toc(hdf, env, curpage, name), env)
    187194    if not toc:
    188195        msg = '<div class="system-message">' \
     
    255262            else:
    256263                cls = ''
    257             html += '%s<li%s%s>' % (indentation(col), li_style, cls)
    258             if name == None:
    259                 html += title
    260             else:
    261                 html += '<a href="%s">%s</a>' % (env.href.wiki(name), title)
    262             html += '</li>\n'
     264            html += '%s<li%s%s>%s</li>\n' % \
     265                    (indentation(col), li_style, cls, title)
    263266        else:
    264267            html += '%s<li%s>\n' % (indentation(col), li_style)
    265268            col += 1
    266             if name == None or len(sub) > 0:
    267                 html += '%s<h4>%s</h4>\n' % (indentation(col), title)
    268             else:
    269                 html += '%s<h4><a href="%s">%s</a>...</h4>\n' % \
    270                         (indentation(col), env.href.wiki(name), title)
     269            if name == None or sub:
     270                html += '%s<h4>%s</h4>\n' % \
     271                        (indentation(col), title)
     272            else:
     273                html += '%s<h4>%s...</h4>\n' % \
     274                        (indentation(col), title)
    271275            col -= 1
    272276            html += '%s</li>\n' % indentation(col)
Note: See TracChangeset for help on using the changeset viewer.