# HG changeset patch
# User Paul Boddie
# Date 1493586922 -7200
# Node ID 3e5b1b8cb456025305e0af6839cb25e7a821b5a8
# Parent 81089c4cb6ebbf21bce4387d61523751b048be95
Added initial definition list element support.
Consolidated common serialisation routines.
diff -r 81089c4cb6eb -r 3e5b1b8cb456 moinformat/__init__.py
--- a/moinformat/__init__.py Sun Apr 30 17:59:52 2017 +0200
+++ b/moinformat/__init__.py Sun Apr 30 23:15:22 2017 +0200
@@ -19,7 +19,7 @@
this program. If not, see .
"""
-from moinformat.tree import Block, Break, Heading, ListItem, Region, Rule, Text
+from moinformat.tree import Block, Break, DefItem, DefTerm, Heading, ListItem, Region, Rule, Text
import re
# Regular expressions.
@@ -34,17 +34,21 @@
# Line-oriented patterns:
# blank line
"break" : r"^(\s*?)\n",
+ # ws... expecting text ::
+ "defterm" : r"^(\s+)(?=.+?::)",
+ # ws... expecting :: ws...
+ "defterm_empty" : r"^(\s+)(?=::\s+)",
# [ws...] =... ws... expecting headingend
"heading" : r"^(\s*)(?P=+)(\s+)(?=.*?\s+(?P=x)\s*\n)",
- # indent list-item [ws...]
+ # ws... list-item [ws...]
"listitem" : r"^(\s+)(\*)(\s*)",
- # indent number-item ws...
+ # ws... number-item ws...
"listitem_num" : r"^(\s+)(\d+\.)(\s+)",
- # indent alpha-item ws...
+ # ws... alpha-item ws...
"listitem_alpha": r"^(\s+)([aA]\.)(\s+)",
- # indent roman-item ws...
+ # ws... roman-item ws...
"listitem_roman": r"^(\s+)([iI]\.)(\s+)",
- # indent dot-item [ws...]
+ # ws... dot-item [ws...]
"listitem_dot" : r"^(\s+)(\.)(\s*)",
# Region contents:
@@ -55,6 +59,8 @@
"headingend" : r"(\s+)(=+)(\s*\n)", # ws... =... [ws...] nl
# List contents:
+ "deftermend" : r"::(\s*?\n)",
+ "deftermsep" : r"::(\s+)",
"listitemend" : r"^", # next line
}
@@ -176,8 +182,11 @@
new_block(region)
parse_region_details(items, region, [
- "break", "heading", "listitem", "listitem_num", "listitem_alpha",
- "listitem_roman", "listitem_dot", "regionstart", "regionend", "rule"])
+ "break", "heading",
+ "defterm", "defterm_empty",
+ "listitem", "listitem_alpha", "listitem_dot", "listitem_num",
+ "listitem_roman",
+ "regionstart", "regionend", "rule"])
def parse_region_opaque(items, region):
@@ -233,6 +242,38 @@
region.add(Break())
new_block(region)
+def parse_defitem(items, region, extra=""):
+
+ "Handle a definition item within 'region'."
+
+ pad = items.read_match(1)
+ item = DefItem([], pad, extra)
+ parse_region_details(items, item, ["listitemend"])
+ region.append(item)
+ new_block(region)
+
+def parse_defterm(items, region):
+
+ "Handle a definition term within 'region'."
+
+ pad = items.read_match(1)
+ term = DefTerm([], pad)
+ parse_region_details(items, term, ["deftermend", "deftermsep"])
+ region.append(term)
+ if items.matching == "deftermsep":
+ parse_defitem(items, region)
+
+def parse_defterm_empty(items, region):
+
+ "Handle an empty definition term within 'region'."
+
+ extra = items.read_match(1)
+ parse_region_details(items, region, ["deftermsep"])
+ parse_defitem(items, region, extra)
+
+parse_defterm_end = end_region
+parse_defterm_sep = end_region
+
def parse_heading(items, region):
"Handle a heading."
@@ -267,11 +308,7 @@
region.append(item)
new_block(region)
-def parse_listitem_end(items, item):
-
- "Handle the end of a list."
-
- raise StopIteration
+parse_listitem_end = end_region
def parse_rule(items, region):
@@ -308,6 +345,10 @@
handlers = {
None : end_region,
"break" : parse_break,
+ "defterm" : parse_defterm,
+ "defterm_empty" : parse_defterm_empty,
+ "deftermend" : parse_defterm_end,
+ "deftermsep" : parse_defterm_sep,
"heading" : parse_heading,
"headingend" : parse_heading_end,
"listitemend" : parse_listitem_end,
diff -r 81089c4cb6eb -r 3e5b1b8cb456 moinformat/serialisers.py
--- a/moinformat/serialisers.py Sun Apr 30 17:59:52 2017 +0200
+++ b/moinformat/serialisers.py Sun Apr 30 23:15:22 2017 +0200
@@ -50,6 +50,18 @@
def end_block(self):
pass
+ def start_defitem(self, pad, extra):
+ self.out((extra and "\n" + extra + "::" or "") + pad)
+
+ def end_defitem(self, pad, extra):
+ pass
+
+ def start_defterm(self, pad):
+ self.out(pad)
+
+ def end_defterm(self, pad):
+ self.out("::")
+
def start_heading(self, level, extra, pad):
self.out(extra + "=" * level + pad)
@@ -100,6 +112,18 @@
def end_block(self):
self.out("
")
+ def start_defitem(self, pad, extra):
+ self.out("")
+
+ def end_defitem(self, pad, extra):
+ self.out("")
+
+ def start_defterm(self, pad):
+ self.out("")
+
+ def end_defterm(self, pad):
+ self.out("")
+
def start_heading(self, level, extra, pad):
self.out("" % level)
diff -r 81089c4cb6eb -r 3e5b1b8cb456 moinformat/tree.py
--- a/moinformat/tree.py Sun Apr 30 17:59:52 2017 +0200
+++ b/moinformat/tree.py Sun Apr 30 23:15:22 2017 +0200
@@ -76,8 +76,14 @@
def __str__(self):
return self.prettyprint()
- def prettyprint(self, indent=""):
- pass
+ def _prettyprint(self, l, indent=""):
+ for node in self.nodes:
+ l.append(node.prettyprint(indent + " "))
+ return "\n".join(l)
+
+ def _to_string(self, out):
+ for node in self.nodes:
+ node.to_string(out)
class Region(Container):
@@ -115,14 +121,11 @@
def prettyprint(self, indent=""):
l = ["%sRegion: level=%d indent=%d type=%s" % (indent, self.level, self.indent, self.type)]
- for node in self.nodes:
- l.append(node.prettyprint(indent + " "))
- return "\n".join(l)
+ return self._prettyprint(l, indent)
def to_string(self, out):
out.start_region(self.level, self.indent, self.type)
- for node in self.nodes:
- node.to_string(out)
+ self._to_string(out)
out.end_region(self.level, self.indent, self.type)
class Block(Container):
@@ -134,16 +137,54 @@
def prettyprint(self, indent=""):
l = ["%sBlock" % indent]
- for node in self.nodes:
- l.append(node.prettyprint(indent + " "))
- return "\n".join(l)
+ return self._prettyprint(l, indent)
def to_string(self, out):
out.start_block()
- for node in self.nodes:
- node.to_string(out)
+ self._to_string(out)
out.end_block()
+class DefItem(Container):
+
+ "A definition item."
+
+ def __init__(self, nodes, pad, extra):
+ Container.__init__(self, nodes)
+ self.pad = pad
+ self.extra = extra
+
+ def __repr__(self):
+ return "DefItem(%r, %r, %r)" % (self.nodes, self.pad, self.extra)
+
+ def prettyprint(self, indent=""):
+ l = ["%sDefItem: pad=%r extra=%r" % (indent, self.pad, self.extra)]
+ return self._prettyprint(l, indent)
+
+ def to_string(self, out):
+ out.start_defitem(self.pad, self.extra)
+ self._to_string(out)
+ out.end_defitem(self.pad, self.extra)
+
+class DefTerm(Container):
+
+ "A definition term."
+
+ def __init__(self, nodes, pad):
+ Container.__init__(self, nodes)
+ self.pad = pad
+
+ def __repr__(self):
+ return "DefTerm(%r, %r)" % (self.nodes, self.pad)
+
+ def prettyprint(self, indent=""):
+ l = ["%sDefTerm: pad=%r" % (indent, self.pad)]
+ return self._prettyprint(l, indent)
+
+ def to_string(self, out):
+ out.start_defterm(self.pad)
+ self._to_string(out)
+ out.end_defterm(self.pad)
+
class Heading(Container):
"A heading."
@@ -163,14 +204,11 @@
def prettyprint(self, indent=""):
l = ["%sHeading: level=%d start_extra=%r start_pad=%r end_pad=%r end_extra=%r" % (
indent, self.level, self.start_extra, self.start_pad, self.end_pad, self.end_extra)]
- for node in self.nodes:
- l.append(node.prettyprint(indent + " "))
- return "\n".join(l)
+ return self._prettyprint(l, indent)
def to_string(self, out):
out.start_heading(self.level, self.start_extra, self.start_pad)
- for node in self.nodes:
- node.to_string(out)
+ self._to_string(out)
out.end_heading(self.level, self.end_pad, self.end_extra)
class ListItem(Container):
@@ -188,14 +226,11 @@
def prettyprint(self, indent=""):
l = ["%sListItem: indent=%d marker=%r space=%r" % (indent, self.indent, self.marker, self.space)]
- for node in self.nodes:
- l.append(node.prettyprint(indent + " "))
- return "\n".join(l)
+ return self._prettyprint(l, indent)
def to_string(self, out):
out.start_listitem(self.indent, self.marker, self.space)
- for node in self.nodes:
- node.to_string(out)
+ self._to_string(out)
out.end_listitem(self.indent, self.marker)
diff -r 81089c4cb6eb -r 3e5b1b8cb456 tests/test_parser.py
--- a/tests/test_parser.py Sun Apr 30 17:59:52 2017 +0200
+++ b/tests/test_parser.py Sun Apr 30 23:15:22 2017 +0200
@@ -25,6 +25,10 @@
. Item 3
. Item 3.1
XXX
+""")
+
+sl.append("""\
+XXX
a. Appendix
i. Romanus eunt domus!
@@ -32,6 +36,14 @@
""")
sl.append("""\
+ term:: item
+not a term:: nor an item
+ term::
+ :: item
+ ::non-item
+""")
+
+sl.append("""\
Hello
{{{{#!xxx
A region