1 #!/usr/bin/env python 2 3 """ 4 HTML-to-Moin translator. 5 6 Copyright (C) 2023 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.translators.common import Translator 23 from moinformat.tree.moin import Block, Heading, Region, Text 24 25 def int_or_default(s, default): 26 if not s: 27 return default 28 try: 29 return int(s) 30 except ValueError: 31 return default 32 33 class HTMLToMoinTranslator(Translator): 34 35 "Translation of HTML document nodes to Moin document nodes." 36 37 input_formats = ["html"] 38 formats = ["moin"] 39 40 def _get_attribute(self, element, name): 41 for attribute in element.attributes: 42 if attribute.name == name: 43 return attribute.value and attribute.value.value 44 return None 45 46 def _get_class_values(self, element): 47 class_value = self._get_attribute(element, "class") 48 if not class_value: 49 return {} 50 51 d = {} 52 for token in class_value.split(): 53 if token and token.startswith("region-"): 54 _region, name, value = token.split("-", 2) 55 d[name] = value 56 return d 57 58 def element(self, element): 59 if not element.name: 60 return None 61 elif element.name[0] == "h" and element.name[1:].isdigit(): 62 return Heading(self.container(element), int(element.name[1:]), 63 start_pad=" ", end_pad=" ", end_extra="\n", 64 identifier=self._get_attribute(element, "id")) 65 elif element.name == "p": 66 return Block(self.container(element)) 67 elif element.name == "span": 68 d = self._get_class_values(element) 69 if d.has_key("type"): 70 return Region(self.container(element), 71 int_or_default(d.get("level"), 0), 72 int_or_default(d.get("indent"), 0), 73 d.get("type"), 74 extra="\n") 75 else: 76 return Block(self.container(element)) 77 else: 78 return None 79 80 def fragment(self, fragment): 81 return self.container(fragment) 82 83 def text(self, text): 84 return Text(text.value) 85 86 # Some nodes are not directly translated. 87 88 def node(self, node): 89 return None 90 91 attribute = node 92 attribute_value = node 93 comment = node 94 directive = node 95 inclusion = node 96 97 translator = HTMLToMoinTranslator 98 99 # vim: tabstop=4 expandtab shiftwidth=4