1. 2006-04-06点记macro hack

1.1. TableOfContents

   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黵gen Hermann <[email protected]>
   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>(?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         try:
  56             self.mindepth = int(macro.request.getPragma('section-numbers', 1))
  57         except (ValueError, TypeError):
  58             self.mindepth = 1
  59 
  60         try:
  61             self.maxdepth = max(int(args), 1)
  62         except (ValueError, TypeError):
  63             self.maxdepth = 99
  64 
  65     def IncludeMacro(self, *args, **kwargs):
  66         if self.include_macro is None:
  67             self.include_macro = wikiutil.importPlugin(self.macro.request.cfg,
  68                                                        'macro', "Include")
  69         return self.pre_re.sub('',apply(self.include_macro, args, kwargs)).split('\n')
  70 
  71     def run(self):
  72         self.process_lines(self.pre_re.sub('',self.macro.parser.raw).split('\n'),
  73                            self.macro.formatter.page.page_name)
  74         # Close pending lists
  75         for i in range(self.baseindent, self.indent):
  76             self.result.append(self.macro.formatter.listitem(0))
  77             self.result.append(self.macro.formatter.number_list(0))
  78         #Zoomq:050425 add div for TableOfContents
  79         cntTree = '\n'.join(self.result)
  80         return "<div id='TableOfContents'>"+cntTree+"</div>"
  81         #return '\n'.join(self.result)
  82 
  83 
  84     def process_lines(self, lines, pagename):
  85         for line in lines:
  86             # Filter out the headings
  87             self.lineno = self.lineno + 1
  88             match = self.inc_re.match(line)
  89             if match:
  90                 # this is an [[Include()]] line.
  91                 # now parse the included page and do the work on it.
  92 
  93                 ## get heading and level from Include() line.
  94                 tmp = self.arg_re.match(match.group(1))
  95                 if tmp and tmp.group("name"):
  96                     inc_pagename = tmp.group("name")
  97                 else:
  98                     # no pagename?  ignore it
  99                     continue
 100                 if tmp.group("heading"):
 101                     if tmp.group("htext"):
 102                         heading = tmp.group("htext")
 103                     else:
 104                         heading = inc_pagename
 105                     if tmp.group("level"):
 106                         level = int(tmp.group("level"))
 107                     else:
 108                         level = 1
 109                     inc_page_lines = ["%s %s %s" %("=" * level, heading, "=" * level)]
 110                 else:
 111                     inc_page_lines = []
 112 
 113                 inc_page_lines = inc_page_lines + self.IncludeMacro(self.macro, match.group(1), called_by_toc=1)
 114 
 115                 self.process_lines(inc_page_lines, inc_pagename)
 116             else:
 117                 self.parse_line(line, pagename)
 118 
 119     def parse_line(self, line, pagename):
 120         # FIXME this also finds "headlines" in {{{ code sections

:

  • match = self.head_re.match(line) if not match: return title_text = match.group('htext').strip() pntt = pagename + title_text self.titles.setdefault(pntt, 0) self.titles[pntt] += 1 # Get new indent level newindent = len(match.group('hmarker'))

    if newindent > self.maxdepth: return if newindent < self.mindepth: return if not self.indent:

    • self.baseindent = newindent - 1 self.indent = self.baseindent
    # Close lists for i in range(0,self.indent-newindent):
    • self.result.append(self.macro.formatter.listitem(0)) self.result.append(self.macro.formatter.number_list(0))
    # Open Lists for i in range(0,newindent-self.indent):
    • self.result.append(self.macro.formatter.number_list(1)) self.result.append(self.macro.formatter.listitem(1))
    # Add the heading

    unique_id = if self.titles[pntt] > 1:

    • unique_id = '-%d' % (self.titles[pntt],)
    # close last listitem if same level if self.indent == newindent:
    • self.result.append(self.macro.formatter.listitem(0))

    if self.indent >= newindent:

    • self.result.append(self.macro.formatter.listitem(1))
    self.result.append(self.macro.formatter.anchorlink(1,
    • "head-" + sha.new(pntt.encode(config.charset)).hexdigest() + unique_id) +
      • self.macro.formatter.text(title_text) + self.macro.formatter.anchorlink(0))
    # Set new indent level self.indent = newindent

def execute(macro, args):

}}}

这样一来,CSS配合一下子:

#TableOfContents {
    float: right;
    border: 3px solid #B8C5D9;
    background-color: whitesmoke;
    margin: 0px 0px 0px 5px;
    padding: 2px;
}
/* 忽略包含在表格中的索引
 */
table div #TableOfContents {
    float: none;
    border: 2px dashed #fff;
    background-color: whitesmoke;
    padding: 4px;
}

就是啄木鸟现在的效果了