1 #!/usr/bin/env python 2 3 """ 4 Moin wiki text serialiser. 5 6 Copyright (C) 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from moinformat.serialisers.common import escape_attr, escape_text, Serialiser 23 24 class MoinSerialiser(Serialiser): 25 26 "Serialisation of the page." 27 28 input_formats = ["moin", "wiki"] 29 formats = ["moin", "wiki"] 30 31 def start_region(self, level, indent, type, extra): 32 out = self.out 33 if level: 34 out(" " * indent + "{" * level) 35 36 # Produce a header for regions within a top-level region. 37 38 if type and type != "inline" and level: 39 out("#!%s\n" % type) 40 41 def end_region(self, level, indent, type, extra): 42 out = self.out 43 if level: 44 out("%s%s" % ("}" * level, extra or "")) 45 46 def start_block(self): 47 pass 48 49 def end_block(self): 50 pass 51 52 def start_defitem(self, pad, extra): 53 self.out((extra and extra + "::" or "") + pad) 54 55 def end_defitem(self, pad, extra): 56 pass 57 58 def start_defterm(self, pad, extra): 59 self.out(pad) 60 61 def end_defterm(self, pad, extra): 62 self.out("::" + extra) 63 64 def start_emphasis(self): 65 self.out("''") 66 67 def end_emphasis(self): 68 self.out("''") 69 70 def start_heading(self, level, extra, pad, identifier): 71 self.out(extra + "=" * level + pad) 72 73 def end_heading(self, level, pad, extra): 74 self.out(pad + "=" * level + extra) 75 76 def start_larger(self): 77 self.out("~+") 78 79 def end_larger(self): 80 self.out("+~") 81 82 def start_list(self, indent, marker, num): 83 pass 84 85 def end_list(self, indent, marker, num): 86 pass 87 88 def start_listitem(self, indent, marker, space, num): 89 self.out("%s%s%s%s" % (indent * " ", marker, num and "#%s" % num or "", space)) 90 91 def end_listitem(self, indent, marker, space, num): 92 pass 93 94 def start_macro(self, name, args, nodes, inline): 95 96 # Fallback case for when macros are not replaced. 97 98 if not nodes: 99 self.out("<<%s%s>>" % (name, args and "(%s)" % ",".join(args) or "")) 100 101 def end_macro(self, inline): 102 pass 103 104 def start_monospace(self): 105 self.out("`") 106 107 def end_monospace(self): 108 self.out("`") 109 110 def start_smaller(self): 111 self.out("~-") 112 113 def end_smaller(self): 114 self.out("-~") 115 116 def start_strong(self): 117 self.out("'''") 118 119 def end_strong(self): 120 self.out("'''") 121 122 def start_strikethrough(self): 123 self.out("--(") 124 125 def end_strikethrough(self): 126 self.out(")--") 127 128 def start_subscript(self): 129 self.out(",,") 130 131 def end_subscript(self): 132 self.out(",,") 133 134 def start_superscript(self): 135 self.out("^") 136 137 def end_superscript(self): 138 self.out("^") 139 140 def start_table(self): 141 pass 142 143 def end_table(self): 144 pass 145 146 def start_table_attrs(self): 147 self.out("<") 148 149 def end_table_attrs(self): 150 self.out(">") 151 152 def start_table_cell(self, attrs, leading, padding): 153 self.out("||") 154 155 def end_table_cell(self): 156 pass 157 158 def start_table_row(self, leading, padding): 159 pass 160 161 def end_table_row(self, trailing): 162 self.out("||") 163 self.out(trailing) 164 165 def start_underline(self): 166 self.out("__") 167 168 def end_underline(self): 169 self.out("__") 170 171 def anchor(self, target): 172 self.out("((%s))" % target) 173 174 def break_(self): 175 self.out("\n") 176 177 def comment(self, comment, extra): 178 self.out("##%s%s" % (comment, extra)) 179 180 def directive(self, directive, extra): 181 self.out("#%s%s" % (directive, extra)) 182 183 def linebreak(self): 184 self.out(r"\\") 185 186 def link(self, target, nodes): 187 self.out("[[%s" % target) 188 for node in nodes: 189 self.out("|") 190 node.to_string(self) 191 self.out("]]") 192 193 def link_label(self, nodes): 194 for node in nodes: 195 node.to_string(self) 196 197 def link_parameter(self, key_value): 198 if len(key_value) == 1: 199 self.out(key_value[0]) 200 else: 201 self.out("=".join(key_value)) 202 203 def rule(self, height): 204 self.out("-" * (height + 4)) 205 206 def table_attrs(self, nodes): 207 for node in nodes: 208 node.to_string(self) 209 210 def table_attr(self, name, value, concise, quote): 211 if concise: 212 if name == "bgcolor": self.out(value) 213 elif name == "colspan": self.out("-%s" % value) 214 elif name == "align" : self.out(value == "left" and "(" or value == "right" and ")" or ":") 215 elif name == "rowspan": self.out("|%s" % value) 216 elif name == "valign" : self.out(value == "top" and "^" or "v") 217 elif name == "width" : self.out(value) 218 else: 219 self.out("%s%s" % (escape_text(name), value is not None and 220 "=%s%s%s" % (quote or '"', escape_attr(value), quote or '"') or "")) 221 222 def text(self, s): 223 self.out(s) 224 225 def transclusion(self, target, nodes): 226 self.out("{{%s" % target) 227 for node in nodes: 228 self.out("|") 229 node.to_string(self) 230 self.out("}}") 231 232 def verbatim(self, text): 233 self.out("<<<") 234 self.out(text) 235 self.out(">>>") 236 237 serialiser = MoinSerialiser 238 239 # vim: tabstop=4 expandtab shiftwidth=4