1.1 --- a/convert.py Tue Jul 24 12:58:58 2018 +0200
1.2 +++ b/convert.py Tue Jul 24 15:43:20 2018 +0200
1.3 @@ -1,6 +1,6 @@
1.4 #!/usr/bin/env python
1.5
1.6 -from moinformat import all_parsers, all_serialisers, parse, serialise
1.7 +from moinformat import all_parsers, get_serialiser, parse, serialise
1.8 from os.path import split
1.9 import sys
1.10
1.11 @@ -50,7 +50,7 @@
1.12 print d.prettyprint()
1.13 else:
1.14 format = formats and formats[0] or "html"
1.15 - print serialise(d, all_serialisers[format])
1.16 + print serialise(d, get_serialiser(format))
1.17 finally:
1.18 f.close()
1.19
2.1 --- a/moinformat/__init__.py Tue Jul 24 12:58:58 2018 +0200
2.2 +++ b/moinformat/__init__.py Tue Jul 24 15:43:20 2018 +0200
2.3 @@ -22,4 +22,10 @@
2.4 from moinformat.parsers import parse, parsers as all_parsers
2.5 from moinformat.serialisers import serialise, serialisers as all_serialisers
2.6
2.7 +def get_serialiser(name):
2.8 +
2.9 + "Return the main serialiser for the format having the given 'name'."
2.10 +
2.11 + return all_serialisers["%s.moin" % name]
2.12 +
2.13 # vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/moinformat/imports.py Tue Jul 24 12:58:58 2018 +0200
3.2 +++ b/moinformat/imports.py Tue Jul 24 15:43:20 2018 +0200
3.3 @@ -3,7 +3,7 @@
3.4 """
3.5 Import utilities.
3.6
3.7 -Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
3.8 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
3.9
3.10 This program is free software; you can redistribute it and/or modify it under
3.11 the terms of the GNU General Public License as published by the Free Software
3.12 @@ -23,18 +23,19 @@
3.13 from os import listdir
3.14 from importlib import import_module
3.15
3.16 -def get_extensions(dirname, modname, stores, reserved):
3.17 +def get_extensions(dirname, modname, stores, reserved, prefix=None):
3.18
3.19 "Import extensions inside 'dirname'."
3.20
3.21 for filename in listdir(dirname):
3.22 pathname = join(dirname, filename)
3.23
3.24 - # Descend into directories.
3.25 + # Descend into directories, prefixing the identified modules.
3.26
3.27 if isdir(pathname):
3.28 + store_name = prefix and "%s.%s" % (prefix, modname) or filename
3.29 get_extensions(pathname, "%s.%s" % (modname, filename),
3.30 - stores, reserved)
3.31 + stores, reserved, store_name)
3.32 continue
3.33
3.34 # Identify modules and import them.
3.35 @@ -42,6 +43,7 @@
3.36 leafname, ext = splitext(filename)
3.37
3.38 if ext == ".py" and leafname not in reserved:
3.39 - stores[leafname] = import_module("%s.%s" % (modname, leafname))
3.40 + store_name = prefix and "%s.%s" % (prefix, leafname) or leafname
3.41 + stores[store_name] = import_module("%s.%s" % (modname, leafname))
3.42
3.43 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/moinformat/serialisers/__init__.py Tue Jul 24 12:58:58 2018 +0200
4.2 +++ b/moinformat/serialisers/__init__.py Tue Jul 24 15:43:20 2018 +0200
4.3 @@ -20,7 +20,7 @@
4.4 """
4.5
4.6 from moinformat.serialisers.manifest import serialisers
4.7 -from moinformat.serialisers.moin import MoinSerialiser
4.8 +from moinformat.serialisers.moin.moin import MoinSerialiser
4.9
4.10 # Top-level functions.
4.11
4.12 @@ -28,12 +28,8 @@
4.13
4.14 "Serialise 'doc' using 'serialiser' or the Moin serialiser if omitted."
4.15
4.16 - # Permit serialisation back to source form if Moin format is used.
4.17 -
4.18 - formats = serialiser is MoinSerialiser and serialisers or None
4.19 -
4.20 l = []
4.21 - doc.to_string(serialiser(l.append, formats))
4.22 + doc.to_string(serialiser(l.append, serialisers))
4.23 return "".join(l)
4.24
4.25 # vim: tabstop=4 expandtab shiftwidth=4
5.1 --- a/moinformat/serialisers/common.py Tue Jul 24 12:58:58 2018 +0200
5.2 +++ b/moinformat/serialisers/common.py Tue Jul 24 15:43:20 2018 +0200
5.3 @@ -23,6 +23,8 @@
5.4
5.5 "General serialisation support."
5.6
5.7 + format = None # defined by subclasses
5.8 +
5.9 def __init__(self, out, formats=None):
5.10
5.11 """
6.1 --- a/moinformat/serialisers/html.py Tue Jul 24 12:58:58 2018 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,255 +0,0 @@
6.4 -#!/usr/bin/env python
6.5 -
6.6 -"""
6.7 -HTML serialiser.
6.8 -
6.9 -Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
6.10 -
6.11 -This program is free software; you can redistribute it and/or modify it under
6.12 -the terms of the GNU General Public License as published by the Free Software
6.13 -Foundation; either version 3 of the License, or (at your option) any later
6.14 -version.
6.15 -
6.16 -This program is distributed in the hope that it will be useful, but WITHOUT
6.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
6.19 -details.
6.20 -
6.21 -You should have received a copy of the GNU General Public License along with
6.22 -this program. If not, see <http://www.gnu.org/licenses/>.
6.23 -"""
6.24 -
6.25 -from moinformat.serialisers.common import escape_attr, escape_text, Serialiser
6.26 -
6.27 -class HTMLSerialiser(Serialiser):
6.28 -
6.29 - "Serialisation of the page."
6.30 -
6.31 - def _region_tag(self, type):
6.32 -
6.33 - # NOTE: Need to support types in general.
6.34 -
6.35 - type = type and type.split()[0]
6.36 -
6.37 - if type == "inline":
6.38 - return "tt"
6.39 - elif type in (None, "python"):
6.40 - return "pre"
6.41 - else:
6.42 - return "span"
6.43 -
6.44 - def start_region(self, level, indent, type, extra):
6.45 - l = []
6.46 - out = l.append
6.47 - if level:
6.48 - out("level-%d" % level)
6.49 -
6.50 - if indent:
6.51 - out("indent-%d" % indent)
6.52 -
6.53 - # NOTE: Encode type details for CSS.
6.54 -
6.55 - out("type-%s" % escape_attr(type or "opaque"))
6.56 -
6.57 - tag = self._region_tag(type)
6.58 - self.out("<%s class='%s'>" % (tag, " ".join(l)))
6.59 -
6.60 - def end_region(self, level, indent, type, extra):
6.61 - tag = self._region_tag(type)
6.62 - self.out("</%s>" % tag)
6.63 -
6.64 - def start_block(self):
6.65 - self.out("<p>")
6.66 -
6.67 - def end_block(self):
6.68 - self.out("</p>")
6.69 -
6.70 - def start_defitem(self, pad, extra):
6.71 - self.out("<dd>")
6.72 -
6.73 - def end_defitem(self, pad, extra):
6.74 - self.out("</dd>")
6.75 -
6.76 - def start_defterm(self, pad):
6.77 - self.out("<dt>")
6.78 -
6.79 - def end_defterm(self, pad):
6.80 - self.out("</dt>")
6.81 -
6.82 - def start_emphasis(self):
6.83 - self.out("<em>")
6.84 -
6.85 - def end_emphasis(self):
6.86 - self.out("</em>")
6.87 -
6.88 - def start_heading(self, level, extra, pad):
6.89 - self.out("<h%d>" % level)
6.90 -
6.91 - def end_heading(self, level, pad, extra):
6.92 - self.out("</h%d>" % level)
6.93 -
6.94 - def start_larger(self):
6.95 - self.out("<big>")
6.96 -
6.97 - def end_larger(self):
6.98 - self.out("</big>")
6.99 -
6.100 - def start_link(self, target):
6.101 - self.out('<a href="%s">' % escape_attr(target))
6.102 -
6.103 - def end_link(self):
6.104 - self.out("</a>")
6.105 -
6.106 - def start_linktext(self):
6.107 - pass
6.108 -
6.109 - def end_linktext(self):
6.110 - pass
6.111 -
6.112 - list_tags = {
6.113 - "i" : "lower-roman",
6.114 - "I" : "upper-roman",
6.115 - "a" : "lower-latin",
6.116 - "A" : "upper-latin",
6.117 - }
6.118 -
6.119 - def _get_list_tag(self, marker):
6.120 - if marker:
6.121 - if marker[0].isdigit():
6.122 - return "ol", "decimal"
6.123 - style_type = self.list_tags.get(marker[0])
6.124 - if style_type:
6.125 - return "ol", style_type
6.126 -
6.127 - return "ul", None
6.128 -
6.129 - def start_list(self, indent, marker, num):
6.130 - tag, style_type = self._get_list_tag(marker)
6.131 - style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or ""
6.132 - start = style_type and num is not None and ' start="%s"' % escape_attr(num) or ""
6.133 - self.out("<%s%s%s>" % (tag, style, start))
6.134 -
6.135 - def end_list(self, indent, marker, num):
6.136 - tag, style = self._get_list_tag(marker)
6.137 - self.out("</%s>" % tag)
6.138 -
6.139 - def start_listitem(self, indent, marker, space, num):
6.140 - self.out("<li>")
6.141 -
6.142 - def end_listitem(self, indent, marker, space, num):
6.143 - self.out("</li>")
6.144 -
6.145 - def start_monospace(self):
6.146 - self.out("<tt>")
6.147 -
6.148 - def end_monospace(self):
6.149 - self.out("</tt>")
6.150 -
6.151 - def start_smaller(self):
6.152 - self.out("<small>")
6.153 -
6.154 - def end_smaller(self):
6.155 - self.out("</small>")
6.156 -
6.157 - def start_strikethrough(self):
6.158 - self.out("<del>")
6.159 -
6.160 - def end_strikethrough(self):
6.161 - self.out("</del>")
6.162 -
6.163 - def start_strong(self):
6.164 - self.out("<strong>")
6.165 -
6.166 - def end_strong(self):
6.167 - self.out("</strong>")
6.168 -
6.169 - def start_subscript(self):
6.170 - self.out("<sub>")
6.171 -
6.172 - def end_subscript(self):
6.173 - self.out("</sub>")
6.174 -
6.175 - def start_superscript(self):
6.176 - self.out("<sup>")
6.177 -
6.178 - def end_superscript(self):
6.179 - self.out("</sup>")
6.180 -
6.181 - def start_table(self):
6.182 - self.out("<table>")
6.183 -
6.184 - def end_table(self):
6.185 - self.out("</table>")
6.186 -
6.187 - def start_table_attrs(self):
6.188 - pass
6.189 -
6.190 - def end_table_attrs(self):
6.191 - pass
6.192 -
6.193 - def start_table_cell(self, attrs):
6.194 - self.out("<td")
6.195 - if attrs and not attrs.empty():
6.196 - attrs.to_string(self)
6.197 - self.out(">")
6.198 -
6.199 - def end_table_cell(self):
6.200 - self.out("</td>")
6.201 -
6.202 - def start_table_row(self):
6.203 - self.out("<tr>")
6.204 -
6.205 - def end_table_row(self, trailing):
6.206 - self.out("</tr>")
6.207 -
6.208 - def start_underline(self):
6.209 - self.out("<span style='text-decoration: underline'>")
6.210 -
6.211 - def end_underline(self):
6.212 - self.out("</span>")
6.213 -
6.214 - def break_(self):
6.215 - pass
6.216 -
6.217 - def continuation(self, text):
6.218 - pass
6.219 -
6.220 - def macro(self, name, args):
6.221 -
6.222 - # NOTE: Special case.
6.223 -
6.224 - if name == "BR":
6.225 - self.out("<br />")
6.226 - return
6.227 -
6.228 - # Fallback case.
6.229 -
6.230 - self.out("<span class='macro'>")
6.231 - self.out(escape_text("<<"))
6.232 - self.out("<span class='name'>%s</span>" % escape_text(name))
6.233 - if args:
6.234 - self.out("(")
6.235 - first = True
6.236 - for arg in args:
6.237 - if not first:
6.238 - self.out(",")
6.239 - self.out("<span class='arg'>%s</span>" % escape_text(arg))
6.240 - first = False
6.241 - if args:
6.242 - self.out(")")
6.243 - self.out(escape_text(">>"))
6.244 - self.out("</span>")
6.245 -
6.246 - def rule(self, length):
6.247 - self.out("<hr style='height: %dpt' />" % min(length, 10))
6.248 -
6.249 - def table_attr(self, name, value, concise, quote):
6.250 - self.out(" %s%s" % (escape_text(name), value is not None and
6.251 - "='%s'" % escape_attr(value) or ""))
6.252 -
6.253 - def text(self, s):
6.254 - self.out(escape_text(s))
6.255 -
6.256 -serialiser = HTMLSerialiser
6.257 -
6.258 -# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/moinformat/serialisers/html/__init__.py Tue Jul 24 15:43:20 2018 +0200
7.3 @@ -0,0 +1,22 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +"""
7.7 +A package of modules containing HTML format serialisers.
7.8 +
7.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
7.10 +
7.11 +This program is free software; you can redistribute it and/or modify it under
7.12 +the terms of the GNU General Public License as published by the Free Software
7.13 +Foundation; either version 3 of the License, or (at your option) any later
7.14 +version.
7.15 +
7.16 +This program is distributed in the hope that it will be useful, but WITHOUT
7.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
7.19 +details.
7.20 +
7.21 +You should have received a copy of the GNU General Public License along with
7.22 +this program. If not, see <http://www.gnu.org/licenses/>.
7.23 +"""
7.24 +
7.25 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/moinformat/serialisers/html/moin.py Tue Jul 24 15:43:20 2018 +0200
8.3 @@ -0,0 +1,254 @@
8.4 +#!/usr/bin/env python
8.5 +
8.6 +"""
8.7 +HTML serialiser.
8.8 +
8.9 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
8.10 +
8.11 +This program is free software; you can redistribute it and/or modify it under
8.12 +the terms of the GNU General Public License as published by the Free Software
8.13 +Foundation; either version 3 of the License, or (at your option) any later
8.14 +version.
8.15 +
8.16 +This program is distributed in the hope that it will be useful, but WITHOUT
8.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8.19 +details.
8.20 +
8.21 +You should have received a copy of the GNU General Public License along with
8.22 +this program. If not, see <http://www.gnu.org/licenses/>.
8.23 +"""
8.24 +
8.25 +from moinformat.serialisers.common import escape_attr, escape_text, Serialiser
8.26 +
8.27 +class HTMLSerialiser(Serialiser):
8.28 +
8.29 + "Serialisation of the page."
8.30 +
8.31 + format = "html"
8.32 +
8.33 + def _region_tag(self, type):
8.34 +
8.35 + # NOTE: Need to support types in general.
8.36 +
8.37 + type = type and type.split()[0]
8.38 +
8.39 + if type == "inline":
8.40 + return "tt"
8.41 + elif type in (None, "python"):
8.42 + return "pre"
8.43 + else:
8.44 + return "span"
8.45 +
8.46 + def start_region(self, level, indent, type, extra):
8.47 + l = []
8.48 + out = l.append
8.49 + if level:
8.50 + out("level-%d" % level)
8.51 +
8.52 + if indent:
8.53 + out("indent-%d" % indent)
8.54 +
8.55 + # NOTE: Encode type details for CSS.
8.56 +
8.57 + out("type-%s" % escape_attr(type or "opaque"))
8.58 +
8.59 + tag = self._region_tag(type)
8.60 + self.out("<%s class='%s'>" % (tag, " ".join(l)))
8.61 +
8.62 + def end_region(self, level, indent, type, extra):
8.63 + tag = self._region_tag(type)
8.64 + self.out("</%s>" % tag)
8.65 +
8.66 + def start_block(self):
8.67 + self.out("<p>")
8.68 +
8.69 + def end_block(self):
8.70 + self.out("</p>")
8.71 +
8.72 + def start_defitem(self, pad, extra):
8.73 + self.out("<dd>")
8.74 +
8.75 + def end_defitem(self, pad, extra):
8.76 + self.out("</dd>")
8.77 +
8.78 + def start_defterm(self, pad):
8.79 + self.out("<dt>")
8.80 +
8.81 + def end_defterm(self, pad):
8.82 + self.out("</dt>")
8.83 +
8.84 + def start_emphasis(self):
8.85 + self.out("<em>")
8.86 +
8.87 + def end_emphasis(self):
8.88 + self.out("</em>")
8.89 +
8.90 + def start_heading(self, level, extra, pad):
8.91 + self.out("<h%d>" % level)
8.92 +
8.93 + def end_heading(self, level, pad, extra):
8.94 + self.out("</h%d>" % level)
8.95 +
8.96 + def start_larger(self):
8.97 + self.out("<big>")
8.98 +
8.99 + def end_larger(self):
8.100 + self.out("</big>")
8.101 +
8.102 + def start_link(self, target):
8.103 + self.out('<a href="%s">' % escape_attr(target))
8.104 +
8.105 + def end_link(self):
8.106 + self.out("</a>")
8.107 +
8.108 + def start_linktext(self):
8.109 + pass
8.110 +
8.111 + def end_linktext(self):
8.112 + pass
8.113 +
8.114 + list_tags = {
8.115 + "i" : "lower-roman",
8.116 + "I" : "upper-roman",
8.117 + "a" : "lower-latin",
8.118 + "A" : "upper-latin",
8.119 + }
8.120 +
8.121 + def _get_list_tag(self, marker):
8.122 + if marker:
8.123 + if marker[0].isdigit():
8.124 + return "ol", "decimal"
8.125 + style_type = self.list_tags.get(marker[0])
8.126 + if style_type:
8.127 + return "ol", style_type
8.128 +
8.129 + return "ul", None
8.130 +
8.131 + def start_list(self, indent, marker, num):
8.132 + tag, style_type = self._get_list_tag(marker)
8.133 + style = style_type and ' style="list-style-type: %s"' % escape_attr(style_type) or ""
8.134 + start = style_type and num is not None and ' start="%s"' % escape_attr(num) or ""
8.135 + self.out("<%s%s%s>" % (tag, style, start))
8.136 +
8.137 + def end_list(self, indent, marker, num):
8.138 + tag, style = self._get_list_tag(marker)
8.139 + self.out("</%s>" % tag)
8.140 +
8.141 + def start_listitem(self, indent, marker, space, num):
8.142 + self.out("<li>")
8.143 +
8.144 + def end_listitem(self, indent, marker, space, num):
8.145 + self.out("</li>")
8.146 +
8.147 + def start_monospace(self):
8.148 + self.out("<tt>")
8.149 +
8.150 + def end_monospace(self):
8.151 + self.out("</tt>")
8.152 +
8.153 + def start_smaller(self):
8.154 + self.out("<small>")
8.155 +
8.156 + def end_smaller(self):
8.157 + self.out("</small>")
8.158 +
8.159 + def start_strikethrough(self):
8.160 + self.out("<del>")
8.161 +
8.162 + def end_strikethrough(self):
8.163 + self.out("</del>")
8.164 +
8.165 + def start_strong(self):
8.166 + self.out("<strong>")
8.167 +
8.168 + def end_strong(self):
8.169 + self.out("</strong>")
8.170 +
8.171 + def start_subscript(self):
8.172 + self.out("<sub>")
8.173 +
8.174 + def end_subscript(self):
8.175 + self.out("</sub>")
8.176 +
8.177 + def start_superscript(self):
8.178 + self.out("<sup>")
8.179 +
8.180 + def end_superscript(self):
8.181 + self.out("</sup>")
8.182 +
8.183 + def start_table(self):
8.184 + self.out("<table>")
8.185 +
8.186 + def end_table(self):
8.187 + self.out("</table>")
8.188 +
8.189 + def start_table_attrs(self):
8.190 + pass
8.191 +
8.192 + def end_table_attrs(self):
8.193 + pass
8.194 +
8.195 + def start_table_cell(self, attrs):
8.196 + self.out("<td")
8.197 + if attrs and not attrs.empty():
8.198 + attrs.to_string(self)
8.199 + self.out(">")
8.200 +
8.201 + def end_table_cell(self):
8.202 + self.out("</td>")
8.203 +
8.204 + def start_table_row(self):
8.205 + self.out("<tr>")
8.206 +
8.207 + def end_table_row(self, trailing):
8.208 + self.out("</tr>")
8.209 +
8.210 + def start_underline(self):
8.211 + self.out("<span style='text-decoration: underline'>")
8.212 +
8.213 + def end_underline(self):
8.214 + self.out("</span>")
8.215 +
8.216 + def break_(self):
8.217 + pass
8.218 +
8.219 + def macro(self, name, args):
8.220 +
8.221 + # NOTE: Special case.
8.222 +
8.223 + if name == "BR":
8.224 + self.out("<br />")
8.225 + return
8.226 +
8.227 + # Fallback case.
8.228 +
8.229 + self.out("<span class='macro'>")
8.230 + self.out(escape_text("<<"))
8.231 + self.out("<span class='name'>%s</span>" % escape_text(name))
8.232 + if args:
8.233 + self.out("(")
8.234 + first = True
8.235 + for arg in args:
8.236 + if not first:
8.237 + self.out(",")
8.238 + self.out("<span class='arg'>%s</span>" % escape_text(arg))
8.239 + first = False
8.240 + if args:
8.241 + self.out(")")
8.242 + self.out(escape_text(">>"))
8.243 + self.out("</span>")
8.244 +
8.245 + def rule(self, length):
8.246 + self.out("<hr style='height: %dpt' />" % min(length, 10))
8.247 +
8.248 + def table_attr(self, name, value, concise, quote):
8.249 + self.out(" %s%s" % (escape_text(name), value is not None and
8.250 + "='%s'" % escape_attr(value) or ""))
8.251 +
8.252 + def text(self, s):
8.253 + self.out(escape_text(s))
8.254 +
8.255 +serialiser = HTMLSerialiser
8.256 +
8.257 +# vim: tabstop=4 expandtab shiftwidth=4
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/moinformat/serialisers/html/table.py Tue Jul 24 15:43:20 2018 +0200
9.3 @@ -0,0 +1,34 @@
9.4 +#!/usr/bin/env python
9.5 +
9.6 +"""
9.7 +HTML serialiser.
9.8 +
9.9 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
9.10 +
9.11 +This program is free software; you can redistribute it and/or modify it under
9.12 +the terms of the GNU General Public License as published by the Free Software
9.13 +Foundation; either version 3 of the License, or (at your option) any later
9.14 +version.
9.15 +
9.16 +This program is distributed in the hope that it will be useful, but WITHOUT
9.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
9.19 +details.
9.20 +
9.21 +You should have received a copy of the GNU General Public License along with
9.22 +this program. If not, see <http://www.gnu.org/licenses/>.
9.23 +"""
9.24 +
9.25 +from moinformat.serialisers.common import escape_attr, escape_text
9.26 +from moinformat.serialisers.html.moin import HTMLSerialiser
9.27 +
9.28 +class HTMLTableSerialiser(HTMLSerialiser):
9.29 +
9.30 + "Serialisation of the page."
9.31 +
9.32 + def continuation(self, text):
9.33 + pass
9.34 +
9.35 +serialiser = HTMLTableSerialiser
9.36 +
9.37 +# vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/moinformat/serialisers/moin.py Tue Jul 24 12:58:58 2018 +0200
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,201 +0,0 @@
10.4 -#!/usr/bin/env python
10.5 -
10.6 -"""
10.7 -Moin wiki text serialiser.
10.8 -
10.9 -Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
10.10 -
10.11 -This program is free software; you can redistribute it and/or modify it under
10.12 -the terms of the GNU General Public License as published by the Free Software
10.13 -Foundation; either version 3 of the License, or (at your option) any later
10.14 -version.
10.15 -
10.16 -This program is distributed in the hope that it will be useful, but WITHOUT
10.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.19 -details.
10.20 -
10.21 -You should have received a copy of the GNU General Public License along with
10.22 -this program. If not, see <http://www.gnu.org/licenses/>.
10.23 -"""
10.24 -
10.25 -from moinformat.serialisers.common import escape_attr, escape_text, Serialiser
10.26 -
10.27 -class MoinSerialiser(Serialiser):
10.28 -
10.29 - "Serialisation of the page."
10.30 -
10.31 - def start_region(self, level, indent, type, extra):
10.32 - out = self.out
10.33 - if level:
10.34 - out(" " * indent + "{" * level)
10.35 -
10.36 - # Produce a header for regions within a top-level region.
10.37 -
10.38 - if type and type != "inline" and level:
10.39 - out("#!%s\n" % type)
10.40 -
10.41 - def end_region(self, level, indent, type, extra):
10.42 - out = self.out
10.43 - if level:
10.44 - out("%s%s" % ("}" * level, extra or ""))
10.45 -
10.46 - def start_block(self):
10.47 - pass
10.48 -
10.49 - def end_block(self):
10.50 - pass
10.51 -
10.52 - def start_defitem(self, pad, extra):
10.53 - self.out((extra and "\n" + extra + "::" or "") + pad)
10.54 -
10.55 - def end_defitem(self, pad, extra):
10.56 - pass
10.57 -
10.58 - def start_defterm(self, pad):
10.59 - self.out(pad)
10.60 -
10.61 - def end_defterm(self, pad):
10.62 - self.out("::")
10.63 -
10.64 - def start_emphasis(self):
10.65 - self.out("''")
10.66 -
10.67 - def end_emphasis(self):
10.68 - self.out("''")
10.69 -
10.70 - def start_heading(self, level, extra, pad):
10.71 - self.out(extra + "=" * level + pad)
10.72 -
10.73 - def end_heading(self, level, pad, extra):
10.74 - self.out(pad + "=" * level + extra)
10.75 -
10.76 - def start_larger(self):
10.77 - self.out("~+")
10.78 -
10.79 - def end_larger(self):
10.80 - self.out("+~")
10.81 -
10.82 - def start_link(self, target):
10.83 - self.out("[[%s" % target)
10.84 -
10.85 - def end_link(self):
10.86 - self.out("]]")
10.87 -
10.88 - def start_linktext(self):
10.89 - self.out("|")
10.90 -
10.91 - def end_linktext(self):
10.92 - pass
10.93 -
10.94 - def start_list(self, indent, marker, num):
10.95 - pass
10.96 -
10.97 - def end_list(self, indent, marker, num):
10.98 - pass
10.99 -
10.100 - def start_listitem(self, indent, marker, space, num):
10.101 - self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space))
10.102 -
10.103 - def end_listitem(self, indent, marker, space, num):
10.104 - pass
10.105 -
10.106 - def start_monospace(self):
10.107 - self.out("`")
10.108 -
10.109 - def end_monospace(self):
10.110 - self.out("`")
10.111 -
10.112 - def start_smaller(self):
10.113 - self.out("~-")
10.114 -
10.115 - def end_smaller(self):
10.116 - self.out("-~")
10.117 -
10.118 - def start_strong(self):
10.119 - self.out("'''")
10.120 -
10.121 - def end_strong(self):
10.122 - self.out("'''")
10.123 -
10.124 - def start_strikethrough(self):
10.125 - self.out("--(")
10.126 -
10.127 - def end_strikethrough(self):
10.128 - self.out(")--")
10.129 -
10.130 - def start_subscript(self):
10.131 - self.out(",,")
10.132 -
10.133 - def end_subscript(self):
10.134 - self.out(",,")
10.135 -
10.136 - def start_superscript(self):
10.137 - self.out("^")
10.138 -
10.139 - def end_superscript(self):
10.140 - self.out("^")
10.141 -
10.142 - def start_table(self):
10.143 - pass
10.144 -
10.145 - def end_table(self):
10.146 - pass
10.147 -
10.148 - def start_table_attrs(self):
10.149 - self.out("<")
10.150 -
10.151 - def end_table_attrs(self):
10.152 - self.out(">")
10.153 -
10.154 - def start_table_cell(self, attrs):
10.155 - self.out("||")
10.156 - if attrs and not attrs.empty():
10.157 - attrs.to_string(self)
10.158 -
10.159 - def end_table_cell(self):
10.160 - pass
10.161 -
10.162 - def start_table_row(self):
10.163 - pass
10.164 -
10.165 - def end_table_row(self, trailing):
10.166 - self.out("||")
10.167 - self.out(trailing)
10.168 -
10.169 - def start_underline(self):
10.170 - self.out("__")
10.171 -
10.172 - def end_underline(self):
10.173 - self.out("__")
10.174 -
10.175 - def break_(self):
10.176 - self.out("\n")
10.177 -
10.178 - def continuation(self, text):
10.179 - self.out(text)
10.180 -
10.181 - def macro(self, name, args):
10.182 - self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or ""))
10.183 -
10.184 - def rule(self, length):
10.185 - self.out("-" * length)
10.186 -
10.187 - def table_attr(self, name, value, concise, quote):
10.188 - if concise:
10.189 - if name == "colour": self.out(value)
10.190 - elif name == "colspan": self.out("-%s" % value)
10.191 - elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":")
10.192 - elif name == "rowspan": self.out("|%s" % value)
10.193 - elif name == "valign" : self.out(value == "top" and "^" or "v")
10.194 - elif name == "width" : self.out(value)
10.195 - else:
10.196 - self.out("%s%s" % (escape_text(name), value is not None and
10.197 - "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or ""))
10.198 -
10.199 - def text(self, s):
10.200 - self.out(s)
10.201 -
10.202 -serialiser = MoinSerialiser
10.203 -
10.204 -# vim: tabstop=4 expandtab shiftwidth=4
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/moinformat/serialisers/moin/__init__.py Tue Jul 24 15:43:20 2018 +0200
11.3 @@ -0,0 +1,22 @@
11.4 +#!/usr/bin/env python
11.5 +
11.6 +"""
11.7 +A package of modules containing Moin format serialisers.
11.8 +
11.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
11.10 +
11.11 +This program is free software; you can redistribute it and/or modify it under
11.12 +the terms of the GNU General Public License as published by the Free Software
11.13 +Foundation; either version 3 of the License, or (at your option) any later
11.14 +version.
11.15 +
11.16 +This program is distributed in the hope that it will be useful, but WITHOUT
11.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11.19 +details.
11.20 +
11.21 +You should have received a copy of the GNU General Public License along with
11.22 +this program. If not, see <http://www.gnu.org/licenses/>.
11.23 +"""
11.24 +
11.25 +# vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/moinformat/serialisers/moin/moin.py Tue Jul 24 15:43:20 2018 +0200
12.3 @@ -0,0 +1,203 @@
12.4 +#!/usr/bin/env python
12.5 +
12.6 +"""
12.7 +Moin wiki text serialiser.
12.8 +
12.9 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
12.10 +
12.11 +This program is free software; you can redistribute it and/or modify it under
12.12 +the terms of the GNU General Public License as published by the Free Software
12.13 +Foundation; either version 3 of the License, or (at your option) any later
12.14 +version.
12.15 +
12.16 +This program is distributed in the hope that it will be useful, but WITHOUT
12.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12.19 +details.
12.20 +
12.21 +You should have received a copy of the GNU General Public License along with
12.22 +this program. If not, see <http://www.gnu.org/licenses/>.
12.23 +"""
12.24 +
12.25 +from moinformat.serialisers.common import escape_attr, escape_text, Serialiser
12.26 +
12.27 +class MoinSerialiser(Serialiser):
12.28 +
12.29 + "Serialisation of the page."
12.30 +
12.31 + format = "moin"
12.32 +
12.33 + def start_region(self, level, indent, type, extra):
12.34 + out = self.out
12.35 + if level:
12.36 + out(" " * indent + "{" * level)
12.37 +
12.38 + # Produce a header for regions within a top-level region.
12.39 +
12.40 + if type and type != "inline" and level:
12.41 + out("#!%s\n" % type)
12.42 +
12.43 + def end_region(self, level, indent, type, extra):
12.44 + out = self.out
12.45 + if level:
12.46 + out("%s%s" % ("}" * level, extra or ""))
12.47 +
12.48 + def start_block(self):
12.49 + pass
12.50 +
12.51 + def end_block(self):
12.52 + pass
12.53 +
12.54 + def start_defitem(self, pad, extra):
12.55 + self.out((extra and "\n" + extra + "::" or "") + pad)
12.56 +
12.57 + def end_defitem(self, pad, extra):
12.58 + pass
12.59 +
12.60 + def start_defterm(self, pad):
12.61 + self.out(pad)
12.62 +
12.63 + def end_defterm(self, pad):
12.64 + self.out("::")
12.65 +
12.66 + def start_emphasis(self):
12.67 + self.out("''")
12.68 +
12.69 + def end_emphasis(self):
12.70 + self.out("''")
12.71 +
12.72 + def start_heading(self, level, extra, pad):
12.73 + self.out(extra + "=" * level + pad)
12.74 +
12.75 + def end_heading(self, level, pad, extra):
12.76 + self.out(pad + "=" * level + extra)
12.77 +
12.78 + def start_larger(self):
12.79 + self.out("~+")
12.80 +
12.81 + def end_larger(self):
12.82 + self.out("+~")
12.83 +
12.84 + def start_link(self, target):
12.85 + self.out("[[%s" % target)
12.86 +
12.87 + def end_link(self):
12.88 + self.out("]]")
12.89 +
12.90 + def start_linktext(self):
12.91 + self.out("|")
12.92 +
12.93 + def end_linktext(self):
12.94 + pass
12.95 +
12.96 + def start_list(self, indent, marker, num):
12.97 + pass
12.98 +
12.99 + def end_list(self, indent, marker, num):
12.100 + pass
12.101 +
12.102 + def start_listitem(self, indent, marker, space, num):
12.103 + self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space))
12.104 +
12.105 + def end_listitem(self, indent, marker, space, num):
12.106 + pass
12.107 +
12.108 + def start_monospace(self):
12.109 + self.out("`")
12.110 +
12.111 + def end_monospace(self):
12.112 + self.out("`")
12.113 +
12.114 + def start_smaller(self):
12.115 + self.out("~-")
12.116 +
12.117 + def end_smaller(self):
12.118 + self.out("-~")
12.119 +
12.120 + def start_strong(self):
12.121 + self.out("'''")
12.122 +
12.123 + def end_strong(self):
12.124 + self.out("'''")
12.125 +
12.126 + def start_strikethrough(self):
12.127 + self.out("--(")
12.128 +
12.129 + def end_strikethrough(self):
12.130 + self.out(")--")
12.131 +
12.132 + def start_subscript(self):
12.133 + self.out(",,")
12.134 +
12.135 + def end_subscript(self):
12.136 + self.out(",,")
12.137 +
12.138 + def start_superscript(self):
12.139 + self.out("^")
12.140 +
12.141 + def end_superscript(self):
12.142 + self.out("^")
12.143 +
12.144 + def start_table(self):
12.145 + pass
12.146 +
12.147 + def end_table(self):
12.148 + pass
12.149 +
12.150 + def start_table_attrs(self):
12.151 + self.out("<")
12.152 +
12.153 + def end_table_attrs(self):
12.154 + self.out(">")
12.155 +
12.156 + def start_table_cell(self, attrs):
12.157 + self.out("||")
12.158 + if attrs and not attrs.empty():
12.159 + attrs.to_string(self)
12.160 +
12.161 + def end_table_cell(self):
12.162 + pass
12.163 +
12.164 + def start_table_row(self):
12.165 + pass
12.166 +
12.167 + def end_table_row(self, trailing):
12.168 + self.out("||")
12.169 + self.out(trailing)
12.170 +
12.171 + def start_underline(self):
12.172 + self.out("__")
12.173 +
12.174 + def end_underline(self):
12.175 + self.out("__")
12.176 +
12.177 + def break_(self):
12.178 + self.out("\n")
12.179 +
12.180 + def continuation(self, text):
12.181 + self.out(text)
12.182 +
12.183 + def macro(self, name, args):
12.184 + self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or ""))
12.185 +
12.186 + def rule(self, length):
12.187 + self.out("-" * length)
12.188 +
12.189 + def table_attr(self, name, value, concise, quote):
12.190 + if concise:
12.191 + if name == "colour": self.out(value)
12.192 + elif name == "colspan": self.out("-%s" % value)
12.193 + elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":")
12.194 + elif name == "rowspan": self.out("|%s" % value)
12.195 + elif name == "valign" : self.out(value == "top" and "^" or "v")
12.196 + elif name == "width" : self.out(value)
12.197 + else:
12.198 + self.out("%s%s" % (escape_text(name), value is not None and
12.199 + "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or ""))
12.200 +
12.201 + def text(self, s):
12.202 + self.out(s)
12.203 +
12.204 +serialiser = MoinSerialiser
12.205 +
12.206 +# vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/moinformat/serialisers/moin/table.py Tue Jul 24 15:43:20 2018 +0200
13.3 @@ -0,0 +1,56 @@
13.4 +#!/usr/bin/env python
13.5 +
13.6 +"""
13.7 +Moin wiki table serialiser.
13.8 +
13.9 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
13.10 +
13.11 +This program is free software; you can redistribute it and/or modify it under
13.12 +the terms of the GNU General Public License as published by the Free Software
13.13 +Foundation; either version 3 of the License, or (at your option) any later
13.14 +version.
13.15 +
13.16 +This program is distributed in the hope that it will be useful, but WITHOUT
13.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13.19 +details.
13.20 +
13.21 +You should have received a copy of the GNU General Public License along with
13.22 +this program. If not, see <http://www.gnu.org/licenses/>.
13.23 +"""
13.24 +
13.25 +from moinformat.serialisers.moin.moin import MoinSerialiser
13.26 +
13.27 +class MoinTableSerialiser(MoinSerialiser):
13.28 +
13.29 + "Serialisation of the page."
13.30 +
13.31 + def init(self):
13.32 + self.first_cell = False
13.33 + self.first_row = False
13.34 +
13.35 + def start_table(self):
13.36 + self.first_row = True
13.37 +
13.38 + def start_table_cell(self, attrs):
13.39 + if not self.first_cell:
13.40 + self.out("||")
13.41 + else:
13.42 + self.first_cell = False
13.43 +
13.44 + if attrs and not attrs.empty():
13.45 + attrs.to_string(self)
13.46 +
13.47 + def start_table_row(self):
13.48 + self.first_cell = True
13.49 + if not self.first_row:
13.50 + self.out("==")
13.51 + else:
13.52 + self.first_row = False
13.53 +
13.54 + def end_table_row(self, trailing):
13.55 + self.out(trailing)
13.56 +
13.57 +serialiser = MoinTableSerialiser
13.58 +
13.59 +# vim: tabstop=4 expandtab shiftwidth=4
14.1 --- a/moinformat/serialisers/table.py Tue Jul 24 12:58:58 2018 +0200
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,56 +0,0 @@
14.4 -#!/usr/bin/env python
14.5 -
14.6 -"""
14.7 -Moin wiki table serialiser.
14.8 -
14.9 -Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
14.10 -
14.11 -This program is free software; you can redistribute it and/or modify it under
14.12 -the terms of the GNU General Public License as published by the Free Software
14.13 -Foundation; either version 3 of the License, or (at your option) any later
14.14 -version.
14.15 -
14.16 -This program is distributed in the hope that it will be useful, but WITHOUT
14.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14.19 -details.
14.20 -
14.21 -You should have received a copy of the GNU General Public License along with
14.22 -this program. If not, see <http://www.gnu.org/licenses/>.
14.23 -"""
14.24 -
14.25 -from moinformat.serialisers.moin import MoinSerialiser
14.26 -
14.27 -class TableSerialiser(MoinSerialiser):
14.28 -
14.29 - "Serialisation of the page."
14.30 -
14.31 - def init(self):
14.32 - self.first_cell = False
14.33 - self.first_row = False
14.34 -
14.35 - def start_table(self):
14.36 - self.first_row = True
14.37 -
14.38 - def start_table_cell(self, attrs):
14.39 - if not self.first_cell:
14.40 - self.out("||")
14.41 - else:
14.42 - self.first_cell = False
14.43 -
14.44 - if attrs and not attrs.empty():
14.45 - attrs.to_string(self)
14.46 -
14.47 - def start_table_row(self):
14.48 - self.first_cell = True
14.49 - if not self.first_row:
14.50 - self.out("==")
14.51 - else:
14.52 - self.first_row = False
14.53 -
14.54 - def end_table_row(self, trailing):
14.55 - self.out(trailing)
14.56 -
14.57 -serialiser = TableSerialiser
14.58 -
14.59 -# vim: tabstop=4 expandtab shiftwidth=4
15.1 --- a/moinformat/tree/moin.py Tue Jul 24 12:58:58 2018 +0200
15.2 +++ b/moinformat/tree/moin.py Tue Jul 24 15:43:20 2018 +0200
15.3 @@ -138,10 +138,16 @@
15.4 def to_string(self, out):
15.5 out.start_region(self.level, self.indent, self.type, self.extra)
15.6
15.7 - # Obtain a serialiser for the region, if appropriate.
15.8 + # Obtain a serialiser class for the region from the same format family.
15.9 +
15.10 + serialiser_name = "%s.%s" % (out.format, self.type)
15.11 + serialiser_cls = out.formats and out.formats.get(serialiser_name)
15.12
15.13 - serialiser = out.formats and out.formats.get(self.type)
15.14 - region_out = serialiser and serialiser(out.out, out.formats) or out
15.15 + # Retain the same serialiser if no appropriate serialiser could be
15.16 + # obtained.
15.17 +
15.18 + region_out = serialiser_cls and serialiser_cls(out.out, out.formats) \
15.19 + or out
15.20
15.21 # Serialise the region.
15.22
16.1 --- a/tests/test_parser.py Tue Jul 24 12:58:58 2018 +0200
16.2 +++ b/tests/test_parser.py Tue Jul 24 15:43:20 2018 +0200
16.3 @@ -12,7 +12,7 @@
16.4 if split(parent)[1] == "MoinLight":
16.5 sys.path.append(parent)
16.6
16.7 -from moinformat import all_parsers, all_serialisers, parse, serialise
16.8 +from moinformat import all_parsers, get_serialiser, parse, serialise
16.9 from moinformat.tree.moin import Container
16.10 from glob import glob
16.11
16.12 @@ -36,7 +36,7 @@
16.13 print "-" * 60
16.14 print s
16.15 print "-" * 60
16.16 - print serialise(d, all_serialisers["html"])
16.17 + print serialise(d, get_serialiser("html"))
16.18 print "-" * 60
16.19 print
16.20