Index: trac/wiki/formatter.py
===================================================================
--- trac/wiki/formatter.py	(revision 3271)
+++ trac/wiki/formatter.py	(working copy)
@@ -193,7 +193,7 @@
          r"(\]\]|\((?P<macroargs>.*?)\)\]\]))"),
         # heading, list, definition, indent, table...
         r"(?P<heading>^\s*(?P<hdepth>=+)\s.*\s(?P=hdepth)\s*$)",
-        r"(?P<list>^(?P<ldepth>\s+)(?:\*|\d+\.|[a-zA-Z]\.|[ivxIVX]{1,5}\.) )",
+        r"(?P<list>^(?P<ldepth>\s+)(?:[-*]|\d+\.|[a-zA-Z]\.|[ivxIVX]{1,5}\.) )",
         r"(?P<definition>^\s+((?:%s.*?%s|%s.*?%s|[^%s%s])+?::)(?:\s+|$))"
         % (INLINE_TOKEN, INLINE_TOKEN, STARTBLOCK_TOKEN, ENDBLOCK_TOKEN,
            INLINE_TOKEN, STARTBLOCK[0]),
@@ -456,11 +456,10 @@
     
     def _list_formatter(self, match, fullmatch):
         ldepth = len(fullmatch.group('ldepth'))
-        depth = int((len(fullmatch.group('ldepth')) + 1) / 2)
         listid = match[ldepth]
-        self.in_list_item = depth > 0
+        self.in_list_item = True
         class_ = start = None
-        if listid == '*':
+        if listid in '-*':
             type_ = 'ul'
         else:
             type_ = 'ol'
@@ -473,41 +472,47 @@
                 class_ = 'loweralpha'
             elif listid.isupper():
                 class_ = 'upperalpha'
-        self._set_list_depth(depth, type_, class_, start)
+        self._set_list_depth(ldepth, type_, class_, start)
         return ''
 
-    def _set_list_depth(self, depth, type_, class_, start):
-        current_depth = len(self._list_stack)
-        diff = depth - current_depth
+    def _get_list_depth(self):
+        """Return the space offset associated to the deepest opened list."""
+        return self._list_stack and self._list_stack[-1][1] or 0
+        
+    def _set_list_depth(self, depth, new_type, class_, start):
         self.close_table()
         self.close_paragraph()
         self.close_indentation()
-        begin_list = type_
-        if class_:
-            begin_list += ' class="%s"' % class_
-        if start:
-            begin_list += start and ' start="%s"' % start
-        if diff > 0:
-            for i in range(diff):
-                self._list_stack.append(type_)
-                self.out.write('<%s><li>' % begin_list)
-        elif diff < 0:
-            for i in range(-diff):
-                tmp = self._list_stack.pop()
-                self.out.write('</li></%s>' % tmp)
-            if self._list_stack != [] and type_ != self._list_stack[-1]:
-                tmp = self._list_stack.pop()
-                self._list_stack.append(type_)
-                self.out.write('</li></%s><%s><li>' % (tmp, begin_list))
+        def open_list():
+            self._list_stack.append((new_type, depth))
+            self.out.write('<%s%s%s><li>' %
+                           (new_type, class_ and ' class="%s"' % class_ or '',
+                            start and ' start="%s"' % start or ''))
+        def close_list(tp):
+            self._list_stack.pop()
+            self.out.write('</li></%s>' % tp)
+
+        # depending on the indent/dedent, open or close lists
+        if depth > self._get_list_depth():
+            open_list()
+        else:
+            while self._list_stack:
+                deepest_type, deepest_offset = self._list_stack[-1]
+                if depth >= deepest_offset:
+                    break
+                close_list(deepest_type)
             if depth > 0:
-                self.out.write('</li><li>')
-        # diff == 0
-        elif self._list_stack != [] and type_ != self._list_stack[-1]:
-            tmp = self._list_stack.pop()
-            self._list_stack.append(type_)
-            self.out.write('</li></%s><%s><li>' % (tmp, begin_list))
-        elif depth > 0:
-            self.out.write('</li><li>')
+                if self._list_stack:
+                    old_type, old_offset = self._list_stack[-1]
+                    if old_type != new_type:
+                        close_list(old_type)
+                        open_list()
+                    else:
+                        if old_offset != depth: # adjust last depth
+                            self._list_stack[-1] = (old_type, depth)
+                        self.out.write('</li><li>')
+                else:
+                    open_list()
 
     def close_list(self):
         if self._list_stack != []:
@@ -536,6 +541,8 @@
         self.indent_level = 0
 
     def open_indentation(self, depth):
+        # transform number of space characters into indent level
+        depth = (depth+1)/2
         if self.in_def_list:
             return
         diff = depth - self.indent_level
@@ -545,15 +552,15 @@
             self.close_indentation()
             self.close_list()
             self.indent_level = depth
-            self.out.write(('<blockquote>' + os.linesep) * depth)
+            self.out.write(('<blockquote>' + os.linesep) * self.indent_level)
 
     def _indent_formatter(self, match, fullmatch):
-        depth = int((len(fullmatch.group('idepth')) + 1) / 2)
-        list_depth = len(self._list_stack)
-        if list_depth > 0 and depth == list_depth + 1:
-            self.in_list_item = 1
+        idepth = len(fullmatch.group('idepth'))
+        ldepth = self._get_list_depth()
+        if ldepth > 0 and 0 <= (idepth - ldepth) <= 2:
+            self.in_list_item = True
         else:
-            self.open_indentation(depth)
+            self.open_indentation(idepth)
         return ''
 
     # Table

