1.1 --- a/moinformat/serialisers/moin/moin.py Tue Jun 20 18:58:47 2023 +0200
1.2 +++ b/moinformat/serialisers/moin/moin.py Wed Jun 28 16:12:26 2023 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Moin wiki text serialiser.
1.6
1.7 -Copyright (C) 2017, 2018, 2021, 2022 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2017, 2018, 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -28,224 +28,216 @@
1.13 input_formats = ["moin", "wiki"]
1.14 formats = ["moin", "wiki"]
1.15
1.16 - def start_region(self, level, indent, type, args, extra):
1.17 + # Node handler methods.
1.18 +
1.19 + def region(self, region):
1.20 out = self.out
1.21 - if level:
1.22 - out(" " * indent + "{" * level)
1.23
1.24 - # Produce a header for regions within a top-level region.
1.25 + if region.level:
1.26 + out(" " * region.indent + "{" * region.level)
1.27
1.28 - if type and type != "inline" and level:
1.29 + # Produce a header for regions within a top-level region.
1.30
1.31 - # Obtain individual arguments, excluding the region type.
1.32 + if region.type and region.type != "inline":
1.33 +
1.34 + # Obtain individual arguments, excluding the region type.
1.35
1.36 - args = args.split(" ")[1:]
1.37 - args_str = args and (" %s" % " ".join(args)) or ""
1.38 + args = region.args.split(" ")[1:]
1.39 + args_str = args and (" %s" % " ".join(args)) or ""
1.40
1.41 - out("#!%s%s\n" % (type, args_str))
1.42 + out("#!%s%s\n" % (region.type, args_str))
1.43 +
1.44 + # Serialise the region content.
1.45
1.46 - def end_region(self, level, indent, type, args, extra):
1.47 - out = self.out
1.48 - if level:
1.49 - out("%s%s" % ("}" * level, extra or ""))
1.50 + self.region_to_string(region)
1.51
1.52 - def start_block(self):
1.53 - pass
1.54 + if region.level:
1.55 + out("%s%s" % ("}" * region.level, region.extra or ""))
1.56
1.57 - def end_block(self):
1.58 - pass
1.59 + # Block node methods.
1.60
1.61 - def start_defitem(self, pad, extra):
1.62 - self.out((extra and extra + "::" or "") + pad)
1.63 -
1.64 - def end_defitem(self, pad, extra):
1.65 - pass
1.66 + def block(self, block):
1.67 + self.container(block)
1.68
1.69 - def start_defterm(self, pad, extra):
1.70 - self.out(pad)
1.71 + def defitem(self, defitem):
1.72 + self.out((defitem.extra and defitem.extra + "::" or "") + defitem.pad)
1.73 + self.container(defitem)
1.74
1.75 - def end_defterm(self, pad, extra):
1.76 - self.out("::" + extra)
1.77 + def defterm(self, defterm):
1.78 + self.out(defterm.pad)
1.79 + self.container(defterm)
1.80 + self.out("::" + defterm.extra)
1.81
1.82 - def start_emphasis(self):
1.83 - self.out("''")
1.84 -
1.85 - def end_emphasis(self):
1.86 - self.out("''")
1.87 + def fontstyle(self, fontstyle):
1.88 + if fontstyle.emphasis:
1.89 + self.out("''")
1.90 + elif fontstyle.strong:
1.91 + self.out("'''")
1.92 + self.container(fontstyle)
1.93 + if fontstyle.emphasis:
1.94 + self.out("''")
1.95 + elif fontstyle.strong:
1.96 + self.out("'''")
1.97
1.98 - def start_heading(self, level, extra, pad, identifier):
1.99 - self.out(extra + "=" * level + pad)
1.100 + def heading(self, heading):
1.101 + self.out(heading.start_extra + "=" * heading.level + heading.start_pad)
1.102 + self.container(heading)
1.103 + self.out(heading.end_pad + "=" * heading.level + heading.end_extra)
1.104
1.105 - def end_heading(self, level, pad, extra):
1.106 - self.out(pad + "=" * level + extra)
1.107 -
1.108 - def start_larger(self):
1.109 + def larger(self, larger):
1.110 self.out("~+")
1.111 -
1.112 - def end_larger(self):
1.113 + self.container(larger)
1.114 self.out("+~")
1.115
1.116 - def start_list(self, indent, marker, num):
1.117 - pass
1.118 -
1.119 - def end_list(self, indent, marker, num):
1.120 - pass
1.121 + def list(self, list):
1.122 + self.container(list)
1.123
1.124 - def start_listitem(self, indent, marker, space, num):
1.125 - self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space))
1.126 + def listitem(self, listitem):
1.127 + self.out("%s%s%s%s" % (
1.128 + listitem.indent * " ",
1.129 + listitem.marker,
1.130 + listitem.num and "#%s" % listitem.num or "",
1.131 + listitem.space))
1.132 + self.container(listitem)
1.133
1.134 - def end_listitem(self, indent, marker, space, num):
1.135 - pass
1.136 -
1.137 - def start_macro(self, name, args, nodes, inline):
1.138 + def macro(self, macro):
1.139
1.140 # Special case of a deliberately unexpanded macro.
1.141
1.142 - if nodes is None:
1.143 + if macro.nodes is None:
1.144 return
1.145
1.146 # Fallback case for when macros are not replaced.
1.147
1.148 - if not nodes:
1.149 - self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or ""))
1.150 + if not macro.nodes:
1.151 + self.out("<<%s%s>>" % (macro.name, macro.args and "(%s)" % ",".join(macro.args) or ""))
1.152
1.153 - def end_macro(self, inline):
1.154 - pass
1.155 -
1.156 - def start_monospace(self):
1.157 + def monospace(self, monospace):
1.158 + self.out("`")
1.159 + self.container(monospace)
1.160 self.out("`")
1.161
1.162 - def end_monospace(self):
1.163 - self.out("`")
1.164 -
1.165 - def start_smaller(self):
1.166 + def smaller(self, smaller):
1.167 self.out("~-")
1.168 -
1.169 - def end_smaller(self):
1.170 + self.container(smaller)
1.171 self.out("-~")
1.172
1.173 - def start_strong(self):
1.174 - self.out("'''")
1.175 -
1.176 - def end_strong(self):
1.177 - self.out("'''")
1.178 -
1.179 - def start_strikethrough(self):
1.180 + def strikethrough(self, strikethrough):
1.181 self.out("--(")
1.182 -
1.183 - def end_strikethrough(self):
1.184 + self.container(strikethrough)
1.185 self.out(")--")
1.186
1.187 - def start_subscript(self):
1.188 + def subscript(self, subscript):
1.189 + self.out(",,")
1.190 + self.container(subscript)
1.191 self.out(",,")
1.192
1.193 - def end_subscript(self):
1.194 - self.out(",,")
1.195 -
1.196 - def start_superscript(self):
1.197 + def superscript(self, superscript):
1.198 self.out("^")
1.199 -
1.200 - def end_superscript(self):
1.201 + self.container(superscript)
1.202 self.out("^")
1.203
1.204 - def start_table(self):
1.205 - pass
1.206 -
1.207 - def end_table(self):
1.208 - pass
1.209 + def table(self, table):
1.210 + self.container(table)
1.211
1.212 - def start_table_attrs(self):
1.213 - self.out("<")
1.214 -
1.215 - def end_table_attrs(self):
1.216 - self.out(">")
1.217 + def table_cell(self, table_cell):
1.218 + self.out("||")
1.219 + self.container(table_cell)
1.220
1.221 - def start_table_cell(self, attrs, leading, padding):
1.222 + def table_row(self, table_row):
1.223 + self.container(table_row)
1.224 self.out("||")
1.225 -
1.226 - def end_table_cell(self):
1.227 - pass
1.228 + self.out(table_row.trailing)
1.229
1.230 - def start_table_row(self, leading, padding):
1.231 - pass
1.232 -
1.233 - def end_table_row(self, trailing):
1.234 - self.out("||")
1.235 - self.out(trailing)
1.236 -
1.237 - def start_underline(self):
1.238 + def underline(self, underline):
1.239 + self.out("__")
1.240 + self.container(underline)
1.241 self.out("__")
1.242
1.243 - def end_underline(self):
1.244 - self.out("__")
1.245 + # Inline node methods.
1.246
1.247 - def anchor(self, target):
1.248 - self.out("((%s))" % target)
1.249 + def anchor(self, anchor):
1.250 + self.out("((%s))" % anchor.target)
1.251
1.252 - def break_(self):
1.253 + def break_(self, break_):
1.254 self.out("\n")
1.255
1.256 - def comment(self, comment, extra):
1.257 - self.out("##%s%s" % (comment, extra))
1.258 + def comment(self, comment):
1.259 + self.out("##%s%s" % (comment.comment, comment.extra))
1.260
1.261 - def directive(self, directive, extra):
1.262 - self.out("#%s%s" % (directive, extra))
1.263 + def directive(self, directive):
1.264 + self.out("#%s%s" % (directive.directive, directive.extra))
1.265
1.266 - def linebreak(self):
1.267 + def linebreak(self, linebreak):
1.268 self.out(r"\\")
1.269
1.270 - def link(self, target, nodes):
1.271 - self.out("[[%s" % target)
1.272 - for node in nodes:
1.273 + def link(self, link):
1.274 + self.out("[[%s" % link.target)
1.275 + for node in link.nodes:
1.276 self.out("|")
1.277 - node.to_string(self)
1.278 + node.visit(self)
1.279 self.out("]]")
1.280
1.281 - def link_label(self, nodes):
1.282 - for node in nodes:
1.283 - node.to_string(self)
1.284 + def link_label(self, link_label):
1.285 + self.container(link_label)
1.286
1.287 - def link_parameter(self, key_value):
1.288 + def link_parameter(self, link_parameter):
1.289 + s = link_parameter.text_content()
1.290 + key_value = s.split("=", 1)
1.291 +
1.292 if len(key_value) == 1:
1.293 self.out(key_value[0])
1.294 else:
1.295 self.out("=".join(key_value))
1.296
1.297 - def nbsp(self):
1.298 + def nbsp(self, nbsp):
1.299 self.out(r"\_")
1.300
1.301 - def rule(self, height):
1.302 - self.out("-" * (height + 4))
1.303 + def rule(self, rule):
1.304 + self.out("-" * (rule.height + 4))
1.305
1.306 - def table_attrs(self, nodes):
1.307 - for node in nodes:
1.308 - node.to_string(self)
1.309 + def table_attrs(self, table_attrs):
1.310 + self.out("<")
1.311 + self.container(table_attrs)
1.312 + if not table_attrs.incomplete:
1.313 + self.out(">")
1.314
1.315 - def table_attr(self, name, value, concise, quote):
1.316 - if concise:
1.317 - if name == "bgcolor": self.out(value)
1.318 - elif name == "colspan": self.out("-%s" % value)
1.319 - elif name == "align" : self.out(value == "left" and "(" or value == "right" and ")" or ":")
1.320 - elif name == "rowspan": self.out("|%s" % value)
1.321 - elif name == "valign" : self.out(value == "top" and "^" or "v")
1.322 - elif name == "width" : self.out(value)
1.323 + def table_attr(self, table_attr):
1.324 + if table_attr.concise:
1.325 + if table_attr.name == "bgcolor":
1.326 + self.out(table_attr.value)
1.327 + elif table_attr.name == "colspan":
1.328 + self.out("-%s" % table_attr.value)
1.329 + elif table_attr.name == "align":
1.330 + self.out(table_attr.value == "left" and "(" or table_attr.value == "right" and ")" or ":")
1.331 + elif table_attr.name == "rowspan":
1.332 + self.out("|%s" % table_attr.value)
1.333 + elif table_attr.name == "valign":
1.334 + self.out(table_attr.value == "top" and "^" or "v")
1.335 + elif table_attr.name == "width":
1.336 + self.out(table_attr.value)
1.337 else:
1.338 - self.out("%s%s" % (escape_text(name), value is not None and
1.339 - "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or ""))
1.340 -
1.341 - def text(self, s):
1.342 - self.out(s)
1.343 + self.out("%s%s" % (
1.344 + escape_text(table_attr.name),
1.345 + table_attr.value is not None and "=%s%s%s" % (
1.346 + table_attr.quote or '"',
1.347 + escape_attr(table_attr.value),
1.348 + table_attr.quote or '"')
1.349 + or ""))
1.350
1.351 - def transclusion(self, target, nodes):
1.352 - self.out("{{%s" % target)
1.353 - for node in nodes:
1.354 + def text(self, text):
1.355 + self.out(text.s)
1.356 +
1.357 + def transclusion(self, transclusion):
1.358 + self.out("{{%s" % transclusion.target)
1.359 + for node in transclusion.nodes:
1.360 self.out("|")
1.361 - node.to_string(self)
1.362 + node.visit(self)
1.363 self.out("}}")
1.364
1.365 - def verbatim(self, text):
1.366 + def verbatim(self, verbatim):
1.367 self.out("<<<")
1.368 - self.out(text)
1.369 + self.out(verbatim.text)
1.370 self.out(">>>")
1.371
1.372 serialiser = MoinSerialiser