# HG changeset patch # User Paul Boddie # Date 1493398610 -7200 # Node ID 3c29a8a6263548bbc6c107a77e0267e0803084ec # Parent c3831bd8835fe151360f71f78d245692968f9aa0 Capture indents used when starting regions/sections. diff -r c3831bd8835f -r 3c29a8a62635 moinformat.py --- a/moinformat.py Fri Apr 28 01:09:46 2017 +0200 +++ b/moinformat.py Fri Apr 28 18:56:50 2017 +0200 @@ -26,7 +26,7 @@ syntax = { # Page regions: - "regionstart" : (r"^\s*([{]{3,})", re.MULTILINE | re.DOTALL), # {{{... + "regionstart" : (r"((^\s*)([{]{3,}))", re.MULTILINE | re.DOTALL), # {{{... "regionend" : (r"^\s*([}]{3,})", re.MULTILINE | re.DOTALL), # }}}... "header" : (r"#!(.*?)\n", 0), # #! char-excl-nl @@ -106,9 +106,10 @@ transparent_region_types = ["wiki"] - def __init__(self, nodes, level=0, type=None): + def __init__(self, nodes, level=0, indent=0, type=None): Container.__init__(self, nodes) self.level = level + self.indent = indent self.type = type def append(self, node): @@ -131,19 +132,19 @@ return not self.level or self.type in self.transparent_region_types def __repr__(self): - return "Region(%r, %r, %r)" % (self.nodes, self.level, self.type) + return "Region(%r, %r, %r, %r)" % (self.nodes, self.level, self.indent, self.type) def prettyprint(self, indent=""): - l = ["%sRegion: level=%d type=%s" % (indent, self.level, self.type)] + 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) def to_string(self, out): - out.start_region(self.level, self.type) + out.start_region(self.level, self.indent, self.type) for node in self.nodes: node.to_string(out) - out.end_region(self.level, self.type) + out.end_region(self.level, self.indent, self.type) class Block(Container): @@ -225,17 +226,17 @@ "Serialisation of the page." - def start_region(self, level, type): + def start_region(self, level, indent, type): out = self.out if level: - out("{" * level) # marker + out(" " * indent + "{" * level) if type and level: - out("#!%s\n" % type) # header + out("#!%s\n" % type) - def end_region(self, level, type): + def end_region(self, level, indent, type): out = self.out if level: - out("}" * level) # marker + out("}" * level) def start_block(self, final): pass @@ -257,20 +258,23 @@ "Serialisation of the page." - def start_region(self, level, type): + def start_region(self, level, indent, type): l = [] out = l.append if level: - out("level-%d" % level) # marker + out("level-%d" % level) + + if indent: + out("indent-%d" % indent) # NOTE: Encode type details for CSS. if type: - out("type-%s" % escape(type, True)) # header + out("type-%s" % escape(type, True)) self.out("" % " ".join(l)) - def end_region(self, level, type): + def end_region(self, level, indent, type): self.out("") def start_block(self, final): @@ -332,14 +336,19 @@ else: return self.s[self.pos:first] - def read_match(self): + def read_match(self, group=1): - "Return the matched text, updating the position in the stream." + """ + Return the matched text, updating the position in the stream. If 'group' + is specified, the indicated group in a match will be returned. + Typically, group 1 should contain all pertinent data, but groups defined + within group 1 can provide sections of the data. + """ if self.match: _start, self.pos = self.match.span() try: - return self.match.group(1) + return self.match.group(group) except IndexError: return "" else: @@ -358,14 +367,14 @@ return parse_region(TokenStream(s)) -def parse_region(items, level=0): +def parse_region(items, level=0, indent=0): """ - Parse the data provided by 'items' to populate a region at the given - 'level'. + Parse the data provided by 'items' to populate a region with the given + 'level' at the given 'indent'. """ - region = Region([], level) + region = Region([], level, indent) # Parse section headers. @@ -474,8 +483,9 @@ # Parse the section and start a new block after the section. - level = len(items.read_match()) - region.append(parse_region(items, level)) + indent = len(items.read_match(2)) + level = len(items.read_match(3)) + region.append(parse_region(items, level, indent)) new_block(region) def parse_section_end(items, region): diff -r c3831bd8835f -r 3c29a8a62635 tests/test_parser.py --- a/tests/test_parser.py Fri Apr 28 01:09:46 2017 +0200 +++ b/tests/test_parser.py Fri Apr 28 18:56:50 2017 +0200 @@ -6,7 +6,7 @@ Hello {{{{#!wiki A region -{{{ + {{{ Another }}} End