WikiProcessors: fix a potential problem with processor arguments.

At the same time, this makes it now possible to differentiate between being callled as a macro (`self.args is None`) and via a code block.

Related to #8204.

diff --git a/trac/wiki/formatter.py b/trac/wiki/formatter.py
--- a/trac/wiki/formatter.py
+++ b/trac/wiki/formatter.py
@@ -67,7 +67,7 @@ class WikiProcessor(object):
     _block_elem_re = re.compile(r'^\s*<(?:div|table)(?:\s+[^>]+)?>',
                                 re.I | re.M)
 
-    def __init__(self, formatter, name, args={}):
+    def __init__(self, formatter, name, args=None):
         """Find the processor by name
         
         :param formatter: the formatter embedding a call for this processor 
@@ -155,7 +155,7 @@ class WikiProcessor(object):
         
     def _elt_processor(self, eltname, format_to, text, args):
         # Note: as long as _processor_param_re is not re.UNICODE, **args is OK
-        elt = getattr(tag, eltname)(**args)
+        elt = getattr(tag, eltname)(**(args or {}))
         if not WikiSystem(self.env).render_unsafe_content:
             sanitized_elt = getattr(tag, eltname)
             for (k, data, pos) in (Stream(elt) | self._sanitizer):
@@ -166,6 +166,8 @@ class WikiProcessor(object):
         return elt
 
     def _div_processor(self, text):
+        if not self.args:
+            self.args = {}
         if 'class' not in self.args:
             self.args['class'] = 'wikipage'
         return self._elt_processor('div', format_to_html, text, self.args)
@@ -190,6 +192,8 @@ class WikiProcessor(object):
             return system_message(e)
     
     def _table_processor(self, text):
+        if not self.args:
+            self.args = {}
         if 'class' not in self.args:
             self.args['class'] = 'wiki'
         try:
diff --git a/trac/wiki/tests/formatter.py b/trac/wiki/tests/formatter.py
--- a/trac/wiki/tests/formatter.py
+++ b/trac/wiki/tests/formatter.py
@@ -66,6 +66,15 @@ class NoneMacro(WikiMacroBase):
     def expand_macro(self, formatter, name, content):
         return None
 
+class WikiProcessorSampleMacro(WikiMacroBase):
+    def expand_macro(self, formatter, name, content, args):
+        if args is None:
+            return 'Called as a macro: ' + content
+        else:
+            return 'Called as a processor with params: <dl>%s</dl>' % \
+                ''.join('<dt>%s</dt><dd>%s</dd>' % kv for kv in args.items()) \
+                + content
+
 class SampleResolver(Component):
     """A dummy macro returning a div block, used by the unit test."""
 
diff --git a/trac/wiki/tests/wiki-tests.txt b/trac/wiki/tests/wiki-tests.txt
--- a/trac/wiki/tests/wiki-tests.txt
+++ b/trac/wiki/tests/wiki-tests.txt
@@ -687,6 +687,20 @@ After
 Before
  […]
 After
+============================== WikiProcessor default arguments
+[[div(Div has 'wikipage' class.)]]
+[[table()]]
+Table must have 'wiki' class.
+------------------------------
+<p>
+</p><div class="wikipage"><p>
+Div has 'wikipage' class.
+</p>
+</div><p>
+</p><table class="wiki"></table><p>
+Table must have 'wiki' class.
+</p>
+------------------------------
 ============================== div and span wiki processors
 And now it's [[span('''TIME FOR BED!,class=important)]]. Really.
 {{{
@@ -870,6 +884,21 @@ Hello World, args = hej hopp Hello World
 </p>
 ------------------------------
 [[None(...)]] nada
+============================== WikiProcessor defined as a macro
+[[WikiProcessorSample(inlined content)]]
+{{{#!WikiProcessorSample arg1=this arg2="the second argument"
+multiline
+content
+}}}
+------------------------------
+<p>
+Called as a macro: inlined content
+</p>
+Called as a processor with params: <dl><dt>arg1</dt><dd>this</dd><dt>arg2</dt><dd>the second argument</dd></dl>multiline
+content
+------------------------------
+[[WikiProcessorSample(...)]]
+ […]
 ============================== Inlined HTML wiki processor
 Inline [[html(<B> Test </B>)]] text
 ------------------------------

