# HG changeset patch # User Paul Boddie # Date 1532439800 -7200 # Node ID 15c19a3d61e91702213e84071c618d3647717fea # Parent 7922c674372b436499a83472aae20e0c08dc26a2 Introduced families of serialisers for each output format, with parser-specific serialisers retaining knowledge of how their document tree nodes are to be serialised. Introduced a get_serialiser function as a convenience to replace general access to the all_serialisers dictionary. Changed the dynamic import mechanism to qualify identified module names using package name information. diff -r 7922c674372b -r 15c19a3d61e9 convert.py --- a/convert.py Tue Jul 24 12:58:58 2018 +0200 +++ b/convert.py Tue Jul 24 15:43:20 2018 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python -from moinformat import all_parsers, all_serialisers, parse, serialise +from moinformat import all_parsers, get_serialiser, parse, serialise from os.path import split import sys @@ -50,7 +50,7 @@ print d.prettyprint() else: format = formats and formats[0] or "html" - print serialise(d, all_serialisers[format]) + print serialise(d, get_serialiser(format)) finally: f.close() diff -r 7922c674372b -r 15c19a3d61e9 moinformat/__init__.py --- a/moinformat/__init__.py Tue Jul 24 12:58:58 2018 +0200 +++ b/moinformat/__init__.py Tue Jul 24 15:43:20 2018 +0200 @@ -22,4 +22,10 @@ from moinformat.parsers import parse, parsers as all_parsers from moinformat.serialisers import serialise, serialisers as all_serialisers +def get_serialiser(name): + + "Return the main serialiser for the format having the given 'name'." + + return all_serialisers["%s.moin" % name] + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/imports.py --- a/moinformat/imports.py Tue Jul 24 12:58:58 2018 +0200 +++ b/moinformat/imports.py Tue Jul 24 15:43:20 2018 +0200 @@ -3,7 +3,7 @@ """ Import utilities. -Copyright (C) 2017 Paul Boddie +Copyright (C) 2017, 2018 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,18 +23,19 @@ from os import listdir from importlib import import_module -def get_extensions(dirname, modname, stores, reserved): +def get_extensions(dirname, modname, stores, reserved, prefix=None): "Import extensions inside 'dirname'." for filename in listdir(dirname): pathname = join(dirname, filename) - # Descend into directories. + # Descend into directories, prefixing the identified modules. if isdir(pathname): + store_name = prefix and "%s.%s" % (prefix, modname) or filename get_extensions(pathname, "%s.%s" % (modname, filename), - stores, reserved) + stores, reserved, store_name) continue # Identify modules and import them. @@ -42,6 +43,7 @@ leafname, ext = splitext(filename) if ext == ".py" and leafname not in reserved: - stores[leafname] = import_module("%s.%s" % (modname, leafname)) + store_name = prefix and "%s.%s" % (prefix, leafname) or leafname + stores[store_name] = import_module("%s.%s" % (modname, leafname)) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/__init__.py --- a/moinformat/serialisers/__init__.py Tue Jul 24 12:58:58 2018 +0200 +++ b/moinformat/serialisers/__init__.py Tue Jul 24 15:43:20 2018 +0200 @@ -20,7 +20,7 @@ """ from moinformat.serialisers.manifest import serialisers -from moinformat.serialisers.moin import MoinSerialiser +from moinformat.serialisers.moin.moin import MoinSerialiser # Top-level functions. @@ -28,12 +28,8 @@ "Serialise 'doc' using 'serialiser' or the Moin serialiser if omitted." - # Permit serialisation back to source form if Moin format is used. - - formats = serialiser is MoinSerialiser and serialisers or None - l = [] - doc.to_string(serialiser(l.append, formats)) + doc.to_string(serialiser(l.append, serialisers)) return "".join(l) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/common.py --- a/moinformat/serialisers/common.py Tue Jul 24 12:58:58 2018 +0200 +++ b/moinformat/serialisers/common.py Tue Jul 24 15:43:20 2018 +0200 @@ -23,6 +23,8 @@ "General serialisation support." + format = None # defined by subclasses + def __init__(self, out, formats=None): """ diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/html.py --- a/moinformat/serialisers/html.py Tue Jul 24 12:58:58 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -#!/usr/bin/env python - -""" -HTML serialiser. - -Copyright (C) 2017, 2018 Paul Boddie - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -from moinformat.serialisers.common import escape_attr, escape_text, Serialiser - -class HTMLSerialiser(Serialiser): - - "Serialisation of the page." - - def _region_tag(self, type): - - # NOTE: Need to support types in general. - - type = type and type.split()[0] - - if type == "inline": - return "tt" - elif type in (None, "python"): - return "pre" - else: - return "span" - - def start_region(self, level, indent, type, extra): - l = [] - out = l.append - if level: - out("level-%d" % level) - - if indent: - out("indent-%d" % indent) - - # NOTE: Encode type details for CSS. - - out("type-%s" % escape_attr(type or "opaque")) - - tag = self._region_tag(type) - self.out("<%s class='%s'>" % (tag, " ".join(l))) - - def end_region(self, level, indent, type, extra): - tag = self._region_tag(type) - self.out("" % tag) - - def start_block(self): - self.out("

