1.1 --- a/moinformat.py Fri Apr 28 01:09:46 2017 +0200
1.2 +++ b/moinformat.py Fri Apr 28 18:56:50 2017 +0200
1.3 @@ -26,7 +26,7 @@
1.4
1.5 syntax = {
1.6 # Page regions:
1.7 - "regionstart" : (r"^\s*([{]{3,})", re.MULTILINE | re.DOTALL), # {{{...
1.8 + "regionstart" : (r"((^\s*)([{]{3,}))", re.MULTILINE | re.DOTALL), # {{{...
1.9 "regionend" : (r"^\s*([}]{3,})", re.MULTILINE | re.DOTALL), # }}}...
1.10 "header" : (r"#!(.*?)\n", 0), # #! char-excl-nl
1.11
1.12 @@ -106,9 +106,10 @@
1.13
1.14 transparent_region_types = ["wiki"]
1.15
1.16 - def __init__(self, nodes, level=0, type=None):
1.17 + def __init__(self, nodes, level=0, indent=0, type=None):
1.18 Container.__init__(self, nodes)
1.19 self.level = level
1.20 + self.indent = indent
1.21 self.type = type
1.22
1.23 def append(self, node):
1.24 @@ -131,19 +132,19 @@
1.25 return not self.level or self.type in self.transparent_region_types
1.26
1.27 def __repr__(self):
1.28 - return "Region(%r, %r, %r)" % (self.nodes, self.level, self.type)
1.29 + return "Region(%r, %r, %r, %r)" % (self.nodes, self.level, self.indent, self.type)
1.30
1.31 def prettyprint(self, indent=""):
1.32 - l = ["%sRegion: level=%d type=%s" % (indent, self.level, self.type)]
1.33 + l = ["%sRegion: level=%d indent=%d type=%s" % (indent, self.level, self.indent, self.type)]
1.34 for node in self.nodes:
1.35 l.append(node.prettyprint(indent + " "))
1.36 return "\n".join(l)
1.37
1.38 def to_string(self, out):
1.39 - out.start_region(self.level, self.type)
1.40 + out.start_region(self.level, self.indent, self.type)
1.41 for node in self.nodes:
1.42 node.to_string(out)
1.43 - out.end_region(self.level, self.type)
1.44 + out.end_region(self.level, self.indent, self.type)
1.45
1.46 class Block(Container):
1.47
1.48 @@ -225,17 +226,17 @@
1.49
1.50 "Serialisation of the page."
1.51
1.52 - def start_region(self, level, type):
1.53 + def start_region(self, level, indent, type):
1.54 out = self.out
1.55 if level:
1.56 - out("{" * level) # marker
1.57 + out(" " * indent + "{" * level)
1.58 if type and level:
1.59 - out("#!%s\n" % type) # header
1.60 + out("#!%s\n" % type)
1.61
1.62 - def end_region(self, level, type):
1.63 + def end_region(self, level, indent, type):
1.64 out = self.out
1.65 if level:
1.66 - out("}" * level) # marker
1.67 + out("}" * level)
1.68
1.69 def start_block(self, final):
1.70 pass
1.71 @@ -257,20 +258,23 @@
1.72
1.73 "Serialisation of the page."
1.74
1.75 - def start_region(self, level, type):
1.76 + def start_region(self, level, indent, type):
1.77 l = []
1.78 out = l.append
1.79 if level:
1.80 - out("level-%d" % level) # marker
1.81 + out("level-%d" % level)
1.82 +
1.83 + if indent:
1.84 + out("indent-%d" % indent)
1.85
1.86 # NOTE: Encode type details for CSS.
1.87
1.88 if type:
1.89 - out("type-%s" % escape(type, True)) # header
1.90 + out("type-%s" % escape(type, True))
1.91
1.92 self.out("<span class='%s'>" % " ".join(l))
1.93
1.94 - def end_region(self, level, type):
1.95 + def end_region(self, level, indent, type):
1.96 self.out("</span>")
1.97
1.98 def start_block(self, final):
1.99 @@ -332,14 +336,19 @@
1.100 else:
1.101 return self.s[self.pos:first]
1.102
1.103 - def read_match(self):
1.104 + def read_match(self, group=1):
1.105
1.106 - "Return the matched text, updating the position in the stream."
1.107 + """
1.108 + Return the matched text, updating the position in the stream. If 'group'
1.109 + is specified, the indicated group in a match will be returned.
1.110 + Typically, group 1 should contain all pertinent data, but groups defined
1.111 + within group 1 can provide sections of the data.
1.112 + """
1.113
1.114 if self.match:
1.115 _start, self.pos = self.match.span()
1.116 try:
1.117 - return self.match.group(1)
1.118 + return self.match.group(group)
1.119 except IndexError:
1.120 return ""
1.121 else:
1.122 @@ -358,14 +367,14 @@
1.123
1.124 return parse_region(TokenStream(s))
1.125
1.126 -def parse_region(items, level=0):
1.127 +def parse_region(items, level=0, indent=0):
1.128
1.129 """
1.130 - Parse the data provided by 'items' to populate a region at the given
1.131 - 'level'.
1.132 + Parse the data provided by 'items' to populate a region with the given
1.133 + 'level' at the given 'indent'.
1.134 """
1.135
1.136 - region = Region([], level)
1.137 + region = Region([], level, indent)
1.138
1.139 # Parse section headers.
1.140
1.141 @@ -474,8 +483,9 @@
1.142
1.143 # Parse the section and start a new block after the section.
1.144
1.145 - level = len(items.read_match())
1.146 - region.append(parse_region(items, level))
1.147 + indent = len(items.read_match(2))
1.148 + level = len(items.read_match(3))
1.149 + region.append(parse_region(items, level, indent))
1.150 new_block(region)
1.151
1.152 def parse_section_end(items, region):