# -*- coding: utf-8 -*- """ MoinMoin - Dokuwiki Formatter @copyright: 2000, 2001, 2002 by Jürgen Hermann @copyright: 2011-2012 Elan Ruusamäe @license: GNU GPL, see COPYING for details. """ from xml.sax import saxutils from MoinMoin.formatter.base import FormatterBase from MoinMoin import config from MoinMoin.Page import Page from types import * # TODO: let base class MoinMoin/formatter/base.py handle not implemented methods class Formatter(FormatterBase): """ Send Dokuwiki formatted data. """ hardspace = ' ' # hardspace = ' ' def __init__(self, request, **kw): apply(FormatterBase.__init__, (self, request), kw) self._current_depth = 1 self._base_depth = 0 self.in_pre = 0 self.in_table = 0 self._text = None # XXX does not work with links in headings!!!!! self.list_depth = 0 self.list_type = ' ' def _escape(self, text, extra_mapping={"'": "'", '"': """}): return saxutils.escape(text, extra_mapping) def startDocument(self, pagename): encoding = config.charset return '\n' % ( encoding, self._escape(pagename)) def endDocument(self): result = "" while self._current_depth > 1: result += "" % self._current_depth self._current_depth -= 1 return result + '' def lang(self, on, lang_name): return ('
' % lang_name, '
')[not on] def sysmsg(self, on, **kw): return ('', '')[not on] def rawHTML(self, markup): return '' + markup + '' def pagelink(self, on, pagename='', page=None, **kw): if on: return '[[:' + ":".join(pagename.split("/")) + "|" else: return ']]' def interwikilink(self, on, interwiki='', pagename='', **kw): if on: return '[[%s>%s|' % (interwiki, pagename) else: return ']]' def url(self, on, url='', css=None, **kw): return ('[[%s|' % (self._escape(url)), ']]')[not on] def attachment_link(self, url, text, **kw): return '{{%s|%s}}' % (url, text) def attachment_image(self, url, **kw): return '{{%s|}}' % (url,) def attachment_drawing(self, url, text, **kw): return '{{%s|%s}}' % (url, text) def text(self, text, **kw): self._did_para = 0 if self._text is not None: self._text.append(text) return text def rule(self, size=0, **kw): # size not supported if size >= 4: return '----\n' else: return '-' * size + '\n' def icon(self, type): return '' % type def strong(self, on, **kw): return ['**', '**'][not on] def emphasis(self, on, **kw): return ['//', '//'][not on] def highlight(self, on, **kw): return ['**', '**'][not on] def number_list(self, on, type=None, start=None, **kw): # list type not supported if on: self.list_depth += 1 self.list_type = '-' else: self.list_depth -= 1 self.list_type = ' ' return ['', '\n'][on] def bullet_list(self, on, **kw): if on: self.list_depth += 1 self.list_type = '*' else: self.list_depth -= 1 self.list_type = ' ' return ['', '\n'][on] def listitem(self, on, **kw): # somewhy blockquote uses "listitem" call return [(' ' * self.list_depth * 2) + self.list_type + ' ', '\n'][not on] def code(self, on, **kw): """ `typewriter` or {{{typerwriter}}, for code blocks i hope codeblock works """ return ["''", "''"][not on] def sup(self, on, **kw): return ['', ''][not on] def sub(self, on, **kw): return ['', ''][not on] def strike(self, on, **kw): return ['', ''][not on] def preformatted(self, on, **kw): FormatterBase.preformatted(self, on) result = '' if self.in_p: result = self.paragraph(0) return result + ['', '\n'][not on] def paragraph(self, on, **kw): FormatterBase.paragraph(self, on) if self.in_table or self.list_depth: return '' return ['', '\n\n'][not on] def linebreak(self, preformatted=1): return ['\n', '\\\n'][not preformatted] def heading(self, on, depth, **kw): # heading depth reversed in dokuwiki heading_depth = 7 - depth if on: return u'%s ' % (u'=' * heading_depth) else: return u' %s\n' % (u'=' * heading_depth) def table(self, on, attrs={}, **kw): if on: self.in_table = 1 else: self.in_table = 0 return '' def table_row(self, on, attrs={}, **kw): return ['\n', '|'][not on] def table_cell(self, on, attrs={}, **kw): return ['|', ''][not on] def anchordef(self, id): # not supported return '' def anchorlink(self, on, name='', **kw): # kw.id not supported, we hope the anchor matches existing heading on page return ('[[#', ']]') [not on] def underline(self, on, **kw): return ['__', '__'][not on] def definition_list(self, on, **kw): result = '' if self.in_p: result = self.paragraph(0) return result + ['', ''][not on] def definition_term(self, on, compact=0, **kw): return [''][not on] def definition_desc(self, on, **kw): return ['', ''][not on] def image(self, src=None, **kw): valid_attrs = ['src', 'width', 'height', 'alt', 'title'] url = src if '?' in url: url += '&' else: url += '?' attrs = {} for key, value in kw.items(): if key in valid_attrs: attrs[key] = value # TODO: finish this if attrs.has_key('width'): url += attrs['width'] return '{{' + url + '}}' def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1): syntax = '' # switch for Python: http://simonwillison.net/2004/may/7/switch/ try: syntax = { 'ColorizedPython': 'python', 'ColorizedCPlusPlus': 'cpp', }[code_type] except KeyError: pass return ('' % syntax , '')[not on] def code_line(self, on): return ('', '\n')[on] def code_token(self, on, tok_type): # not supported return '' def comment(self, text): # real comments (lines with two hash marks) if text[0:2] == '##': return "/* %s */\n" % text[2:].strip() # Some kind of Processing Instruction # http://moinmo.in/HelpOnProcessingInstructions tokens = text.lstrip('#').split(None, 1) if tokens[0] in ('language', 'format', 'refresh'): return '' if tokens[0] == 'acl': # TODO: fill acl.auth.php return '' if tokens[0] == 'deprecated': return 'This page is deprecated\n' if tokens[0] == 'redirect': return text + "\n" if tokens[0] == 'pragma': # TODO: can do 'description' via 'meta' dokuwiki plugin return "/* pragma: %s */\n" % " ".join(tokens[1:]) return "/* %s */\n" % text.lstrip('#') def macro(self, macro_obj, name, args): def email(args): mail = args.replace(' AT ', '@') mail = mail.replace(' DOT ', '.') return '[[%s|%s]]' % (mail, args) # function which will just do what parent class would def inherit(args): return apply(FormatterBase.macro, (self, macro_obj, name, args)) try: lookup = { 'BR' : '\\\\', 'MailTo' : email, 'GetText' : args, 'ShowSmileys' : inherit, }[name] except KeyError: lookup = '/* UndefinedMacro: %s(%s) */' % (name, args) if type(lookup) == FunctionType: text = lookup(args) else: text = lookup return text def smiley(self, text): try: # https://www.dokuwiki.org/devel:smileys.conf return { # note: reverse sorted '(./)' : u'✓', ':o' : ':-o', ':D' : ':-D', 'B)' : ':-D', 'B-)' : ':-D', ':\\' : ':-\\', ':))' : ':-)', ':)' : ':-)', ':(' : ':-(', ':-))' : ':-)', ';)' : ';-)', '|)' : '|-)', '' : ':!:', }[text] except KeyError: return text