1.1 --- a/moinformat/__init__.py Sat Apr 29 23:04:30 2017 +0200
1.2 +++ b/moinformat/__init__.py Sun Apr 30 01:43:33 2017 +0200
1.3 @@ -32,9 +32,16 @@
1.4
1.5 # Region contents:
1.6 # Line-oriented patterns:
1.7 - "break" : r"^(\s*?)\n", # blank line
1.8 - "heading" : r"^(\s*)(?P<x>=+)(\s+)(?=.*?\s+(?P=x)\s*\n)", # [ws...] =... ws... expecting headingend
1.9 - "listitem" : r"^((\s+)([*]|\d+[.]))", # indent (list-item or number-item)
1.10 + # blank line
1.11 + "break" : r"^(\s*?)\n",
1.12 + # [ws...] =... ws... expecting headingend
1.13 + "heading" : r"^(\s*)(?P<x>=+)(\s+)(?=.*?\s+(?P=x)\s*\n)",
1.14 + # indent (list-item or number-item or alpha-item or roman-item or dot-item)
1.15 + "listitem" : r"^(\s+)(\*)(\s*)",
1.16 + "listitem_num" : r"^(\s+)(\d+\.)(\s+)",
1.17 + "listitem_alpha": r"^(\s+)([aA]\.)(\s+)",
1.18 + "listitem_roman": r"^(\s+)([iI]\.)(\s+)",
1.19 + "listitem_dot" : r"^(\s+)(\.)(\s*)",
1.20
1.21 # Region contents:
1.22 # Inline patterns:
1.23 @@ -164,7 +171,9 @@
1.24 "Parse the data provided by 'items' to populate a wiki 'region'."
1.25
1.26 new_block(region)
1.27 - parse_region_details(items, region, ["break", "heading", "listitem", "regionstart", "regionend", "rule"])
1.28 + parse_region_details(items, region, [
1.29 + "break", "heading", "listitem", "listitem_num", "listitem_alpha",
1.30 + "listitem_roman", "listitem_dot", "regionstart", "regionend", "rule"])
1.31
1.32 def parse_region_opaque(items, region):
1.33
1.34 @@ -219,8 +228,9 @@
1.35
1.36 # Mark any previous block as not being the final one in a sequence.
1.37
1.38 - block = region.nodes[-1]
1.39 - block.final = False
1.40 + block = region.last()
1.41 + if isinstance(block, Block):
1.42 + block.final = False
1.43 new_block(region)
1.44
1.45 def parse_heading(items, region):
1.46 @@ -249,7 +259,10 @@
1.47
1.48 "Handle a list item marker within 'region'."
1.49
1.50 - item = ListItem([])
1.51 + indent = len(items.read_match(1))
1.52 + marker = items.read_match(2)
1.53 + space = items.read_match(3)
1.54 + item = ListItem([], indent, marker, space)
1.55 parse_region_details(items, item, ["listitemend"])
1.56 region.append(item)
1.57 new_block(region)
1.58 @@ -299,6 +312,10 @@
1.59 "headingend" : parse_heading_end,
1.60 "listitemend" : parse_listitem_end,
1.61 "listitem" : parse_listitem,
1.62 + "listitem_alpha" : parse_listitem,
1.63 + "listitem_dot" : parse_listitem,
1.64 + "listitem_num" : parse_listitem,
1.65 + "listitem_roman" : parse_listitem,
1.66 "regionstart" : parse_section,
1.67 "regionend" : parse_section_end,
1.68 "rule" : parse_rule,
2.1 --- a/moinformat/serialisers.py Sat Apr 29 23:04:30 2017 +0200
2.2 +++ b/moinformat/serialisers.py Sun Apr 30 01:43:33 2017 +0200
2.3 @@ -57,10 +57,10 @@
2.4 def end_heading(self, level, pad, extra):
2.5 self.out(pad + "=" * level + extra)
2.6
2.7 - def start_listitem(self):
2.8 - self.out(" *")
2.9 + def start_listitem(self, indent, marker, space):
2.10 + self.out("%s%s%s" % (indent * " ", marker, space))
2.11
2.12 - def end_listitem(self):
2.13 + def end_listitem(self, indent, marker):
2.14 pass
2.15
2.16 def rule(self, length):
2.17 @@ -104,10 +104,10 @@
2.18 def end_heading(self, level, pad, extra):
2.19 self.out("</h%d>" % level)
2.20
2.21 - def start_listitem(self):
2.22 + def start_listitem(self, indent, marker, space):
2.23 self.out("<li>")
2.24
2.25 - def end_listitem(self):
2.26 + def end_listitem(self, indent, marker):
2.27 self.out("</li>")
2.28
2.29 def rule(self, length):
3.1 --- a/moinformat/tree.py Sat Apr 29 23:04:30 2017 +0200
3.2 +++ b/moinformat/tree.py Sun Apr 30 01:43:33 2017 +0200
3.3 @@ -34,6 +34,9 @@
3.4 def empty(self):
3.5 return not self.nodes
3.6
3.7 + def last(self):
3.8 + return self.nodes and self.nodes[-1] or None
3.9 +
3.10 def normalise(self):
3.11
3.12 "Combine adjacent text nodes."
3.13 @@ -84,7 +87,7 @@
3.14 self.type = type
3.15
3.16 def append(self, node):
3.17 - last = self.nodes and self.nodes[-1]
3.18 + last = self.last()
3.19 if last and last.empty():
3.20 self.nodes[-1] = node
3.21 else:
3.22 @@ -173,20 +176,26 @@
3.23
3.24 "A list item."
3.25
3.26 + def __init__(self, nodes, indent, marker, space):
3.27 + Container.__init__(self, nodes)
3.28 + self.indent = indent
3.29 + self.marker = marker
3.30 + self.space = space
3.31 +
3.32 def __repr__(self):
3.33 - return "ListItem(%r)" % self.nodes
3.34 + return "ListItem(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space)
3.35
3.36 def prettyprint(self, indent=""):
3.37 - l = ["%sListItem:" % indent]
3.38 + l = ["%sListItem: indent=%d marker=%r space=%r" % (indent, self.indent, self.marker, self.space)]
3.39 for node in self.nodes:
3.40 l.append(node.prettyprint(indent + " "))
3.41 return "\n".join(l)
3.42
3.43 def to_string(self, out):
3.44 - out.start_listitem()
3.45 + out.start_listitem(self.indent, self.marker, self.space)
3.46 for node in self.nodes:
3.47 node.to_string(out)
3.48 - out.end_listitem()
3.49 + out.end_listitem(self.indent, self.marker)
3.50
3.51
3.52
4.1 --- a/tests/test_parser.py Sat Apr 29 23:04:30 2017 +0200
4.2 +++ b/tests/test_parser.py Sun Apr 30 01:43:33 2017 +0200
4.3 @@ -15,10 +15,20 @@
4.4 End
4.5 }}}}
4.6 XXX
4.7 +""")
4.8
4.9 +sl.append("""\
4.10 +XXX
4.11 * Item 1
4.12 + * Item 1.1
4.13 * Item 2
4.14 + . Item 3
4.15 + . Item 3.1
4.16 XXX
4.17 + a. Appendix
4.18 +
4.19 + i. Romanus eunt domus!
4.20 + I. What did they do for us?
4.21 """)
4.22
4.23 sl.append("""\