Index: trac/tests/wiki-tests.txt
===================================================================
--- trac/tests/wiki-tests.txt	(revision 1343)
+++ trac/tests/wiki-tests.txt	(working copy)
@@ -216,3 +216,33 @@
 <p>
 <sup>superscript</sup>, <sub>subscript</sub>, normal.
 </p>
+==============================
+[[HelloWorld(hej hopp)]]
+------------------------------
+<p>
+<pre class="wiki">hej hopp</pre>
+</p>
+==============================
+[[HelloWorld(hej hopp) ]] # This shouldnt executed as macro since it contain whitespace between ) and ]
+------------------------------
+<p>
+[[HelloWorld(hej hopp) ]] # This shouldnt executed as macro since it contain whitespace between ) and ]
+</p>
+==============================
+[[HelloWorld(hej hopp))]] # Extra right brace and still executed
+------------------------------
+<p>
+<pre class="wiki">hej hopp)</pre> # Extra right brace and still executed
+</p>
+==============================
+[[HelloWorld(hej hopp)]] [[HelloWorld(hej hopp2)]] # Test non greedy match
+------------------------------
+<p>
+<pre class="wiki">hej hopp</pre> <pre class="wiki">hej hopp2</pre> # Test non greedy match
+</p>
+==============================
+Inline [[html(<B> Test </B>)]] text
+------------------------------
+<p>
+Inline <B> Test </B> text
+</p>
Index: trac/tests/wiki.py
===================================================================
--- trac/tests/wiki.py	(revision 1343)
+++ trac/tests/wiki.py	(working copy)
@@ -4,6 +4,7 @@
 import StringIO
 import unittest
 
+
 class WikiTestCase(unittest.TestCase):
 
     def __init__(self, input, correct):
@@ -13,7 +14,7 @@
     
     def test(self):
         """Testing WikiFormatter"""
-        from trac import Href, Logging
+        from trac import Href, Mimeview, Logging
         class Environment:
             def __init__(self):
                 self.log = Logging.logger_factory('null')
@@ -21,6 +22,7 @@
                 self.href = Href.Href('/')
                 self.abs_href = Href.Href('http://www.example.com/')
                 self._wiki_pages = {}
+                self.mimeview = Mimeview.Mimeview(self)
         class Cursor:
             def execute(self, *kwargs): pass
             def fetchone(self): return []
@@ -30,7 +32,8 @@
 
         out = StringIO.StringIO()
         Formatter(None, Environment(), Connection()).format(self.input, out)
-        self.assertEquals(self.correct, out.getvalue())
+        v = out.getvalue().replace('\r','')
+        self.assertEquals(self.correct, v)
 
 def suite():
     suite = unittest.TestSuite()
Index: trac/util.py
===================================================================
--- trac/util.py	(revision 1343)
+++ trac/util.py	(working copy)
@@ -62,6 +62,17 @@
                     .replace('>', '&gt;') \
                     .replace('"', '&#34;')
 
