1.1 --- a/moinformat/parsers/common.py Mon Jul 16 19:19:31 2018 +0200
1.2 +++ b/moinformat/parsers/common.py Tue Jul 17 19:19:59 2018 +0200
1.3 @@ -407,7 +407,7 @@
1.4
1.5 # Obtain any feature.
1.6
1.7 - feature = self.match_group()
1.8 + feature = self.match_group("feature") or self.match_group()
1.9 handler = self.handlers.get(self.matching_pattern())
1.10
1.11 # Handle each feature or add text to the region.
2.1 --- a/moinformat/parsers/moin.py Mon Jul 16 19:19:31 2018 +0200
2.2 +++ b/moinformat/parsers/moin.py Tue Jul 17 19:19:59 2018 +0200
2.3 @@ -275,15 +275,30 @@
2.4
2.5 indent = len(self.match_group("indent"))
2.6 level = len(self.match_group("level"))
2.7 - self.add_node(region, self.parse_region(level, indent, "inline"))
2.8 - self.new_block(region)
2.9 +
2.10 + section = self.parse_region(level, indent, "inline")
2.11 +
2.12 + # If the section is inline, treat it like any other inline element.
2.13 +
2.14 + if section.type == "inline":
2.15 + region.append_inline(section)
2.16 +
2.17 + # Otherwise, add it as a new block element.
2.18 +
2.19 + else:
2.20 + self.add_node(region, section)
2.21 + if region.allow_blocks:
2.22 + self.new_block(region)
2.23
2.24 def parse_section_end(self, region):
2.25
2.26 "Handle the end of a new section within 'region'."
2.27
2.28 - feature = self.match_group("level")
2.29 - if region.have_end(feature):
2.30 + level = self.match_group("level")
2.31 + feature = self.match_group("feature")
2.32 + region.extra = self.match_group("extra")
2.33 +
2.34 + if region.have_end(level):
2.35 raise StopIteration
2.36 else:
2.37 region.append_inline(Text(feature))
2.38 @@ -317,6 +332,9 @@
2.39 # All nodes were valid: preserve the collection.
2.40
2.41 else:
2.42 + # Add the attributes as a node, also recording their presence.
2.43 +
2.44 + cell.append(attrs)
2.45 cell.attrs = attrs
2.46 return
2.47
2.48 @@ -354,8 +372,7 @@
2.49 if not row.nodes or not cell.empty():
2.50 for node in row.nodes:
2.51 region.append_inline(Text(serialise(node)))
2.52 - region.append_inline(Text(serialise(cell)))
2.53 - region.append_inline(Text(trailing))
2.54 + region.append_inline(Text(serialise(cell) + trailing))
2.55
2.56 self.new_block(region)
2.57 return
2.58 @@ -463,7 +480,10 @@
2.59 group("level", repeat("[{]", 3)))), # {{{...
2.60
2.61 "regionend" : join((r"\N*", # ws... (optional)
2.62 - group("level", repeat("[}]", 3)))), # }}}...
2.63 + group("feature", join((
2.64 + group("level", repeat("[}]", 3)), # }}}...
2.65 + group("extra", r"\n"),
2.66 + "?"))))), # nl (optional)
2.67
2.68 "header" : join(("#!", # #!
2.69 group("args", ".*?"), "\n")), # text-excl-nl
3.1 --- a/moinformat/parsers/table.py Mon Jul 16 19:19:31 2018 +0200
3.2 +++ b/moinformat/parsers/table.py Tue Jul 17 19:19:59 2018 +0200
3.3 @@ -79,8 +79,11 @@
3.4
3.5 "Handle the end of a region within 'cell'."
3.6
3.7 - feature = self.match_group("level")
3.8 - if self.region.have_end(feature):
3.9 + level = self.match_group("level")
3.10 + feature = self.match_group("feature")
3.11 + self.region.extra = self.match_group("extra")
3.12 +
3.13 + if self.region.have_end(level):
3.14 raise StopIteration
3.15 else:
3.16 cell.append_inline(Text(feature))
4.1 --- a/moinformat/serialisers/html.py Mon Jul 16 19:19:31 2018 +0200
4.2 +++ b/moinformat/serialisers/html.py Tue Jul 17 19:19:59 2018 +0200
4.3 @@ -38,7 +38,7 @@
4.4 else:
4.5 return "span"
4.6
4.7 - def start_region(self, level, indent, type):
4.8 + def start_region(self, level, indent, type, extra):
4.9 l = []
4.10 out = l.append
4.11 if level:
4.12 @@ -54,7 +54,7 @@
4.13 tag = self._region_tag(type)
4.14 self.out("<%s class='%s'>" % (tag, " ".join(l)))
4.15
4.16 - def end_region(self, level, indent, type):
4.17 + def end_region(self, level, indent, type, extra):
4.18 tag = self._region_tag(type)
4.19 self.out("</%s>" % tag)
4.20
5.1 --- a/moinformat/serialisers/moin.py Mon Jul 16 19:19:31 2018 +0200
5.2 +++ b/moinformat/serialisers/moin.py Tue Jul 17 19:19:59 2018 +0200
5.3 @@ -25,7 +25,7 @@
5.4
5.5 "Serialisation of the page."
5.6
5.7 - def start_region(self, level, indent, type):
5.8 + def start_region(self, level, indent, type, extra):
5.9 out = self.out
5.10 if level:
5.11 out(" " * indent + "{" * level)
5.12 @@ -35,10 +35,10 @@
5.13 if type and type != "inline" and level:
5.14 out("#!%s\n" % type)
5.15
5.16 - def end_region(self, level, indent, type):
5.17 + def end_region(self, level, indent, type, extra):
5.18 out = self.out
5.19 if level:
5.20 - out("}" * level)
5.21 + out("%s%s" % ("}" * level, extra or ""))
5.22
5.23 def start_block(self):
5.24 pass
6.1 --- a/moinformat/tree.py Mon Jul 16 19:19:31 2018 +0200
6.2 +++ b/moinformat/tree.py Tue Jul 17 19:19:59 2018 +0200
6.3 @@ -26,6 +26,11 @@
6.4 def __init__(self, nodes):
6.5 self.nodes = nodes
6.6
6.7 + # In principle, allow blocks within containers. Some nodes may forbid
6.8 + # them to simplify the document structure.
6.9 +
6.10 + self.allow_blocks = True
6.11 +
6.12 def append(self, node):
6.13 self.nodes.append(node)
6.14
6.15 @@ -97,12 +102,13 @@
6.16
6.17 "A region of the page."
6.18
6.19 - def __init__(self, nodes, level=0, indent=0, type=None, transparent=True):
6.20 + def __init__(self, nodes, level=0, indent=0, type=None, transparent=True, extra=None):
6.21 Container.__init__(self, nodes)
6.22 self.level = level
6.23 self.indent = indent
6.24 self.type = type
6.25 self.transparent = transparent
6.26 + self.extra = extra
6.27
6.28 def add(self, node):
6.29 last = self.node(-1)
6.30 @@ -121,14 +127,16 @@
6.31 return self.level and s.startswith("}") and self.level == len(s)
6.32
6.33 def __repr__(self):
6.34 - return "Region(%r, %r, %r, %r)" % (self.nodes, self.level, self.indent, self.type)
6.35 + return "Region(%r, %r, %r, %r, %r, %r)" % (self.nodes, self.level,
6.36 + self.indent, self.type, self.transparent, self.extra)
6.37
6.38 def prettyprint(self, indent=""):
6.39 - l = ["%sRegion: level=%d indent=%d type=%s" % (indent, self.level, self.indent, self.type)]
6.40 + l = ["%sRegion: level=%d indent=%d type=%s extra=%r" % (indent,
6.41 + self.level, self.indent, self.type, self.extra)]
6.42 return self._prettyprint(l, indent)
6.43
6.44 def to_string(self, out):
6.45 - out.start_region(self.level, self.indent, self.type)
6.46 + out.start_region(self.level, self.indent, self.type, self.extra)
6.47
6.48 # Obtain a serialiser for the region, if appropriate.
6.49
6.50 @@ -139,7 +147,7 @@
6.51
6.52 self._to_string(region_out)
6.53
6.54 - out.end_region(self.level, self.indent, self.type)
6.55 + out.end_region(self.level, self.indent, self.type, self.extra)
6.56
6.57
6.58
6.59 @@ -300,6 +308,10 @@
6.60 self.space = space
6.61 self.num = num
6.62
6.63 + # Forbid blocks within list items for simpler structure.
6.64 +
6.65 + self.allow_blocks = False
6.66 +
6.67 def __repr__(self):
6.68 return "ListItem(%r, %r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.space, self.num)
6.69
6.70 @@ -353,17 +365,17 @@
6.71 self.attrs = attrs
6.72
6.73 def __repr__(self):
6.74 - return "TableCell(%r, %f)" % (self.nodes, self.attrs)
6.75 + return "TableCell(%r, %r)" % (self.nodes, self.attrs)
6.76
6.77 def prettyprint(self, indent=""):
6.78 l = ["%sTableCell:" % indent]
6.79 - if self.attrs:
6.80 - l.append(self.attrs.prettyprint(indent + " "))
6.81 return self._prettyprint(l, indent)
6.82
6.83 def to_string(self, out):
6.84 out.start_table_cell(self.attrs)
6.85 - self._to_string(out)
6.86 + for node in self.nodes:
6.87 + if node is not self.attrs:
6.88 + node.to_string(out)
6.89 out.end_table_cell()
6.90
6.91 class TableRow(Container):