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.You are not allowed to attach a file to this page.