+def unescape(text):
+    """Reverses Escapes &, <, > and \""""
+    if not text:
+        return ''
+    if type(text) is StringType:
+        text = text.replace('&#34;', '"') \
+               .replace('&gt;', '>') \
+               .replace('&lt;', '<') \
+               .replace('&amp;', '&') 
+    return text
+
 def get_first_line(text, maxlen):
     """
     returns the first line of text. If the line is longer then
Index: trac/wikimacros/rst.py
===================================================================
--- trac/wikimacros/rst.py	(revision 1343)
+++ trac/wikimacros/rst.py	(working copy)
@@ -44,16 +44,20 @@
     raise EnvironmentError, 'Docutils version >= %s required, %s found' % (docutils_required, __version__)
 
 from trac.Href import Href
+from trac.WikiFormatter import WikiProcessor
 
 __docformat__ = 'reStructuredText'
 
-WIKI_LINK = re.compile(r'(?:wiki:)?(?P<w>[A-Za-z][\w\#\?]*[^\w\#\?]*)') # Links must begin with Letters, \# ? so we can link inside pages.
-#WIKI_LINK = re.compile(r'(?:wiki:)?(?P<w>(^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)')
+WIKI_LINK = re.compile(r'(?:wiki:)?(.+)')
+#WIKI_LINK = re.compile(r'(?:wiki:)?(?P<wikilink>[A-Za-z][\w\-]*[^\w\#\?]*)')
 TICKET_LINK = re.compile(r'(?:#(\d+))|(?:ticket:(\d+))')
 REPORT_LINK = re.compile(r'(?:{(\d+)})|(?:report:(\d+))')
 CHANGESET_LINK = re.compile(r'(?:\[(\d+)\])|(?:changeset:(\d+))')
 FILE_LINK = re.compile(r'(?:browser|repos|source):([^#]+)#?(.*)')
 
+#import trac.Logging
+#log = trac.Logging.logger_factory(logtype='file', logfile="/tmp/debug_rst.txt", level='ALL')
+
 def _wikipage(href, args):
     return href.wiki(args[0])
 
@@ -72,23 +76,26 @@
     return href.browser(path, rev)
 
 # TracLink REs and callback functions
-LINKS = [(WIKI_LINK, _wikipage),
-         (TICKET_LINK, _ticket),
+LINKS = [(TICKET_LINK, _ticket),
          (REPORT_LINK, _report),
          (CHANGESET_LINK, _changeset),
-         (FILE_LINK, _browser)]
+         (FILE_LINK, _browser),
+         (WIKI_LINK, _wikipage)]
 
 
-def trac_get_reference(env, rawtext, text):
+def trac_get_reference(env, rawtext, link, text):
     for (pattern, function) in LINKS:
-        m = pattern.match(text)
+        m = pattern.match(link)
         if m:
             g = filter(None, m.groups())
             missing = 0
+            if not text:
+                text = g[0]
             if pattern == WIKI_LINK:
-                if not (env._wiki_pages.has_key(g[0])):
-                        missing = 1
-                        text = text + "?"
+                pagename = re.search(r'^[^\#]+',g[0])
+                if not (env._wiki_pages.has_key(pagename.group())):
+                    missing = 1
+                    text = text + "?"
             uri = function(env.href, g)
             reference = nodes.reference(rawtext, text)
             reference['refuri']= uri
@@ -120,8 +127,12 @@
 
     .. _TracLink: http://projects.edgewall.com/trac/wiki/TracLinks
     """
-    text = arguments[int(len(arguments) == 2)]
-    reference = trac_get_reference(env, block_text, text)
+    link = arguments[0]
+    if len(arguments) == 2:
+        text = arguments[1]
+    else:
+        text = None
+    reference = trac_get_reference(env, block_text, link, text)
     if reference:
         return reference
     # didn't find a match (invalid TracLink),
@@ -134,7 +145,13 @@
 
 
 def trac_role(env, name, rawtext, text, lineno, inliner, options={}, content=[]):
