MoinLight

Annotated moinformat/links/common.py

176:47af441b48bf
2018-11-26 Paul Boddie Support linking to stylesheets based on the collection of available files.
paul@91 1
#!/usr/bin/env python
paul@91 2
paul@91 3
"""
paul@91 4
Common linking scheme functionality.
paul@91 5
paul@91 6
Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
paul@91 7
paul@91 8
This program is free software; you can redistribute it and/or modify it under
paul@91 9
the terms of the GNU General Public License as published by the Free Software
paul@91 10
Foundation; either version 3 of the License, or (at your option) any later
paul@91 11
version.
paul@91 12
paul@91 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@91 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@91 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@91 16
details.
paul@91 17
paul@91 18
You should have received a copy of the GNU General Public License along with
paul@91 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@91 20
"""
paul@91 21
paul@91 22
class Linker:
paul@91 23
paul@91 24
    "Translate Moin links into other forms."
paul@91 25
paul@165 26
    def __init__(self, metadata):
paul@165 27
paul@165 28
        "Initialise the linker with the 'metadata'."
paul@91 29
paul@165 30
        self.metadata = metadata
paul@91 31
paul@165 32
        # Obtain essential metadata.
paul@159 33
paul@165 34
        self.mapping = metadata.get("mapping", {})
paul@165 35
        self.root_pagename = metadata.get("root_pagename", "FrontPage")
paul@159 36
paul@159 37
def resolve(path, pagename, root_pagename):
paul@159 38
paul@159 39
    "Resolve 'path' relative to 'pagename'."
paul@159 40
paul@159 41
    # Omit the root pagename from the resolved path components.
paul@159 42
paul@159 43
    if pagename == root_pagename:
paul@159 44
        parts = []
paul@159 45
    else:
paul@159 46
        parts = pagename.rstrip("/").split("/")
paul@159 47
paul@159 48
    t = path.split("/")
paul@159 49
paul@159 50
    first = True
paul@159 51
paul@159 52
    for p in t:
paul@159 53
paul@159 54
        # Handle replacement of the page with another.
paul@159 55
paul@159 56
        if p == ".":
paul@159 57
            parts = []
paul@159 58
paul@159 59
        # Handle ascent in the page hierarchy.
paul@159 60
paul@159 61
        elif p == "..":
paul@159 62
            if parts:
paul@159 63
                parts.pop()
paul@159 64
paul@159 65
        # Any non-navigation element replaces the path at the start.
paul@159 66
        # Otherwise, the path is extended.
paul@159 67
        # Omit the root pagename from the resolved path components if it would
paul@159 68
        # appear at the start.
paul@159 69
paul@159 70
        elif p:
paul@159 71
            if first:
paul@159 72
                if p == root_pagename:
paul@159 73
                    parts = []
paul@159 74
                else:
paul@159 75
                    parts = [p]
paul@159 76
            else:
paul@159 77
                if parts or p != root_pagename:
paul@159 78
                    parts.append(p)
paul@159 79
paul@159 80
        first = False
paul@159 81
paul@159 82
    return "/".join(parts)
paul@91 83
paul@91 84
# vim: tabstop=4 expandtab shiftwidth=4