# -*- coding: iso8859-1 -*- # # Copyright (C) 2003-2005 Edgewall Software # Copyright (C) 2003-2005 Jonas Borgström # Copyright (C) 2004-2005 Christopher Lenz # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.com/license.html. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://projects.edgewall.com/trac/. # # Author: Jonas Borgström # Christopher Lenz from __future__ import generators import re import os import string import urllib try: from cStringIO import StringIO except ImportError: from StringIO import StringIO from trac import util from trac.mimeview import * from trac.wiki.api import WikiSystem __all__ = ['wiki_to_html', 'wiki_to_oneliner', 'wiki_to_outline'] # # Customization of the Wiki syntax ***use with care*** # BOLDITALIC_TOKEN = "'''''" BOLD_TOKEN = "'''" ITALIC_TOKEN = "''" UNDERLINE_TOKEN = "__" STRIKE_TOKEN = "~~" SUBSCRIPT_TOKEN = ",," SUPERSCRIPT_TOKEN = r"\^" INLINE_TOKEN = "`" LINK_SCHEME = r"[\w.+-]+" # as per RFC 2396 def system_message(msg, text): return """
%s
%s
""" % (msg, util.escape(text)) class WikiProcessor(object): def __init__(self, env, name): self.env = env self.name = name self.error = None builtin_processors = {'html': self._html_processor, 'default': self._default_processor, 'comment': self._comment_processor} self.processor = builtin_processors.get(name) if not self.processor: # Find a matching wiki macro from trac.wiki import WikiSystem wiki = WikiSystem(self.env) for macro_provider in wiki.macro_providers: if self.name in list(macro_provider.get_macros()): self.processor = self._macro_processor break if not self.processor: # Find a matching mimeview renderer from trac.mimeview.api import MIME_MAP if self.name in MIME_MAP.keys(): self.name = MIME_MAP[self.name] self.processor = self._mimeview_processor elif self.name in MIME_MAP.values(): self.processor = self._mimeview_processor else: self.processor = self._default_processor self.error = 'No macro named [[%s]] found' % name def _comment_processor(self, req, text): return '' def _default_processor(self, req, text): return '
' + util.escape(text) + '
\n' def _html_processor(self, req, text): if Formatter._htmlproc_disallow_rule.search(text): err = system_message('Error: HTML block contains disallowed tags.', text) self.env.log.error(err) return err if Formatter._htmlproc_disallow_attribute.search(text): err = system_message('Error: HTML block contains disallowed attributes.', text) self.env.log.error(err) return err return text def _macro_processor(self, req, text): from trac.wiki import WikiSystem wiki = WikiSystem(self.env) for macro_provider in wiki.macro_providers: if self.name in list(macro_provider.get_macros()): self.env.log.debug('Executing Wiki macro %s by provider %s' % (self.name, macro_provider)) return macro_provider.render_macro(req, self.name, text) def _mimeview_processor(self, req, text): return Mimeview(self.env).render(req, self.name, text) def process(self, req, text, inline=False): if self.error: return system_message('Error: Failed to load processor %s' % self.name, self.error) text = self.processor(req, text) if inline: code_block_start = re.compile('^
') code_block_end = re.compile('
$') text, nr = code_block_start.subn('', text, 1 ) if nr: text, nr = code_block_end.subn('', text, 1 ) return text else: return text class Formatter(object): flavor = 'default' _link_resolvers = None # Rules provided by IWikiSyntaxProviders are inserted between pre_rules and post_rules _pre_rules = [r"(?P%s)" % BOLDITALIC_TOKEN, r"(?P%s)" % BOLD_TOKEN, r"(?P%s)" % ITALIC_TOKEN, r"(?P!?%s)" % UNDERLINE_TOKEN, r"(?P!?%s)" % STRIKE_TOKEN, r"(?P!?%s)" % SUBSCRIPT_TOKEN, r"(?P!?%s)" % SUPERSCRIPT_TOKEN, r"(?P!?\{\{\{(?P.*?)\}\}\})", r"(?P!?%s(?P.*?)%s)" % (INLINE_TOKEN, INLINE_TOKEN), r"(?P!?&#\d+;)"] _post_rules = [(r"(?P!?((?P%s):" % LINK_SCHEME + r"(?P'[^']+'|\"[^\"]+\"|" r"((\|(?=[^| ])|[^| ])*[^|'~_\., \)]))))"), (r"(?P!?\[(?:(?P%s):" % LINK_SCHEME + r"(?P'[^']+'|\"[^\"]+\"|[^\] ]+)" r"|(?P[/.][^ [\]]*))" r"(?: (?P