1.1 --- a/moinconvert Fri Jul 12 21:54:20 2019 +0200
1.2 +++ b/moinconvert Fri Jul 12 22:04:11 2019 +0200
1.3 @@ -107,6 +107,7 @@
1.4 # Flags.
1.5
1.6 all = False
1.7 + bundle = False
1.8 fragment = False
1.9 macros = False
1.10 tree = False
1.11 @@ -120,6 +121,11 @@
1.12 if arg == "--all":
1.13 all = True
1.14
1.15 + # Detect resource bundling.
1.16 +
1.17 + elif arg == "--bundle":
1.18 + bundle = True
1.19 +
1.20 # Detect fragment output (if serialising).
1.21
1.22 elif arg == "--fragment":
1.23 @@ -237,6 +243,7 @@
1.24
1.25 metadata = Metadata({
1.26 "attachments" : getvalue(attachments_dir, "attachments"),
1.27 + "bundle" : bundle,
1.28 "document_index" : getvalue(document_indexes),
1.29 "input_context" : input_dir and \
1.30 getvalue(input_dir_types, "directory") or \
1.31 @@ -367,6 +374,9 @@
1.32
1.33 Output options:
1.34
1.35 +--bundle Bundle resources such as stylesheets within every document,
1.36 + useful for publishing documents that need to be copied or
1.37 + distributed individually.
1.38 --document-index Provide a "DocumentIndex" filename to be used in links in
1.39 HTML format output, useful for local file browsing instead
1.40 of Web-published content
2.1 --- a/moinformat/themes/common.py Fri Jul 12 21:54:20 2019 +0200
2.2 +++ b/moinformat/themes/common.py Fri Jul 12 22:04:11 2019 +0200
2.3 @@ -19,10 +19,10 @@
2.4 this program. If not, see <http://www.gnu.org/licenses/>.
2.5 """
2.6
2.7 +from moinformat.utils.file import readfile
2.8 from os import listdir, makedirs
2.9 from os.path import exists, isfile, join, split
2.10 from shutil import copy
2.11 -import codecs
2.12
2.13 class Theme:
2.14
2.15 @@ -41,6 +41,10 @@
2.16 self.linker = metadata.get_linker()
2.17 self.output = metadata.get_output()
2.18
2.19 + # Determine whether to bundle styles within documents.
2.20 +
2.21 + self.bundle = metadata.get("bundle")
2.22 +
2.23 def apply(self, text):
2.24
2.25 "Apply this theme to the given 'text', returning a themed version."
2.26 @@ -53,11 +57,14 @@
2.27
2.28 return split(self.__class__.origin)[0]
2.29
2.30 - def get_resource(self, filename):
2.31 + def get_resource(self, filename, base=None):
2.32
2.33 - "Return the complete path for the resource with the given 'filename'."
2.34 + """
2.35 + Return the complete path for the resource with the given 'filename'. If
2.36 + the optional 'base' is given, use this as the location of 'filename'.
2.37 + """
2.38
2.39 - base = self.get_resource_base()
2.40 + base = base or self.get_resource_base()
2.41 return join(base, filename)
2.42
2.43 def install_resource(self, filename, target=None):
2.44 @@ -90,14 +97,24 @@
2.45 for filename in listdir(pathname):
2.46 self.copy(join(pathname, filename), join(outpath, filename))
2.47
2.48 - def load_resource(self, filename):
2.49 + # NOTE: Also defined in moinformat.input.common.
2.50 +
2.51 + def readpath(self, filename, encoding=None):
2.52
2.53 - "Return the textual content of the resource with the given 'filename'."
2.54 + """
2.55 + Return the contents of the file having the given 'filename'. If the
2.56 + optional 'encoding' is specified, override the general encoding.
2.57 + """
2.58
2.59 - f = codecs.open(self.get_resource(filename), encoding=self.default_encoding)
2.60 - try:
2.61 - return f.read()
2.62 - finally:
2.63 - f.close()
2.64 + return readfile(filename, encoding or self.default_encoding)
2.65 +
2.66 + def load_resource(self, filename, base=None):
2.67 +
2.68 + """
2.69 + Return the textual content of the resource with the given 'filename'. If
2.70 + the optional 'base' is given, use this as the location of 'filename'.
2.71 + """
2.72 +
2.73 + return self.readpath(self.get_resource(filename, base))
2.74
2.75 # vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/moinformat/themes/html.py Fri Jul 12 21:54:20 2019 +0200
3.2 +++ b/moinformat/themes/html.py Fri Jul 12 22:04:11 2019 +0200
3.3 @@ -29,18 +29,27 @@
3.4
3.5 # Support a collection of links to stylesheets provided by each theme.
3.6
3.7 - link = '<link rel="stylesheet" type="text/css" charset="utf-8" media="%(media)s" href="%(root)s/_css/%(filename)s" />\n'
3.8 + link = '<link rel="stylesheet" type="text/css" charset="utf-8"' \
3.9 + ' media="%(media)s" href="%(root)s/_css/%(filename)s" />\n'
3.10 +
3.11 + bundled_link = '<style type="text/css" media="%(media)s">\n%(data)s' \
3.12 + '</style>\n'
3.13
3.14 - def get_links(self, subs):
3.15 + def get_links(self, subs, bundle=False):
3.16
3.17 - "Using 'subs', return a string containing markup linking to resources."
3.18 + """
3.19 + Using 'subs', return a string containing markup linking to resources if
3.20 + 'bundle' is a false value or omitted. If 'bundle' is a true value,
3.21 + incorporate resources within the document.
3.22 + """
3.23
3.24 d = {}
3.25 d.update(subs)
3.26
3.27 + css = self.get_resource("css")
3.28 links = []
3.29
3.30 - for filename in listdir(self.get_resource("css")):
3.31 + for filename in listdir(css):
3.32
3.33 # Only link to CSS files.
3.34
3.35 @@ -56,7 +65,11 @@
3.36 d["media"] = t[0] or "all"
3.37 d["filename"] = filename
3.38
3.39 - links.append(self.link % d)
3.40 + if bundle:
3.41 + d["data"] = self.load_resource(filename, css)
3.42 +
3.43 + template = bundle and self.bundled_link or self.link
3.44 + links.append(template % d)
3.45
3.46 return "".join(links)
3.47
3.48 @@ -73,13 +86,14 @@
3.49 "text" : text,
3.50 "title" : self.metadata.get("title") or self.metadata.get("pagename"),
3.51 }
3.52 - subs["links"] = self.get_links(subs)
3.53 + subs["links"] = self.get_links(subs, self.bundle)
3.54 return template % subs
3.55
3.56 def install_resources(self):
3.57
3.58 "Install resources for this theme."
3.59
3.60 - self.install_resource("css", "_css")
3.61 + if not self.bundle:
3.62 + self.install_resource("css", "_css")
3.63
3.64 # vim: tabstop=4 expandtab shiftwidth=4