# HG changeset patch # User Paul Boddie # Date 1533654423 -7200 # Node ID bc7fb867436e24d903bed509c0d854f12f0c73af # Parent 2e00922a236d0bf3493345821e9a940153040d28# Parent f54f64f11d3a59559e3f39981c155d6f12488c97 Merged changes from the default branch. diff -r 2e00922a236d -r bc7fb867436e moinformat/links/html.py --- a/moinformat/links/html.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/links/html.py Tue Aug 07 17:07:03 2018 +0200 @@ -63,10 +63,10 @@ if target.startswith("#"): return self.quote(target), None - # Sub-pages. + # Sub-pages. Remove the leading slash for the label. elif target.startswith("/"): - return self.translate_subpage(target), None + return self.translate_subpage(target), target.lstrip("/") # Sibling (of ancestor) pages. diff -r 2e00922a236d -r bc7fb867436e moinformat/parsers/common.py --- a/moinformat/parsers/common.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/parsers/common.py Tue Aug 07 17:07:03 2018 +0200 @@ -387,9 +387,11 @@ region = Region([], level, indent, type) - # Parse section headers, then parse according to region type. + # Parse section headers and directives, then parse according to region + # type. self.parse_region_header(region) + self.parse_region_directives(region) self.parse_region_type(region) return region @@ -418,6 +420,30 @@ region.args = self.match_group("args") region.type = region.args.split(" ", 1)[0] + def parse_region_directives(self, region): + + """ + Parse any directives immediately after the region header, adding them to + the 'region' object. + """ + + while True: + preceding = self.read_until(["directive"], False) + + # With an immediately-appearing directive, handle its details. + + if preceding == "": + handler = self.handlers.get(self.matching_pattern()) + if handler: + handler(self, region) + else: + break + + # Otherwise, with no immediate directive (or none at all), stop. + + else: + break + # Parsing utilities. def parse_region_details(self, region, pattern_names, strict=False): diff -r 2e00922a236d -r bc7fb867436e moinformat/parsers/moin.py --- a/moinformat/parsers/moin.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/parsers/moin.py Tue Aug 07 17:07:03 2018 +0200 @@ -35,12 +35,13 @@ # Document tree nodes. -from moinformat.tree.moin import Anchor, Break, DefItem, DefTerm, FontStyle, \ - Heading, Larger, LineBreak, Link, List, \ - ListItem, Macro, Monospace, Region, Rule, \ - Smaller, Strikethrough, Subscript, \ - Superscript, Table, TableAttr, TableAttrs, \ - TableCell, TableRow, Text, Underline +from moinformat.tree.moin import Anchor, Break, Comment, DefItem, DefTerm, \ + Directive, FontStyle, Heading, Larger, \ + LineBreak, Link, List, ListItem, Macro, \ + Monospace, Region, Rule, Smaller, \ + Strikethrough, Subscript, Superscript, Table, \ + TableAttr, TableAttrs, TableCell, TableRow, \ + Text, Underline join = "".join @@ -85,9 +86,10 @@ self.items = self.get_items(s) self.region = Region([], type="moin") - # Parse page header. + # Parse page header and directives. self.parse_region_header(self.region) + self.parse_region_directives(self.region) # Handle pages directly with this parser. Pages do not need to use an # explicit format indicator. @@ -170,6 +172,15 @@ self.add_node(region, Break()) self.new_block(region) + def parse_comment(self, region): + + "Handle a comment within 'region'." + + comment = self.match_group("comment") + extra = self.match_group("extra") + self.add_node(region, Comment(comment, extra)) + self.new_block(region) + def parse_defitem(self, region, extra=""): "Handle a definition item within 'region'." @@ -205,6 +216,15 @@ self.parse_region_details(region, ["deftermsep"]) self.parse_defitem(region, extra) + def parse_directive(self, region): + + "Handle a processing directive within 'region'." + + directive = self.match_group("directive") + extra = self.match_group("extra") + self.add_node(region, Directive(directive, extra)) + self.new_block(region) + def parse_fontstyle(self, region): "Handle emphasis and strong styles." @@ -581,12 +601,17 @@ "regionend" : join((r"\N*", # ws... (optional) group("feature", join(( group("level", repeat("[}]", 3)), # }}}... - group("extra", r"\n"), - "?"))))), # nl (optional) + optional(group("extra", r"\n"))))))), # nl (optional) + + # Region header and directives: "header" : join(("#!", # #! group("args", ".*?"), "\n")), # text-excl-nl + "directive" : join((r"^#", # # + group("directive", r".*?$"), # rest of line + optional(group("extra", r"\n")))), # nl (optional) + # Region contents: # Line-oriented patterns support features which require their own @@ -594,6 +619,10 @@ "break" : r"^(\s*?)\n", # blank line + "comment" : join((r"^##", # ## + group("comment", r".*?$"), # rest of line + optional(group("extra", r"\n")))), # nl (optional) + "defterm" : join(("^", group("pad", r"\N+"), # ws... expect(".+?::"))), # text :: @@ -703,7 +732,8 @@ # ws... "listitemend" : join((r"^", # next line - choice((excl(r"\N"), # without indent + choice((expect(r"[^\s]"), # without indent + expect(r"\Z"), # end of string expect(r"\N+\*"), # or with ws... list-marker expect(r"\N+\d\."), # or with ws... decimal-marker expect(r"\N+[aA]\."), # or with ws... alpha-marker @@ -771,7 +801,7 @@ listitem_pattern_names = inline_pattern_names + ["listitemend"] region_without_table_pattern_names = inline_pattern_names + list_pattern_names + [ - "break", "heading", "defterm", "defterm_empty", + "break", "comment", "heading", "defterm", "defterm_empty", "regionend", "rule", ] @@ -798,10 +828,12 @@ "break" : parse_break, "colour" : parse_colour, "colspan" : parse_colspan, + "comment" : parse_comment, "defterm" : parse_defterm, "defterm_empty" : parse_defterm_empty, "deftermend" : end_region, "deftermsep" : end_region, + "directive" : parse_directive, "fontstyle" : parse_fontstyle, "halign" : parse_halign, "heading" : parse_heading, diff -r 2e00922a236d -r bc7fb867436e moinformat/serialisers/html/moin.py --- a/moinformat/serialisers/html/moin.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/serialisers/html/moin.py Tue Aug 07 17:07:03 2018 +0200 @@ -253,6 +253,12 @@ def break_(self): pass + def comment(self, comment, extra): + pass + + def directive(self, directive, extra): + pass + def linebreak(self): self.out("
") diff -r 2e00922a236d -r bc7fb867436e moinformat/serialisers/moin/moin.py --- a/moinformat/serialisers/moin/moin.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/serialisers/moin/moin.py Tue Aug 07 17:07:03 2018 +0200 @@ -185,8 +185,11 @@ def break_(self): self.out("\n") - def continuation(self, text): - self.out(text) + def comment(self, comment, extra): + self.out("##%s%s" % (comment, extra)) + + def directive(self, directive, extra): + self.out("#%s%s" % (directive, extra)) def linebreak(self): self.out(r"\\") diff -r 2e00922a236d -r bc7fb867436e moinformat/serialisers/moin/table.py --- a/moinformat/serialisers/moin/table.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/serialisers/moin/table.py Tue Aug 07 17:07:03 2018 +0200 @@ -48,6 +48,9 @@ def end_table_row(self, trailing): self.out(trailing) + def continuation(self, text): + self.out(text) + serialiser = MoinTableSerialiser # vim: tabstop=4 expandtab shiftwidth=4 diff -r 2e00922a236d -r bc7fb867436e moinformat/tree/moin.py --- a/moinformat/tree/moin.py Mon Aug 06 15:55:46 2018 +0200 +++ b/moinformat/tree/moin.py Tue Aug 07 17:07:03 2018 +0200 @@ -621,6 +621,40 @@ def to_string(self, out): out.break_() +class Comment(Node): + + "A comment." + + def __init__(self, comment, extra): + self.comment = comment + self.extra = extra + + def __repr__(self): + return "Comment(%r, %r)" % (self.comment, self.extra) + + def prettyprint(self, indent=""): + return "%sComment: comment=%r extra=%r" % (indent, self.comment, self.extra) + + def to_string(self, out): + out.comment(self.comment, self.extra) + +class Directive(Node): + + "A processing directive." + + def __init__(self, directive, extra): + self.directive = directive + self.extra = extra + + def __repr__(self): + return "Directive(%r, %r)" % (self.directive, self.extra) + + def prettyprint(self, indent=""): + return "%sDirective: directive=%r extra=%r" % (indent, self.directive, self.extra) + + def to_string(self, out): + out.directive(self.directive, self.extra) + class LineBreak(Node): "A line break within a block." diff -r 2e00922a236d -r bc7fb867436e tests/test_directives.tree --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_directives.tree Tue Aug 07 17:07:03 2018 +0200 @@ -0,0 +1,20 @@ +Region + Directive + Directive + Block + Text + Break + Region + Directive + Break + Block + Text + Comment + Block + Break + Region + Directive + Directive + Block + Text + Block diff -r 2e00922a236d -r bc7fb867436e tests/test_directives.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_directives.txt Tue Aug 07 17:07:03 2018 +0200 @@ -0,0 +1,17 @@ +#language en_GB +# A directive +Hello +# Visible non-comment + +{{{{#!wiki +## A comment + +# Visible non-comment +### Another comment +}}}} + +{{{#!wiki +# A directive +## A comment +Goodbye +}}} diff -r 2e00922a236d -r bc7fb867436e tests/test_lists2.tree --- a/tests/test_lists2.tree Mon Aug 06 15:55:46 2018 +0200 +++ b/tests/test_lists2.tree Tue Aug 07 17:07:03 2018 +0200 @@ -4,7 +4,6 @@ List ListItem Text - Break List ListItem Text @@ -30,7 +29,6 @@ List ListItem Text - Break List ListItem Text @@ -46,12 +44,10 @@ List ListItem Text - Break List ListItem Text ListItem Text - Break Block Text