MoinLight

Annotated moinformat/output/common.py

226:68e7dbbd6ed8
2019-04-13 Paul Boddie Obtain serialised documents as Unicode, eventually encoding them for output. This helps various processing operations such as theme templating.
paul@100 1
#!/usr/bin/env python
paul@100 2
paul@100 3
"""
paul@100 4
Output context common functionality.
paul@100 5
paul@100 6
Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
paul@100 7
paul@100 8
This program is free software; you can redistribute it and/or modify it under
paul@100 9
the terms of the GNU General Public License as published by the Free Software
paul@100 10
Foundation; either version 3 of the License, or (at your option) any later
paul@100 11
version.
paul@100 12
paul@100 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@100 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@100 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@100 16
details.
paul@100 17
paul@100 18
You should have received a copy of the GNU General Public License along with
paul@100 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@100 20
"""
paul@100 21
paul@131 22
import codecs
paul@131 23
paul@100 24
class Output:
paul@100 25
paul@100 26
    "A common output context abstraction."
paul@100 27
paul@104 28
    default_encoding = "utf-8"
paul@104 29
paul@165 30
    def __init__(self, metadata):
paul@165 31
paul@165 32
        "Initialise the output context with the 'metadata'."
paul@100 33
paul@165 34
        self.metadata = metadata
paul@104 35
paul@165 36
        # Obtain essential metadata.
paul@165 37
paul@165 38
        self.encoding = metadata.get("output_encoding", self.default_encoding)
paul@135 39
        self.reset()
paul@104 40
paul@135 41
    def reset(self):
paul@135 42
paul@135 43
        "Set up an output collector."
paul@100 44
paul@100 45
        self.output = []
paul@104 46
paul@104 47
    def encode(self, text):
paul@104 48
paul@104 49
        "Encode 'text' using the configured encoding."
paul@104 50
paul@104 51
        return encode(text, self.encoding)
paul@104 52
paul@104 53
    def out(self, text):
paul@104 54
paul@104 55
        "Add 'text' to the output collector."
paul@104 56
paul@226 57
        self.output.append(text)
paul@100 58
paul@139 59
    # Page characteristics.
paul@139 60
paul@139 61
    def parent(self, pagename):
paul@139 62
paul@139 63
        "Return the parent of 'pagename'."
paul@139 64
paul@139 65
        return "/" in pagename and pagename.rsplit("/", 1)[0] or None
paul@139 66
paul@131 67
    # Serialisation methods.
paul@131 68
paul@100 69
    def to_string(self):
paul@100 70
paul@226 71
        "Return the output as a single Unicode string."
paul@100 72
paul@226 73
        s = u"".join(self.output)
paul@135 74
        self.reset()
paul@135 75
        return s
paul@100 76
paul@131 77
    def can_write(self):
paul@131 78
paul@131 79
        "Return whether this context supports page writing."
paul@131 80
paul@131 81
        return False
paul@131 82
paul@131 83
    def writefile(self, text, filename, encoding=None):
paul@131 84
paul@131 85
        """
paul@131 86
        Write 'text' to the file having the given 'filename'. If the
paul@131 87
        optional 'encoding' is specified, override the general encoding.
paul@131 88
paul@131 89
        Subclasses need to override this method for it to have an effect.
paul@131 90
        """
paul@131 91
paul@131 92
        pass
paul@131 93
paul@131 94
    def writepage(self, text, pagename, encoding=None):
paul@131 95
paul@131 96
        """
paul@131 97
        Write 'text' to the file having the given 'pagename' and optional
paul@131 98
        'encoding'.
paul@131 99
        """
paul@131 100
paul@131 101
        return self.writefile(text, self.to_filename(pagename), encoding)
paul@131 102
paul@131 103
    # Output methods.
paul@131 104
paul@131 105
    def writepath(self, text, filename, encoding=None):
paul@131 106
paul@131 107
        """
paul@131 108
        Write 'text' to the file having the given 'filename'. If the
paul@131 109
        optional 'encoding' is specified, override the general encoding.
paul@131 110
        """
paul@131 111
paul@131 112
        f = codecs.open(filename, "w", encoding=encoding or self.encoding)
paul@131 113
        try:
paul@131 114
            f.write(text)
paul@131 115
        finally:
paul@131 116
            f.close()
paul@131 117
paul@104 118
def encode(s, encoding):
paul@104 119
paul@104 120
    "Encode 's' using 'encoding' if Unicode."
paul@104 121
paul@104 122
    if isinstance(s, unicode):
paul@104 123
        return s.encode(encoding)
paul@104 124
    else:
paul@104 125
        return s
paul@104 126
paul@100 127
# vim: tabstop=4 expandtab shiftwidth=4