# HG changeset patch # User Paul Boddie # Date 1531577856 -7200 # Node ID 21bc17cf10003d91dec54da2b4cffb5ea0c07098 # Parent 7a75493076a80c9234297baa6d9438804b618829 Added list item renumbering support. diff -r 7a75493076a8 -r 21bc17cf1000 moinformat/parsers/common.py --- a/moinformat/parsers/common.py Sat Jul 14 15:36:34 2018 +0200 +++ b/moinformat/parsers/common.py Sat Jul 14 16:17:36 2018 +0200 @@ -137,6 +137,15 @@ self.pos = len(self.s) return None + def match_groups(self): + + "Return the match groups." + + if self.match: + return self.match.groups() + else: + return [] + # Parser abstractions. @@ -214,6 +223,12 @@ return self.items.matching + def match_groups(self): + + "Return the number of groups in the match." + + return self.items.match_groups() + # Parser methods invoked from other objects. def parse(self, s): diff -r 7a75493076a8 -r 21bc17cf1000 moinformat/parsers/moin.py --- a/moinformat/parsers/moin.py Sat Jul 14 15:36:34 2018 +0200 +++ b/moinformat/parsers/moin.py Sat Jul 14 16:17:36 2018 +0200 @@ -201,7 +201,7 @@ "Create a list, starting with 'item'." - list = List([item], item.indent, item.marker) + list = List([item], item.indent, item.marker, item.num) self.parse_region_details(list, self.list_pattern_names, True) return list @@ -209,24 +209,37 @@ "Handle a list item marker within 'region'." + final = len(self.match_groups()) + indent = len(self.read_match(1)) marker = self.read_match(2) - space = self.read_match(3) + space = self.read_match(final) + + if final > 3: + num = self.read_match(3) + else: + num = None last = region.node(-1) - new_list = not isinstance(last, (List, ListItem)) - # If the marker is different and not starting a new list, or the indent + new_list = not isinstance(last, (List, ListItem)) + same_indent = not new_list and indent == last.indent + new_marker = not new_list and last.marker != marker and same_indent + new_num = not new_list and num is not None and last.num != num and same_indent + + # If the marker or number changes at the same indent, or if the indent # is smaller, queue the item and end the list. - if not new_list and (last.marker != marker and indent == last.indent or - indent < last.indent): + # Note that Moin format does not seek to support item renumbering, + # instead starting new lists on number changes. + + if not new_list and (new_marker or new_num or indent < last.indent): self.queue_match() self.end_region(region) # Obtain a list item and populate it. - item = ListItem([], indent, marker, space) + item = ListItem([], indent, marker, space, num) self.parse_region_details(item, self.listitem_pattern_names) # Start a new list if not preceded by a list item, adding a trailing @@ -462,12 +475,12 @@ "heading" : r"^(\N*)(?P=+)(\s+)(?=.*?\N+(?P=x)\N*$)", # ws... list-item [ws...] "listitem" : r"^(\N+)(\*)(\s*)", - # ws... number-item ws... - "listitem_num" : r"^(\N+)(\d+\.)(\s+)", - # ws... alpha-item ws... - "listitem_alpha": r"^(\N+)([aA]\.)(\s+)", - # ws... roman-item ws... - "listitem_roman": r"^(\N+)([iI]\.)(\s+)", + # ws... number-item ws... [# number] + "listitem_num" : r"^(\N+)(\d+\.)(?:#(\d+))?(\s+)", + # ws... alpha-item ws... [# number] + "listitem_alpha": r"^(\N+)([aA]\.)(?:#(\d+))?(\s+)", + # ws... roman-item ws... [# number] + "listitem_roman": r"^(\N+)([iI]\.)(?:#(\d+))?(\s+)", # ws... dot-item [ws...] "listitem_dot" : r"^(\N+)(\.)(\s*)", # || diff -r 7a75493076a8 -r 21bc17cf1000 moinformat/serialisers/html.py --- a/moinformat/serialisers/html.py Sat Jul 14 15:36:34 2018 +0200 +++ b/moinformat/serialisers/html.py Sat Jul 14 16:17:36 2018 +0200 @@ -109,19 +109,20 @@ return "ul", None - def start_list(self, indent, marker): + def start_list(self, indent, marker, num): tag, style_type = self._get_list_tag(marker) style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or "" - self.out("<%s%s>" % (tag, style)) + start = style_type and num is not None and ' start="%s"' % escape_attr(num) or "" + self.out("<%s%s%s>" % (tag, style, start)) - def end_list(self, indent, marker): + def end_list(self, indent, marker, num): tag, style = self._get_list_tag(marker) self.out("" % tag) - def start_listitem(self, indent, marker, space): + def start_listitem(self, indent, marker, space, num): self.out("
  • ") - def end_listitem(self, indent, marker): + def end_listitem(self, indent, marker, space, num): self.out("
  • ") def start_monospace(self): diff -r 7a75493076a8 -r 21bc17cf1000 moinformat/serialisers/moin.py --- a/moinformat/serialisers/moin.py Sat Jul 14 15:36:34 2018 +0200 +++ b/moinformat/serialisers/moin.py Sat Jul 14 16:17:36 2018 +0200 @@ -85,16 +85,16 @@ def end_linktext(self): pass - def start_list(self, indent, marker): + def start_list(self, indent, marker, num): pass - def end_list(self, indent, marker): + def end_list(self, indent, marker, num): pass - def start_listitem(self, indent, marker, space): - self.out("%s%s%s" % (indent * " ", marker, space)) + def start_listitem(self, indent, marker, space, num): + self.out("%s%s%s%s" % (indent * " ", marker, num is not None and "#%s" % num or "", space)) - def end_listitem(self, indent, marker): + def end_listitem(self, indent, marker, space, num): pass def start_monospace(self): diff -r 7a75493076a8 -r 21bc17cf1000 moinformat/tree.py --- a/moinformat/tree.py Sat Jul 14 15:36:34 2018 +0200 +++ b/moinformat/tree.py Sat Jul 14 16:17:36 2018 +0200 @@ -271,44 +271,46 @@ "A list." - def __init__(self, nodes, indent, marker): + def __init__(self, nodes, indent, marker, num): Container.__init__(self, nodes) self.indent = indent self.marker = marker + self.num = num def __repr__(self): - return "List(%r, %r, %r)" % (self.nodes, self.indent, self.marker) + return "List(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.num) def prettyprint(self, indent=""): - l = ["%sList: indent=%d marker=%r" % (indent, self.indent, self.marker)] + l = ["%sList: indent=%d marker=%r num=%r" % (indent, self.indent, self.marker, self.num)] return self._prettyprint(l, indent) def to_string(self, out): - out.start_list(self.indent, self.marker) + out.start_list(self.indent, self.marker, self.num) self._to_string(out) - out.end_list(self.indent, self.marker) + out.end_list(self.indent, self.marker, self.num) class ListItem(Container): "A list item." - def __init__(self, nodes, indent, marker, space): + def __init__(self, nodes, indent, marker, space, num): Container.__init__(self, nodes) self.indent = indent self.marker = marker self.space = space + self.num = num def __repr__(self): - return "ListItem(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space) + return "ListItem(%r, %r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space, self.num) def prettyprint(self, indent=""): - l = ["%sListItem: indent=%d marker=%r space=%r" % (indent, self.indent, self.marker, self.space)] + l = ["%sListItem: indent=%d marker=%r space=%r num=%r" % (indent, self.indent, self.marker, self.space, self.num)] return self._prettyprint(l, indent) def to_string(self, out): - out.start_listitem(self.indent, self.marker, self.space) + out.start_listitem(self.indent, self.marker, self.space, self.num) self._to_string(out) - out.end_listitem(self.indent, self.marker) + out.end_listitem(self.indent, self.marker, self.space, self.num) class TableAttrs(Container): diff -r 7a75493076a8 -r 21bc17cf1000 tests/test3.txt --- a/tests/test3.txt Sat Jul 14 15:36:34 2018 +0200 +++ b/tests/test3.txt Sat Jul 14 16:17:36 2018 +0200 @@ -5,4 +5,16 @@ I. What did they do for us? 1. {{{ Doing for us}}} - a. The Romans. + a.#18 The Romans. + + 1. Starting from one + 1. Two + 1.#3 Three? + 1. Four? + 1. Three + 1.#10 New list at ten + + I.#100 Century + I. Century plus one + +The end!