Attachment 'formatter-patch.diff'
Download 1 diff -ur moin-1.5.0/MoinMoin/formatter/base.py moin-1.5.0-formatter-patch/MoinMoin/formatter/base.py
2 --- moin-1.5.0/MoinMoin/formatter/base.py 2005-11-18 14:16:35.000000000 -0500
3 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/base.py 2006-01-16 12:08:36.000000000 -0500
4 @@ -135,23 +135,20 @@
5 def line_anchordef(self, lineno):
6 return ""
7
8 - def anchorlink(self, on, name='', id=None):
9 + def anchorlink(self, on, name='', **kw):
10 return ""
11
12 def line_anchorlink(self, on, lineno=0):
13 return ""
14
15 - def image(self, **kw):
16 + def image(self, src=None, **kw):
17 """ Take HTML <IMG> tag attributes in `attr`.
18
19 Attribute names have to be lowercase!
20 """
21 - attrstr = u''
22 - for attr, value in kw.items():
23 - if attr=='html_class':
24 - attr='class'
25 - attrstr = attrstr + u' %s="%s"' % (attr, wikiutil.escape(value))
26 - return u'<img%s>' % attrstr
27 + if src:
28 + return '[Image:%s]' % src
29 + return '[Image]'
30
31 def smiley(self, text):
32 return text
33 @@ -161,7 +158,7 @@
34
35 # Text and Text Attributes ###########################################
36
37 - def text(self, text):
38 + def text(self, text, **kw):
39 if not self._highlight_re:
40 return self._text(text)
41
42 @@ -185,37 +182,37 @@
43 def _text(self, text):
44 raise NotImplementedError
45
46 - def strong(self, on):
47 + def strong(self, on, **kw):
48 raise NotImplementedError
49
50 - def emphasis(self, on):
51 + def emphasis(self, on, **kw):
52 raise NotImplementedError
53
54 - def underline(self, on):
55 + def underline(self, on, **kw):
56 raise NotImplementedError
57
58 - def highlight(self, on):
59 + def highlight(self, on, **kw):
60 raise NotImplementedError
61
62 - def sup(self, on):
63 + def sup(self, on, **kw):
64 raise NotImplementedError
65
66 - def sub(self, on):
67 + def sub(self, on, **kw):
68 raise NotImplementedError
69
70 - def strike(self, on):
71 + def strike(self, on, **kw):
72 raise NotImplementedError
73
74 def code(self, on, **kw):
75 raise NotImplementedError
76
77 - def preformatted(self, on):
78 + def preformatted(self, on, **kw):
79 self.in_pre = on != 0
80
81 - def small(self, on):
82 + def small(self, on, **kw):
83 raise NotImplementedError
84
85 - def big(self, on):
86 + def big(self, on, **kw):
87 raise NotImplementedError
88
89 # special markup for syntax highlighting #############################
90 @@ -234,10 +231,10 @@
91 def linebreak(self, preformatted=1):
92 raise NotImplementedError
93
94 - def paragraph(self, on):
95 + def paragraph(self, on, **kw):
96 self.in_p = (on != 0)
97
98 - def rule(self, size=0):
99 + def rule(self, size=0, **kw):
100 raise NotImplementedError
101
102 def icon(self, type):
103 @@ -245,22 +242,22 @@
104
105 # Lists ##############################################################
106
107 - def number_list(self, on, type=None, start=None):
108 + def number_list(self, on, type=None, start=None, **kw):
109 raise NotImplementedError
110
111 - def bullet_list(self, on):
112 + def bullet_list(self, on, **kw):
113 raise NotImplementedError
114
115 def listitem(self, on, **kw):
116 raise NotImplementedError
117
118 - def definition_list(self, on):
119 + def definition_list(self, on, **kw):
120 raise NotImplementedError
121
122 - def definition_term(self, on, compact=0):
123 + def definition_term(self, on, compact=0, **kw):
124 raise NotImplementedError
125
126 - def definition_desc(self, on):
127 + def definition_desc(self, on, **kw):
128 raise NotImplementedError
129
130 def heading(self, on, depth, **kw):
131 @@ -268,13 +265,13 @@
132
133 # Tables #############################################################
134
135 - def table(self, on, attrs={}):
136 + def table(self, on, attrs={}, **kw):
137 raise NotImplementedError
138
139 - def table_row(self, on, attrs={}):
140 + def table_row(self, on, attrs={}, **kw):
141 raise NotImplementedError
142
143 - def table_cell(self, on, attrs={}):
144 + def table_cell(self, on, attrs={}, **kw):
145 raise NotImplementedError
146
147 # Dynamic stuff / Plugins ############################################
148 @@ -342,7 +339,7 @@
149
150 return self.text(f.getvalue())
151
152 - def escapedText(self, on):
153 + def escapedText(self, on, **kw):
154 """ This allows emitting text as-is, anything special will
155 be escaped (at least in HTML, some text output format
156 would possibly do nothing here)
157 diff -ur moin-1.5.0/MoinMoin/formatter/dom_xml.py moin-1.5.0-formatter-patch/MoinMoin/formatter/dom_xml.py
158 --- moin-1.5.0/MoinMoin/formatter/dom_xml.py 2005-11-18 14:16:35.000000000 -0500
159 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/dom_xml.py 2006-01-16 12:09:17.000000000 -0500
160 @@ -253,7 +253,7 @@
161 kw['type'] = 'inline'
162 return self._add_tag('attachment', **kw)
163
164 - def rule(self, size=0):
165 + def rule(self, size=0, **kw):
166 return self._add_tag('hr', size=str(size))
167
168 def icon(self, type):
169 @@ -262,41 +262,41 @@
170 def smiley(self, type):
171 return self._add_tag('smiley', type=type)
172
173 - def strong(self, on):
174 + def strong(self, on, **kw):
175 return self._set_tag('b', on)
176
177 - def emphasis(self, on):
178 + def emphasis(self, on, **kw):
179 return self._set_tag('em', on)
180
181 - def highlight(self, on):
182 + def highlight(self, on, **kw):
183 return self._set_tag('highlight', on)
184
185 - def number_list(self, on, type=None, start=None):
186 + def number_list(self, on, type=None, start=None, **kw):
187 return self._set_tag('ol', on, type=type, start=start)
188
189 - def bullet_list(self, on):
190 + def bullet_list(self, on, **kw):
191 return self._set_tag('ul', on)
192
193 def listitem(self, on, **kw):
194 return self._set_tag('li', on)
195
196 - def sup(self, on):
197 + def sup(self, on, **kw):
198 return self._set_tag('sup', on)
199
200 - def sub(self, on):
201 + def sub(self, on, **kw):
202 return self._set_tag('sub', on)
203
204 - def strike(self, on):
205 + def strike(self, on, **kw):
206 return self._set_tag('strike', on)
207
208 def code(self, on, **kw):
209 return self._set_tag('code', on)
210
211 - def preformatted(self, on):
212 + def preformatted(self, on, **kw):
213 self.in_pre = on != 0
214 return self._set_tag('pre', on)
215
216 - def paragraph(self, on):
217 + def paragraph(self, on, **kw):
218 FormatterBase.paragraph(self, on)
219 return self._set_tag('p', on)
220
221 @@ -315,31 +315,28 @@
222 result[str(name)] = value
223 return result
224
225 - def table(self, on, attrs={}):
226 + def table(self, on, attrs={}, **kw):
227 return self._set_tag('table', on, **self._check_attrs(attrs))
228
229 - def table_row(self, on, attrs={}):
230 + def table_row(self, on, attrs={}, **kw):
231 return self._set_tag('tr', on, **self._check_attrs(attrs))
232
233 - def table_cell(self, on, attrs={}):
234 + def table_cell(self, on, attrs={}, **kw):
235 return self._set_tag('td', on, **self._check_attrs(attrs))
236
237 def anchordef(self, name):
238 return self._add_tag('anchor', name=name)
239
240 - def anchorlink(self, on, name, id=None):
241 - kw = {}
242 - if id:
243 - kw['id'] = str(id)
244 + def anchorlink(self, on, name, **kw):
245 return self.url(on, "#" + name, **kw)
246
247 - def underline(self, on):
248 + def underline(self, on, **kw):
249 return self._set_tag('u', on)
250
251 - def definition_list(self, on):
252 + def definition_list(self, on, **kw):
253 return self._set_tag('dl', on)
254
255 - def definition_term(self, on, compact=0):
256 + def definition_term(self, on, compact=0, **kw):
257 # XXX may be not correct
258 # self._langAttr() missing
259 if compact and on:
260 @@ -347,24 +344,26 @@
261 else:
262 return self._set_tag('dt', on)
263
264 - def definition_desc(self, on):
265 + def definition_desc(self, on, **kw):
266 # self._langAttr() missing
267 return self._set_tag('dd', on)
268
269 - def image(self, **kw):
270 + def image(self, src=None, **kw):
271 """ Take HTML <IMG> tag attributes in `attr`.
272
273 Attribute names have to be lowercase!
274 """
275 + if src:
276 + kw['src']=src
277 return self._add_tag('img', **kw)
278
279 - def escapedText(self, text):
280 + def escapedText(self, text, **kw):
281 return wikiutil.escape(text)
282
283 - def small(self, on):
284 + def small(self, on, **kw):
285 return self._set_tag('small', on)
286
287 - def big(self, on):
288 + def big(self, on, **kw):
289 return self._set_tag('big', on)
290
291 def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
292 diff -ur moin-1.5.0/MoinMoin/formatter/text_gedit.py moin-1.5.0-formatter-patch/MoinMoin/formatter/text_gedit.py
293 --- moin-1.5.0/MoinMoin/formatter/text_gedit.py 2005-12-04 07:37:54.000000000 -0500
294 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/text_gedit.py 2006-01-16 12:06:31.000000000 -0500
295 @@ -140,13 +140,13 @@
296
297 # Change nesting: sub lists are no longer within the <li> tags
298
299 - def number_list(self, on, type=None, start=None):
300 + def number_list(self, on, type=None, start=None, **kw):
301 li = ""
302 if self._in_li: # close <li>
303 li = self.listitem(False)
304 return li + text_html.Formatter.number_list(self, on, type, start)
305
306 - def bullet_list(self, on):
307 + def bullet_list(self, on, **kw):
308 li = ""
309 if self._in_li: # close <li>
310 li = self.listitem(False)
311 @@ -197,7 +197,7 @@
312 attrs = text_html.Formatter._checkTableAttr(self, attrs, prefix)
313 return self._style_to_attributes(attrs)
314
315 - def table(self, on, attrs=None):
316 + def table(self, on, attrs=None, **kw):
317 """ Create table
318
319 @param on: start table
320 @@ -221,29 +221,31 @@
321
322 return ''.join(result)
323
324 - def comment(self, text):
325 + def comment(self, text, **kw):
326 text = text.rstrip() # workaround for growing amount of blanks at EOL
327 return self.preformatted(1, attr={'class': 'comment'}) + text + self.preformatted(0)
328
329 - def underline(self, on):
330 + def underline(self, on, **kw):
331 tag = 'u'
332 if on:
333 return self.open(tag)
334 return self.close(tag)
335
336 - def strong(self, on):
337 + def strong(self, on, **kw):
338 tag = 'b'
339 if on:
340 return self.open(tag)
341 return self.close(tag)
342
343 - def emphasis(self, on):
344 + def emphasis(self, on, **kw):
345 tag = 'i'
346 if on:
347 return self.open(tag)
348 return self.close(tag)
349
350 - def code(self, on, css=None):
351 + def code(self, on, css=None, **kw):
352 + if not css and kw.has_key('css_class'):
353 + css=kw['css_class']
354 tag = 'tt'
355 # Maybe we don't need this, because we have tt will be in inlineStack.
356 self._in_code = on
357 diff -ur moin-1.5.0/MoinMoin/formatter/text_html.py moin-1.5.0-formatter-patch/MoinMoin/formatter/text_html.py
358 --- moin-1.5.0/MoinMoin/formatter/text_html.py 2005-12-04 07:37:54.000000000 -0500
359 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/text_html.py 2006-01-16 15:04:44.000000000 -0500
360 @@ -11,6 +11,103 @@
361 from MoinMoin.Page import Page
362 from MoinMoin.action import AttachFile
363
364 +def repair_attribute_name( name ):
365 + """Takes an attribute name and tries to make it HTML correct.
366 +
367 + This function takes an attribute name as a string, as it may be
368 + passed in to a formatting method using a keyword-argument syntax,
369 + and tries to convert it into the real HTML attribute name. This is
370 + necessary because some HTML attributes are in fact Python reserved
371 + words (like "for"), and also to help with backwards compatibility
372 + with older versions of MoinMoin where different names may have
373 + been used (like "content_id" or "css").
374 +
375 + Returns a tuple of (namespace, attribute).
376 +
377 + The default namespace is always assumed to be "html", unless the
378 + input string contains a colon or a double-underscore (in which
379 + case the first such occurance is assumed to separate the namespace
380 + prefix from name. So for example to get the HTML attribute "for"
381 + (on a <label> element), you can pass in the string "html__for".
382 +
383 + (In actuality we only deal with namespace prefixes, not any real
384 + namespace URI...we only care about the syntax not the meanings)
385 + """
386 +
387 + # Handle any namespaces (just in case someday we support XHTML)
388 + if ':' in name:
389 + ns, name = name.split(':',1)
390 + elif '__' in name:
391 + ns, name = name.split('__',1)
392 + elif name == 'xmlns':
393 + ns = ''
394 + else:
395 + ns = 'html'
396 +
397 + if ns == 'html':
398 + # We have an HTML attribute, fix according to DTD
399 + if name == 'content_type': # MIME type such as in <a> and <link> elements
400 + name = 'type'
401 + elif name == 'content_id': # moin historical convention
402 + name = 'id'
403 + elif name == 'http_equiv': # underscore to hyphen
404 + name = 'http-equiv'
405 + elif name == 'z_index': # underscore to hyphen
406 + name = 'z-index'
407 + elif name in ('css_class','css'): # to avoid python word 'class'
408 + name = 'class'
409 + elif name.startswith('on'): # event handler hook
410 + name = name.lower()
411 + return (ns, name)
412 +
413 +
414 +# These are standard HTML attributes which are typically used without any
415 +# value; e.g., as boolean flags indicated by their presence.
416 +
417 +html_attribute_flags = ['compact','disabled','ismap','nohref','noresize','noshade',
418 + 'nowrap','readonly','selected','wrap']
419 +
420 +
421 +def extend_attribute_dictionary( attributedict, ns, name, value ):
422 + """Add a new attribute to an attribute dictionary, merging values where possible.
423 +
424 + The attributedict must be a dictionary with tuple-keys of the form:
425 + (namespace, attrname).
426 +
427 + The given ns, name, and value will be added to the dictionary. It
428 + will replace the old value if it existed, except for a few special
429 + cases where the values are logically merged instead (CSS class
430 + names and style rules).
431 +
432 + As a special case, if value is None (not just ''), then the
433 + attribute is actually deleted from the dictionary.
434 + """
435 +
436 + key = (ns, name)
437 + if attributedict.has_key(key):
438 + if value is None:
439 + del attributedict[key]
440 + return
441 + elif ns == 'html':
442 + if name == 'class':
443 + # CSS classes are appended by space-separated list
444 + classlist = attributedict[key]
445 + classlist += ' ' + value
446 + value = classlist
447 + elif name == 'style':
448 + # CSS styles are appended by semicolon-separated rules list
449 + stylelist = attributedict[key]
450 + stylelist += '; ' + value
451 + value = stylelist
452 + elif name in html_attribute_flags:
453 + # All attributes must have a value. According to XHTML those
454 + # traditionally used as flags should have their value set to
455 + # the same as the attribute name.
456 + value = name
457 + attributedict[key] = value
458 + return
459 +
460 +
461 class Formatter(FormatterBase):
462 """
463 Send HTML data.
464 @@ -67,35 +164,128 @@
465 # lang is inherited from content div
466 return {}
467
468 - attr = {'lang': lang, 'dir': i18n.getDirection(lang),}
469 + attr = {'xml:lang': lang, 'lang': lang, 'dir': i18n.getDirection(lang),}
470 return attr
471
472 - def formatAttributes(self, attr=None):
473 - """ Return formatted attributes string
474 + # These are all the standard HTML attributes that can be on any element.
475 + _common_attrs = ['accesskey','class','dir','disabled','id','lang','style','tabindex','title']
476 +
477 + def formatAttributes(self, attr=None, allowed_attrs=None, **kw):
478 + """ Return HTML attributes formatted as a single string.
479
480 @param attr: dict containing keys and values
481 - @rtype: string ?
482 + @param allowed_attrs: A list of allowable attribute names
483 + @param **kw: other arbitrary attributes expressed as keyword arguments.
484 + @rtype: string
485 @return: formated attributes or empty string
486 +
487 + The attributes and their values can either be given in the 'attr'
488 + dictionary, or as extra keyword arguments. They are both
489 + merged together. See the function repair_attribute_name() for
490 + special notes on how to name attributes.
491 +
492 + Setting a value to None rather than a string (or string
493 + coercible) will remove that attribute from the list.
494 +
495 + If the list of allowed_attrs is provided, then an error is
496 + raised if an HTML attribute is encountered that is not in that
497 + list (or is not a common attribute which is always allowed or
498 + is not in another XML namespace using the double-underscore
499 + syntax).
500 """
501 +
502 + # Merge the attr dict and kw dict into a single attributes dictionary
503 + # (repairing any attribute names, extracting namespaces, and merging
504 + # some values like css classes).
505 + attributes = {} # dict of key=(namespace,name): value=attribute_value
506 if attr:
507 - attr = [' %s="%s"' % (k, v) for k, v in attr.items()]
508 - return ''.join(attr)
509 + for a,v in attr.items():
510 + a_ns, a_name = repair_attribute_name(a)
511 + extend_attribute_dictionary( attributes, a_ns, a_name, v )
512 + if kw:
513 + for a,v in kw.items():
514 + a_ns, a_name = repair_attribute_name(a)
515 + extend_attribute_dictionary( attributes, a_ns, a_name, v )
516 +
517 + # Add title attribute if missing, but it has an alt.
518 + if attributes.has_key(('html','alt')) and not attributes.has_key(('html','title')):
519 + attributes[('html','title')] = attributes[('html','alt')]
520 +
521 + # Force both lang and xml:lang to be present and identical if either exists.
522 + # The lang takes precedence over xml:lang if both exist.
523 + if attributes.has_key(('html','lang')):
524 + attributes[('xml','lang')] = attributes[('html','lang')]
525 + elif attributes.has_key(('xml','lang')):
526 + attributes[('html','lang')] = attributes[('xml','lang')]
527 +
528 + # Check all the HTML attributes to see if they are known and allowed. Ignore
529 + # attributes if in non-HTML namespaces.
530 + if allowed_attrs:
531 + for name in [key[1] for key in attributes.keys() if key[0] == 'html']:
532 + if name in self._common_attrs or name in allowed_attrs:
533 + pass
534 + elif name.startswith('on'):
535 + pass # Too many event handlers to enumerate, just let them all pass.
536 + else:
537 + # Unknown or unallowed attribute.
538 + err = 'Illegal HTML attribute "%s" passed to formatter' % name
539 + raise ValueError(err)
540 +
541 + # Finally, format them all as a single string.
542 + if attributes:
543 + # Construct a formatted string containing all attributes
544 + # with their values escaped. Any html:* namespace
545 + # attributes drop the namespace prefix. We build this by
546 + # separating the attributes into three categories:
547 + #
548 + # * Those without any namespace (should only be xmlns attributes)
549 + # * Those in the HTML namespace (we drop the html: prefix for these)
550 + # * Those in any other non-HTML namespace, including xml:
551 +
552 + xmlnslist = ['%s="%s"' % (k[1], wikiutil.escape(v,1))
553 + for k, v in attributes.items() if not k[0]]
554 + htmllist = ['%s="%s"' % (k[1], wikiutil.escape(v,1))
555 + for k, v in attributes.items() if k[0] == 'html']
556 + otherlist = ['%s:%s="%s"' % (k[0], k[1], wikiutil.escape(v,1))
557 + for k, v in attributes.items() if k[0] and k[0] != 'html']
558 +
559 + # Join all these lists together in a space-separated string. Also
560 + # prefix the whole thing with a space too.
561 + htmllist.sort()
562 + otherlist.sort()
563 + all = [''] + xmlnslist + htmllist + otherlist
564 + return ' ' + ' '.join(all)
565 return ''
566
567 # TODO: use set when we require Python 2.3
568 # TODO: The list is not complete, add missing from dtd
569 - _blocks = 'p div pre table tr td ol ul dl li dt dd h1 h2 h3 h4 h5 h6 hr form'
570 + _blocks = 'p div pre table tbody thead tfoot tr th td ol ul dl li dt dd h1 h2 h3 h4 h5 h6 hr form'
571 _blocks = dict(zip(_blocks.split(), [1] * len(_blocks)))
572
573 - def open(self, tag, newline=False, attr=None):
574 + # These are the HTML elements which are typically only used with
575 + # an opening tag without a separate closing tag. We do not
576 + # include 'script' or 'style' because sometimes they do have
577 + # content, and also IE has a parsing bug with those two elements (only)
578 + # when they don't have a closing tag even if valid XHTML.
579 +
580 + _self_closing_tags = ['base','br','frame','hr','img','input','isindex','link','meta','param']
581 +
582 + def open(self, tag, newline=False, attr=None, allowed_attrs=None, **kw):
583 """ Open a tag with optional attributes
584
585 @param tag: html tag, string
586 - @param newline: render tag on a separate line
587 - @parm attr: dict with tag attributes
588 + @param newline: render tag so following data is on a separate line
589 + @param attr: dict with tag attributes
590 + @param allowed_attrs: list of allowed attributes for this element
591 + @param kw: arbitrary attributes and values
592 @rtype: string ?
593 - @return: open tag with attributes
594 + @return: open tag with attributes as a string
595 """
596 + self_close = ''
597 + if tag in self._self_closing_tags:
598 + # Don't expect a closing tag later on.
599 + self_close = ' /'
600 +
601 if tag in self._blocks:
602 # Block elements
603 result = []
604 @@ -106,25 +296,33 @@
605 attributes.update(attr)
606
607 # Format
608 - attributes = self.formatAttributes(attributes)
609 - result.append('<%s%s>' % (tag, attributes))
610 + attributes = self.formatAttributes(attributes, allowed_attrs=allowed_attrs, **kw)
611 + result.append('<%s%s%s>' % (tag, attributes, self_close))
612 if newline:
613 result.append('\n')
614 return ''.join(result)
615 else:
616 # Inline elements
617 # Add to inlineStack
618 - self._inlineStack.append(tag)
619 + if not self_close:
620 + # Only push on stack if we expect a close-tag later
621 + self._inlineStack.append(tag)
622 # Format
623 - return '<%s%s>' % (tag, self.formatAttributes(attr))
624 -
625 + return '<%s%s%s>' % (tag,
626 + self.formatAttributes(attr, allowed_attrs, **kw),
627 + self_close)
628 +
629 def close(self, tag, newline=False):
630 """ Close tag
631
632 @param tag: html tag, string
633 - @rtype: string ?
634 - @return: closing tag
635 + @param newline: render tag so following data is on a separate line
636 + @rtype: string
637 + @return: closing tag as a string
638 """
639 + if tag in self._self_closing_tags:
640 + # This tag was already closed
641 + return ''
642 if tag in self._blocks:
643 # Block elements
644 # Close all tags in inline stack
645 @@ -137,7 +335,9 @@
646 # Format with newline
647 if newline:
648 result.append('\n')
649 - result.append('</%s>\n' % (tag))
650 + result.append('</%s>' % (tag))
651 + if newline:
652 + result.append('\n')
653 return ''.join(result)
654 else:
655 # Inline elements
656 @@ -150,7 +350,7 @@
657
658 # Public methods ###################################################
659
660 - def startContent(self, content_id='content', **kwargs):
661 + def startContent(self, content_id='content', newline=True, **kw):
662 """ Start page content div """
663
664 # Setup id
665 @@ -163,11 +363,12 @@
666 # Use the content language
667 attr = self.langAttr(self.request.content_lang)
668 attr['id'] = content_id
669 - result.append(self.open('div', newline=1, attr=attr))
670 + result.append(self.open('div', newline=newline, attr=attr,
671 + allowed_attrs=['align'], **kw))
672 result.append(self.anchordef(aid))
673 return ''.join(result)
674
675 - def endContent(self):
676 + def endContent(self,newline=True):
677 """ Close page content div """
678
679 # Setup id
680 @@ -182,7 +383,7 @@
681
682 result = []
683 result.append(self.anchordef(aid))
684 - result.append(self.close('div', newline=1))
685 + result.append(self.close('div', newline=newline))
686 return ''.join(result)
687
688 def lang(self, on, lang_name):
689 @@ -205,7 +406,7 @@
690 def sysmsg(self, on, **kw):
691 tag = 'div'
692 if on:
693 - return self.open(tag, attr={'class': 'message'})
694 + return self.open(tag, attr={'class': 'message'}, **kw)
695 return self.close(tag)
696
697 # Links ##############################################################
698 @@ -259,41 +460,96 @@
699 # unescaped=1 was changed to 0 to make interwiki links with pages with umlauts (or other non-ascii) work
700
701 def url(self, on, url=None, css=None, **kw):
702 - """
703 + """ Inserts an <a> element.
704 +
705 + Call once with on=1 to start the link, and again with on=0
706 + to end it (no other arguments are needed when on==0).
707 +
708 Keyword params:
709 - title - <a> title attribute
710 - attrs - just include those <a> attrs "as is"
711 + url - the URL to link to; will go through Wiki URL mapping.
712 + type - icon type: one of "www" or "mailto" to use that icon
713 + css - a space-separated list of CSS classes
714 + attrs - just include this string verbatim inside
715 + the <a> element; can be used for arbitrary attrs
716 """
717 + if not on:
718 + return self.close('a')
719 + attrs = self.langAttr()
720 +
721 + # Handle the URL mapping
722 + if url is None and kw.has_key('href'):
723 + url = kw['href']
724 + del kw['href']
725 if url is not None:
726 url = wikiutil.mapURL(self.request, url)
727 - title = kw.get('title', None)
728 - attrs = kw.get('attrs', None)
729 + attrs['href'] = url
730 +
731 + if css:
732 + attrs['class'] = css
733 +
734 + if kw.has_key('type'): # Icon type
735 + icon_type = kw['type']
736 + del kw['type']
737 + else:
738 + icon_type = None
739 +
740 + if kw.has_key('attrs'):
741 + # for backwards compatibility, raw pre-formated attribute string
742 + extra_attrs = kw['attrs']
743 + del kw['attrs']
744 + else:
745 + extra_attrs = None
746 +
747 + # create link
748 if on:
749 - str = '<a'
750 - if css:
751 - str = '%s class="%s"' % (str, css)
752 - if title:
753 - str = '%s title="%s"' % (str, title)
754 - if attrs:
755 - str = '%s %s' % (str, attrs)
756 - str = '%s href="%s">' % (str, wikiutil.escape(url, 1))
757 + str = self.open('a', attr=attrs, **kw)
758 + if extra_attrs:
759 + # insert this into the tag (messy)
760 + if str[-2:] == '/>':
761 + str = '%s %s />' % (str[:-2], extra_attrs)
762 + else:
763 + str = '%s %s>' % (str[:-1], extra_attrs)
764 else:
765 - str = '</a>'
766 + str = self.close('a')
767 +
768 + if icon_type == 'www':
769 + str = '%s%s ' % (str, self.icon("www"))
770 + elif icon_type == 'mailto':
771 + str = '%s%s ' % (str, self.icon('mailto'))
772 return str
773
774 def anchordef(self, id):
775 - #return '<a id="%s"></a>' % (id, ) # this breaks PRE sections for IE
776 - # do not add a \n here, it breaks pre sections with line_anchordef
777 - return '<span id="%s" class="anchor"></span>' % (id, )
778 + """Inserts an element with an id attribute, used as an anchor
779 + for link references. We use <span></span> rather than <span/>
780 + for browser portability.
781 + """
782 + return '<span class="anchor" id="%s"></span>' % wikiutil.escape(id, 1)
783
784 def line_anchordef(self, lineno):
785 return self.anchordef("line-%d" % lineno)
786
787 - def anchorlink(self, on, name='', id=None):
788 - extra = ''
789 - if id:
790 - extra = ' id="%s"' % id
791 - return ['<a href="#%s"%s>' % (name, extra), '</a>'][not on]
792 + def anchorlink(self, on, name='', **kw):
793 + """Inserts an <a> link pointing to an anchor within the same
794 + document. Call once with on=1 to start the link, and a
795 + second time with on=0 to end it. No other arguments are
796 + needed on the second call.
797 +
798 + The name argument should be the same as the id provided to the
799 + anchordef() method, or some other elment. The id argument, if
800 + provided, is instead the id of this link itself and not of the
801 + element the link references.
802 + """
803 +
804 + attrs = self.langAttr()
805 + if name:
806 + attrs['href'] = '#%s' % name
807 + if kw.has_key('href'):
808 + del kw['href']
809 + if on:
810 + str = self.open('a', attr=attrs, **kw)
811 + else:
812 + str = self.close('a')
813 + return str
814
815 def line_anchorlink(self, on, lineno=0):
816 return self.anchorlink(on, name="line-%d" % lineno)
817 @@ -415,81 +671,138 @@
818
819 # Inline ###########################################################
820
821 - def strong(self, on):
822 + def strong(self, on, **kw):
823 + """Creates an HTML <strong> element.
824 +
825 + Call once with on=1 to start the region, and a second time
826 + with on=0 to end it.
827 + """
828 +
829 tag = 'strong'
830 if on:
831 - return self.open(tag)
832 + return self.open(tag, allowed_attrs=[], **kw)
833 return self.close(tag)
834
835 - def emphasis(self, on):
836 + def emphasis(self, on, **kw):
837 + """Creates an HTML <em> element.
838 +
839 + Call once with on=1 to start the region, and a second time
840 + with on=0 to end it.
841 + """
842 +
843 tag = 'em'
844 if on:
845 - return self.open(tag)
846 + return self.open(tag, allowed_attrs=[], **kw)
847 return self.close(tag)
848
849 - def underline(self, on):
850 + def underline(self, on, **kw):
851 + """Creates a text span for underlining (css class "u").
852 +
853 + Call once with on=1 to start the region, and a second time
854 + with on=0 to end it.
855 + """
856 tag = 'span'
857 if on:
858 - return self.open(tag, attr={'class': 'u'})
859 + return self.open(tag, attr={'class': 'u'}, allowed_attrs=[], **kw)
860 return self.close(tag)
861
862 - def highlight(self, on):
863 + def highlight(self, on, **kw):
864 + """Creates a text span for highlighting (css class "highlight").
865 +
866 + Call once with on=1 to start the region, and a second time
867 + with on=0 to end it.
868 + """
869 tag = 'strong'
870 if on:
871 - return self.open(tag, attr={'class': 'highlight'})
872 + return self.open(tag, attr={'class': 'highlight'}, allowed_attrs=[], **kw)
873 return self.close(tag)
874
875 - def sup(self, on):
876 + def sup(self, on, **kw):
877 + """Creates a <sup> element for superscript text.
878 +
879 + Call once with on=1 to start the region, and a second time
880 + with on=0 to end it.
881 + """
882 tag = 'sup'
883 if on:
884 - return self.open(tag)
885 + return self.open(tag, allowed_attrs=[], **kw)
886 return self.close(tag)
887
888 - def sub(self, on):
889 + def sub(self, on, **kw):
890 + """Creates a <sub> element for subscript text.
891 +
892 + Call once with on=1 to start the region, and a second time
893 + with on=0 to end it.
894 + """
895 tag = 'sub'
896 if on:
897 - return self.open(tag)
898 + return self.open(tag, allowed_attrs=[], **kw)
899 return self.close(tag)
900
901 - def strike(self, on):
902 + def strike(self, on, **kw):
903 + """Creates a <strike> element for line-through (strikeout) text.
904 +
905 + Call once with on=1 to start the region, and a second time
906 + with on=0 to end it.
907 + """
908 tag = 'strike'
909 if on:
910 - return self.open(tag)
911 + return self.open(tag, allowed_attrs=[], **kw)
912 return self.close(tag)
913
914 def code(self, on, **kw):
915 + """Creates a <tt> element for inline code text.
916 +
917 + Call once with on=1 to start the region, and a second time
918 + with on=0 to end it.
919 + """
920 tag = 'tt'
921 # Maybe we don't need this, because we have tt will be in inlineStack.
922 self._in_code = on
923 if on:
924 - return self.open(tag)
925 + return self.open(tag, allowed_attrs=[], **kw)
926 return self.close(tag)
927
928 - def small(self, on):
929 + def small(self, on, **kw):
930 + """Creates a <small> element for smaller font.
931 +
932 + Call once with on=1 to start the region, and a second time
933 + with on=0 to end it.
934 + """
935 tag = 'small'
936 if on:
937 - return self.open(tag)
938 + return self.open(tag, allowed_attrs=[], **kw)
939 return self.close(tag)
940
941 - def big(self, on):
942 + def big(self, on, **kw):
943 + """Creates a <big> element for larger font.
944 +
945 + Call once with on=1 to start the region, and a second time
946 + with on=0 to end it.
947 + """
948 tag = 'big'
949 if on:
950 - return self.open(tag)
951 + return self.open(tag, allowed_attrs=[], **kw)
952 return self.close(tag)
953
954
955 # Block elements ####################################################
956
957 - def preformatted(self, on, attr=None):
958 + def preformatted(self, on, **kw):
959 + """Creates a preformatted text region, with a <pre> element.
960 +
961 + Call once with on=1 to start the region, and a second time
962 + with on=0 to end it.
963 + """
964 FormatterBase.preformatted(self, on)
965 tag = 'pre'
966 if on:
967 - return self.open(tag, newline=1, attr=attr)
968 + return self.open(tag, newline=1, **kw)
969 return self.close(tag)
970
971 # Use by code area
972 _toggleLineNumbersScript = """
973 -<script type="text/JavaScript">
974 +<script type="text/javascript">
975 function isnumbered(obj) {
976 return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber';
977 }
978 @@ -541,6 +854,19 @@
979 """
980
981 def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
982 + """Creates a formatted code region, with line numbering.
983 +
984 + This region is formatted as a <div> with a <pre> inside it. The
985 + code_id argument is assigned to the 'id' of the div element, and
986 + must be unique within the document. The show, start, and step are
987 + used for line numbering.
988 +
989 + Note this is not like most formatter methods, it can not take any
990 + extra keyword arguments.
991 +
992 + Call once with on=1 to start the region, and a second time
993 + with on=0 to end it.
994 + """
995 res = []
996 ci = self.request.makeUniqueID('CA-%s_%03d' % (code_id, self._code_area_num))
997 if on:
998 @@ -562,7 +888,7 @@
999 if self._code_area_state[1] >= 0:
1000 toggleLineNumbersLink = r'''
1001 <script type="text/javascript">
1002 -document.write('<a href="#" onClick="return togglenumber(\'%s\', %d, %d);" \
1003 +document.write('<a href="#" onclick="return togglenumber(\'%s\', %d, %d);" \
1004 class="codenumbers">Toggle line numbers<\/a>');
1005 </script>
1006 ''' % (self._code_area_state[0], self._code_area_state[2], self._code_area_state[3])
1007 @@ -603,11 +929,21 @@
1008 # Paragraphs, Lines, Rules ###########################################
1009
1010 def linebreak(self, preformatted=1):
1011 + """Creates a line break in the HTML output.
1012 +
1013 + If preformatted is true a <br> element is inserted, otherwise
1014 + the linebreak will only be visible in the HTML source.
1015 + """
1016 if self._in_code_area:
1017 preformatted = 1
1018 - return ['\n', '<br>\n'][not preformatted]
1019 + return ['\n', '<br />\n'][not preformatted]
1020
1021 - def paragraph(self, on):
1022 + def paragraph(self, on, **kw):
1023 + """Creates a paragraph with a <p> element.
1024 +
1025 + Call once with on=1 to start the region, and a second time
1026 + with on=0 to end it.
1027 + """
1028 if self._terse:
1029 return ''
1030 FormatterBase.paragraph(self, on)
1031 @@ -615,14 +951,20 @@
1032 self._in_li = self._in_li + 1
1033 tag = 'p'
1034 if on:
1035 - return self.open(tag)
1036 - return self.close(tag)
1037 + return self.open(tag,**kw)
1038 + return self.close(tag) + '\n'
1039
1040 - def rule(self, size=None):
1041 - if size:
1042 + def rule(self, size=None, **kw):
1043 + """Creates a horizontal rule with an <hr> element.
1044 +
1045 + If size is a number in the range [1..6], the CSS class of the rule
1046 + is set to 'hr1' through 'hr6'. The intent is that the larger the
1047 + size number the thicker or bolder the rule will be.
1048 + """
1049 + if size and 1 <= size <= 6:
1050 # Add hr class: hr1 - hr6
1051 - return self.open('hr', newline=1, attr={'class': 'hr%d' % size})
1052 - return self.open('hr', newline=1)
1053 + return self.open('hr', newline=1, attr={'class': 'hr%d' % size}, **kw)
1054 + return self.open('hr', newline=1, **kw)
1055
1056 def icon(self, type):
1057 return self.request.theme.make_icon(type)
1058 @@ -634,9 +976,35 @@
1059 href = self.request.theme.img_url(img)
1060 return self.image(src=href, alt=text, width=str(w), height=str(h))
1061
1062 + def image(self, src=None, **kw):
1063 + """Creates an inline image with an <img> element.
1064 +
1065 + The src argument must be the URL to the image file.
1066 + """
1067 + if src:
1068 + kw['src']=src
1069 + return self.open('img',**kw)
1070 +
1071 # Lists ##############################################################
1072
1073 - def number_list(self, on, type=None, start=None):
1074 + _list_stack=[]
1075 + def _indent_list(self):
1076 + if not self._list_stack:
1077 + return ''
1078 + return '\n' + ' '*len(self._list_stack)
1079 +
1080 + def number_list(self, on, type=None, start=None, **kw):
1081 + """Creates an HTML ordered list, <ol> element.
1082 +
1083 + The 'type' if specified can be any legal numbered
1084 + list-style-type, such as 'decimal','lower-roman', etc.
1085 +
1086 + The 'start' argument if specified gives the numeric value of
1087 + the first list item (default is 1).
1088 +
1089 + Call once with on=1 to start the list, and a second time
1090 + with on=0 to end it.
1091 + """
1092 tag = 'ol'
1093 if on:
1094 attr = {}
1095 @@ -644,49 +1012,80 @@
1096 attr['type'] = type
1097 if start is not None:
1098 attr['start'] = start
1099 - return self.open(tag, newline=1, attr=attr)
1100 - return self.close(tag)
1101 + tagstr = self.open(tag, newline=0, attr=attr, **kw)
1102 + self._list_stack.append(tag)
1103 + return self._indent_list() + tagstr + '\n'
1104 + else:
1105 + self._list_stack.pop()
1106 + tagstr = self.close(tag)
1107 + return self._indent_list() + tagstr
1108
1109 - def bullet_list(self, on):
1110 + def bullet_list(self, on, **kw):
1111 + """Creates an HTML ordered list, <ol> element.
1112 +
1113 + The 'type' if specified can be any legal unnumbered
1114 + list-style-type, such as 'disc','square', etc.
1115 +
1116 + Call once with on=1 to start the list, and a second time
1117 + with on=0 to end it.
1118 + """
1119 tag = 'ul'
1120 if on:
1121 - return self.open(tag, newline=1)
1122 - return self.close(tag)
1123 + tagstr = self.open(tag, newline=0, **kw)
1124 + self._list_stack.append(tag)
1125 + return self._indent_list() + tagstr + '\n'
1126 + else:
1127 + self._list_stack.pop()
1128 + tagstr = self.close(tag)
1129 + return self._indent_list() + tagstr
1130
1131 def listitem(self, on, **kw):
1132 - """ List item inherit its lang from the list. """
1133 + """Adds a list item, <li> element, to a previously opened
1134 + bullet or number list.
1135 +
1136 + Call once with on=1 to start the region, and a second time
1137 + with on=0 to end it.
1138 + """
1139 tag = 'li'
1140 self._in_li = on != 0
1141 if on:
1142 - attr = {}
1143 - css_class = kw.get('css_class', None)
1144 - if css_class:
1145 - attr['class'] = css_class
1146 - style = kw.get('style', None)
1147 - if style:
1148 - attr['style'] = style
1149 - return self.open(tag, attr=attr)
1150 - return self.close(tag)
1151 + return ' ' + self.open(tag, **kw)
1152 + return self.close(tag) + '\n'
1153 +
1154 + def definition_list(self, on, **kw):
1155 + """Creates an HTML definition list, <dl> element.
1156
1157 - def definition_list(self, on):
1158 + Call once with on=1 to start the list, and a second time
1159 + with on=0 to end it.
1160 + """
1161 tag = 'dl'
1162 if on:
1163 - return self.open(tag, newline=1)
1164 + return self.open(tag, newline=1, **kw)
1165 return self.close(tag)
1166
1167 - def definition_term(self, on):
1168 + def definition_term(self, on, **kw):
1169 + """Adds a new term to a definition list, HTML element <dt>.
1170 +
1171 + Call once with on=1 to start the term, and a second time
1172 + with on=0 to end it.
1173 + """
1174 tag = 'dt'
1175 if on:
1176 - return self.open(tag)
1177 - return self.close(tag)
1178 + return self.open(tag, **kw)
1179 + return self.close(tag) + '\n'
1180
1181 - def definition_desc(self, on):
1182 + def definition_desc(self, on, **kw):
1183 + """Gives the definition to a definition item, HTML element <dd>.
1184 +
1185 + Call once with on=1 to start the definition, and a second time
1186 + with on=0 to end it.
1187 + """
1188 tag = 'dd'
1189 if on:
1190 - return self.open(tag)
1191 - return self.close(tag)
1192 + return ' ' + self.open(tag, **kw)
1193 + return self.close(tag) + '\n'
1194
1195 - def heading(self, on, depth, id = None, **kw):
1196 + def heading(self, on, depth, **kw):
1197 # remember depth of first heading, and adapt counting depth accordingly
1198 if not self._base_depth:
1199 self._base_depth = depth
1200 @@ -722,11 +1121,8 @@
1201 number = '.'.join(map(str, self.request._fmt_hd_counters[self._show_section_numbers-1:]))
1202 if number: number += ". "
1203
1204 - attr = {}
1205 - if id:
1206 - attr['id'] = id
1207 # Add space before heading, easier to check source code
1208 - result = '\n' + self.open('h%d' % heading_depth, attr=attr)
1209 + result = '\n' + self.open('h%d' % heading_depth, **kw)
1210
1211 # TODO: convert this to readable code
1212 if self.request.user.show_topbottom:
1213 @@ -795,7 +1191,7 @@
1214 return result
1215
1216
1217 - def table(self, on, attrs=None):
1218 + def table(self, on, attrs=None, **kw):
1219 """ Create table
1220
1221 @param on: start table
1222 @@ -814,36 +1210,53 @@
1223 attrs = {}
1224 else:
1225 attrs = self._checkTableAttr(attrs, 'table')
1226 - result.append(self.open('table', newline=1, attr=attrs))
1227 + result.append(self.open('table', newline=1, attr=attrs,
1228 + allowed_attrs=self._allowed_table_attrs['table'],
1229 + **kw))
1230 + result.append(self.open('tbody', newline=1))
1231 else:
1232 - # Close table then div
1233 + # Close tbody, table, and then div
1234 + result.append(self.close('tbody'))
1235 result.append(self.close('table'))
1236 result.append(self.close('div'))
1237
1238 return ''.join(result)
1239
1240 - def table_row(self, on, attrs=None):
1241 + def table_row(self, on, attrs=None, **kw):
1242 tag = 'tr'
1243 if on:
1244 if not attrs:
1245 attrs = {}
1246 else:
1247 attrs = self._checkTableAttr(attrs, 'row')
1248 - return self.open(tag, newline=1, attr=attrs)
1249 - return self.close(tag)
1250 + return self.open(tag, newline=1, attr=attrs,
1251 + allowed_attrs=self._allowed_table_attrs['row'],
1252 + **kw)
1253 + return self.close(tag) + '\n'
1254
1255 - def table_cell(self, on, attrs=None):
1256 + def table_cell(self, on, attrs=None, **kw):
1257 tag = 'td'
1258 if on:
1259 if not attrs:
1260 attrs = {}
1261 else:
1262 attrs = self._checkTableAttr(attrs, '')
1263 - return self.open(tag, newline=1, attr=attrs)
1264 - return self.close(tag)
1265 -
1266 - def escapedText(self, text):
1267 - return wikiutil.escape(text)
1268 + return ' ' + self.open(tag, attr=attrs,
1269 + allowed_attrs=self._allowed_table_attrs[''],
1270 + **kw)
1271 + return self.close(tag) + '\n'
1272 +
1273 + def text(self, text, **kw):
1274 + txt = FormatterBase.text( self, text, **kw )
1275 + if kw:
1276 + return self.open('span',**kw) + txt + self.close('span')
1277 + return txt
1278 +
1279 + def escapedText(self, text, **kw):
1280 + txt = wikiutil.escape(text)
1281 + if kw:
1282 + return self.open('span',**kw) + txt + self.close('span')
1283 + return txt
1284
1285 def rawHTML(self, markup):
1286 return markup
1287 Only in moin-1.5.0-formatter-patch/MoinMoin/formatter: text_html.pyc
1288 diff -ur moin-1.5.0/MoinMoin/formatter/text_plain.py moin-1.5.0-formatter-patch/MoinMoin/formatter/text_plain.py
1289 --- moin-1.5.0/MoinMoin/formatter/text_plain.py 2005-11-18 14:24:24.000000000 -0500
1290 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/text_plain.py 2006-01-16 12:06:32.000000000 -0500
1291 @@ -79,27 +79,27 @@
1292 def attachment_drawing(self, url, text, **kw):
1293 return "[drawing:%s]" % text
1294
1295 - def text(self, text):
1296 + def text(self, text, **kw):
1297 self._did_para = 0
1298 if self._text is not None:
1299 self._text.append(text)
1300 return text
1301
1302 - def rule(self, size=0):
1303 + def rule(self, size=0, **kw):
1304 size = min(size, 10)
1305 ch = u"---~=*+#####"[size]
1306 return (ch * 79) + u'\n'
1307
1308 - def strong(self, on):
1309 + def strong(self, on, **kw):
1310 return u'*'
1311
1312 - def emphasis(self, on):
1313 + def emphasis(self, on, **kw):
1314 return u'/'
1315
1316 - def highlight(self, on):
1317 + def highlight(self, on, **kw):
1318 return u''
1319
1320 - def number_list(self, on, type=None, start=None):
1321 + def number_list(self, on, type=None, start=None, **kw):
1322 if on:
1323 self._in_list = 1
1324 return [u'\n', u'\n\n'][not self._did_para]
1325 @@ -110,7 +110,7 @@
1326 return u'\n'
1327 return u''
1328
1329 - def bullet_list(self, on):
1330 + def bullet_list(self, on, **kw):
1331 if on:
1332 self._in_list = -1
1333 return [u'\n', u'\n\n'][not self._did_para]
1334 @@ -136,20 +136,20 @@
1335 self._did_para = 1
1336 return u'\n'
1337
1338 - def sup(self, on):
1339 + def sup(self, on, **kw):
1340 return u'^'
1341
1342 - def sub(self, on):
1343 + def sub(self, on, **kw):
1344 return u'_'
1345
1346 - def strike(self, on):
1347 + def strike(self, on, **kw):
1348 return u'__'
1349
1350 def code(self, on, **kw):
1351 #return [unichr(0x60), unichr(0xb4)][not on]
1352 return u"'" # avoid high-ascii
1353
1354 - def preformatted(self, on):
1355 + def preformatted(self, on, **kw):
1356 FormatterBase.preformatted(self, on)
1357 snip = u'---%<'
1358 snip = snip + (u'-' * (78 - len(snip)))
1359 @@ -158,10 +158,10 @@
1360 else:
1361 return snip + u'\n'
1362
1363 - def small(self, on):
1364 + def small(self, on, **kw):
1365 return u''
1366
1367 - def big(self, on):
1368 + def big(self, on, **kw):
1369 return u''
1370
1371 def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
1372 @@ -191,7 +191,7 @@
1373 def code_token(self, on, tok_type):
1374 return ""
1375
1376 - def paragraph(self, on):
1377 + def paragraph(self, on, **kw):
1378 FormatterBase.paragraph(self, on)
1379 if self._did_para:
1380 on = 0
1381 @@ -212,33 +212,34 @@
1382 self._text = None
1383 return result
1384
1385 - def table(self, on, attrs={}):
1386 + def table(self, on, attrs={}, **kw):
1387 return u''
1388
1389 - def table_row(self, on, attrs={}):
1390 + def table_row(self, on, attrs={}, **kw):
1391 return u''
1392
1393 - def table_cell(self, on, attrs={}):
1394 + def table_cell(self, on, attrs={}, **kw):
1395 return u''
1396
1397 - def underline(self, on):
1398 + def underline(self, on, **kw):
1399 return u'_'
1400
1401 - def definition_list(self, on):
1402 + def definition_list(self, on, **kw):
1403 return u''
1404
1405 - def definition_term(self, on, compact=0):
1406 + def definition_term(self, on, compact=0, **kw):
1407 result = u''
1408 if not compact: result = result + u'\n'
1409 if not on: result = result + u':\n'
1410 return result
1411
1412 - def definition_desc(self, on):
1413 + def definition_desc(self, on, **kw):
1414 return [u' ', u'\n'][not on]
1415
1416 - def image(self, **kw):
1417 - if kw.has_key(u'alt'):
1418 - return kw[u'alt']
1419 + def image(self, src=None, **kw):
1420 + for a in (u'alt',u'title'):
1421 + if kw.has_key(a):
1422 + return kw[a]
1423 return u''
1424
1425 def lang(self, on, lang_name):
1426 diff -ur moin-1.5.0/MoinMoin/formatter/text_xml.py moin-1.5.0-formatter-patch/MoinMoin/formatter/text_xml.py
1427 --- moin-1.5.0/MoinMoin/formatter/text_xml.py 2005-12-01 20:30:07.000000000 -0500
1428 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/text_xml.py 2006-01-16 12:06:32.000000000 -0500
1429 @@ -77,12 +77,12 @@
1430 return '<attachmentdrawing href="%s">%s</attachmentdrawing>' % (
1431 url, text)
1432
1433 - def text(self, text):
1434 + def text(self, text, **kw):
1435 if self.in_pre:
1436 return text.replace(']]>', ']]>]]><![CDATA[')
1437 return self._escape(text)
1438
1439 - def rule(self, size=0):
1440 + def rule(self, size=0, **kw):
1441 return "\n<br/>%s<br/>\n" % ("-"*78,) # <hr/> not supported in stylebook
1442 if size:
1443 return '<hr size="%d"/>\n' % (size,)
1444 @@ -92,21 +92,21 @@
1445 def icon(self, type):
1446 return '<icon type="%s" />' % type
1447
1448 - def strong(self, on):
1449 + def strong(self, on, **kw):
1450 return ['<strong>', '</strong>'][not on]
1451
1452 - def emphasis(self, on):
1453 + def emphasis(self, on, **kw):
1454 return ['<em>', '</em>'][not on]
1455
1456 - def highlight(self, on):
1457 + def highlight(self, on, **kw):
1458 return ['<strong>', '</strong>'][not on]
1459
1460 - def number_list(self, on, type=None, start=None):
1461 + def number_list(self, on, type=None, start=None, **kw):
1462 result = ''
1463 if self.in_p: result = self.paragraph(0)
1464 return result + ['<ol>', '</ol>\n'][not on]
1465
1466 - def bullet_list(self, on):
1467 + def bullet_list(self, on, **kw):
1468 result = ''
1469 if self.in_p: result = self.paragraph(0)
1470 return result + ['<ul>', '</ul>\n'][not on]
1471 @@ -117,22 +117,22 @@
1472 def code(self, on, **kw):
1473 return ['<code>', '</code>'][not on]
1474
1475 - def sup(self, on):
1476 + def sup(self, on, **kw):
1477 return ['<sup>', '</sup>'][not on]
1478
1479 - def sub(self, on):
1480 + def sub(self, on, **kw):
1481 return ['<sub>', '</sub>'][not on]
1482
1483 - def strike(self, on):
1484 + def strike(self, on, **kw):
1485 return ['<strike>', '</strike>'][not on]
1486
1487 - def preformatted(self, on):
1488 + def preformatted(self, on, **kw):
1489 FormatterBase.preformatted(self, on)
1490 result = ''
1491 if self.in_p: result = self.paragraph(0)
1492 return result + ['<source><![CDATA[', ']]></source>'][not on]
1493
1494 - def paragraph(self, on):
1495 + def paragraph(self, on, **kw):
1496 FormatterBase.paragraph(self, on)
1497 return ['<p>', '</p>\n'][not on]
1498
1499 @@ -160,41 +160,42 @@
1500
1501 return result + '<s%d%s title="' % (depth, id_text)
1502
1503 - def table(self, on, attrs={}):
1504 + def table(self, on, attrs={}, **kw):
1505 return ['<table>', '</table>'][not on]
1506
1507 - def table_row(self, on, attrs={}):
1508 + def table_row(self, on, attrs={}, **kw):
1509 return ['<tr>', '</tr>'][not on]
1510
1511 - def table_cell(self, on, attrs={}):
1512 + def table_cell(self, on, attrs={}, **kw):
1513 return ['<td>', '</td>'][not on]
1514
1515 def anchordef(self, id):
1516 return '<anchor id="%s"/>' % id
1517
1518 - def anchorlink(self, on, name='', id=None):
1519 + def anchorlink(self, on, name='', **kw):
1520 + id = kw.get('id',None)
1521 extra = ''
1522 if id:
1523 extra = ' id="%s"' % id
1524 return ('<link anchor="%s"%s>' % (name, extra) ,'</link>') [not on]
1525
1526 - def underline(self, on):
1527 + def underline(self, on, **kw):
1528 return self.strong(on) # no underline in StyleBook
1529
1530 - def definition_list(self, on):
1531 + def definition_list(self, on, **kw):
1532 result = ''
1533 if self.in_p: result = self.paragraph(0)
1534 return result + ['<gloss>', '</gloss>'][not on]
1535
1536 - def definition_term(self, on, compact=0):
1537 + def definition_term(self, on, compact=0, **kw):
1538 return ['<label>', '</label>'][not on]
1539
1540 - def definition_desc(self, on):
1541 + def definition_desc(self, on, **kw):
1542 return ['<item>', '</item>'][not on]
1543
1544 - def image(self, **kw):
1545 + def image(self, src=None, **kw):
1546 valid_attrs = ['src', 'width', 'height', 'alt']
1547 - attrs = {}
1548 + attrs = {'src':src}
1549 for key, value in kw.items():
1550 if key in valid_attrs:
1551 attrs[key] = value
1552 diff -ur moin-1.5.0/MoinMoin/formatter/xml_docbook.py moin-1.5.0-formatter-patch/MoinMoin/formatter/xml_docbook.py
1553 --- moin-1.5.0/MoinMoin/formatter/xml_docbook.py 2005-12-01 20:30:07.000000000 -0500
1554 +++ moin-1.5.0-formatter-patch/MoinMoin/formatter/xml_docbook.py 2006-01-16 12:06:33.000000000 -0500
1555 @@ -132,7 +132,7 @@
1556 def endDocument(self):
1557 return self.outputFormatter.getFooter()
1558
1559 - def text(self, text):
1560 + def text(self, text, **kw):
1561 if text == "\\n":
1562 srcText = "\n"
1563 else:
1564 @@ -183,7 +183,7 @@
1565
1566 return ""
1567
1568 - def paragraph(self, on):
1569 + def paragraph(self, on, **kw):
1570 FormatterBase.paragraph(self, on)
1571 if on:
1572 para = self.doc.createElement("para")
1573 @@ -269,40 +269,40 @@
1574
1575 return self._handleNode(name, on, attributes)
1576
1577 - def strong(self, on):
1578 + def strong(self, on, **kw):
1579 return self._handleFormatting("emphasis", on, (('role','strong'), ))
1580
1581 - def emphasis(self, on):
1582 + def emphasis(self, on, **kw):
1583 return self._handleFormatting("emphasis", on)
1584
1585 - def underline(self, on):
1586 + def underline(self, on, **kw):
1587 return self._handleFormatting("emphasis", on, (('role','underline'), ))
1588
1589 - def highlight(self, on):
1590 + def highlight(self, on, **kw):
1591 return self._handleFormatting("emphasis", on, (('role','highlight'), ))
1592
1593 - def sup(self, on):
1594 + def sup(self, on, **kw):
1595 return self._handleFormatting("superscript", on)
1596
1597 - def sub(self, on):
1598 + def sub(self, on, **kw):
1599 return self._handleFormatting("subscript", on)
1600
1601 - def strike(self, on):
1602 + def strike(self, on, **kw):
1603 # does not yield <strike> using the HTML XSLT files here ...
1604 # but seems to be correct
1605 return self._handleFormatting("emphasis", on,
1606 (('role','strikethrough'), ))
1607
1608 - def code(self, on, **kwargs):
1609 + def code(self, on, **kw):
1610 return self._handleFormatting("code", on)
1611
1612 - def preformatted(self, on):
1613 + def preformatted(self, on, **kw):
1614 return self._handleFormatting("screen", on)
1615
1616
1617 ### Lists ###########################################################
1618
1619 - def number_list(self, on, type=None, start=None):
1620 + def number_list(self, on, type=None, start=None, **kw):
1621 docbook_ol_types = {'1': "arabic",
1622 'a': "loweralpha",
1623 'A': "upperalpha",
1624 @@ -316,16 +316,16 @@
1625
1626 return self._handleNode('orderedlist', on, attrs)
1627
1628 - def bullet_list(self, on):
1629 + def bullet_list(self, on, **kw):
1630 return self._handleNode("itemizedlist", on)
1631
1632 - def definition_list(self, on):
1633 + def definition_list(self, on, **kw):
1634 return self._handleNode("glosslist", on)
1635
1636 '''When on is false, we back out just on level. This is
1637 ok because we know definition_desc gets called, and we
1638 back out two levels there'''
1639 - def definition_term(self, on, compact=0):
1640 + def definition_term(self, on, compact=0, **kw):
1641 if on:
1642 entry=self.doc.createElement('glossentry')
1643 term=self.doc.createElement('glossterm')
1644 @@ -337,7 +337,7 @@
1645 return ""
1646
1647 '''We backout two levels when 'on' is false, to leave the glossentry stuff'''
1648 - def definition_desc(self, on):
1649 + def definition_desc(self, on, **kw):
1650 if on:
1651 return self._handleNode("glossdef", on)
1652 else:
1653 @@ -381,7 +381,8 @@
1654 self._handleNode("ulink", False)
1655 return ""
1656
1657 - def anchorlink(self, on, name='', id=None):
1658 + def anchorlink(self, on, name='', **kw):
1659 + id = kw.get('id',None)
1660 attrs = []
1661 if name != '':
1662 attrs.append(('endterm', name))
1663 @@ -438,7 +439,9 @@
1664
1665
1666 ### Images and Smileys ##############################################
1667 - def image(self, **kw):
1668 + def image(self, src=None, **kw):
1669 + if src:
1670 + kw['src']=src
1671 media = self.doc.createElement('inlinemediaobject')
1672
1673 imagewrap = self.doc.createElement('imageobject')
1674 @@ -477,7 +480,7 @@
1675
1676 #FIXME: We should copy code from text_html.py for attr handling
1677
1678 - def table(self, on, attrs=None):
1679 + def table(self, on, attrs=None, **kw):
1680 sanitized_attrs = []
1681 if attrs and attrs.has_key('id'):
1682 sanitized_attrs[id] = attrs['id']
1683 @@ -489,14 +492,14 @@
1684 self._handleNode("tbody", on)
1685 return ""
1686
1687 - def table_row(self, on, attrs=None):
1688 + def table_row(self, on, attrs=None, **kw):
1689 self.table_current_row_cells = 0
1690 sanitized_attrs = []
1691 if attrs and attrs.has_key('id'):
1692 sanitized_attrs[id] = attrs['id']
1693 return self._handleNode("row", on, sanitized_attrs)
1694
1695 - def table_cell(self, on, attrs=None):
1696 + def table_cell(self, on, attrs=None, **kw):
1697 # Finish row definition
1698 sanitized_attrs = []
1699 if attrs and attrs.has_key('id'):
1700 @@ -572,11 +575,11 @@
1701 return u""
1702
1703 ### Not supported ###################################################
1704 - def rule(self, size = 0):
1705 + def rule(self, size = 0, **kw):
1706 return ""
1707
1708 - def small(self, on):
1709 + def small(self, on, **kw):
1710 return ""
1711
1712 - def big(self, on):
1713 + def big(self, on, **kw):
1714 return ""
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.