") - - def end_block(self): - self.out("

") - - def start_defitem(self, pad, extra): - self.out("
") - - def end_defitem(self, pad, extra): - self.out("
") - - def start_defterm(self, pad): - self.out("
") - - def end_defterm(self, pad): - self.out("
") - - def start_emphasis(self): - self.out("") - - def end_emphasis(self): - self.out("") - - def start_heading(self, level, extra, pad): - self.out("" % level) - - def end_heading(self, level, pad, extra): - self.out("" % level) - - def start_larger(self): - self.out("") - - def end_larger(self): - self.out("") - - def start_link(self, target): - self.out('' % escape_attr(target)) - - def end_link(self): - self.out("") - - def start_linktext(self): - pass - - def end_linktext(self): - pass - - list_tags = { - "i" : "lower-roman", - "I" : "upper-roman", - "a" : "lower-latin", - "A" : "upper-latin", - } - - def _get_list_tag(self, marker): - if marker: - if marker[0].isdigit(): - return "ol", "decimal" - style_type = self.list_tags.get(marker[0]) - if style_type: - return "ol", style_type - - return "ul", None - - def start_list(self, indent, marker, num): - tag, style_type = self._get_list_tag(marker) - style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or "" - start = style_type and num is not None and ' start="%s"' % escape_attr(num) or "" - self.out("<%s%s%s>" % (tag, style, start)) - - def end_list(self, indent, marker, num): - tag, style = self._get_list_tag(marker) - self.out("" % tag) - - def start_listitem(self, indent, marker, space, num): - self.out("
  • ") - - def end_listitem(self, indent, marker, space, num): - self.out("
  • ") - - def start_monospace(self): - self.out("") - - def end_monospace(self): - self.out("") - - def start_smaller(self): - self.out("") - - def end_smaller(self): - self.out("") - - def start_strikethrough(self): - self.out("") - - def end_strikethrough(self): - self.out("") - - def start_strong(self): - self.out("") - - def end_strong(self): - self.out("") - - def start_subscript(self): - self.out("") - - def end_subscript(self): - self.out("") - - def start_superscript(self): - self.out("") - - def end_superscript(self): - self.out("") - - def start_table(self): - self.out("") - - def end_table(self): - self.out("
    ") - - def start_table_attrs(self): - pass - - def end_table_attrs(self): - pass - - def start_table_cell(self, attrs): - self.out("") - - def end_table_cell(self): - self.out("") - - def start_table_row(self): - self.out("") - - def end_table_row(self, trailing): - self.out("") - - def start_underline(self): - self.out("") - - def end_underline(self): - self.out("") - - def break_(self): - pass - - def continuation(self, text): - pass - - def macro(self, name, args): - - # NOTE: Special case. - - if name == "BR": - self.out("
    ") - return - - # Fallback case. - - self.out("") - self.out(escape_text("<<")) - self.out("%s" % escape_text(name)) - if args: - self.out("(") - first = True - for arg in args: - if not first: - self.out(",") - self.out("%s" % escape_text(arg)) - first = False - if args: - self.out(")") - self.out(escape_text(">>")) - self.out("") - - def rule(self, length): - self.out("
    " % min(length, 10)) - - def table_attr(self, name, value, concise, quote): - self.out(" %s%s" % (escape_text(name), value is not None and - "='%s'" % escape_attr(value) or "")) - - def text(self, s): - self.out(escape_text(s)) - -serialiser = HTMLSerialiser - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/html/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/html/__init__.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +""" +A package of modules containing HTML format serialisers. + +Copyright (C) 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/html/moin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/html/moin.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,254 @@ +#!/usr/bin/env python + +""" +HTML serialiser. + +Copyright (C) 2017, 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from moinformat.serialisers.common import escape_attr, escape_text, Serialiser + +class HTMLSerialiser(Serialiser): + + "Serialisation of the page." + + format = "html" + + def _region_tag(self, type): + + # NOTE: Need to support types in general. + + type = type and type.split()[0] + + if type == "inline": + return "tt" + elif type in (None, "python"): + return "pre" + else: + return "span" + + def start_region(self, level, indent, type, extra): + l = [] + out = l.append + if level: + out("level-%d" % level) + + if indent: + out("indent-%d" % indent) + + # NOTE: Encode type details for CSS. + + out("type-%s" % escape_attr(type or "opaque")) + + tag = self._region_tag(type) + self.out("<%s class='%s'>" % (tag, " ".join(l))) + + def end_region(self, level, indent, type, extra): + tag = self._region_tag(type) + self.out("" % tag) + + def start_block(self): + self.out("

    ") + + def end_block(self): + self.out("

    ") + + def start_defitem(self, pad, extra): + self.out("
    ") + + def end_defitem(self, pad, extra): + self.out("
    ") + + def start_defterm(self, pad): + self.out("
    ") + + def end_defterm(self, pad): + self.out("
    ") + + def start_emphasis(self): + self.out("") + + def end_emphasis(self): + self.out("") + + def start_heading(self, level, extra, pad): + self.out("" % level) + + def end_heading(self, level, pad, extra): + self.out("" % level) + + def start_larger(self): + self.out("") + + def end_larger(self): + self.out("") + + def start_link(self, target): + self.out('' % escape_attr(target)) + + def end_link(self): + self.out("") + + def start_linktext(self): + pass + + def end_linktext(self): + pass + + list_tags = { + "i" : "lower-roman", + "I" : "upper-roman", + "a" : "lower-latin", + "A" : "upper-latin", + } + + def _get_list_tag(self, marker): + if marker: + if marker[0].isdigit(): + return "ol", "decimal" + style_type = self.list_tags.get(marker[0]) + if style_type: + return "ol", style_type + + return "ul", None + + def start_list(self, indent, marker, num): + tag, style_type = self._get_list_tag(marker) + style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or "" + start = style_type and num is not None and ' start="%s"' % escape_attr(num) or "" + self.out("<%s%s%s>" % (tag, style, start)) + + def end_list(self, indent, marker, num): + tag, style = self._get_list_tag(marker) + self.out("" % tag) + + def start_listitem(self, indent, marker, space, num): + self.out("
  • ") + + def end_listitem(self, indent, marker, space, num): + self.out("
  • ") + + def start_monospace(self): + self.out("") + + def end_monospace(self): + self.out("") + + def start_smaller(self): + self.out("") + + def end_smaller(self): + self.out("") + + def start_strikethrough(self): + self.out("") + + def end_strikethrough(self): + self.out("") + + def start_strong(self): + self.out("") + + def end_strong(self): + self.out("") + + def start_subscript(self): + self.out("") + + def end_subscript(self): + self.out("") + + def start_superscript(self): + self.out("") + + def end_superscript(self): + self.out("") + + def start_table(self): + self.out("") + + def end_table(self): + self.out("
    ") + + def start_table_attrs(self): + pass + + def end_table_attrs(self): + pass + + def start_table_cell(self, attrs): + self.out("") + + def end_table_cell(self): + self.out("") + + def start_table_row(self): + self.out("") + + def end_table_row(self, trailing): + self.out("") + + def start_underline(self): + self.out("") + + def end_underline(self): + self.out("") + + def break_(self): + pass + + def macro(self, name, args): + + # NOTE: Special case. + + if name == "BR": + self.out("
    ") + return + + # Fallback case. + + self.out("") + self.out(escape_text("<<")) + self.out("%s" % escape_text(name)) + if args: + self.out("(") + first = True + for arg in args: + if not first: + self.out(",") + self.out("%s" % escape_text(arg)) + first = False + if args: + self.out(")") + self.out(escape_text(">>")) + self.out("") + + def rule(self, length): + self.out("
    " % min(length, 10)) + + def table_attr(self, name, value, concise, quote): + self.out(" %s%s" % (escape_text(name), value is not None and + "='%s'" % escape_attr(value) or "")) + + def text(self, s): + self.out(escape_text(s)) + +serialiser = HTMLSerialiser + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/html/table.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/html/table.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" +HTML serialiser. + +Copyright (C) 2017, 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from moinformat.serialisers.common import escape_attr, escape_text +from moinformat.serialisers.html.moin import HTMLSerialiser + +class HTMLTableSerialiser(HTMLSerialiser): + + "Serialisation of the page." + + def continuation(self, text): + pass + +serialiser = HTMLTableSerialiser + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/moin.py --- a/moinformat/serialisers/moin.py Tue Jul 24 12:58:58 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -#!/usr/bin/env python - -""" -Moin wiki text serialiser. - -Copyright (C) 2017, 2018 Paul Boddie - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -from moinformat.serialisers.common import escape_attr, escape_text, Serialiser - -class MoinSerialiser(Serialiser): - - "Serialisation of the page." - - def start_region(self, level, indent, type, extra): - out = self.out - if level: - out(" " * indent + "{" * level) - - # Produce a header for regions within a top-level region. - - if type and type != "inline" and level: - out("#!%s\n" % type) - - def end_region(self, level, indent, type, extra): - out = self.out - if level: - out("%s%s" % ("}" * level, extra or "")) - - def start_block(self): - pass - - def end_block(self): - pass - - def start_defitem(self, pad, extra): - self.out((extra and "\n" + extra + "::" or "") + pad) - - def end_defitem(self, pad, extra): - pass - - def start_defterm(self, pad): - self.out(pad) - - def end_defterm(self, pad): - self.out("::") - - def start_emphasis(self): - self.out("''") - - def end_emphasis(self): - self.out("''") - - def start_heading(self, level, extra, pad): - self.out(extra + "=" * level + pad) - - def end_heading(self, level, pad, extra): - self.out(pad + "=" * level + extra) - - def start_larger(self): - self.out("~+") - - def end_larger(self): - self.out("+~") - - def start_link(self, target): - self.out("[[%s" % target) - - def end_link(self): - self.out("]]") - - def start_linktext(self): - self.out("|") - - def end_linktext(self): - pass - - def start_list(self, indent, marker, num): - pass - - def end_list(self, indent, marker, num): - pass - - def start_listitem(self, indent, marker, space, num): - self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space)) - - def end_listitem(self, indent, marker, space, num): - pass - - def start_monospace(self): - self.out("`") - - def end_monospace(self): - self.out("`") - - def start_smaller(self): - self.out("~-") - - def end_smaller(self): - self.out("-~") - - def start_strong(self): - self.out("'''") - - def end_strong(self): - self.out("'''") - - def start_strikethrough(self): - self.out("--(") - - def end_strikethrough(self): - self.out(")--") - - def start_subscript(self): - self.out(",,") - - def end_subscript(self): - self.out(",,") - - def start_superscript(self): - self.out("^") - - def end_superscript(self): - self.out("^") - - def start_table(self): - pass - - def end_table(self): - pass - - def start_table_attrs(self): - self.out("<") - - def end_table_attrs(self): - self.out(">") - - def start_table_cell(self, attrs): - self.out("||") - if attrs and not attrs.empty(): - attrs.to_string(self) - - def end_table_cell(self): - pass - - def start_table_row(self): - pass - - def end_table_row(self, trailing): - self.out("||") - self.out(trailing) - - def start_underline(self): - self.out("__") - - def end_underline(self): - self.out("__") - - def break_(self): - self.out("\n") - - def continuation(self, text): - self.out(text) - - def macro(self, name, args): - self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or "")) - - def rule(self, length): - self.out("-" * length) - - def table_attr(self, name, value, concise, quote): - if concise: - if name == "colour": self.out(value) - elif name == "colspan": self.out("-%s" % value) - elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":") - elif name == "rowspan": self.out("|%s" % value) - elif name == "valign" : self.out(value == "top" and "^" or "v") - elif name == "width" : self.out(value) - else: - self.out("%s%s" % (escape_text(name), value is not None and - "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or "")) - - def text(self, s): - self.out(s) - -serialiser = MoinSerialiser - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/moin/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/moin/__init__.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +""" +A package of modules containing Moin format serialisers. + +Copyright (C) 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/moin/moin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/moin/moin.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +""" +Moin wiki text serialiser. + +Copyright (C) 2017, 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from moinformat.serialisers.common import escape_attr, escape_text, Serialiser + +class MoinSerialiser(Serialiser): + + "Serialisation of the page." + + format = "moin" + + def start_region(self, level, indent, type, extra): + out = self.out + if level: + out(" " * indent + "{" * level) + + # Produce a header for regions within a top-level region. + + if type and type != "inline" and level: + out("#!%s\n" % type) + + def end_region(self, level, indent, type, extra): + out = self.out + if level: + out("%s%s" % ("}" * level, extra or "")) + + def start_block(self): + pass + + def end_block(self): + pass + + def start_defitem(self, pad, extra): + self.out((extra and "\n" + extra + "::" or "") + pad) + + def end_defitem(self, pad, extra): + pass + + def start_defterm(self, pad): + self.out(pad) + + def end_defterm(self, pad): + self.out("::") + + def start_emphasis(self): + self.out("''") + + def end_emphasis(self): + self.out("''") + + def start_heading(self, level, extra, pad): + self.out(extra + "=" * level + pad) + + def end_heading(self, level, pad, extra): + self.out(pad + "=" * level + extra) + + def start_larger(self): + self.out("~+") + + def end_larger(self): + self.out("+~") + + def start_link(self, target): + self.out("[[%s" % target) + + def end_link(self): + self.out("]]") + + def start_linktext(self): + self.out("|") + + def end_linktext(self): + pass + + def start_list(self, indent, marker, num): + pass + + def end_list(self, indent, marker, num): + pass + + def start_listitem(self, indent, marker, space, num): + self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space)) + + def end_listitem(self, indent, marker, space, num): + pass + + def start_monospace(self): + self.out("`") + + def end_monospace(self): + self.out("`") + + def start_smaller(self): + self.out("~-") + + def end_smaller(self): + self.out("-~") + + def start_strong(self): + self.out("'''") + + def end_strong(self): + self.out("'''") + + def start_strikethrough(self): + self.out("--(") + + def end_strikethrough(self): + self.out(")--") + + def start_subscript(self): + self.out(",,") + + def end_subscript(self): + self.out(",,") + + def start_superscript(self): + self.out("^") + + def end_superscript(self): + self.out("^") + + def start_table(self): + pass + + def end_table(self): + pass + + def start_table_attrs(self): + self.out("<") + + def end_table_attrs(self): + self.out(">") + + def start_table_cell(self, attrs): + self.out("||") + if attrs and not attrs.empty(): + attrs.to_string(self) + + def end_table_cell(self): + pass + + def start_table_row(self): + pass + + def end_table_row(self, trailing): + self.out("||") + self.out(trailing) + + def start_underline(self): + self.out("__") + + def end_underline(self): + self.out("__") + + def break_(self): + self.out("\n") + + def continuation(self, text): + self.out(text) + + def macro(self, name, args): + self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or "")) + + def rule(self, length): + self.out("-" * length) + + def table_attr(self, name, value, concise, quote): + if concise: + if name == "colour": self.out(value) + elif name == "colspan": self.out("-%s" % value) + elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":") + elif name == "rowspan": self.out("|%s" % value) + elif name == "valign" : self.out(value == "top" and "^" or "v") + elif name == "width" : self.out(value) + else: + self.out("%s%s" % (escape_text(name), value is not None and + "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or "")) + + def text(self, s): + self.out(s) + +serialiser = MoinSerialiser + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/moin/table.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/serialisers/moin/table.py Tue Jul 24 15:43:20 2018 +0200 @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +""" +Moin wiki table serialiser. + +Copyright (C) 2017, 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from moinformat.serialisers.moin.moin import MoinSerialiser + +class MoinTableSerialiser(MoinSerialiser): + + "Serialisation of the page." + + def init(self): + self.first_cell = False + self.first_row = False + + def start_table(self): + self.first_row = True + + def start_table_cell(self, attrs): + if not self.first_cell: + self.out("||") + else: + self.first_cell = False + + if attrs and not attrs.empty(): + attrs.to_string(self) + + def start_table_row(self): + self.first_cell = True + if not self.first_row: + self.out("==") + else: + self.first_row = False + + def end_table_row(self, trailing): + self.out(trailing) + +serialiser = MoinTableSerialiser + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/serialisers/table.py --- a/moinformat/serialisers/table.py Tue Jul 24 12:58:58 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#!/usr/bin/env python - -""" -Moin wiki table serialiser. - -Copyright (C) 2017 Paul Boddie - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -from moinformat.serialisers.moin import MoinSerialiser - -class TableSerialiser(MoinSerialiser): - - "Serialisation of the page." - - def init(self): - self.first_cell = False - self.first_row = False - - def start_table(self): - self.first_row = True - - def start_table_cell(self, attrs): - if not self.first_cell: - self.out("||") - else: - self.first_cell = False - - if attrs and not attrs.empty(): - attrs.to_string(self) - - def start_table_row(self): - self.first_cell = True - if not self.first_row: - self.out("==") - else: - self.first_row = False - - def end_table_row(self, trailing): - self.out(trailing) - -serialiser = TableSerialiser - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7922c674372b -r 15c19a3d61e9 moinformat/tree/moin.py --- a/moinformat/tree/moin.py Tue Jul 24 12:58:58 2018 +0200 +++ b/moinformat/tree/moin.py Tue Jul 24 15:43:20 2018 +0200 @@ -138,10 +138,16 @@ def to_string(self, out): out.start_region(self.level, self.indent, self.type, self.extra) - # Obtain a serialiser for the region, if appropriate. + # Obtain a serialiser class for the region from the same format family. + + serialiser_name = "%s.%s" % (out.format, self.type) + serialiser_cls = out.formats and out.formats.get(serialiser_name) - serialiser = out.formats and out.formats.get(self.type) - region_out = serialiser and serialiser(out.out, out.formats) or out + # Retain the same serialiser if no appropriate serialiser could be + # obtained. + + region_out = serialiser_cls and serialiser_cls(out.out, out.formats) \ + or out # Serialise the region. diff -r 7922c674372b -r 15c19a3d61e9 tests/test_parser.py --- a/tests/test_parser.py Tue Jul 24 12:58:58 2018 +0200 +++ b/tests/test_parser.py Tue Jul 24 15:43:20 2018 +0200 @@ -12,7 +12,7 @@ if split(parent)[1] == "MoinLight": sys.path.append(parent) -from moinformat import all_parsers, all_serialisers, parse, serialise +from moinformat import all_parsers, get_serialiser, parse, serialise from moinformat.tree.moin import Container from glob import glob @@ -36,7 +36,7 @@ print "-" * 60 print s print "-" * 60 - print serialise(d, all_serialisers["html"]) + print serialise(d, get_serialiser("html")) print "-" * 60 print