-    reference = trac_get_reference(env, rawtext, text)
+    args  = text.split(" ",1)
+    link = args[0]
+    if len(args)==2:
+        text = args[1]
+    else:
+        text = None
+    reference = trac_get_reference(env, rawtext, link, text)
     if reference:
         return [reference], []
     warning = nodes.warning(None,
@@ -160,6 +177,27 @@
     rst.roles.register_local_role('trac', do_trac_role)
 
     # The code_block could is taken from the leo plugin rst2
+    def code_formatter(language, text):
+        #log.debug("language '%s' args '%s'", % (language, arguments))
+        Format = WikiProcessor(env, language)
+        html = Format.process(hdf, text)        
+        #log.debug("language '%s' htmltext '%s'" % (language, html))
+        raw = nodes.raw('',html, format='html') #(self, rawsource='', text='', *children, **attributes):
+        return raw
+        
+    def code_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
+        args  = text.split(":",1)
+        language = args[0]
+        if len(args)==2:
+            text = args[1]
+        else:
+            text = ""
+        #log.debug("coderole '%s' text '%s'" % (language, text))
+        reference = code_formatter(language, text)
+        return [reference], []
+        
+
+      
     def code_block(name,arguments,options,content,lineno,content_offset,block_text,state,state_machine):
 
         """Create a code-block directive for docutils.
@@ -167,24 +205,11 @@
         Usage: .. code-block:: language
 
         If the language can be syntax highlighted it will be."""
-
-
-        
-        from trac.WikiFormatter import Formatter
-        
         language = arguments[0]
+        text = '\n'.join(content)        
+        reference = code_formatter(language, text)
+        return [reference]
 
-        code_processor = None
-        if  Formatter.builtin_processors.has_key(language):
-            code_processor = Formatter.builtin_processors[language]
-        else:
-            code_processor = Formatter.builtin_processors['default']
-
-
-        html = code_processor(hdf, '\n'.join(content), env)        
-        raw = nodes.raw('',html, format='html') #(self, rawsource='', text='', *children, **attributes):
-        return [raw]
-
     # These are documented at http://docutils.sourceforge.net/spec/howto/rst-directives.html.
     code_block.arguments = (
         1, # Number of required arguments.
@@ -200,6 +225,7 @@
     code_block.content = 1 # True if content is allowed.
     # Register the directive with docutils.
     rst.directives.register_directive('code-block',code_block)
+    rst.roles.register_local_role('code-block', code_role)
     
     
 
Index: trac/Mimeview.py
===================================================================
--- trac/Mimeview.py	(revision 1343)
+++ trac/Mimeview.py	(working copy)
@@ -52,14 +52,14 @@
     'make':'text/x-makefile', 'mk':'text/x-makefile', 'Makefile':'text/x-makefile',
     'mail':'text/x-mail',
     'pas':'text/x-pascal',
-    'pl':'text/x-perl', 'pm':'text/x-perl', 'PL':'text/x-perl',
+    'pl':'text/x-perl', 'pm':'text/x-perl', 'PL':'text/x-perl', 'perl':'text/x-perl',
     'php':'text/x-php', 'php4':'text/x-php', 'php3':'text/x-php',
     'ps':'application/postscript',
     'psp':'text/x-psp',
-    'py':'text/x-python',
+    'py':'text/x-python', 'python':'text/x-python',
     'pyx':'text/x-pyrex',
     'nroff':'application/x-troff', 'roff':'application/x-troff', 'troff':'application/x-troff',
-    'rb':'text/x-ruby',
+    'rb':'text/x-ruby', 'ruby':'text/x-ruby',
     'rfc':'text/x-rfc',
     'scm':'text/x-scheme',
     'sh':'application/x-sh',
@@ -69,7 +69,7 @@
     'tex':'text/x-tex',
     'vba':'text/x-vba',
     'bas':'text/x-vba',
-    'v':'text/x-verilog',
+    'v':'text/x-verilog', 'verilog':'text/x-verilog',
     'vhd':'text/x-vhdl',
     'vrml':'model/vrml',
     'wrl':'model/vrml',
Index: trac/WikiFormatter.py
===================================================================
--- trac/WikiFormatter.py	(revision 1343)
+++ trac/WikiFormatter.py	(working copy)
@@ -26,10 +26,89 @@
 import StringIO
 
 import util
+import Mimeview
 
-__all__ = ['Formatter', 'OneLinerFormatter', 'wiki_to_html', 'wiki_to_oneliner']
+__all__ = ['Formatter', 'OneLinerFormatter', 'wiki_to_html', 'wiki_to_oneliner', 'WikiProcessor']
 
 
+def system_message(msg, text):
+    return """<div class="system-message">
+ <strong>%s</strong>
+ <pre>%s</pre>
+</div>
+""" % (msg, util.escape(text))
+    
+
+class WikiProcessor:
+
+    mime_type = ""
+
+    def __init__(self, env, name):
+        self.env = env
+        self.error = self.set_code_processor(name)
+    
+    def default_processor(hdf, text, env):
+        return '<pre class="wiki">' + util.escape(text) + '</pre>'
+    
+    def html_processor(hdf, text, env):
+        if Formatter._htmlproc_disallow_rule.search(text):
+            err = system_message('Error: HTML block contains disallowed tags.', text)
+            env.log.error(err)
+            return err
+        if Formatter._htmlproc_disallow_attribute.search(text):
+            err = system_message('Error: HTML block contains disallowed attributes.', text)
+            env.log.error(err)
+            return err
+        return text
+
+    def mime_processor(self, hdf, text, env):
+        return env.mimeview.display(text, self.mime_type)
+    
+    builtin_processors = { 'html': html_processor,
+                           'default': default_processor}
+
+    def process(self, hdf, text, inline=False):
+        text = self.code_processor(hdf, text, self.env)
+        if inline:
+            code_block_start = re.compile('^<div class="code-block">')
+            code_block_end = re.compile('</div>$')
+            text, nr = code_block_start.subn('<span class="code-block">', text, 1 )
+            if nr:
+                text, nr = code_block_end.subn('</span>', text, 1 )
+            return text
+        else:
+            return text
+    
+
+    def set_code_processor(self, name):
+        if  self.builtin_processors.has_key(name):
+            self.code_processor = self.builtin_processors[name]
+        else:
+            try:
+                self.code_processor = self.load_macro(name)
+            except Exception, e:
+                if Mimeview.MIME_MAP.has_key(name):
+                    name = Mimeview.MIME_MAP[name]
+                mimeviewer, exists = self.env.mimeview.get_viewer(name)
+                if exists != -1:
+                    self.mime_type = name
+                    self.code_processor = self.mime_processor
+                else:
+                    self.code_processor = self.builtin_processors['default']
+                    return 1
+        return 0
+    
+    def load_macro(self, name):
+        # Look in envdir/wiki-macros/ first
+        try:
+            module = imp.load_source(name, os.path.join(self.env.path, 'wiki-macros', name+'.py'))
+        except IOError:
+            # fall back to site-wide macros
+            macros = __import__('wikimacros.' + name, globals(),  locals(), [])
+            module = getattr(macros, name)
+        return module.execute
+
+
 class CommonFormatter:
     """This class contains the patterns common to both Formatter and
     OneLinerFormatter"""
@@ -263,7 +342,7 @@
     """
     _rules = [r"""(?P<svnimg>(source|repos):([^ ]+)\.(PNG|png|JPG|jpg|JPEG|jpeg|GIF|gif))"""] + \
              CommonFormatter._rules + \
-             [r"""(?P<macro>!?\[\[(?P<macroname>[a-zA-Z]+)(\((?P<macroargs>[^\)]*)\))?\]\])""",
+             [r"""(?P<macro>!?\[\[(?P<macroname>[\w/+-]+)(\]\]|\((?P<macroargs>.*?)\)\]\]))""",
               r"""(?P<heading>^\s*(?P<hdepth>=+)\s.*\s(?P=hdepth)\s*$)""",
               r"""(?P<list>^(?P<ldepth>\s+)(?:\*|[0-9]+\.) )""",
               r"""(?P<indent>^(?P<idepth>\s+)(?=\S))""",
@@ -273,9 +352,9 @@
               r"""(?P<table_cell>\|\|)"""]
 
     _compiled_rules = re.compile('(?:' + string.join(_rules, '|') + ')')
-    _processor_re = re.compile('#\!([a-zA-Z0-9/+-]+)')
+    _processor_re = re.compile('#\!([\w/+-]+)')
     _anchor_re = re.compile('[^\w\d\.-:]+', re.UNICODE)
-    mime_type = ""
+    #801- mime_type = ""
     anchors = None
 
     hdf = None
@@ -296,89 +375,17 @@
         self.hdf = hdf
         self.anchors = []
 
-    def default_processor(hdf, text, env):
-        return '<pre class="wiki">' + util.escape(text) + '</pre>'
-    def asp_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-asp')
-    def c_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-csrc')
-    def css_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/css')
-    def java_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-java')
-    def cpp_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-c++src')
-    def perl_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-perl')
-    def php_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-php')
-    def python_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-python')
-    def ruby_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-ruby')
-    def sql_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-sql')
-    def xml_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/xml')
-    def verilog_processor(hdf, text, env):
-        return env.mimeview.display(text, 'text/x-verilog')
-    def html_processor(hdf, text, env):
-        if Formatter._htmlproc_disallow_rule.search(text):
-            err = """\
-<div class="system-message">
- <strong>Error: HTML block contains disallowed tags.</strong>
- <pre>%s</pre>
-</div>\n""" % util.escape(text)
-            env.log.error(err)
-            return err
-        if Formatter._htmlproc_disallow_attribute.search(text):
-            err = """\
-<div class="system-message">
- <strong>Error: HTML block contains disallowed attributes.</strong>
- <pre>%s</pre>
-</div>\n""" % util.escape(text)
-            env.log.error(err)
-            return err
-        return text
-    def mime_processor(self, hdf, text, env):
-        return env.mimeview.display(text, self.mime_type)
-
-    builtin_processors = { 'html': html_processor,
-                           'asp': asp_processor,
-                           'c': c_processor,
-                           'css': css_processor,
-                           'cpp': cpp_processor,
-                           'java': java_processor,
-                           'php': php_processor,
-                           'perl': perl_processor,
-                           'python': python_processor,
-                           'ruby': ruby_processor,
-                           'sql': sql_processor,
-                           'xml': xml_processor,
-                           'verilog': verilog_processor,
-                           'default': default_processor}
-
-    def load_macro(self, name):
-        # Look in envdir/wiki-macros/ first
-        try:
-            module = imp.load_source(name, os.path.join(self.env.path, 'wiki-macros', name+'.py'))
-        except IOError:
-            # fall back to site-wide macros
-            macros = __import__('wikimacros.' + name, globals(),  locals(), [])
-            module = getattr(macros, name)
-        return module.execute
-
     def _macro_formatter(self, match, fullmatch):
         name = fullmatch.group('macroname')
         if name in ['br', 'BR']:
             return '<br />'
         args = fullmatch.group('macroargs')
+        args = util.unescape(args)
         try:
-            macro = self.load_macro(name)
-            return macro(self.hdf, args, self.env)
+            macro = WikiProcessor(self.env, name)
+            return macro.process(self.hdf, args, 1)
         except Exception, e:
-            return '<div class="system-message"><strong>Error: Macro %s(%s) failed</strong><pre>%s</pre></div>' \
-                   % (name, args, e)
+            return system_message('Error: Macro %s(%s) failed' % (name, args), e)
 
     def _heading_formatter(self, match, fullmatch):
         match = match.strip()
@@ -533,36 +540,26 @@
             else:
                 self.code_text += line + os.linesep
                 if not self.code_processor:
-                    self.code_processor = Formatter.builtin_processors['default']
+                    self.code_processor = WikiProcessor(self.env, 'default')
         elif line.strip() == '}}}':
             self.in_code_block -= 1
             if self.in_code_block == 0 and self.code_processor:
                 self.close_paragraph()
                 self.close_table()
-                self.out.write(self.code_processor(self.hdf, self.code_text, self.env))
+                self.out.write(self.code_processor.process(self.hdf, self.code_text))
             else:
                 self.code_text += line + os.linesep
         elif not self.code_processor:
             match = Formatter._processor_re.search(line)
             if match:
                 name = match.group(1)
-                if  Formatter.builtin_processors.has_key(name):
-                    self.code_processor = Formatter.builtin_processors[name]
-                else:
-                    try:
-                        self.code_processor = self.load_macro(name)
-                    except Exception, e:
-                        mimeviewer, exists = self.env.mimeview.get_viewer(name)
-                        if exists != -1:
-                            self.mime_type = name
-                            self.code_processor = self.mime_processor
-                        else:
-                            self.code_text += line + os.linesep
-                            self.code_processor = Formatter.builtin_processors['default']
-                            self.out.write('<div class="system-message"><strong>Error: Failed to load processor <code>%s</code></strong>:<pre>%s</pre></div>' % (name, e))
+                self.code_processor = WikiProcessor(self.env, name)
+                if self.code_processor.error:
+                    self.out.write(system_message('Error: Failed to load processor <code>%s</code>' % name, e))
+                    self.code_text += line + os.linesep
             else:
                 self.code_text += line + os.linesep 
-                self.code_processor = Formatter.builtin_processors['default']
+                self.code_processor = WikiProcessor(self.env, 'default')
         else:
             self.code_text += line + os.linesep
 
