Changeset 3106


Ignore:
Timestamp:
08/23/06 20:02:56 (7 years ago)
Author:
moschny
Message:
  • Refactoring: Capture the state of one macro invocation in an instance of the new Invocation class. This way, fewer variables need to be passed around. Additionally, the indented output can be handled by methods, which is much cleaner.
  • Make 'WikiStart' the default for curpage, as suggested on the TracNav homepage.
  • Clean-ups.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trac/plugins/tracnav/tracnav/tracnav.py

    r3097 r3106  
    5656""" 
    5757__id__        = '$Id$' 
    58 __version__   = '3.92pre5' 
     58__version__   = '3.92pre6' 
    5959__revision__  = '$LastChangedRevision$' 
    6060 
     
    110110 
    111111 
    112 class TracNav(Component): 
    113  
    114     implements(IWikiMacroProvider, ITemplateProvider) 
    115  
    116     def get_toc(self, req, name): 
     112class Invocation(object): 
     113 
     114    def __init__(self, env, req, args, out): 
     115 
     116        #save for later use 
     117        self.env = env 
     118        self.req = req 
     119        self.out = out 
     120        self.col = 0 
     121         
     122        #needed several times 
     123        self.preview = req.args.get('preview', '') 
     124        self.curpage = req.args.get('page', 'WikiStart') 
     125        self.modify = req.perm.has_permission('WIKI_MODIFY') 
     126 
     127        # parse arguments 
     128        self.names = [] 
     129        self.collapse = True 
     130        if args: 
     131            for arg in args.split('|'): 
     132                if arg == 'nocollapse': 
     133                    self.collapse = False 
     134                else: 
     135                    self.names.append(arg) 
     136 
     137    def get_toc(self, name): 
    117138        """ 
    118139        Fetch the wiki page containing the toc, if available. 
    119140        """ 
    120         preview = req.args.get('preview', '') 
    121         curpage = req.args.get('page') 
    122  
    123         if preview and name == curpage: 
    124             return req.args.get('text', '') 
     141        if self.preview and name == self.curpage: 
     142            return self.req.args.get('text', '') 
    125143        elif WikiSystem(self.env).has_page(name): 
    126144            return WikiPage(self.env, name).text 
     
    128146            return '' 
    129147 
    130  
    131     def get_toc_entry(self, toc_text, req): 
     148    def get_toc_entry(self, toc_text): 
    132149        """ 
    133150        Parse and format the entries in toc_text. 
    134151        """ 
    135         formatter = TocFormatter(self.env, req) 
     152        formatter = TocFormatter(self.env, self.req) 
    136153        for match in LISTRULE.finditer(toc_text): 
    137154            indent = len(match.group('indent')) 
    138155            label, link = formatter.format_toc(match.group('rest')) 
    139156            yield indent, link, label 
    140  
    141157 
    142158    def get_toc_entry_and_indent(self, gen): 
     
    154170            yield indent 
    155171            yield link, label         
    156  
    157172 
    158173    def _parse_toc(self, gen, next_indent, level = 0): 
     
    179194                return toclist, next_indent 
    180195 
    181  
    182     def parse_toc(self, toc_text, req = None): 
     196    def parse_toc(self, toc_text): 
    183197        """ 
    184198        Recursively construct the toc tree using _parse_toc(). 
    185199        """ 
    186         gen = self.get_toc_entry(toc_text, req) 
    187         gen = self.get_toc_entry_and_indent(gen) 
     200        gen = self.get_toc_entry_and_indent(self.get_toc_entry(toc_text)) 
    188201        toc, _ = self._parse_toc(gen, gen.next()) 
    189202        return toc 
    190203 
    191  
    192     def execute(self, req, args): 
     204    def write(self, what): 
     205        self.out.write(' ' * self.col) 
     206        self.out.write(what) 
     207        return self 
     208 
     209    def indent_more(self): 
     210        self.col += 1 
     211        return self 
     212 
     213    def indent_less(self): 
     214        self.col -= 1 
     215        return self 
     216 
     217    def run(self): 
    193218        """ 
    194219        Main routine of the wiki macro. 
    195220        """ 
    196  
    197         #init 
    198         out = StringIO() 
    199         names = [] 
    200         collapse = True 
    201         curpage = req.args.get('page','') 
    202  
    203         # parse arguments 
    204         if args: 
    205             for arg in args.split('|'): 
    206                 if arg == 'nocollapse': 
    207                     collapse = False 
    208                 else: 
    209                     names.append(arg) 
    210          
    211221        # header 
    212         col = 0 
    213         out.write('%s<div class="wiki-toc trac-nav">\n' % self.i(col)) 
    214         col += 1 
    215         out.write('%s<h2><a href="%s">TracNav</a> menu</h2>\n' % \ 
    216                   (self.i(col), TRACNAVHOME)) 
     222        self.write('<div class="wiki-toc trac-nav">\n').indent_more() 
     223        self.write('<h2><a href="%s">TracNav</a> menu</h2>\n' % TRACNAVHOME) 
    217224 
    218225        # add TOCs 
    219         for name in (names or ["TOC"]): 
    220             toc_text = self.get_toc(req, name) 
    221             toc = self.parse_toc(toc_text, req) 
     226        for name in (self.names or ["TOC"]): 
     227            toc = self.parse_toc(self.get_toc(name)) 
    222228            if not toc: 
    223229                toc = self.parse_toc(' * TOC "%s" is empty!' % name) 
    224             if collapse: 
    225                 (found, filtered) = self.filter_toc(curpage, toc) 
    226                 if found: 
    227                     self.display_all(out, req, name, filtered, col) 
    228                 else: 
    229                     self.display_all(out, req, name, toc, col) 
     230            found, filtered = self.filter_toc(toc) 
     231            if (not self.collapse) or (not found): 
     232                self.display_all(name, toc) 
    230233            else: 
    231                 self.display_all(out, req, name, toc, col) 
    232  
    233         # footer  
    234         col -= 1 
    235         out.write('%s</div>\n' % self.i(col)) 
     234                self.display_all(name, filtered) 
     235 
     236        # footer 
     237        self.indent_less().write('</div>\n') 
    236238 
    237239        # add our stylesheet 
    238         add_stylesheet(req, 'tracnav/css/tracnav.css') 
    239  
    240         # emit  
    241         return out.getvalue() 
    242  
    243  
    244     def filter_toc(self, curpage, toc, level = 0): 
    245         found = 0 
     240        add_stylesheet(self.req, 'tracnav/css/tracnav.css') 
     241 
     242    def filter_toc(self, toc, level = 0): 
     243        found = False 
    246244        result = [] 
    247245        for name, title, sub in toc: 
    248246            if sub == None: 
    249                 if name == curpage: 
    250                     found = 1 
     247                if name == self.curpage: 
     248                    found = True 
    251249                result.append((name, title, None)) 
    252250            else: 
    253                 (subfound, subtoc) = self.filter_toc(curpage, sub, level + 1) 
     251                subfound, subtoc = self.filter_toc(sub, level + 1) 
    254252                if subfound: 
    255                     found = 1 
     253                    found = True 
    256254                if subfound or (name == None): 
    257255                    if level == 0 and name != None: 
     
    263261                else: 
    264262                    result.append((name, title, [])) 
    265         return (found, result) 
    266  
    267  
    268     def i(self, col): 
    269         return ' ' * col 
    270  
    271  
    272     def display_all(self, out, req, name, toc, col): 
    273         preview = req.hdf.getValue('args.preview', '') 
    274         curpage = req.hdf.getValue('wiki.page_name', '') 
    275  
    276         if (not preview) and req.hdf.getValue('trac.acl.WIKI_MODIFY', ''): 
    277             out.write('%s<div class="edit"><a href="%s?action=edit">edit</a></div>\n' % \ 
    278                     (self.i(col), self.env.href.wiki(name))) 
    279         out.write('%s<ul>\n' % self.i(col)) 
    280         col += 1 
    281         self.display(out, curpage, toc, 0, col) 
    282         col -= 1 
    283         out.write('%s</ul>\n' % self.i(col)) 
    284  
    285  
    286     def display(self, out, curpage, toc, depth, col): 
     263        return found, result 
     264 
     265    def display_all(self, name, toc): 
     266        if (not self.preview) and (self.modify): 
     267            self.write('<div class="edit"><a href="%s?action=edit">edit</a></div>\n' % \ 
     268                self.env.href.wiki(name)) 
     269        self.write('<ul>\n').indent_more() 
     270        self.display(toc, 0) 
     271        self.indent_less().write('</ul>\n') 
     272 
     273    def display(self, toc, depth): 
    287274        for name, title, sub in toc: 
    288275            li_style = ' style="padding-left: %dem;"' % (depth + 1) 
    289276            if sub == None: 
    290                 if name == curpage: 
     277                if name == self.curpage: 
    291278                    cls = ' class="active"' 
    292279                else: 
    293280                    cls = '' 
    294                 out.write('%s<li%s%s>%s</li>\n' % \ 
    295                         (self.i(col), li_style, cls, title)) 
     281                self.write('<li%s%s>%s</li>\n' % (li_style, cls, title)) 
    296282            else: 
    297                 out.write('%s<li%s>\n' % (self.i(col), li_style)) 
    298                 col += 1 
     283                self.write('<li%s>\n' % li_style).indent_more() 
    299284                if name == None or sub: 
    300                     out.write('%s<h4>%s</h4>\n' % (self.i(col), title)) 
    301                 else: 
    302                     out.write('%s<h4>%s...</h4>\n' % (self.i(col), title)) 
    303                 col -= 1 
    304                 out.write('%s</li>\n' % self.i(col)) 
     285                    self.write('<h4>%s</h4>\n' % title) 
     286                else: 
     287                    self.write('<h4>%s...</h4>\n' % title) 
     288                self.indent_less().write('</li>\n') 
    305289                if len(sub) > 0: 
    306                     self.display(out, curpage, sub, depth + 1, col) 
    307  
     290                    self.display(sub, depth + 1) 
     291 
     292 
     293class TracNav(Component): 
     294 
     295    implements(IWikiMacroProvider, ITemplateProvider) 
    308296 
    309297    def get_macros(self): 
    310298        yield 'TracNav' 
    311         yield 'JPNav' 
    312  
     299        yield 'JPNav' # legacy 
    313300 
    314301    def render_macro(self, req, name, args): 
    315         return self.execute(req, args) 
    316      
     302        out = StringIO() 
     303        Invocation(self.env, req, args, out).run() 
     304        return out.getvalue() 
    317305 
    318306    def get_macro_description(self, name): 
     
    320308        return getdoc(getmodule(self)) 
    321309 
    322  
    323310    def get_htdocs_dirs(self): 
    324311        from pkg_resources import resource_filename 
    325312        return [('tracnav', resource_filename(__name__, 'htdocs'))] 
    326313 
    327  
    328314    def get_templates_dirs(self): 
    329315        # we don't provide templates 
    330316        return [] 
    331      
Note: See TracChangeset for help on using the changeset viewer.