Attachment '03.extract-page-functions.patch'
Download 1 # HG changeset patch
2 # User gerg.ward+moin@gmail.com
3 # Date 1225380804 14400
4 # Node ID 53ff55dee8f99d6d3e78e73cab1c2c3d6b3df8e4
5 # Parent 4eae0f3824d2084833ff9397ec48bc6b3a684d61
6 Factor out functions that work on including a single page.
7
8 diff -r 4eae0f3824d2 -r 53ff55dee8f9 MoinMoin/macro/Include.py
9 --- a/MoinMoin/macro/Include.py Thu Oct 30 11:16:34 2008 -0400
10 +++ b/MoinMoin/macro/Include.py Thu Oct 30 11:33:24 2008 -0400
11 @@ -80,6 +80,120 @@
12 if skipitems:
13 del pagelist[:int(skipitems)]
14
15 +class NoIncludeError(Exception):
16 + def __init__(self, message=None):
17 + self.message = message
18 +
19 +def check_page(macro, request, this_page, inc_name):
20 + """
21 + Check if it's OK to include the page named by 'inc_name' and return
22 + a Page object corresponding to 'inc_page' if so. If not, raise
23 + NoIncludeError with an untranslated end-user error message. The
24 + NoIncludeError have no message, in which case no error message will
25 + be shown to the end user.
26 + """
27 + if not request.user.may.read(inc_name):
28 + raise NoIncludeError()
29 + if inc_name in this_page._macroInclude_pagelist:
30 + raise NoIncludeError(u'Recursive include of "%s" forbidden' % (inc_name, ))
31 + fmt = macro.formatter.__class__(request, is_included=True)
32 + fmt._base_depth = macro.formatter._base_depth
33 + inc_page = Page(request, inc_name, formatter=fmt)
34 + if not inc_page.exists():
35 + raise NoIncludeError()
36 +
37 + return inc_page
38 +
39 +def trim_page_body(request, inc_page, args, result):
40 + _ = request.getText
41 + body = inc_page.get_raw_body() + '\n'
42 + from_pos = 0
43 + to_pos = -1
44 + from_re = args.group('from')
45 + if from_re:
46 + try:
47 + from_match = re.compile(from_re, re.M).search(body)
48 + except re.error:
49 + ##result.append("*** fe=%s ***" % e)
50 + from_match = re.compile(re.escape(from_re), re.M).search(body)
51 + if from_match:
52 + from_pos = from_match.end()
53 + else:
54 + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
55 + to_re = args.group('to')
56 + if to_re:
57 + try:
58 + to_match = re.compile(to_re, re.M).search(body, from_pos)
59 + except re.error:
60 + to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
61 + if to_match:
62 + to_pos = to_match.start()
63 + else:
64 + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
65 +
66 + trimmed = (from_pos > 0 or to_pos > -1)
67 + return (body[from_pos:to_pos], trimmed)
68 +
69 +def format_titles(macro, request, title_re, inc_page, body, result):
70 + levelstack = []
71 + for title, level in extract_titles(body, title_re):
72 + if levelstack:
73 + if level > levelstack[-1]:
74 + result.append(macro.formatter.bullet_list(1))
75 + levelstack.append(level)
76 + else:
77 + while levelstack and level < levelstack[-1]:
78 + result.append(macro.formatter.bullet_list(0))
79 + levelstack.pop()
80 + if not levelstack or level != levelstack[-1]:
81 + result.append(macro.formatter.bullet_list(1))
82 + levelstack.append(level)
83 + else:
84 + result.append(macro.formatter.bullet_list(1))
85 + levelstack.append(level)
86 + result.append(macro.formatter.listitem(1))
87 + result.append(inc_page.link_to(request, title))
88 + result.append(macro.formatter.listitem(0))
89 + while levelstack:
90 + result.append(macro.formatter.bullet_list(0))
91 + levelstack.pop()
92 +
93 +def add_heading(macro, request, print_mode, inc_page, args, result):
94 + level = None
95 + if args.group('heading') and args.group('hquote'):
96 + # XXX that "or ..." clause is dead code: the arg_heading regex
97 + # guarantees that args.group('htext') will return a non-empty
98 + # string as long as args.group('hquote') does too.
99 + heading = args.group('htext') or inc_page.split_title()
100 + level = 1
101 + if args.group('level'):
102 + level = int(args.group('level'))
103 + if print_mode:
104 + result.append(macro.formatter.heading(1, level) +
105 + macro.formatter.text(heading) +
106 + macro.formatter.heading(0, level))
107 + else:
108 + url = inc_page.url(request)
109 + result.extend([
110 + macro.formatter.heading(1, level, id=heading),
111 + macro.formatter.url(1, url, css="include-heading-link"),
112 + macro.formatter.text(heading),
113 + macro.formatter.url(0),
114 + macro.formatter.heading(0, level),
115 + ])
116 + return True
117 + else:
118 + return False
119 +
120 +def add_editlink(macro, request, inc_name, inc_page, result):
121 + _ = request.getText
122 + result.extend([
123 + macro.formatter.div(1, css_class="include-link"),
124 + inc_page.link_to(request, '[%s]' % (inc_name, ), css_class="include-page-link"),
125 + inc_page.link_to(request, '[%s]' % (_('edit'), ), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
126 + macro.formatter.div(0),
127 + ])
128 +
129 def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M)):
130 request = macro.request
131 _ = request.getText
132 @@ -112,97 +226,31 @@
133
134 # iterate over pages
135 for inc_name in pagelist:
136 - if not request.user.may.read(inc_name):
137 + try:
138 + inc_page = check_page(macro, request, this_page, inc_name)
139 + except NoIncludeError, err:
140 + if err.message:
141 + result.append(u'<p><strong class="error">%s</strong></p>' % (err.message, ))
142 continue
143 - if inc_name in this_page._macroInclude_pagelist:
144 - result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name, ))
145 - continue
146 - fmt = macro.formatter.__class__(request, is_included=True)
147 - fmt._base_depth = macro.formatter._base_depth
148 - inc_page = Page(request, inc_name, formatter=fmt)
149 - if not inc_page.exists():
150 - continue
151 +
152 inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
153
154 - # check for "from" and "to" arguments (allowing partial includes)
155 - body = inc_page.get_raw_body() + '\n'
156 - from_pos = 0
157 - to_pos = -1
158 - from_re = args.group('from')
159 - if from_re:
160 - try:
161 - from_match = re.compile(from_re, re.M).search(body)
162 - except re.error:
163 - ##result.append("*** fe=%s ***" % e)
164 - from_match = re.compile(re.escape(from_re), re.M).search(body)
165 - if from_match:
166 - from_pos = from_match.end()
167 - else:
168 - result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
169 - to_re = args.group('to')
170 - if to_re:
171 - try:
172 - to_match = re.compile(to_re, re.M).search(body, from_pos)
173 - except re.error:
174 - to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
175 - if to_match:
176 - to_pos = to_match.start()
177 - else:
178 - result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
179 + # get the body of the included page, applying 'from' and 'to' to trim it
180 + # (partial includes)
181 + (body, trimmed) = trim_page_body(request, inc_page, args, result)
182
183 if titlesonly:
184 - levelstack = []
185 - for title, level in extract_titles(body[from_pos:to_pos], title_re):
186 - if levelstack:
187 - if level > levelstack[-1]:
188 - result.append(macro.formatter.bullet_list(1))
189 - levelstack.append(level)
190 - else:
191 - while levelstack and level < levelstack[-1]:
192 - result.append(macro.formatter.bullet_list(0))
193 - levelstack.pop()
194 - if not levelstack or level != levelstack[-1]:
195 - result.append(macro.formatter.bullet_list(1))
196 - levelstack.append(level)
197 - else:
198 - result.append(macro.formatter.bullet_list(1))
199 - levelstack.append(level)
200 - result.append(macro.formatter.listitem(1))
201 - result.append(inc_page.link_to(request, title))
202 - result.append(macro.formatter.listitem(0))
203 - while levelstack:
204 - result.append(macro.formatter.bullet_list(0))
205 - levelstack.pop()
206 + format_titles(macro, request, title_re, inc_page, body, result)
207 continue
208
209 - if from_pos or to_pos != -1:
210 - inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
211 - ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
212 - ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
213 + if trimmed:
214 + inc_page.set_raw_body(body, modified=True)
215
216 if not hasattr(request, "_Include_backto"):
217 request._Include_backto = this_page.page_name
218
219 # do headings
220 - level = None
221 - if args.group('heading') and args.group('hquote'):
222 - heading = args.group('htext') or inc_page.split_title()
223 - level = 1
224 - if args.group('level'):
225 - level = int(args.group('level'))
226 - if print_mode:
227 - result.append(macro.formatter.heading(1, level) +
228 - macro.formatter.text(heading) +
229 - macro.formatter.heading(0, level))
230 - else:
231 - url = inc_page.url(request)
232 - result.extend([
233 - macro.formatter.heading(1, level, id=heading),
234 - macro.formatter.url(1, url, css="include-heading-link"),
235 - macro.formatter.text(heading),
236 - macro.formatter.url(0),
237 - macro.formatter.heading(0, level),
238 - ])
239 + added_heading = add_heading(macro, request, print_mode, inc_page, args, result)
240
241 # set or increment include marker
242 this_page._macroInclude_pagelist[inc_name] = \
243 @@ -227,13 +275,9 @@
244 del this_page._macroInclude_pagelist[inc_name]
245
246 # if no heading and not in print mode, then output a helper link
247 - if editlink and not (level or print_mode):
248 - result.extend([
249 - macro.formatter.div(1, css_class="include-link"),
250 - inc_page.link_to(request, '[%s]' % (inc_name, ), css_class="include-page-link"),
251 - inc_page.link_to(request, '[%s]' % (_('edit'), ), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
252 - macro.formatter.div(0),
253 - ])
254 + if editlink and not (added_heading or print_mode):
255 + add_editlink(macro, request, inc_name, inc_page, result)
256 +
257 # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
258
259 # return include text
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.