2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/moinformat/parsers/table.py Tue Dec 12 18:17:08 2017 +0100
2.3 @@ -0,0 +1,121 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Moin wiki table parser.
2.8 +
2.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
2.10 +
2.11 +This program is free software; you can redistribute it and/or modify it under
2.12 +the terms of the GNU General Public License as published by the Free Software
2.13 +Foundation; either version 3 of the License, or (at your option) any later
2.14 +version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful, but WITHOUT
2.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.19 +details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License along with
2.22 +this program. If not, see <http://www.gnu.org/licenses/>.
2.23 +"""
2.24 +
2.25 +from moinformat.parsing import get_patterns
2.26 +from moinformat.tree import Table, TableAttrs, TableCell, TableRow, Text
2.27 +from moinformat import Parser
2.28 +
2.29 +
2.30 +
2.31 +# Parser functionality.
2.32 +
2.33 +class TableParser(Parser):
2.34 +
2.35 + "A parser for improved table syntax."
2.36 +
2.37 + # Principal parser methods.
2.38 +
2.39 + def parse_region_content(self, items, region):
2.40 +
2.41 + "Parse the data provided by 'items' to populate the given 'region'."
2.42 +
2.43 + self.set_region(items, region)
2.44 + self.parse_table_region()
2.45 +
2.46 + def parse_table_region(self):
2.47 +
2.48 + # Start to populate table rows.
2.49 +
2.50 + cell = TableCell([])
2.51 + row = TableRow([cell])
2.52 + table = Table([row])
2.53 + self.region.append(table)
2.54 +
2.55 + while True:
2.56 + self.parse_region_details(cell, self.table_region_pattern_names)
2.57 +
2.58 + # Detect the end of the table.
2.59 +
2.60 + if self.read_matching() == "regionend":
2.61 + break
2.62 +
2.63 + if self.read_matching() == "columnsep":
2.64 + cell = TableCell([])
2.65 + row.append(cell)
2.66 +
2.67 + elif self.read_matching() == "rowsep":
2.68 + row = TableRow([])
2.69 + table.append(row)
2.70 + cell = TableCell([])
2.71 + row.append(cell)
2.72 +
2.73 + # Parser handler methods.
2.74 +
2.75 + def parse_continuation(self, cell):
2.76 + pass
2.77 +
2.78 + def parse_table_end(self, cell):
2.79 +
2.80 + "Handle the end of a region within 'cell'."
2.81 +
2.82 + feature = self.read_match()
2.83 + if self.region.have_end(feature):
2.84 + raise StopIteration
2.85 + else:
2.86 + cell.append_inline(Text(feature))
2.87 +
2.88 + # Regular expressions.
2.89 +
2.90 + syntax = {}
2.91 + syntax.update(Parser.syntax)
2.92 + syntax.update({
2.93 + # At start of line:
2.94 + "rowsep" : r"^==(?!.*==\s*?$)(?=\N*?)", # == not-heading ws-excl-nl
2.95 + "continuation" : r"^(\N*)\.\.(?!\.)(?=\N)", # .. ws-excl-nl or .. not-dot
2.96 +
2.97 + # Within text:
2.98 + "columnsep" : r"\|\|(?!\|)(?=\N)", # || ws-excl-nl or || not-pipe
2.99 + })
2.100 +
2.101 + patterns = get_patterns(syntax)
2.102 +
2.103 +
2.104 +
2.105 + # Pattern details.
2.106 +
2.107 + table_region_pattern_names = Parser.region_pattern_names + [
2.108 + "columnsep", "continuation", "regionend", "rowsep",
2.109 + ]
2.110 +
2.111 +
2.112 +
2.113 + # Pattern handlers.
2.114 +
2.115 + handlers = {}
2.116 + handlers.update(Parser.handlers)
2.117 + handlers.update({
2.118 + "columnsep" : Parser.end_region,
2.119 + "continuation" : parse_continuation,
2.120 + "rowsep" : Parser.end_region,
2.121 + "regionend" : parse_table_end,
2.122 + })
2.123 +
2.124 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/moinformat/serialisers.py Fri May 12 00:51:20 2017 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,331 +0,0 @@
3.4 -#!/usr/bin/env python
3.5 -
3.6 -"""
3.7 -Moin wiki serialisers.
3.8 -
3.9 -Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
3.10 -
3.11 -This program is free software; you can redistribute it and/or modify it under
3.12 -the terms of the GNU General Public License as published by the Free Software
3.13 -Foundation; either version 3 of the License, or (at your option) any later
3.14 -version.
3.15 -
3.16 -This program is distributed in the hope that it will be useful, but WITHOUT
3.17 -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.18 -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
3.19 -details.
3.20 -
3.21 -You should have received a copy of the GNU General Public License along with
3.22 -this program. If not, see <http://www.gnu.org/licenses/>.
3.23 -"""
3.24 -
3.25 -def escape_text(s):
3.26 -
3.27 - "Escape XML document text."
3.28 -
3.29 - return s.replace("&", "&").replace("<", "<").replace(">", ">")
3.30 -
3.31 -def escape_attr(s):
3.32 -
3.33 - "Escape XML document attribute."
3.34 -
3.35 - return escape_text(s).replace("'", "'").replace('"', """)
3.36 -
3.37 -class Serialiser:
3.38 -
3.39 - "General serialisation support."
3.40 -
3.41 - def __init__(self, out):
3.42 - self.out = out
3.43 -
3.44 -class MoinSerialiser(Serialiser):
3.45 -
3.46 - "Serialisation of the page."
3.47 -
3.48 - def start_region(self, level, indent, type):
3.49 - out = self.out
3.50 - if level:
3.51 - out(" " * indent + "{" * level)
3.52 - if type and level:
3.53 - out("#!%s\n" % type)
3.54 -
3.55 - def end_region(self, level, indent, type):
3.56 - out = self.out
3.57 - if level:
3.58 - out("}" * level)
3.59 -
3.60 - def start_block(self):
3.61 - pass
3.62 -
3.63 - def end_block(self):
3.64 - pass
3.65 -
3.66 - def start_defitem(self, pad, extra):
3.67 - self.out((extra and "\n" + extra + "::" or "") + pad)
3.68 -
3.69 - def end_defitem(self, pad, extra):
3.70 - pass
3.71 -
3.72 - def start_defterm(self, pad):
3.73 - self.out(pad)
3.74 -
3.75 - def end_defterm(self, pad):
3.76 - self.out("::")
3.77 -
3.78 - def start_emphasis(self):
3.79 - self.out("''")
3.80 -
3.81 - def end_emphasis(self):
3.82 - self.out("''")
3.83 -
3.84 - def start_heading(self, level, extra, pad):
3.85 - self.out(extra + "=" * level + pad)
3.86 -
3.87 - def end_heading(self, level, pad, extra):
3.88 - self.out(pad + "=" * level + extra)
3.89 -
3.90 - def start_larger(self):
3.91 - self.out("~+")
3.92 -
3.93 - def end_larger(self):
3.94 - self.out("+~")
3.95 -
3.96 - def start_listitem(self, indent, marker, space):
3.97 - self.out("%s%s%s" % (indent * " ", marker, space))
3.98 -
3.99 - def end_listitem(self, indent, marker):
3.100 - pass
3.101 -
3.102 - def start_monospace(self):
3.103 - self.out("`")
3.104 -
3.105 - def end_monospace(self):
3.106 - self.out("`")
3.107 -
3.108 - def start_smaller(self):
3.109 - self.out("~-")
3.110 -
3.111 - def end_smaller(self):
3.112 - self.out("-~")
3.113 -
3.114 - def start_strong(self):
3.115 - self.out("'''")
3.116 -
3.117 - def end_strong(self):
3.118 - self.out("'''")
3.119 -
3.120 - def start_subscript(self):
3.121 - self.out(",,")
3.122 -
3.123 - def end_subscript(self):
3.124 - self.out(",,")
3.125 -
3.126 - def start_superscript(self):
3.127 - self.out("^")
3.128 -
3.129 - def end_superscript(self):
3.130 - self.out("^")
3.131 -
3.132 - def start_table(self):
3.133 - pass
3.134 -
3.135 - def end_table(self):
3.136 - pass
3.137 -
3.138 - def start_table_attrs(self):
3.139 - self.out("<")
3.140 -
3.141 - def end_table_attrs(self):
3.142 - self.out(">")
3.143 -
3.144 - def start_table_cell(self, attrs):
3.145 - self.out("||")
3.146 - if attrs and not attrs.empty():
3.147 - attrs.to_string(self)
3.148 -
3.149 - def end_table_cell(self):
3.150 - pass
3.151 -
3.152 - def start_table_row(self):
3.153 - pass
3.154 -
3.155 - def end_table_row(self, trailing):
3.156 - self.out("||")
3.157 - self.out(trailing)
3.158 -
3.159 - def start_underline(self):
3.160 - self.out("__")
3.161 -
3.162 - def end_underline(self):
3.163 - self.out("__")
3.164 -
3.165 - def break_(self):
3.166 - self.out("\n")
3.167 -
3.168 - def rule(self, length):
3.169 - self.out("-" * length)
3.170 -
3.171 - def table_attr(self, name, value, concise, quote):
3.172 - if concise:
3.173 - if name == "colour": self.out(value)
3.174 - elif name == "colspan": self.out("-%s" % value)
3.175 - elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":")
3.176 - elif name == "rowspan": self.out("|%s" % value)
3.177 - elif name == "valign" : self.out(value == "top" and "^" or "v")
3.178 - elif name == "width" : self.out(value)
3.179 - else:
3.180 - self.out("%s%s" % (escape_text(name), value is not None and
3.181 - "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or ""))
3.182 -
3.183 - def text(self, s):
3.184 - self.out(s)
3.185 -
3.186 -class HTMLSerialiser(Serialiser):
3.187 -
3.188 - "Serialisation of the page."
3.189 -
3.190 - def start_region(self, level, indent, type):
3.191 - l = []
3.192 - out = l.append
3.193 - if level:
3.194 - out("level-%d" % level)
3.195 -
3.196 - if indent:
3.197 - out("indent-%d" % indent)
3.198 -
3.199 - # NOTE: Encode type details for CSS.
3.200 -
3.201 - if type:
3.202 - out("type-%s" % escape_attr(type))
3.203 -
3.204 - self.out("<span class='%s'>" % " ".join(l))
3.205 -
3.206 - def end_region(self, level, indent, type):
3.207 - self.out("</span>")
3.208 -
3.209 - def start_block(self):
3.210 - self.out("<p>")
3.211 -
3.212 - def end_block(self):
3.213 - self.out("</p>")
3.214 -
3.215 - def start_defitem(self, pad, extra):
3.216 - self.out("<dd>")
3.217 -
3.218 - def end_defitem(self, pad, extra):
3.219 - self.out("</dd>")
3.220 -
3.221 - def start_defterm(self, pad):
3.222 - self.out("<dt>")
3.223 -
3.224 - def end_defterm(self, pad):
3.225 - self.out("</dt>")
3.226 -
3.227 - def start_emphasis(self):
3.228 - self.out("<em>")
3.229 -
3.230 - def end_emphasis(self):
3.231 - self.out("</em>")
3.232 -
3.233 - def start_heading(self, level, extra, pad):
3.234 - self.out("<h%d>" % level)
3.235 -
3.236 - def end_heading(self, level, pad, extra):
3.237 - self.out("</h%d>" % level)
3.238 -
3.239 - def start_larger(self):
3.240 - self.out("<big>")
3.241 -
3.242 - def end_larger(self):
3.243 - self.out("</big>")
3.244 -
3.245 - def start_listitem(self, indent, marker, space):
3.246 - self.out("<li>")
3.247 -
3.248 - def end_listitem(self, indent, marker):
3.249 - self.out("</li>")
3.250 -
3.251 - def start_monospace(self):
3.252 - self.out("<tt>")
3.253 -
3.254 - def end_monospace(self):
3.255 - self.out("</tt>")
3.256 -
3.257 - def start_smaller(self):
3.258 - self.out("<small>")
3.259 -
3.260 - def end_smaller(self):
3.261 - self.out("</small>")
3.262 -
3.263 - def start_strong(self):
3.264 - self.out("<strong>")
3.265 -
3.266 - def end_strong(self):
3.267 - self.out("</strong>")
3.268 -
3.269 - def start_subscript(self):
3.270 - self.out("<sub>")
3.271 -
3.272 - def end_subscript(self):
3.273 - self.out("</sub>")
3.274 -
3.275 - def start_superscript(self):
3.276 - self.out("<sup>")
3.277 -
3.278 - def end_superscript(self):
3.279 - self.out("</sup>")
3.280 -
3.281 - def start_table(self):
3.282 - self.out("<table>")
3.283 -
3.284 - def end_table(self):
3.285 - self.out("</table>")
3.286 -
3.287 - def start_table_attrs(self):
3.288 - pass
3.289 -
3.290 - def end_table_attrs(self):
3.291 - pass
3.292 -
3.293 - def start_table_cell(self, attrs):
3.294 - self.out("<td")
3.295 - if attrs and not attrs.empty():
3.296 - attrs.to_string(self)
3.297 - self.out(">")
3.298 -
3.299 - def end_table_cell(self):
3.300 - self.out("</td>")
3.301 -
3.302 - def start_table_row(self):
3.303 - self.out("<tr>")
3.304 -
3.305 - def end_table_row(self, trailing):
3.306 - self.out("</tr>")
3.307 -
3.308 - def start_underline(self):
3.309 - self.out("<span style='text-decoration: underline'>")
3.310 -
3.311 - def end_underline(self):
3.312 - self.out("</span>")
3.313 -
3.314 - def break_(self):
3.315 - pass
3.316 -
3.317 - def rule(self, length):
3.318 - self.out("<hr style='height: %dpt' />" % min(length, 10))
3.319 -
3.320 - def table_attr(self, name, value, concise, quote):
3.321 - self.out(" %s%s" % (escape_text(name), value is not None and
3.322 - "='%s'" % escape_attr(value) or ""))
3.323 -
3.324 - def text(self, s):
3.325 - self.out(escape_text(s))
3.326 -
3.327 -# Top-level functions.
3.328 -
3.329 -def serialise(doc, serialiser=MoinSerialiser):
3.330 - l = []
3.331 - doc.to_string(serialiser(l.append))
3.332 - return "".join(l)
3.333 -
3.334 -# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/moinformat/serialisers/__init__.py Tue Dec 12 18:17:08 2017 +0100
4.3 @@ -0,0 +1,31 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +"""
4.7 +Moin wiki serialisers.
4.8 +
4.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
4.10 +
4.11 +This program is free software; you can redistribute it and/or modify it under
4.12 +the terms of the GNU General Public License as published by the Free Software
4.13 +Foundation; either version 3 of the License, or (at your option) any later
4.14 +version.
4.15 +
4.16 +This program is distributed in the hope that it will be useful, but WITHOUT
4.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4.19 +details.
4.20 +
4.21 +You should have received a copy of the GNU General Public License along with
4.22 +this program. If not, see <http://www.gnu.org/licenses/>.
4.23 +"""
4.24 +
4.25 +from moinformat.serialisers.moin import MoinSerialiser
4.26 +
4.27 +# Top-level functions.
4.28 +
4.29 +def serialise(doc, serialiser=MoinSerialiser):
4.30 + l = []
4.31 + doc.to_string(serialiser(l.append))
4.32 + return "".join(l)
4.33 +
4.34 +# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/moinformat/serialisers/common.py Tue Dec 12 18:17:08 2017 +0100
5.3 @@ -0,0 +1,41 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +"""
5.7 +Moin serialiser support.
5.8 +
5.9 +Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
5.10 +
5.11 +This program is free software; you can redistribute it and/or modify it under
5.12 +the terms of the GNU General Public License as published by the Free Software
5.13 +Foundation; either version 3 of the License, or (at your option) any later
5.14 +version.
5.15 +
5.16 +This program is distributed in the hope that it will be useful, but WITHOUT
5.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
5.19 +details.
5.20 +
5.21 +You should have received a copy of the GNU General Public License along with
5.22 +this program. If not, see <http://www.gnu.org/licenses/>.
5.23 +"""
5.24 +
5.25 +class Serialiser:
5.26 +
5.27 + "General serialisation support."
5.28 +
5.29 + def __init__(self, out):
5.30 + self.out = out
5.31 +
5.32 +def escape_attr(s):
5.33 +
5.34 + "Escape XML document attribute."
5.35 +
5.36 + return escape_text(s).replace("'", "'").replace('"', """)
5.37 +
5.38 +def escape_text(s):
5.39 +
5.40 + "Escape XML document text."
5.41 +
5.42 + return s.replace("&", "&").replace("<", "<").replace(">", ">")
5.43 +
5.44 +# vim: tabstop=4 expandtab shiftwidth=4
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/moinformat/serialisers/html.py Tue Dec 12 18:17:08 2017 +0100
6.3 @@ -0,0 +1,165 @@
6.4 +#!/usr/bin/env python
6.5 +
6.6 +"""
6.7 +HTML serialiser.
6.8 +
6.9 +Copyright (C) 2017 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 start_region(self, level, indent, type):
6.32 + l = []
6.33 + out = l.append
6.34 + if level:
6.35 + out("level-%d" % level)
6.36 +
6.37 + if indent:
6.38 + out("indent-%d" % indent)
6.39 +
6.40 + # NOTE: Encode type details for CSS.
6.41 +
6.42 + if type:
6.43 + out("type-%s" % escape_attr(type))
6.44 +
6.45 + self.out("<span class='%s'>" % " ".join(l))
6.46 +
6.47 + def end_region(self, level, indent, type):
6.48 + self.out("</span>")
6.49 +
6.50 + def start_block(self):
6.51 + self.out("<p>")
6.52 +
6.53 + def end_block(self):
6.54 + self.out("</p>")
6.55 +
6.56 + def start_defitem(self, pad, extra):
6.57 + self.out("<dd>")
6.58 +
6.59 + def end_defitem(self, pad, extra):
6.60 + self.out("</dd>")
6.61 +
6.62 + def start_defterm(self, pad):
6.63 + self.out("<dt>")
6.64 +
6.65 + def end_defterm(self, pad):
6.66 + self.out("</dt>")
6.67 +
6.68 + def start_emphasis(self):
6.69 + self.out("<em>")
6.70 +
6.71 + def end_emphasis(self):
6.72 + self.out("</em>")
6.73 +
6.74 + def start_heading(self, level, extra, pad):
6.75 + self.out("<h%d>" % level)
6.76 +
6.77 + def end_heading(self, level, pad, extra):
6.78 + self.out("</h%d>" % level)
6.79 +
6.80 + def start_larger(self):
6.81 + self.out("<big>")
6.82 +
6.83 + def end_larger(self):
6.84 + self.out("</big>")
6.85 +
6.86 + def start_listitem(self, indent, marker, space):
6.87 + self.out("<li>")
6.88 +
6.89 + def end_listitem(self, indent, marker):
6.90 + self.out("</li>")
6.91 +
6.92 + def start_monospace(self):
6.93 + self.out("<tt>")
6.94 +
6.95 + def end_monospace(self):
6.96 + self.out("</tt>")
6.97 +
6.98 + def start_smaller(self):
6.99 + self.out("<small>")
6.100 +
6.101 + def end_smaller(self):
6.102 + self.out("</small>")
6.103 +
6.104 + def start_strong(self):
6.105 + self.out("<strong>")
6.106 +
6.107 + def end_strong(self):
6.108 + self.out("</strong>")
6.109 +
6.110 + def start_subscript(self):
6.111 + self.out("<sub>")
6.112 +
6.113 + def end_subscript(self):
6.114 + self.out("</sub>")
6.115 +
6.116 + def start_superscript(self):
6.117 + self.out("<sup>")
6.118 +
6.119 + def end_superscript(self):
6.120 + self.out("</sup>")
6.121 +
6.122 + def start_table(self):
6.123 + self.out("<table>")
6.124 +
6.125 + def end_table(self):
6.126 + self.out("</table>")
6.127 +
6.128 + def start_table_attrs(self):
6.129 + pass
6.130 +
6.131 + def end_table_attrs(self):
6.132 + pass
6.133 +
6.134 + def start_table_cell(self, attrs):
6.135 + self.out("<td")
6.136 + if attrs and not attrs.empty():
6.137 + attrs.to_string(self)
6.138 + self.out(">")
6.139 +
6.140 + def end_table_cell(self):
6.141 + self.out("</td>")
6.142 +
6.143 + def start_table_row(self):
6.144 + self.out("<tr>")
6.145 +
6.146 + def end_table_row(self, trailing):
6.147 + self.out("</tr>")
6.148 +
6.149 + def start_underline(self):
6.150 + self.out("<span style='text-decoration: underline'>")
6.151 +
6.152 + def end_underline(self):
6.153 + self.out("</span>")
6.154 +
6.155 + def break_(self):
6.156 + pass
6.157 +
6.158 + def rule(self, length):
6.159 + self.out("<hr style='height: %dpt' />" % min(length, 10))
6.160 +
6.161 + def table_attr(self, name, value, concise, quote):
6.162 + self.out(" %s%s" % (escape_text(name), value is not None and
6.163 + "='%s'" % escape_attr(value) or ""))
6.164 +
6.165 + def text(self, s):
6.166 + self.out(escape_text(s))
6.167 +
6.168 +# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/moinformat/serialisers/moin.py Tue Dec 12 18:17:08 2017 +0100
7.3 @@ -0,0 +1,166 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +"""
7.7 +Moin wiki text serialiser.
7.8 +
7.9 +Copyright (C) 2017 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 +from moinformat.serialisers.common import escape_attr, escape_text, Serialiser
7.26 +
7.27 +class MoinSerialiser(Serialiser):
7.28 +
7.29 + "Serialisation of the page."
7.30 +
7.31 + def start_region(self, level, indent, type):
7.32 + out = self.out
7.33 + if level:
7.34 + out(" " * indent + "{" * level)
7.35 + if type and level:
7.36 + out("#!%s\n" % type)
7.37 +
7.38 + def end_region(self, level, indent, type):
7.39 + out = self.out
7.40 + if level:
7.41 + out("}" * level)
7.42 +
7.43 + def start_block(self):
7.44 + pass
7.45 +
7.46 + def end_block(self):
7.47 + pass
7.48 +
7.49 + def start_defitem(self, pad, extra):
7.50 + self.out((extra and "\n" + extra + "::" or "") + pad)
7.51 +
7.52 + def end_defitem(self, pad, extra):
7.53 + pass
7.54 +
7.55 + def start_defterm(self, pad):
7.56 + self.out(pad)
7.57 +
7.58 + def end_defterm(self, pad):
7.59 + self.out("::")
7.60 +
7.61 + def start_emphasis(self):
7.62 + self.out("''")
7.63 +
7.64 + def end_emphasis(self):
7.65 + self.out("''")
7.66 +
7.67 + def start_heading(self, level, extra, pad):
7.68 + self.out(extra + "=" * level + pad)
7.69 +
7.70 + def end_heading(self, level, pad, extra):
7.71 + self.out(pad + "=" * level + extra)
7.72 +
7.73 + def start_larger(self):
7.74 + self.out("~+")
7.75 +
7.76 + def end_larger(self):
7.77 + self.out("+~")
7.78 +
7.79 + def start_listitem(self, indent, marker, space):
7.80 + self.out("%s%s%s" % (indent * " ", marker, space))
7.81 +
7.82 + def end_listitem(self, indent, marker):
7.83 + pass
7.84 +
7.85 + def start_monospace(self):
7.86 + self.out("`")
7.87 +
7.88 + def end_monospace(self):
7.89 + self.out("`")
7.90 +
7.91 + def start_smaller(self):
7.92 + self.out("~-")
7.93 +
7.94 + def end_smaller(self):
7.95 + self.out("-~")
7.96 +
7.97 + def start_strong(self):
7.98 + self.out("'''")
7.99 +
7.100 + def end_strong(self):
7.101 + self.out("'''")
7.102 +
7.103 + def start_subscript(self):
7.104 + self.out(",,")
7.105 +
7.106 + def end_subscript(self):
7.107 + self.out(",,")
7.108 +
7.109 + def start_superscript(self):
7.110 + self.out("^")
7.111 +
7.112 + def end_superscript(self):
7.113 + self.out("^")
7.114 +
7.115 + def start_table(self):
7.116 + pass
7.117 +
7.118 + def end_table(self):
7.119 + pass
7.120 +
7.121 + def start_table_attrs(self):
7.122 + self.out("<")
7.123 +
7.124 + def end_table_attrs(self):
7.125 + self.out(">")
7.126 +
7.127 + def start_table_cell(self, attrs):
7.128 + self.out("||")
7.129 + if attrs and not attrs.empty():
7.130 + attrs.to_string(self)
7.131 +
7.132 + def end_table_cell(self):
7.133 + pass
7.134 +
7.135 + def start_table_row(self):
7.136 + pass
7.137 +
7.138 + def end_table_row(self, trailing):
7.139 + self.out("||")
7.140 + self.out(trailing)
7.141 +
7.142 + def start_underline(self):
7.143 + self.out("__")
7.144 +
7.145 + def end_underline(self):
7.146 + self.out("__")
7.147 +
7.148 + def break_(self):
7.149 + self.out("\n")
7.150 +
7.151 + def rule(self, length):
7.152 + self.out("-" * length)
7.153 +
7.154 + def table_attr(self, name, value, concise, quote):
7.155 + if concise:
7.156 + if name == "colour": self.out(value)
7.157 + elif name == "colspan": self.out("-%s" % value)
7.158 + elif name == "halign" : self.out(value == "left" and "(" or value == "right" and ")" or ":")
7.159 + elif name == "rowspan": self.out("|%s" % value)
7.160 + elif name == "valign" : self.out(value == "top" and "^" or "v")
7.161 + elif name == "width" : self.out(value)
7.162 + else:
7.163 + self.out("%s%s" % (escape_text(name), value is not None and
7.164 + "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or ""))
7.165 +
7.166 + def text(self, s):
7.167 + self.out(s)
7.168 +
7.169 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/tests/test_parser.py Fri May 12 00:51:20 2017 +0200
8.2 +++ b/tests/test_parser.py Tue Dec 12 18:17:08 2017 +0100
8.3 @@ -2,7 +2,8 @@
8.4
8.5 from moinformat import parse
8.6 from moinformat.parsers import table
8.7 -from moinformat.serialisers import serialise, HTMLSerialiser
8.8 +from moinformat.serialisers import serialise
8.9 +from moinformat.serialisers.html import HTMLSerialiser
8.10 from glob import glob
8.11 from os.path import join, split
8.12 import sys
8.13 @@ -18,6 +19,10 @@
8.14 o = serialise(d)
8.15
8.16 print o == s
8.17 +
8.18 + if quiet:
8.19 + return
8.20 +
8.21 print "-" * 60
8.22 print o
8.23 if o != s:
8.24 @@ -30,7 +35,11 @@
8.25 print
8.26
8.27 if __name__ == "__main__":
8.28 - filenames = sys.argv[1:] or glob(join(dirname, "test*.txt"))
8.29 + args = sys.argv[1:]
8.30 + quiet = "-q" in args
8.31 + if quiet:
8.32 + del args[args.index("-q")]
8.33 + filenames = args or glob(join(dirname, "test*.txt"))
8.34 filenames.sort()
8.35
8.36 for filename in filenames: