1 #!/usr/bin/env python 2 3 """ 4 Theming common functionality. 5 6 Copyright (C) 2018, 2019 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.utils.file import readfile 23 from os import listdir, makedirs 24 from os.path import exists, isfile, join, split 25 from shutil import copy 26 27 class Theme: 28 29 "A common theme abstraction." 30 31 default_encoding = "utf-8" 32 33 def __init__(self, metadata): 34 35 "Initialise the theme with the given 'metadata'." 36 37 self.metadata = metadata 38 39 # Obtain essential metadata. 40 41 self.linker = metadata.get_linker() 42 self.output = metadata.get_output() 43 44 # Determine whether to bundle styles within documents. 45 46 self.bundle = metadata.get("bundle") 47 48 def apply(self, text): 49 50 "Apply this theme to the given 'text', returning a themed version." 51 52 return text 53 54 def get_resource_base(self): 55 56 "Return the filesystem base of resources for instances of this class." 57 58 return split(self.__class__.origin)[0] 59 60 def get_resource(self, filename, base=None): 61 62 """ 63 Return the complete path for the resource with the given 'filename'. If 64 the optional 'base' is given, use this as the location of 'filename'. 65 """ 66 67 base = base or self.get_resource_base() 68 return join(base, filename) 69 70 def install_resource(self, filename, target=None): 71 72 """ 73 Install the resource with the given 'filename' into a location having 74 the given 'target' name (or 'filename' if 'target' is omitted). 75 """ 76 77 if not self.output.can_write(): 78 return 79 80 pathname = self.get_resource(filename) 81 outpath = self.output.get_filename(target or filename) 82 83 self.copy(pathname, outpath) 84 85 def copy(self, pathname, outpath): 86 87 "Copy 'pathname' to 'outpath'." 88 89 if isfile(pathname): 90 outdir = split(outpath)[0] 91 if outdir and not exists(outdir): 92 makedirs(outdir) 93 copy(pathname, outpath) 94 else: 95 if not exists(outpath): 96 makedirs(outpath) 97 for filename in listdir(pathname): 98 self.copy(join(pathname, filename), join(outpath, filename)) 99 100 # NOTE: Also defined in moinformat.input.common. 101 102 def readpath(self, filename, encoding=None): 103 104 """ 105 Return the contents of the file having the given 'filename'. If the 106 optional 'encoding' is specified, override the general encoding. 107 """ 108 109 return readfile(filename, encoding or self.default_encoding) 110 111 def load_resource(self, filename, base=None): 112 113 """ 114 Return the textual content of the resource with the given 'filename'. If 115 the optional 'base' is given, use this as the location of 'filename'. 116 """ 117 118 return self.readpath(self.get_resource(filename, base)) 119 120 # vim: tabstop=4 expandtab shiftwidth=4