1.1 --- a/moinformat/parsers/common.py Tue Aug 07 17:05:58 2018 +0200
1.2 +++ b/moinformat/parsers/common.py Tue Aug 07 17:06:26 2018 +0200
1.3 @@ -348,9 +348,11 @@
1.4
1.5 region = Region([], level, indent, type)
1.6
1.7 - # Parse section headers, then parse according to region type.
1.8 + # Parse section headers and directives, then parse according to region
1.9 + # type.
1.10
1.11 self.parse_region_header(region)
1.12 + self.parse_region_directives(region)
1.13 self.parse_region_type(region)
1.14
1.15 return region
1.16 @@ -379,6 +381,30 @@
1.17 region.args = self.match_group("args")
1.18 region.type = region.args.split(" ", 1)[0]
1.19
1.20 + def parse_region_directives(self, region):
1.21 +
1.22 + """
1.23 + Parse any directives immediately after the region header, adding them to
1.24 + the 'region' object.
1.25 + """
1.26 +
1.27 + while True:
1.28 + preceding = self.read_until(["directive"], False)
1.29 +
1.30 + # With an immediately-appearing directive, handle its details.
1.31 +
1.32 + if preceding == "":
1.33 + handler = self.handlers.get(self.matching_pattern())
1.34 + if handler:
1.35 + handler(self, region)
1.36 + else:
1.37 + break
1.38 +
1.39 + # Otherwise, with no immediate directive (or none at all), stop.
1.40 +
1.41 + else:
1.42 + break
1.43 +
1.44 # Parsing utilities.
1.45
1.46 def parse_region_details(self, region, pattern_names, strict=False):
2.1 --- a/moinformat/parsers/moin.py Tue Aug 07 17:05:58 2018 +0200
2.2 +++ b/moinformat/parsers/moin.py Tue Aug 07 17:06:26 2018 +0200
2.3 @@ -35,12 +35,13 @@
2.4
2.5 # Document tree nodes.
2.6
2.7 -from moinformat.tree.moin import Anchor, Break, DefItem, DefTerm, FontStyle, \
2.8 - Heading, Larger, LineBreak, Link, List, \
2.9 - ListItem, Macro, Monospace, Region, Rule, \
2.10 - Smaller, Strikethrough, Subscript, \
2.11 - Superscript, Table, TableAttr, TableAttrs, \
2.12 - TableCell, TableRow, Text, Underline
2.13 +from moinformat.tree.moin import Anchor, Break, Comment, DefItem, DefTerm, \
2.14 + Directive, FontStyle, Heading, Larger, \
2.15 + LineBreak, Link, List, ListItem, Macro, \
2.16 + Monospace, Region, Rule, Smaller, \
2.17 + Strikethrough, Subscript, Superscript, Table, \
2.18 + TableAttr, TableAttrs, TableCell, TableRow, \
2.19 + Text, Underline
2.20
2.21 join = "".join
2.22
2.23 @@ -85,9 +86,10 @@
2.24 self.items = self.get_items(s)
2.25 self.region = Region([], type="moin")
2.26
2.27 - # Parse page header.
2.28 + # Parse page header and directives.
2.29
2.30 self.parse_region_header(self.region)
2.31 + self.parse_region_directives(self.region)
2.32
2.33 # Handle pages directly with this parser. Pages do not need to use an
2.34 # explicit format indicator.
2.35 @@ -170,6 +172,15 @@
2.36 self.add_node(region, Break())
2.37 self.new_block(region)
2.38
2.39 + def parse_comment(self, region):
2.40 +
2.41 + "Handle a comment within 'region'."
2.42 +
2.43 + comment = self.match_group("comment")
2.44 + extra = self.match_group("extra")
2.45 + self.add_node(region, Comment(comment, extra))
2.46 + self.new_block(region)
2.47 +
2.48 def parse_defitem(self, region, extra=""):
2.49
2.50 "Handle a definition item within 'region'."
2.51 @@ -205,6 +216,15 @@
2.52 self.parse_region_details(region, ["deftermsep"])
2.53 self.parse_defitem(region, extra)
2.54
2.55 + def parse_directive(self, region):
2.56 +
2.57 + "Handle a processing directive within 'region'."
2.58 +
2.59 + directive = self.match_group("directive")
2.60 + extra = self.match_group("extra")
2.61 + self.add_node(region, Directive(directive, extra))
2.62 + self.new_block(region)
2.63 +
2.64 def parse_fontstyle(self, region):
2.65
2.66 "Handle emphasis and strong styles."
2.67 @@ -581,12 +601,17 @@
2.68 "regionend" : join((r"\N*", # ws... (optional)
2.69 group("feature", join((
2.70 group("level", repeat("[}]", 3)), # }}}...
2.71 - group("extra", r"\n"),
2.72 - "?"))))), # nl (optional)
2.73 + optional(group("extra", r"\n"))))))), # nl (optional)
2.74 +
2.75 + # Region header and directives:
2.76
2.77 "header" : join(("#!", # #!
2.78 group("args", ".*?"), "\n")), # text-excl-nl
2.79
2.80 + "directive" : join((r"^#", # #
2.81 + group("directive", r".*?$"), # rest of line
2.82 + optional(group("extra", r"\n")))), # nl (optional)
2.83 +
2.84 # Region contents:
2.85
2.86 # Line-oriented patterns support features which require their own
2.87 @@ -594,6 +619,10 @@
2.88
2.89 "break" : r"^(\s*?)\n", # blank line
2.90
2.91 + "comment" : join((r"^##", # ##
2.92 + group("comment", r".*?$"), # rest of line
2.93 + optional(group("extra", r"\n")))), # nl (optional)
2.94 +
2.95 "defterm" : join(("^",
2.96 group("pad", r"\N+"), # ws...
2.97 expect(".+?::"))), # text ::
2.98 @@ -772,7 +801,7 @@
2.99 listitem_pattern_names = inline_pattern_names + ["listitemend"]
2.100
2.101 region_without_table_pattern_names = inline_pattern_names + list_pattern_names + [
2.102 - "break", "heading", "defterm", "defterm_empty",
2.103 + "break", "comment", "heading", "defterm", "defterm_empty",
2.104 "regionend", "rule",
2.105 ]
2.106
2.107 @@ -799,10 +828,12 @@
2.108 "break" : parse_break,
2.109 "colour" : parse_colour,
2.110 "colspan" : parse_colspan,
2.111 + "comment" : parse_comment,
2.112 "defterm" : parse_defterm,
2.113 "defterm_empty" : parse_defterm_empty,
2.114 "deftermend" : end_region,
2.115 "deftermsep" : end_region,
2.116 + "directive" : parse_directive,
2.117 "fontstyle" : parse_fontstyle,
2.118 "halign" : parse_halign,
2.119 "heading" : parse_heading,
5.1 --- a/moinformat/tree/moin.py Tue Aug 07 17:05:58 2018 +0200
5.2 +++ b/moinformat/tree/moin.py Tue Aug 07 17:06:26 2018 +0200
5.3 @@ -621,6 +621,40 @@
5.4 def to_string(self, out):
5.5 out.break_()
5.6
5.7 +class Comment(Node):
5.8 +
5.9 + "A comment."
5.10 +
5.11 + def __init__(self, comment, extra):
5.12 + self.comment = comment
5.13 + self.extra = extra
5.14 +
5.15 + def __repr__(self):
5.16 + return "Comment(%r, %r)" % (self.comment, self.extra)
5.17 +
5.18 + def prettyprint(self, indent=""):
5.19 + return "%sComment: comment=%r extra=%r" % (indent, self.comment, self.extra)
5.20 +
5.21 + def to_string(self, out):
5.22 + out.comment(self.comment, self.extra)
5.23 +
5.24 +class Directive(Node):
5.25 +
5.26 + "A processing directive."
5.27 +
5.28 + def __init__(self, directive, extra):
5.29 + self.directive = directive
5.30 + self.extra = extra
5.31 +
5.32 + def __repr__(self):
5.33 + return "Directive(%r, %r)" % (self.directive, self.extra)
5.34 +
5.35 + def prettyprint(self, indent=""):
5.36 + return "%sDirective: directive=%r extra=%r" % (indent, self.directive, self.extra)
5.37 +
5.38 + def to_string(self, out):
5.39 + out.directive(self.directive, self.extra)
5.40 +
5.41 class LineBreak(Node):
5.42
5.43 "A line break within a block."