Attachment 'NewTableOfContents-1.3.4.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - TableOfContents Macro
   4 
   5     Optional integer argument: maximal depth of listing.
   6 
   7     @copyright: 2000, 2001, 2002 by Jürgen Hermann <jh@web.de>
   8     @license: GNU GPL, see COPYING for details.
   9 """
  10 
  11 import re, sha
  12 from MoinMoin import config, wikiutil
  13 
  14 #Dependencies = ["page"]
  15 Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
  16 
  17 # from macro Include (keep in sync!)
  18 _arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
  19 _arg_level = r',\s*(?P<level>\d*)'
  20 _arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
  21 _arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
  22 _arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
  23 _arg_items = r'(,\s*items=(?P<items>\d+))?'
  24 _arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
  25 _arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
  26 _arg_editlink = r'(,\s*(?P<editlink>editlink))?'
  27 _args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % (
  28     _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
  29     _arg_skipitems, _arg_titlesonly, _arg_editlink)
  30 
  31 # from Include, too, but with extra htext group around header text
  32 _title_re = r"^(?P<heading>\s*(?P<hmarker>=+)\s(?P<htext>.*)\s(?P=hmarker))$"
  33 
  34 class TableOfContents:
  35     """
  36     TOC Macro wraps all global variables without disturbing threads
  37     """
  38 
  39     def __init__(self, macro, args):
  40         self.macro = macro
  41         
  42         self.inc_re = re.compile(r"^\[\[Include\((.*)\)\]\]")
  43         self.arg_re = re.compile(_args_re_pattern)
  44         self.head_re = re.compile(_title_re) # single lines only
  45         self.pre_re = re.compile(r'\{\{\{.+?\}\}\}', re.S)
  46         
  47         self.result = []
  48         self.baseindent = 0
  49         self.indent = 0
  50         self.lineno = 0
  51         self.titles = {}
  52 
  53         self.include_macro = None
  54 
  55         if args:
  56             self.arglist = args.split(',')
  57         else:
  58             self.arglist = ''
  59 
  60         try:
  61             self.mindepth = int(macro.request.getPragma('section-numbers', 1))
  62         except (ValueError, TypeError):
  63             self.mindepth = 1
  64 
  65         try:
  66             self.maxdepth = max(int(self.arglist[0]), 1)
  67         except (IndexError, ValueError, TypeError):
  68             self.maxdepth = 99
  69 
  70         try:
  71             self.startdepth = min(int(self.arglist[1]), self.maxdepth)
  72         except (IndexError, ValueError, TypeError):
  73             self.startdepth = 1
  74 
  75     def IncludeMacro(self, *args, **kwargs):
  76         if self.include_macro is None:
  77             self.include_macro = wikiutil.importPlugin(self.macro.request.cfg,
  78                                                        'macro', "Include")
  79         return self.pre_re.sub('',apply(self.include_macro, args, kwargs)).split('\n')
  80 
  81     def run(self):
  82         self.process_lines(self.pre_re.sub('',self.macro.parser.raw).split('\n'),
  83                            self.macro.formatter.page.page_name)
  84         # Close pending lists
  85         for i in range(self.baseindent, self.indent):
  86             self.result.append(self.macro.formatter.listitem(0))
  87             self.result.append(self.macro.formatter.number_list(0))
  88         return '\n'.join(self.result)
  89 
  90     def process_lines(self, lines, pagename):
  91         for line in lines:
  92             # Filter out the headings
  93             self.lineno = self.lineno + 1
  94             match = self.inc_re.match(line)
  95             if match:
  96                 # this is an [[Include()]] line.
  97                 # now parse the included page and do the work on it.
  98 
  99                 ## get heading and level from Include() line.
 100                 tmp = self.arg_re.match(match.group(1))
 101                 if tmp and tmp.group("name"):
 102                     inc_pagename = tmp.group("name")
 103                 else:
 104                     # no pagename?  ignore it
 105                     continue
 106                 if tmp.group("heading"):
 107                     if tmp.group("htext"):
 108                         heading = tmp.group("htext")
 109                     else:
 110                         heading = inc_pagename
 111                     if tmp.group("level"):
 112                         level = int(tmp.group("level"))
 113                     else:
 114                         level = 1
 115                     inc_page_lines = ["%s %s %s" %("=" * level, heading, "=" * level)]
 116                 else:
 117                     inc_page_lines = []
 118 
 119                 inc_page_lines = inc_page_lines + self.IncludeMacro(self.macro, match.group(1), called_by_toc=1)
 120                 
 121                 self.process_lines(inc_page_lines, inc_pagename)
 122             else:
 123                 self.parse_line(line, pagename)
 124 
 125     def parse_line(self, line, pagename):
 126         # FIXME this also finds "headlines" in {{{ code sections }}}:
 127         match = self.head_re.match(line)
 128         if not match: return
 129         title_text = match.group('htext').strip()
 130         pntt = pagename + title_text
 131         self.titles.setdefault(pntt, 0)
 132         self.titles[pntt] += 1
 133 
 134         # Get new indent level
 135         newindent = len(match.group('hmarker'))
 136         if newindent > self.maxdepth: return
 137         if newindent < self.startdepth: return
 138         if newindent < self.mindepth: return
 139         if not self.indent:
 140             self.baseindent = newindent - 1
 141             self.indent = self.baseindent
 142 
 143         # Close lists
 144         for i in range(0,self.indent-newindent):
 145             self.result.append(self.macro.formatter.listitem(0))
 146             self.result.append(self.macro.formatter.number_list(0))
 147 
 148         # Open Lists
 149         for i in range(0,newindent-self.indent):
 150             self.result.append(self.macro.formatter.number_list(1))
 151 
 152         # Add the heading
 153         unique_id = ''
 154         if self.titles[pntt] > 1:
 155             unique_id = '-%d' % (self.titles[pntt],)
 156 
 157         if self.indent == newindent:
 158             self.result.append(self.macro.formatter.listitem(0))
 159             
 160         self.result.append(self.macro.formatter.listitem(1))
 161         self.result.append(self.macro.formatter.anchorlink(1,
 162             "head-" + sha.new(pntt.encode(config.charset)).hexdigest() + unique_id) +
 163                            self.macro.formatter.text(title_text) +
 164                            self.macro.formatter.anchorlink(0))
 165 
 166         # Set new indent level
 167         self.indent = newindent
 168 
 169 def execute(macro, args):
 170     toc=TableOfContents(macro,args)
 171     return toc.run()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-07-12 02:26:49, 6.3 KB) [[attachment:NewTableOfContents-1.3.4.py]]
  • [get | view] (2005-05-01 18:12:47, 2.6 KB) [[attachment:README]]
  • [get | view] (2003-12-07 18:15:55, 1.3 KB) [[attachment:TableOfContents-startdepth.diff]]
  • [get | view] (2005-06-25 14:38:34, 4.3 KB) [[attachment:moin-1.3.4-rss_rc.py-per_page_feeds.patch]]
  • [get | view] (2005-06-09 20:25:52, 10.1 KB) [[attachment:moin-cache-friendly.diff]]
  • [get | view] (2005-04-27 17:22:13, 2.3 KB) [[attachment:moin-negotiate-auth.diff]]
  • [get | view] (2005-04-04 05:12:33, 18.0 KB) [[attachment:moinmoin-1.3.4-editor-insert-patch.diff]]
  • [get | view] (2005-04-04 05:50:16, 43.3 KB) [[attachment:moinmoin-1.3.4-editor-insert-screenshot.png]]
  • [get | view] (2005-08-17 20:24:31, 18.1 KB) [[attachment:moinmoin-1.3.5-editor-insert-patch.diff]]
  • [get | view] (2003-12-07 18:15:55, 13.0 KB) [[attachment:multisearch.diff]]
  • [get | view] (2005-06-14 14:45:06, 0.8 KB) [[attachment:vary-cookie.diff]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.