1.1 --- a/convert.py Sun Nov 25 16:59:19 2018 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,265 +0,0 @@
1.4 -#!/usr/bin/env python
1.5 -
1.6 -from moinformat import make_parser, make_serialiser, Metadata, parse, serialise
1.7 -from os.path import split
1.8 -import sys
1.9 -
1.10 -def getmapping(mappings):
1.11 - mapping = {}
1.12 - key = None
1.13 -
1.14 - for arg in mappings:
1.15 - if key is None:
1.16 - key = arg
1.17 - else:
1.18 - mapping[key] = arg
1.19 - key = None
1.20 -
1.21 - return mapping
1.22 -
1.23 -def getvalue(values, default=None):
1.24 - return values and values[0] or default
1.25 -
1.26 -def main():
1.27 - dirname, progname = split(sys.argv[0])
1.28 - args = sys.argv[1:]
1.29 -
1.30 - # Option values.
1.31 -
1.32 - l = filenames = []
1.33 - formats = []
1.34 - input_dir_types = []
1.35 - input_dirs = []
1.36 - input_encodings = []
1.37 - input_page_seps = []
1.38 - mappings = []
1.39 - output_dirs = []
1.40 - output_encodings = []
1.41 - theme_names = []
1.42 - pagenames = []
1.43 - root_pagenames = []
1.44 -
1.45 - # Flags.
1.46 -
1.47 - all = False
1.48 - fragment = False
1.49 - macros = False
1.50 - tree = False
1.51 -
1.52 - for arg in args:
1.53 -
1.54 - # Detect tree output.
1.55 -
1.56 - if arg == "--tree":
1.57 - tree = True
1.58 -
1.59 - # Detect macro evaluation.
1.60 -
1.61 - elif arg == "--macros":
1.62 - macros = True
1.63 -
1.64 - # Detect all documents.
1.65 -
1.66 - elif arg == "--all":
1.67 - all = True
1.68 -
1.69 - # Detect fragment output (if serialising).
1.70 -
1.71 - elif arg == "--fragment":
1.72 - fragment = True
1.73 -
1.74 - # Switch to collecting formats.
1.75 -
1.76 - elif arg == "--format":
1.77 - l = formats
1.78 - continue
1.79 -
1.80 - # Switch to collecting input locations.
1.81 -
1.82 - elif arg == "--input-dir":
1.83 - l = input_dirs
1.84 - continue
1.85 -
1.86 - # Switch to collecting input context types.
1.87 -
1.88 - elif arg == "--input-dir-type":
1.89 - l = input_dir_types
1.90 - continue
1.91 -
1.92 - # Switch to collecting input encodings.
1.93 -
1.94 - elif arg == "--input-encoding":
1.95 - l = input_encodings
1.96 - continue
1.97 -
1.98 - # Switch to collecting input page hierarchy separators.
1.99 -
1.100 - elif arg == "--input-page-sep":
1.101 - l = input_page_seps
1.102 - continue
1.103 -
1.104 - # Switch to collecting mappings.
1.105 -
1.106 - elif arg == "--mapping":
1.107 - l = mappings
1.108 - continue
1.109 -
1.110 - # Switch to collecting output locations.
1.111 -
1.112 - elif arg == "--output-dir":
1.113 - l = output_dirs
1.114 - continue
1.115 -
1.116 - # Switch to collecting output encodings.
1.117 -
1.118 - elif arg == "--output-encoding":
1.119 - l = output_encodings
1.120 - continue
1.121 -
1.122 - # Switch to collecting page names.
1.123 -
1.124 - elif arg == "--pagename":
1.125 - l = pagenames
1.126 - continue
1.127 -
1.128 - # Switch to collecting root page names.
1.129 -
1.130 - elif arg == "--root":
1.131 - l = root_pagenames
1.132 - continue
1.133 -
1.134 - # Switch to collecting theme names.
1.135 -
1.136 - elif arg == "--theme":
1.137 - l = theme_names
1.138 - continue
1.139 -
1.140 - # Collect options and arguments.
1.141 -
1.142 - else:
1.143 - l.append(arg)
1.144 -
1.145 - # Collect multiple mappings.
1.146 -
1.147 - if l is mappings:
1.148 - continue
1.149 -
1.150 - # Collect filenames normally.
1.151 -
1.152 - l = filenames
1.153 -
1.154 - format = formats and formats[0] or "html"
1.155 - input_dir = getvalue(input_dirs)
1.156 - output_dir = getvalue(output_dirs)
1.157 -
1.158 - # Define metadata.
1.159 -
1.160 - metadata = Metadata({
1.161 - "input_context" : input_dir and \
1.162 - getvalue(input_dir_types, "directory") or \
1.163 - "standalone",
1.164 - "input_encoding" : getvalue(input_encodings),
1.165 - "input_filename" : input_dir,
1.166 - "input_separator" : getvalue(input_page_seps),
1.167 - "link_format" : format,
1.168 - "mapping" : getmapping(mappings),
1.169 - "output_context" : output_dir and "directory" or "standalone",
1.170 - "output_encoding" : getvalue(output_encodings),
1.171 - "output_format" : format,
1.172 - "output_filename" : output_dir,
1.173 - "root_pagename" : getvalue(root_pagenames, "FrontPage"),
1.174 - "theme_name" : not fragment and \
1.175 - "%s.%s" % (getvalue(theme_names, "default"), format) or None,
1.176 - })
1.177 -
1.178 - # Define the input context and theme.
1.179 -
1.180 - input = metadata.get_input()
1.181 - theme = metadata.get_theme()
1.182 -
1.183 - # Treat filenames as pagenames if an input directory is indicated and if no
1.184 - # pagenames are explicitly specified.
1.185 -
1.186 - if input_dir:
1.187 - if pagenames:
1.188 - print >>sys.stderr, """\
1.189 -Explicit pagenames (indicated using --pagename) are only to be specified when
1.190 -providing filenames without an input directory (indicated using --input-dir).
1.191 -
1.192 -To indicate pagenames within an input directory, omit any --pagename flags."""
1.193 - sys.exit(1)
1.194 -
1.195 - if all:
1.196 - if filenames:
1.197 - print >>sys.stderr, """\
1.198 -Using --all overrides any indicated pagenames. Either --all or the filenames
1.199 -should be omitted."""
1.200 - sys.exit(1)
1.201 - else:
1.202 - filenames = input.all()
1.203 -
1.204 - pagenames = filenames
1.205 - filenames = []
1.206 -
1.207 - # Open each file or page, parse the content, serialise the document.
1.208 -
1.209 - for pagename, filename in map(None, pagenames, filenames):
1.210 -
1.211 - # Define a pagename if missing.
1.212 -
1.213 - pagename = pagename or split(filename)[-1]
1.214 - metadata.set("pagename", pagename)
1.215 -
1.216 - # Read either from a filename or using a pagename.
1.217 -
1.218 - if filename:
1.219 - pagetext = input.readfile(filename)
1.220 - else:
1.221 - pagetext = input.readpage(pagename)
1.222 -
1.223 - # Parse the page content.
1.224 -
1.225 - p = make_parser(metadata)
1.226 - d = parse(pagetext, p)
1.227 -
1.228 - if macros:
1.229 - p.evaluate_macros()
1.230 -
1.231 - # Show a document tree for debugging purposes, if requested.
1.232 -
1.233 - if tree:
1.234 - print d.prettyprint()
1.235 - continue
1.236 -
1.237 - # Otherwise, serialise the document.
1.238 -
1.239 - # Obtain a serialiser using the configuration.
1.240 -
1.241 - serialiser = make_serialiser(metadata)
1.242 - outtext = serialise(d, serialiser)
1.243 -
1.244 - # With a theme, apply it to the text.
1.245 -
1.246 - if theme:
1.247 - outtext = theme.apply(outtext)
1.248 -
1.249 - # If reading from a file, show the result. Otherwise, write to the
1.250 - # output context.
1.251 -
1.252 - output = metadata.get_output()
1.253 -
1.254 - if not output.can_write():
1.255 - print outtext
1.256 - else:
1.257 - output.writepage(outtext, pagename)
1.258 - print >>sys.stderr, pagename
1.259 -
1.260 - # Install any theme resources.
1.261 -
1.262 - if theme:
1.263 - theme.install_resources()
1.264 -
1.265 -if __name__ == "__main__":
1.266 - main()
1.267 -
1.268 -# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/moinconvert Mon Nov 26 22:59:52 2018 +0100
2.3 @@ -0,0 +1,313 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +"""
2.7 +Moin wiki format converter.
2.8 +
2.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
2.10 +
2.11 +This program is free software; you can redistribute it and/or modify it under
2.12 +the terms of the GNU General Public License as published by the Free Software
2.13 +Foundation; either version 3 of the License, or (at your option) any later
2.14 +version.
2.15 +
2.16 +This program is distributed in the hope that it will be useful, but WITHOUT
2.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
2.19 +details.
2.20 +
2.21 +You should have received a copy of the GNU General Public License along with
2.22 +this program. If not, see <http://www.gnu.org/licenses/>.
2.23 +"""
2.24 +
2.25 +from moinformat import make_parser, make_serialiser, Metadata, parse, serialise
2.26 +from os.path import split
2.27 +import sys
2.28 +
2.29 +# Long messages.
2.30 +
2.31 +message_all_with_filenames = """\
2.32 +Using --all overrides any indicated pagenames. Either --all or the filenames
2.33 +should be omitted."""
2.34 +
2.35 +message_explicit_pagenames = """\
2.36 +Explicit pagenames (indicated using --pagename) are only to be specified when
2.37 +providing filenames without an input directory (indicated using --input-dir).
2.38 +
2.39 +To indicate pagenames within an input directory, omit any --pagename flags."""
2.40 +
2.41 +
2.42 +
2.43 +# Options management.
2.44 +
2.45 +def getmapping(mappings):
2.46 +
2.47 + """
2.48 + Return the given 'mappings' - a collection of key-then-value items - as a
2.49 + dictionary.
2.50 + """
2.51 +
2.52 + mapping = {}
2.53 + key = None
2.54 +
2.55 + for arg in mappings:
2.56 + if key is None:
2.57 + key = arg
2.58 + else:
2.59 + mapping[key] = arg
2.60 + key = None
2.61 +
2.62 + return mapping
2.63 +
2.64 +def getvalue(values, default=None):
2.65 +
2.66 + """
2.67 + Return the first value from 'values' or 'default' if 'values' is empty or
2.68 + the first value tests as false.
2.69 + """
2.70 +
2.71 + return values and values[0] or default
2.72 +
2.73 +
2.74 +
2.75 +# Main program.
2.76 +
2.77 +def main():
2.78 +
2.79 + "Interpret program options and perform the conversion."
2.80 +
2.81 + dirname, progname = split(sys.argv[0])
2.82 + args = sys.argv[1:]
2.83 +
2.84 + # Option values.
2.85 +
2.86 + l = filenames = []
2.87 + formats = []
2.88 + input_dir_types = []
2.89 + input_dirs = []
2.90 + input_encodings = []
2.91 + input_page_seps = []
2.92 + mappings = []
2.93 + output_dirs = []
2.94 + output_encodings = []
2.95 + theme_names = []
2.96 + pagenames = []
2.97 + root_pagenames = []
2.98 +
2.99 + # Flags.
2.100 +
2.101 + all = False
2.102 + fragment = False
2.103 + macros = False
2.104 + tree = False
2.105 +
2.106 + for arg in args:
2.107 +
2.108 + # Detect tree output.
2.109 +
2.110 + if arg == "--tree":
2.111 + tree = True
2.112 +
2.113 + # Detect macro evaluation.
2.114 +
2.115 + elif arg == "--macros":
2.116 + macros = True
2.117 +
2.118 + # Detect all documents.
2.119 +
2.120 + elif arg == "--all":
2.121 + all = True
2.122 +
2.123 + # Detect fragment output (if serialising).
2.124 +
2.125 + elif arg == "--fragment":
2.126 + fragment = True
2.127 +
2.128 + # Switch to collecting formats.
2.129 +
2.130 + elif arg == "--format":
2.131 + l = formats
2.132 + continue
2.133 +
2.134 + # Switch to collecting input locations.
2.135 +
2.136 + elif arg == "--input-dir":
2.137 + l = input_dirs
2.138 + continue
2.139 +
2.140 + # Switch to collecting input context types.
2.141 +
2.142 + elif arg == "--input-dir-type":
2.143 + l = input_dir_types
2.144 + continue
2.145 +
2.146 + # Switch to collecting input encodings.
2.147 +
2.148 + elif arg == "--input-encoding":
2.149 + l = input_encodings
2.150 + continue
2.151 +
2.152 + # Switch to collecting input page hierarchy separators.
2.153 +
2.154 + elif arg == "--input-page-sep":
2.155 + l = input_page_seps
2.156 + continue
2.157 +
2.158 + # Switch to collecting mappings.
2.159 +
2.160 + elif arg == "--mapping":
2.161 + l = mappings
2.162 + continue
2.163 +
2.164 + # Switch to collecting output locations.
2.165 +
2.166 + elif arg == "--output-dir":
2.167 + l = output_dirs
2.168 + continue
2.169 +
2.170 + # Switch to collecting output encodings.
2.171 +
2.172 + elif arg == "--output-encoding":
2.173 + l = output_encodings
2.174 + continue
2.175 +
2.176 + # Switch to collecting page names.
2.177 +
2.178 + elif arg == "--pagename":
2.179 + l = pagenames
2.180 + continue
2.181 +
2.182 + # Switch to collecting root page names.
2.183 +
2.184 + elif arg == "--root":
2.185 + l = root_pagenames
2.186 + continue
2.187 +
2.188 + # Switch to collecting theme names.
2.189 +
2.190 + elif arg == "--theme":
2.191 + l = theme_names
2.192 + continue
2.193 +
2.194 + # Collect options and arguments.
2.195 +
2.196 + else:
2.197 + l.append(arg)
2.198 +
2.199 + # Collect multiple mappings.
2.200 +
2.201 + if l is mappings:
2.202 + continue
2.203 +
2.204 + # Collect filenames normally.
2.205 +
2.206 + l = filenames
2.207 +
2.208 + format = formats and formats[0] or "html"
2.209 + input_dir = getvalue(input_dirs)
2.210 + output_dir = getvalue(output_dirs)
2.211 +
2.212 + # Define metadata.
2.213 +
2.214 + metadata = Metadata({
2.215 + "input_context" : input_dir and \
2.216 + getvalue(input_dir_types, "directory") or \
2.217 + "standalone",
2.218 + "input_encoding" : getvalue(input_encodings),
2.219 + "input_filename" : input_dir,
2.220 + "input_separator" : getvalue(input_page_seps),
2.221 + "link_format" : format,
2.222 + "mapping" : getmapping(mappings),
2.223 + "output_context" : output_dir and "directory" or "standalone",
2.224 + "output_encoding" : getvalue(output_encodings),
2.225 + "output_format" : format,
2.226 + "output_filename" : output_dir,
2.227 + "root_pagename" : getvalue(root_pagenames, "FrontPage"),
2.228 + "theme_name" : not fragment and \
2.229 + "%s.%s" % (getvalue(theme_names, "default"), format) or None,
2.230 + })
2.231 +
2.232 + # Define the input context and theme.
2.233 +
2.234 + input = metadata.get_input()
2.235 + theme = metadata.get_theme()
2.236 +
2.237 + # Treat filenames as pagenames if an input directory is indicated and if no
2.238 + # pagenames are explicitly specified.
2.239 +
2.240 + if input_dir:
2.241 + if pagenames:
2.242 + print >>sys.stderr, message_explicit_pagenames
2.243 + sys.exit(1)
2.244 +
2.245 + if all:
2.246 + if filenames:
2.247 + print >>sys.stderr, message_all_with_filenames
2.248 + sys.exit(1)
2.249 + else:
2.250 + filenames = input.all()
2.251 +
2.252 + pagenames = filenames
2.253 + filenames = []
2.254 +
2.255 + # Open each file or page, parse the content, serialise the document.
2.256 +
2.257 + for pagename, filename in map(None, pagenames, filenames):
2.258 +
2.259 + # Define a pagename if missing.
2.260 +
2.261 + pagename = pagename or split(filename)[-1]
2.262 + metadata.set("pagename", pagename)
2.263 +
2.264 + # Read either from a filename or using a pagename.
2.265 +
2.266 + if filename:
2.267 + pagetext = input.readfile(filename)
2.268 + else:
2.269 + pagetext = input.readpage(pagename)
2.270 +
2.271 + # Parse the page content.
2.272 +
2.273 + p = make_parser(metadata)
2.274 + d = parse(pagetext, p)
2.275 +
2.276 + if macros:
2.277 + p.evaluate_macros()
2.278 +
2.279 + # Show a document tree for debugging purposes, if requested.
2.280 +
2.281 + if tree:
2.282 + print d.prettyprint()
2.283 + continue
2.284 +
2.285 + # Otherwise, serialise the document.
2.286 +
2.287 + # Obtain a serialiser using the configuration.
2.288 +
2.289 + serialiser = make_serialiser(metadata)
2.290 + outtext = serialise(d, serialiser)
2.291 +
2.292 + # With a theme, apply it to the text.
2.293 +
2.294 + if theme:
2.295 + outtext = theme.apply(outtext)
2.296 +
2.297 + # If reading from a file, show the result. Otherwise, write to the
2.298 + # output context.
2.299 +
2.300 + output = metadata.get_output()
2.301 +
2.302 + if not output.can_write():
2.303 + print outtext
2.304 + else:
2.305 + output.writepage(outtext, pagename)
2.306 + print >>sys.stderr, pagename
2.307 +
2.308 + # Install any theme resources.
2.309 +
2.310 + if theme:
2.311 + theme.install_resources()
2.312 +
2.313 +if __name__ == "__main__":
2.314 + main()
2.315 +
2.316 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/moinformat/parsers/common.py Sun Nov 25 16:59:19 2018 +0100
3.2 +++ b/moinformat/parsers/common.py Mon Nov 26 22:59:52 2018 +0100
3.3 @@ -390,11 +390,9 @@
3.4
3.5 region = Region([], level, indent, type)
3.6
3.7 - # Parse section headers and directives, then parse according to region
3.8 - # type.
3.9 + # Parse section headers, then parse according to region type.
3.10
3.11 self.parse_region_header(region)
3.12 - self.parse_region_directives(region)
3.13 self.parse_region_type(region)
3.14
3.15 return region
3.16 @@ -411,6 +409,12 @@
3.17 if not parser:
3.18 region.transparent = False
3.19 parser = parser or self.get_parser("moin")
3.20 +
3.21 + # Only parse directives if the region is transparent.
3.22 +
3.23 + if region.transparent:
3.24 + self.parse_region_directives(region)
3.25 +
3.26 parser.parse_region_content(self.items, region)
3.27
3.28 def parse_region_header(self, region):
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/moinformat/themes/default/css/all.css Mon Nov 26 22:59:52 2018 +0100
4.3 @@ -0,0 +1,9 @@
4.4 +table {
4.5 + border-collapse: collapse;
4.6 + margin: 0.5em 0 0.5em 0;
4.7 +}
4.8 +
4.9 +table td {
4.10 + border: 1px solid #000;
4.11 + padding: 0.5em;
4.12 +}
5.1 --- a/moinformat/themes/default/css/common.css Sun Nov 25 16:59:19 2018 +0100
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,9 +0,0 @@
5.4 -table {
5.5 - border-collapse: collapse;
5.6 - margin: 0.5em 0 0.5em 0;
5.7 -}
5.8 -
5.9 -table td {
5.10 - border: 1px solid #000;
5.11 - padding: 0.5em;
5.12 -}
6.1 --- a/moinformat/themes/default/html.py Sun Nov 25 16:59:19 2018 +0100
6.2 +++ b/moinformat/themes/default/html.py Mon Nov 26 22:59:52 2018 +0100
6.3 @@ -19,34 +19,15 @@
6.4 this program. If not, see <http://www.gnu.org/licenses/>.
6.5 """
6.6
6.7 -from moinformat.themes.common import Theme
6.8 +from moinformat.themes.html import HTMLTheme
6.9
6.10 -class DefaultHTMLTheme(Theme):
6.11 +class DefaultHTMLTheme(HTMLTheme):
6.12
6.13 - "A default theme."
6.14 + "A default HTML theme."
6.15
6.16 name = "html"
6.17 origin = __file__
6.18
6.19 - def apply(self, text):
6.20 -
6.21 - "Apply this theme to the given 'text', returning a themed version."
6.22 -
6.23 - template = self.load_resource("template.html")
6.24 - subs = {
6.25 - "encoding" : self.output.encoding,
6.26 - "root" : self.linker.get_top_level() or ".",
6.27 - "text" : text,
6.28 - "title" : self.metadata.get("pagename"),
6.29 - }
6.30 - return template % subs
6.31 -
6.32 - def install_resources(self):
6.33 -
6.34 - "Install resources for this theme."
6.35 -
6.36 - self.install_resource("css", "_css")
6.37 -
6.38 theme = DefaultHTMLTheme
6.39
6.40 # vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/moinformat/themes/default/template.html Sun Nov 25 16:59:19 2018 +0100
7.2 +++ b/moinformat/themes/default/template.html Mon Nov 26 22:59:52 2018 +0100
7.3 @@ -2,7 +2,7 @@
7.4 <html>
7.5 <head>
7.6 <title>%(title)s</title>
7.7 -<link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="%(root)s/_css/common.css" />
7.8 +%(links)s
7.9 <meta http-equiv="Content-Type" content="text/html;charset=%(encoding)s" />
7.10 </head>
7.11 <body>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/moinformat/themes/html.py Mon Nov 26 22:59:52 2018 +0100
8.3 @@ -0,0 +1,85 @@
8.4 +#!/usr/bin/env python
8.5 +
8.6 +"""
8.7 +Common HTML theme functionality.
8.8 +
8.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
8.10 +
8.11 +This program is free software; you can redistribute it and/or modify it under
8.12 +the terms of the GNU General Public License as published by the Free Software
8.13 +Foundation; either version 3 of the License, or (at your option) any later
8.14 +version.
8.15 +
8.16 +This program is distributed in the hope that it will be useful, but WITHOUT
8.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8.19 +details.
8.20 +
8.21 +You should have received a copy of the GNU General Public License along with
8.22 +this program. If not, see <http://www.gnu.org/licenses/>.
8.23 +"""
8.24 +
8.25 +from moinformat.themes.common import Theme
8.26 +from os import listdir
8.27 +from os.path import splitext
8.28 +
8.29 +class HTMLTheme(Theme):
8.30 +
8.31 + "A common HTML theme abstraction."
8.32 +
8.33 + # Support a collection of links to stylesheets provided by each theme.
8.34 +
8.35 + link = '<link rel="stylesheet" type="text/css" charset="utf-8" media="%(media)s" href="%(root)s/_css/%(filename)s" />\n'
8.36 +
8.37 + def get_links(self, subs):
8.38 +
8.39 + "Using 'subs', return a string containing markup linking to resources."
8.40 +
8.41 + d = {}
8.42 + d.update(subs)
8.43 +
8.44 + links = []
8.45 +
8.46 + for filename in listdir(self.get_resource("css")):
8.47 +
8.48 + # Only link to CSS files.
8.49 +
8.50 + basename, ext = splitext(filename)
8.51 + if ext != ".css":
8.52 + continue
8.53 +
8.54 + # Filenames can have the form <media>.css or <media>-<name>.css to
8.55 + # set the media type.
8.56 +
8.57 + t = basename.split("-", 1)
8.58 +
8.59 + d["media"] = t[0] or "all"
8.60 + d["filename"] = filename
8.61 +
8.62 + links.append(self.link % d)
8.63 +
8.64 + return "".join(links)
8.65 +
8.66 + # Public methods.
8.67 +
8.68 + def apply(self, text):
8.69 +
8.70 + "Apply this theme to the given 'text', returning a themed version."
8.71 +
8.72 + template = self.load_resource("template.html")
8.73 + subs = {
8.74 + "encoding" : self.output.encoding,
8.75 + "root" : self.linker.get_top_level() or ".",
8.76 + "text" : text,
8.77 + "title" : self.metadata.get("pagename"),
8.78 + }
8.79 + subs["links"] = self.get_links(subs)
8.80 + return template % subs
8.81 +
8.82 + def install_resources(self):
8.83 +
8.84 + "Install resources for this theme."
8.85 +
8.86 + self.install_resource("css", "_css")
8.87 +
8.88 +# vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/moinformat/themes/manifest.py Sun Nov 25 16:59:19 2018 +0100
9.2 +++ b/moinformat/themes/manifest.py Mon Nov 26 22:59:52 2018 +0100
9.3 @@ -21,10 +21,18 @@
9.4
9.5 from moinformat.imports import get_extensions, get_mapping, get_modules
9.6
9.7 +ignore = ["html"]
9.8 +
9.9 # Define an attribute mapping names to modules.
9.10
9.11 modules = get_modules(__file__, __name__)
9.12
9.13 +# Filter out modules in this package that provide common functionality.
9.14 +
9.15 +for m in ignore:
9.16 + if modules.has_key(m):
9.17 + del modules[m]
9.18 +
9.19 # Obtain all themes.
9.20
9.21 # Use module paths to register the contexts:
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/moinformat/themes/mercurial/__init__.py Mon Nov 26 22:59:52 2018 +0100
10.3 @@ -0,0 +1,22 @@
10.4 +#!/usr/bin/env python
10.5 +
10.6 +"""
10.7 +A Mercurial-inspired theme.
10.8 +
10.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
10.10 +
10.11 +This program is free software; you can redistribute it and/or modify it under
10.12 +the terms of the GNU General Public License as published by the Free Software
10.13 +Foundation; either version 3 of the License, or (at your option) any later
10.14 +version.
10.15 +
10.16 +This program is distributed in the hope that it will be useful, but WITHOUT
10.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.19 +details.
10.20 +
10.21 +You should have received a copy of the GNU General Public License along with
10.22 +this program. If not, see <http://www.gnu.org/licenses/>.
10.23 +"""
10.24 +
10.25 +# vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/moinformat/themes/mercurial/css/print.css Mon Nov 26 22:59:52 2018 +0100
12.3 @@ -0,0 +1,13 @@
12.4 +html {
12.5 + font-family: Times, serif;
12.6 + font-size: 12pt;
12.7 +}
12.8 +
12.9 +body {
12.10 + margin: 1.5cm;
12.11 +}
12.12 +
12.13 +a, a:visited {
12.14 + color: black;
12.15 + text-decoration: none;
12.16 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/moinformat/themes/mercurial/css/screen.css Mon Nov 26 22:59:52 2018 +0100
13.3 @@ -0,0 +1,12 @@
13.4 +body {
13.5 + font-family: Helvetica, Verdana, Arial, sans-serif;
13.6 + color: #111;
13.7 +}
13.8 +
13.9 +a:link, a:visited { color: #00b5f1; text-decoration: none; }
13.10 +a:link:hover, a:link:active, a:link:focus,
13.11 +a:visited:hover, a:visited:active, a:visited:focus { text-decoration: underline; }
13.12 +
13.13 +h1 { font-size: 2em; }
13.14 +h2 { font-size: 1.6em; }
13.15 +h3 { font-size: 1.3em; }
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/moinformat/themes/mercurial/html.py Mon Nov 26 22:59:52 2018 +0100
14.3 @@ -0,0 +1,33 @@
14.4 +#!/usr/bin/env python
14.5 +
14.6 +"""
14.7 +A Mercurial-inspired theme for HTML output.
14.8 +
14.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
14.10 +
14.11 +This program is free software; you can redistribute it and/or modify it under
14.12 +the terms of the GNU General Public License as published by the Free Software
14.13 +Foundation; either version 3 of the License, or (at your option) any later
14.14 +version.
14.15 +
14.16 +This program is distributed in the hope that it will be useful, but WITHOUT
14.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14.19 +details.
14.20 +
14.21 +You should have received a copy of the GNU General Public License along with
14.22 +this program. If not, see <http://www.gnu.org/licenses/>.
14.23 +"""
14.24 +
14.25 +from moinformat.themes.html import HTMLTheme
14.26 +
14.27 +class MercurialHTMLTheme(HTMLTheme):
14.28 +
14.29 + "A Mercurial-inspired HTML theme."
14.30 +
14.31 + name = "html"
14.32 + origin = __file__
14.33 +
14.34 +theme = MercurialHTMLTheme
14.35 +
14.36 +# vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/moinformat/themes/mercurial/template.html Mon Nov 26 22:59:52 2018 +0100
15.3 @@ -0,0 +1,11 @@
15.4 +<!DOCTYPE html>
15.5 +<html>
15.6 +<head>
15.7 +<title>%(title)s</title>
15.8 +%(links)s
15.9 +<meta http-equiv="Content-Type" content="text/html;charset=%(encoding)s" />
15.10 +</head>
15.11 +<body>
15.12 +%(text)s
15.13 +</body>
15.14 +</html>