1.1 --- a/moinformat/__init__.py Sun Apr 30 17:59:52 2017 +0200
1.2 +++ b/moinformat/__init__.py Sun Apr 30 23:15:22 2017 +0200
1.3 @@ -19,7 +19,7 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from moinformat.tree import Block, Break, Heading, ListItem, Region, Rule, Text
1.8 +from moinformat.tree import Block, Break, DefItem, DefTerm, Heading, ListItem, Region, Rule, Text
1.9 import re
1.10
1.11 # Regular expressions.
1.12 @@ -34,17 +34,21 @@
1.13 # Line-oriented patterns:
1.14 # blank line
1.15 "break" : r"^(\s*?)\n",
1.16 + # ws... expecting text ::
1.17 + "defterm" : r"^(\s+)(?=.+?::)",
1.18 + # ws... expecting :: ws...
1.19 + "defterm_empty" : r"^(\s+)(?=::\s+)",
1.20 # [ws...] =... ws... expecting headingend
1.21 "heading" : r"^(\s*)(?P<x>=+)(\s+)(?=.*?\s+(?P=x)\s*\n)",
1.22 - # indent list-item [ws...]
1.23 + # ws... list-item [ws...]
1.24 "listitem" : r"^(\s+)(\*)(\s*)",
1.25 - # indent number-item ws...
1.26 + # ws... number-item ws...
1.27 "listitem_num" : r"^(\s+)(\d+\.)(\s+)",
1.28 - # indent alpha-item ws...
1.29 + # ws... alpha-item ws...
1.30 "listitem_alpha": r"^(\s+)([aA]\.)(\s+)",
1.31 - # indent roman-item ws...
1.32 + # ws... roman-item ws...
1.33 "listitem_roman": r"^(\s+)([iI]\.)(\s+)",
1.34 - # indent dot-item [ws...]
1.35 + # ws... dot-item [ws...]
1.36 "listitem_dot" : r"^(\s+)(\.)(\s*)",
1.37
1.38 # Region contents:
1.39 @@ -55,6 +59,8 @@
1.40 "headingend" : r"(\s+)(=+)(\s*\n)", # ws... =... [ws...] nl
1.41
1.42 # List contents:
1.43 + "deftermend" : r"::(\s*?\n)",
1.44 + "deftermsep" : r"::(\s+)",
1.45 "listitemend" : r"^", # next line
1.46 }
1.47
1.48 @@ -176,8 +182,11 @@
1.49
1.50 new_block(region)
1.51 parse_region_details(items, region, [
1.52 - "break", "heading", "listitem", "listitem_num", "listitem_alpha",
1.53 - "listitem_roman", "listitem_dot", "regionstart", "regionend", "rule"])
1.54 + "break", "heading",
1.55 + "defterm", "defterm_empty",
1.56 + "listitem", "listitem_alpha", "listitem_dot", "listitem_num",
1.57 + "listitem_roman",
1.58 + "regionstart", "regionend", "rule"])
1.59
1.60 def parse_region_opaque(items, region):
1.61
1.62 @@ -233,6 +242,38 @@
1.63 region.add(Break())
1.64 new_block(region)
1.65
1.66 +def parse_defitem(items, region, extra=""):
1.67 +
1.68 + "Handle a definition item within 'region'."
1.69 +
1.70 + pad = items.read_match(1)
1.71 + item = DefItem([], pad, extra)
1.72 + parse_region_details(items, item, ["listitemend"])
1.73 + region.append(item)
1.74 + new_block(region)
1.75 +
1.76 +def parse_defterm(items, region):
1.77 +
1.78 + "Handle a definition term within 'region'."
1.79 +
1.80 + pad = items.read_match(1)
1.81 + term = DefTerm([], pad)
1.82 + parse_region_details(items, term, ["deftermend", "deftermsep"])
1.83 + region.append(term)
1.84 + if items.matching == "deftermsep":
1.85 + parse_defitem(items, region)
1.86 +
1.87 +def parse_defterm_empty(items, region):
1.88 +
1.89 + "Handle an empty definition term within 'region'."
1.90 +
1.91 + extra = items.read_match(1)
1.92 + parse_region_details(items, region, ["deftermsep"])
1.93 + parse_defitem(items, region, extra)
1.94 +
1.95 +parse_defterm_end = end_region
1.96 +parse_defterm_sep = end_region
1.97 +
1.98 def parse_heading(items, region):
1.99
1.100 "Handle a heading."
1.101 @@ -267,11 +308,7 @@
1.102 region.append(item)
1.103 new_block(region)
1.104
1.105 -def parse_listitem_end(items, item):
1.106 -
1.107 - "Handle the end of a list."
1.108 -
1.109 - raise StopIteration
1.110 +parse_listitem_end = end_region
1.111
1.112 def parse_rule(items, region):
1.113
1.114 @@ -308,6 +345,10 @@
1.115 handlers = {
1.116 None : end_region,
1.117 "break" : parse_break,
1.118 + "defterm" : parse_defterm,
1.119 + "defterm_empty" : parse_defterm_empty,
1.120 + "deftermend" : parse_defterm_end,
1.121 + "deftermsep" : parse_defterm_sep,
1.122 "heading" : parse_heading,
1.123 "headingend" : parse_heading_end,
1.124 "listitemend" : parse_listitem_end,