1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/moinformat/links/html.py Thu Jul 26 16:33:37 2018 +0200
1.3 @@ -0,0 +1,140 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +HTML linking scheme.
1.8 +
1.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This program is free software; you can redistribute it and/or modify it under
1.12 +the terms of the GNU General Public License as published by the Free Software
1.13 +Foundation; either version 3 of the License, or (at your option) any later
1.14 +version.
1.15 +
1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.19 +details.
1.20 +
1.21 +You should have received a copy of the GNU General Public License along with
1.22 +this program. If not, see <http://www.gnu.org/licenses/>.
1.23 +"""
1.24 +
1.25 +from moinformat.links.common import Linker
1.26 +from urlparse import urlparse
1.27 +
1.28 +class HTMLLinker(Linker):
1.29 +
1.30 + "Translate Moin links into HTML links."
1.31 +
1.32 + name = "html"
1.33 +
1.34 + def get_top_level(self):
1.35 +
1.36 + "Return a relative link to the top level."
1.37 +
1.38 + levels = self.pagename.count("/")
1.39 + return "/".join([".."] * levels)
1.40 +
1.41 + def is_url(self, link):
1.42 +
1.43 + "Return whether the 'link' references a URL."
1.44 +
1.45 + scheme, host, path, params, query, fragment = urlparse(link.target)
1.46 + return scheme
1.47 +
1.48 + def normalise(self, path):
1.49 +
1.50 + "Return a normalised form of 'path'."
1.51 +
1.52 + return not path.endswith("/") and "%s/" % path or path
1.53 +
1.54 + def translate(self, link):
1.55 +
1.56 + "Translate the 'link', rewriting the target."
1.57 +
1.58 + target = link.target.rstrip("/")
1.59 +
1.60 + # Sub-pages.
1.61 +
1.62 + if target.startswith("/"):
1.63 + self.translate_subpage(link, target)
1.64 +
1.65 + # Sibling (of ancestor) pages.
1.66 +
1.67 + elif target.startswith("../"):
1.68 + self.translate_relative(link, target)
1.69 +
1.70 + # Attachment or interwiki link.
1.71 +
1.72 + elif self.translate_qualified_link(link, target):
1.73 + pass
1.74 +
1.75 + # Plain URL.
1.76 +
1.77 + elif self.is_url(link):
1.78 + pass
1.79 +
1.80 + # Top-level pages.
1.81 +
1.82 + else:
1.83 + top_level = self.get_top_level()
1.84 + link.target = "%s%s" % (top_level and "%s/" % top_level or "", target)
1.85 +
1.86 + def translate_qualified_link(self, link, target):
1.87 +
1.88 + """
1.89 + Translate a possible qualified 'link', returning whether translation
1.90 + occurred.
1.91 + """
1.92 +
1.93 + t = target.split(":", 1)
1.94 + if len(t) != 2:
1.95 + return False
1.96 +
1.97 + prefix, target = t
1.98 +
1.99 + # Attachment links.
1.100 +
1.101 + if prefix == "attachment":
1.102 + self.translate_attachment(link, target)
1.103 + return True
1.104 +
1.105 + # Interwiki links.
1.106 +
1.107 + url = self.mapping.get(prefix)
1.108 + if url:
1.109 + self.translate_interwiki(link, url, target)
1.110 + return True
1.111 +
1.112 + return False
1.113 +
1.114 + # Specific link translators.
1.115 +
1.116 + def translate_attachment(self, link, target):
1.117 +
1.118 + "Update 'link' for the given attachment 'target'."
1.119 +
1.120 + link.target = "%sattachments/%s/%s" % (
1.121 + self.get_top_level(), self.pagename, target)
1.122 +
1.123 + def translate_interwiki(self, link, url, target):
1.124 +
1.125 + "Update 'link' for the given interwiki 'target'."
1.126 +
1.127 + link.target = "%s%s" % (self.normalise(url), target)
1.128 +
1.129 + def translate_relative(self, link, target):
1.130 +
1.131 + "Update 'link' for the given relative 'target'."
1.132 +
1.133 + link.target = target[len("../"):]
1.134 +
1.135 + def translate_subpage(self, link, target):
1.136 +
1.137 + "Update 'link' for the given subpage 'target'."
1.138 +
1.139 + link.target = ".%s" % target
1.140 +
1.141 +linker = HTMLLinker
1.142 +
1.143 +# vim: tabstop=4 expandtab shiftwidth=4