1.1 --- a/moinformat/parsers/common.py Sat Jul 14 15:36:34 2018 +0200
1.2 +++ b/moinformat/parsers/common.py Sat Jul 14 16:17:36 2018 +0200
1.3 @@ -137,6 +137,15 @@
1.4 self.pos = len(self.s)
1.5 return None
1.6
1.7 + def match_groups(self):
1.8 +
1.9 + "Return the match groups."
1.10 +
1.11 + if self.match:
1.12 + return self.match.groups()
1.13 + else:
1.14 + return []
1.15 +
1.16
1.17
1.18 # Parser abstractions.
1.19 @@ -214,6 +223,12 @@
1.20
1.21 return self.items.matching
1.22
1.23 + def match_groups(self):
1.24 +
1.25 + "Return the number of groups in the match."
1.26 +
1.27 + return self.items.match_groups()
1.28 +
1.29 # Parser methods invoked from other objects.
1.30
1.31 def parse(self, s):
2.1 --- a/moinformat/parsers/moin.py Sat Jul 14 15:36:34 2018 +0200
2.2 +++ b/moinformat/parsers/moin.py Sat Jul 14 16:17:36 2018 +0200
2.3 @@ -201,7 +201,7 @@
2.4
2.5 "Create a list, starting with 'item'."
2.6
2.7 - list = List([item], item.indent, item.marker)
2.8 + list = List([item], item.indent, item.marker, item.num)
2.9 self.parse_region_details(list, self.list_pattern_names, True)
2.10 return list
2.11
2.12 @@ -209,24 +209,37 @@
2.13
2.14 "Handle a list item marker within 'region'."
2.15
2.16 + final = len(self.match_groups())
2.17 +
2.18 indent = len(self.read_match(1))
2.19 marker = self.read_match(2)
2.20 - space = self.read_match(3)
2.21 + space = self.read_match(final)
2.22 +
2.23 + if final > 3:
2.24 + num = self.read_match(3)
2.25 + else:
2.26 + num = None
2.27
2.28 last = region.node(-1)
2.29 - new_list = not isinstance(last, (List, ListItem))
2.30
2.31 - # If the marker is different and not starting a new list, or the indent
2.32 + new_list = not isinstance(last, (List, ListItem))
2.33 + same_indent = not new_list and indent == last.indent
2.34 + new_marker = not new_list and last.marker != marker and same_indent
2.35 + new_num = not new_list and num is not None and last.num != num and same_indent
2.36 +
2.37 + # If the marker or number changes at the same indent, or if the indent
2.38 # is smaller, queue the item and end the list.
2.39
2.40 - if not new_list and (last.marker != marker and indent == last.indent or
2.41 - indent < last.indent):
2.42 + # Note that Moin format does not seek to support item renumbering,
2.43 + # instead starting new lists on number changes.
2.44 +
2.45 + if not new_list and (new_marker or new_num or indent < last.indent):
2.46 self.queue_match()
2.47 self.end_region(region)
2.48
2.49 # Obtain a list item and populate it.
2.50
2.51 - item = ListItem([], indent, marker, space)
2.52 + item = ListItem([], indent, marker, space, num)
2.53 self.parse_region_details(item, self.listitem_pattern_names)
2.54
2.55 # Start a new list if not preceded by a list item, adding a trailing
2.56 @@ -462,12 +475,12 @@
2.57 "heading" : r"^(\N*)(?P<x>=+)(\s+)(?=.*?\N+(?P=x)\N*$)",
2.58 # ws... list-item [ws...]
2.59 "listitem" : r"^(\N+)(\*)(\s*)",
2.60 - # ws... number-item ws...
2.61 - "listitem_num" : r"^(\N+)(\d+\.)(\s+)",
2.62 - # ws... alpha-item ws...
2.63 - "listitem_alpha": r"^(\N+)([aA]\.)(\s+)",
2.64 - # ws... roman-item ws...
2.65 - "listitem_roman": r"^(\N+)([iI]\.)(\s+)",
2.66 + # ws... number-item ws... [# number]
2.67 + "listitem_num" : r"^(\N+)(\d+\.)(?:#(\d+))?(\s+)",
2.68 + # ws... alpha-item ws... [# number]
2.69 + "listitem_alpha": r"^(\N+)([aA]\.)(?:#(\d+))?(\s+)",
2.70 + # ws... roman-item ws... [# number]
2.71 + "listitem_roman": r"^(\N+)([iI]\.)(?:#(\d+))?(\s+)",
2.72 # ws... dot-item [ws...]
2.73 "listitem_dot" : r"^(\N+)(\.)(\s*)",
2.74 # ||
3.1 --- a/moinformat/serialisers/html.py Sat Jul 14 15:36:34 2018 +0200
3.2 +++ b/moinformat/serialisers/html.py Sat Jul 14 16:17:36 2018 +0200
3.3 @@ -109,19 +109,20 @@
3.4
3.5 return "ul", None
3.6
3.7 - def start_list(self, indent, marker):
3.8 + def start_list(self, indent, marker, num):
3.9 tag, style_type = self._get_list_tag(marker)
3.10 style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or ""
3.11 - self.out("<%s%s>" % (tag, style))
3.12 + start = style_type and num is not None and ' start="%s"' % escape_attr(num) or ""
3.13 + self.out("<%s%s%s>" % (tag, style, start))
3.14
3.15 - def end_list(self, indent, marker):
3.16 + def end_list(self, indent, marker, num):
3.17 tag, style = self._get_list_tag(marker)
3.18 self.out("</%s>" % tag)
3.19
3.20 - def start_listitem(self, indent, marker, space):
3.21 + def start_listitem(self, indent, marker, space, num):
3.22 self.out("<li>")
3.23
3.24 - def end_listitem(self, indent, marker):
3.25 + def end_listitem(self, indent, marker, space, num):
3.26 self.out("</li>")
3.27
3.28 def start_monospace(self):
4.1 --- a/moinformat/serialisers/moin.py Sat Jul 14 15:36:34 2018 +0200
4.2 +++ b/moinformat/serialisers/moin.py Sat Jul 14 16:17:36 2018 +0200
4.3 @@ -85,16 +85,16 @@
4.4 def end_linktext(self):
4.5 pass
4.6
4.7 - def start_list(self, indent, marker):
4.8 + def start_list(self, indent, marker, num):
4.9 pass
4.10
4.11 - def end_list(self, indent, marker):
4.12 + def end_list(self, indent, marker, num):
4.13 pass
4.14
4.15 - def start_listitem(self, indent, marker, space):
4.16 - self.out("%s%s%s" % (indent * " ", marker, space))
4.17 + def start_listitem(self, indent, marker, space, num):
4.18 + self.out("%s%s%s%s" % (indent * " ", marker, num is not None and "#%s" % num or "", space))
4.19
4.20 - def end_listitem(self, indent, marker):
4.21 + def end_listitem(self, indent, marker, space, num):
4.22 pass
4.23
4.24 def start_monospace(self):
5.1 --- a/moinformat/tree.py Sat Jul 14 15:36:34 2018 +0200
5.2 +++ b/moinformat/tree.py Sat Jul 14 16:17:36 2018 +0200
5.3 @@ -271,44 +271,46 @@
5.4
5.5 "A list."
5.6
5.7 - def __init__(self, nodes, indent, marker):
5.8 + def __init__(self, nodes, indent, marker, num):
5.9 Container.__init__(self, nodes)
5.10 self.indent = indent
5.11 self.marker = marker
5.12 + self.num = num
5.13
5.14 def __repr__(self):
5.15 - return "List(%r, %r, %r)" % (self.nodes, self.indent, self.marker)
5.16 + return "List(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.num)
5.17
5.18 def prettyprint(self, indent=""):
5.19 - l = ["%sList: indent=%d marker=%r" % (indent, self.indent, self.marker)]
5.20 + l = ["%sList: indent=%d marker=%r num=%r" % (indent, self.indent, self.marker, self.num)]
5.21 return self._prettyprint(l, indent)
5.22
5.23 def to_string(self, out):
5.24 - out.start_list(self.indent, self.marker)
5.25 + out.start_list(self.indent, self.marker, self.num)
5.26 self._to_string(out)
5.27 - out.end_list(self.indent, self.marker)
5.28 + out.end_list(self.indent, self.marker, self.num)
5.29
5.30 class ListItem(Container):
5.31
5.32 "A list item."
5.33
5.34 - def __init__(self, nodes, indent, marker, space):
5.35 + def __init__(self, nodes, indent, marker, space, num):
5.36 Container.__init__(self, nodes)
5.37 self.indent = indent
5.38 self.marker = marker
5.39 self.space = space
5.40 + self.num = num
5.41
5.42 def __repr__(self):
5.43 - return "ListItem(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space)
5.44 + return "ListItem(%r, %r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space, self.num)
5.45
5.46 def prettyprint(self, indent=""):
5.47 - l = ["%sListItem: indent=%d marker=%r space=%r" % (indent, self.indent, self.marker, self.space)]
5.48 + l = ["%sListItem: indent=%d marker=%r space=%r num=%r" % (indent, self.indent, self.marker, self.space, self.num)]
5.49 return self._prettyprint(l, indent)
5.50
5.51 def to_string(self, out):
5.52 - out.start_listitem(self.indent, self.marker, self.space)
5.53 + out.start_listitem(self.indent, self.marker, self.space, self.num)
5.54 self._to_string(out)
5.55 - out.end_listitem(self.indent, self.marker)
5.56 + out.end_listitem(self.indent, self.marker, self.space, self.num)
5.57
5.58 class TableAttrs(Container):
5.59
6.1 --- a/tests/test3.txt Sat Jul 14 15:36:34 2018 +0200
6.2 +++ b/tests/test3.txt Sat Jul 14 16:17:36 2018 +0200
6.3 @@ -5,4 +5,16 @@
6.4 I. What did they do for us?
6.5 1. {{{
6.6 Doing for us}}}
6.7 - a. The Romans.
6.8 + a.#18 The Romans.
6.9 +
6.10 + 1. Starting from one
6.11 + 1. Two
6.12 + 1.#3 Three?
6.13 + 1. Four?
6.14 + 1. Three
6.15 + 1.#10 New list at ten
6.16 +
6.17 + I.#100 Century
6.18 + I. Century plus one
6.19 +
6.20 +The end!