I've been trying to fix MoinMoin's text_plain formatter to produce readable output. It's almost correct, except I don't understand why I can't get the LF-adding rules correct. Either there are too many LFs or too few. And whenever I change something, something else breaks.. It's getting pretty annoying.
So if anyone else wants to try getting it fixed that'd be great. :) Attached the current version that I have. For testing you'll need your own MoinMoin installation. Then replace the included text_plain.py with the attached version. Then test it with for example: http://localhost/wiki/SomePage?action=format;mimetype=text/plain
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - "text/plain" Formatter
@copyright: 2000, 2001, 2002 by Jürgen Hermann <[EMAIL PROTECTED]>
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin.formatter.base import FormatterBase
class Formatter(FormatterBase):
"""
Send plain text data.
"""
hardspace = u' '
def __init__(self, request, **kw):
apply(FormatterBase.__init__, (self, request), kw)
self._in_code_area = 0
self._in_code_line = 0
self._code_area_state = [0, -1, -1, 0]
self._lists = []
self._url = None
self._text = None # XXX does not work with links in headings!!!!!
self._textbuf = ''
self._indent = 0
self._end_indent = -1
self._para_begin = True
self._listitem_on = []
self._last_lf = True
self._empty_line_count = 2
def startDocument(self, pagename):
line = u"*" * (len(pagename) + 2) + u'\n'
return self.wrap(u"%s %s \n%s" % (line, pagename, line))
def endDocument(self):
return self.flush(True)
def sysmsg(self, on, **kw):
return self.wrap((u'\n\n*** ', u' ***\n\n')[not on])
def pagelink(self, on, pagename='', page=None, **kw):
apply(FormatterBase.pagelink, (self, on, pagename, page), kw)
if on:
self._text = []
return self.wrap(u"<")
else:
if "".join(self._text) == pagename:
self._text = None
return self.wrap(u">")
else:
self._text = None
return self.wrap(u"> [%s]" % (pagename))
def interwikilink(self, on, interwiki='', pagename='', **kw):
if on:
self._url = u"%s:%s" % (interwiki, pagename)
self._text = []
return u''
else:
if "".join(self._text) == self._url:
self._url = None
self._text = None
return ''
else:
self._url = None
self._text = None
return self.wrap(u' [%s]' % (self._url))
def url(self, on, url='', css=None, **kw):
if on:
self._url = url
self._text = []
return u''
else:
if "".join(self._text) == self._url:
self._url = None
self._text = None
return ''
else:
self._text = None
return self.wrap(u' [%s]' % (self._url))
def attachment_link(self, url, text, **kw):
return self.wrap("[%s]" % text)
def attachment_image(self, url, **kw):
title = ''
for a in (u'title', u'html__title', u'alt', u'html_alt'):
if kw.has_key(a):
title = ':' + kw[a]
return self.wrap("[image:%s%s]" % (url, title))
def attachment_drawing(self, url, text, **kw):
return self.wrap("[drawing:%s]" % text)
def text(self, text, **kw):
if self._text is not None:
self._text.append(text)
return self.wrap(text)
def rule(self, size=0, **kw):
size = min(size, 10)
ch = u"---~=*+#####"[size]
return self.wrap((ch * 79) + u'\n')
def strong(self, on, **kw):
return self.wrap(u'*')
def emphasis(self, on, **kw):
return self.wrap(u'/')
def highlight(self, on, **kw):
return u''
def number_list(self, on, type=None, start=None, **kw):
if on:
self._para_begin = False
result = self.start_para()
self._lists.append(0)
self._listitem_on.append(False)
else:
result = self.flush(False)
num = self._lists.pop(-1)
listitem_on = self._listitem_on.pop(-1)
if listitem_on:
result += self.wrap('\n')
prefix = ' %d. ' % (num)
self._indent -= len(prefix)
result += self.end_para()
self._end_indent = self._indent
return result
def bullet_list(self, on, **kw):
if on:
self._para_begin = False
result = self.start_para()
self._lists.append(-1)
self._listitem_on.append(False)
else:
result = self.flush(False)
self._lists.pop(-1)
listitem_on = self._listitem_on.pop(-1)
if listitem_on:
result += self.wrap('\n')
self._indent -= 3
result += self.end_para()
self._end_indent = self._indent
return result
def listitem(self, on, **kw):
if not on:
return ''
result = ''
num = self._lists.pop(-1)
listitem_on = self._listitem_on.pop(-1)
if listitem_on and on:
# we didn't receive on=False for previous listitem
if num >= 0:
prefix = ' %d. ' % (num)
self._indent -= len(prefix)
else:
self._indent -= 3
result += self.wrap('\n')
self._listitem_on.append(on)
if num >= 0:
if on:
num += 1
prefix = ' %d. ' % (num)
else:
prefix = ' * '
self._lists.append(num)
if on:
self._para_begin = True
result += self.wrap(prefix)
self._indent += len(prefix)
else:
self._indent -= len(prefix)
result += self.wrap('\n')
self._end_indent = -1
return result;
def sup(self, on, **kw):
if on:
return self.wrap(u'^')
else:
return ''
def sub(self, on, **kw):
return self.wrap(u'_')
def strike(self, on, **kw):
return self.wrap(u'__')
def code(self, on, **kw):
#return [unichr(0x60), unichr(0xb4)][not on]
return self.wrap(u"'") # avoid high-ascii
def preformatted(self, on, **kw):
FormatterBase.preformatted(self, on)
snip = u'---%<'
snip = snip + (u'-' * (78 - len(snip)))
if on:
self._text = []
return self.wrap(u'\n' + snip + u'\n')
else:
if not "".join(self._text).endswith(u'\n'):
snip = u'\n' + snip;
self._text = None
return self.wrap(snip + u'\n')
def small(self, on, **kw):
return u''
def big(self, on, **kw):
return u''
def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
snip = u'---CodeArea'
snip = snip + (u'-' * (78 - len(snip)))
if on:
self._in_code_area = 1
self._in_code_line = 0
self._code_area_state = [show, start, step, start]
return self.wrap(u'\n' + snip + u'\n')
else:
if self._in_code_line:
return self.wrap(self.code_line(0) + snip + u'\n')
return self.wrap(snip + u'\n')
def code_line(self, on):
res = u''
if not on or (on and self._in_code_line):
res += u'\n'
if on:
if self._code_area_state[0] > 0:
res += u' %4d ' % self._code_area_state[3]
self._code_area_state[3] += self._code_area_state[2]
self._in_code_line = on != 0
return self.wrap(res)
def code_token(self, on, tok_type):
return ""
def paragraph(self, on, **kw):
FormatterBase.paragraph(self, on)
if on:
result = self.start_para()
else:
result = self.end_para()
return result
def linebreak(self, preformatted=1):
return self.wrap(u'\n')
def smiley(self, text):
return self.wrap(text)
def heading(self, on, depth, **kw):
if on:
result = self.start_para()
self._text = []
else:
result = u'\n%s\n\n' % (u'=' * len("".join(self._text)))
self._text = None
result = self.wrap(result)
result += self.end_para()
return result;
def table(self, on, attrs={}, **kw):
return u''
def table_row(self, on, attrs={}, **kw):
return u''
def table_cell(self, on, attrs={}, **kw):
return u''
def underline(self, on, **kw):
return self.wrap(u'_')
def definition_list(self, on, **kw):
return u''
def definition_term(self, on, compact=0, **kw):
result = u''
#if not compact:
# result = result + u'\n'
if not on:
result = result + u':\n'
return self.wrap(result)
def definition_desc(self, on, **kw):
return self.wrap([u' ', u'\n'][not on])
def image(self, src=None, **kw):
for a in (u'title', u'html__title', u'alt', u'html_alt'):
if kw.has_key(a):
return self.wrap(kw[a])
return u''
def lang(self, on, lang_name):
return ''
def wrap(self, text):
if len(text) == 0:
return ''
prefix = ''
if len(self._textbuf) == 0 and self._last_lf:
prefix = self.check_para_begin(1)
text = ' ' * self._indent + text
lines = text.split('\n')
text = prefix
while len(lines) > 0:
self._textbuf += lines.pop(0)
if len(lines) > 0:
# LFs found
#text += 'lf<' + self.flush(True) + '>'
text += self.flush(True)
if len(self._textbuf) > 80 and self._textbuf.find(' ') != -1:
# wrap time
text += self.flush(True, False)
return text
def start_para(self):
result = ''
if not self._para_begin:
if len(self._textbuf) > 0:
#result += 'start_para<' + self.flush(True) + '>'
result += self.flush(True)
self._para_begin = True
return result
def end_para(self):
if len(self._textbuf) > 0:
#return 'end_para<' + self.flush(True) + '>'
return self.flush(True)
else:
return ''
def check_para_begin(self, foo=0):
if self._para_begin:
self._para_begin = False
self._empty_line_count += 1
if self._end_indent == self._indent and self._empty_line_count == 1:
#return 'i{' + str(self._indent) + '}' + '\n'
return '\n'
return ''
def flush(self, addlf, full_flush=True):
result = ''
if len(self._textbuf) > 0:
result += self.check_para_begin()
#result = 'n{' + str(self._indent) + '}'
while len(self._textbuf) >= 80:
# need to wrap
last_space = self._textbuf.rfind(' ', self._indent, 80)
if last_space == -1:
# a long line. split at the next possible space
last_space = self._textbuf.find(' ', self._indent)
if last_space == -1:
break
result += self._textbuf[:last_space] + '\n'
self._empty_line_count = 0
self._textbuf = ' ' * self._indent + self._textbuf[last_space+1:]
self._end_indent = self._indent
if not full_flush:
self._para_begin = False
self._last_lf = result[-1] == '\n'
return result
# strip trailing whitespace
while len(self._textbuf) > 0 and self._textbuf[-1] == ' ':
self._textbuf = self._textbuf[:-1]
if len(self._textbuf) == 0:
if not addlf:
return result
self._empty_line_count += 1
if self._empty_line_count >= 2:
return result
else:
self._empty_line_count = 0
result += self._textbuf
if addlf:
result += '\n'
self._textbuf = ''
self._para_begin = False
self._last_lf = result[-1] == '\n'
return result
signature.asc
Description: This is a digitally signed message part
