# HG changeset patch # User Paul Boddie # Date 1533563416 -7200 # Node ID 3dd281615999714ff221d077e76a7709f1784efa # Parent a20caaa18295b842392f6d02a7984deca86db9dd Changed the output directory layout to use page directories for every page and to store page content in index documents within those directories, also supporting attachments in a subdirectory of each page directory. Updated the Graphviz serialiser to employ page attachments. Updated the HTML linker to work with the revised output layout. diff -r a20caaa18295 -r 3dd281615999 convert.py --- a/convert.py Mon Aug 06 15:45:11 2018 +0200 +++ b/convert.py Mon Aug 06 15:50:16 2018 +0200 @@ -220,7 +220,7 @@ # Obtain a serialiser using the configuration. - serialiser = make_serialiser(format, output, linker) + serialiser = make_serialiser(format, output, linker, pagename) outtext = serialise(d, serialiser) # If reading from a file, show the result. Otherwise, write to the diff -r a20caaa18295 -r 3dd281615999 moinformat/links/html.py --- a/moinformat/links/html.py Mon Aug 06 15:45:11 2018 +0200 +++ b/moinformat/links/html.py Mon Aug 06 15:50:16 2018 +0200 @@ -124,8 +124,7 @@ "Return a translation of the given attachment 'target'." - return self.quote("%sattachments/%s/%s" % ( - self.get_top_level(), self.pagename, target)) + return self.quote("./attachments/%s" % target) def translate_interwiki(self, url, target): @@ -137,7 +136,7 @@ "Return a translation of the given relative 'target'." - return self.quote(target[len("../"):]) + return self.quote(target) def translate_subpage(self, target): diff -r a20caaa18295 -r 3dd281615999 moinformat/output/directory.py --- a/moinformat/output/directory.py Mon Aug 06 15:45:11 2018 +0200 +++ b/moinformat/output/directory.py Mon Aug 06 15:50:16 2018 +0200 @@ -21,7 +21,7 @@ from moinformat.output.common import Output from moinformat.utils.directory import Directory -from os.path import extsep, join, split, splitext +from os.path import extsep, join class DirectoryOutput(Output): @@ -42,9 +42,40 @@ self.index_name = self.parameters.get("index_name") or "index.html" self.page_suffix = self.parameters.get("page_suffix") or "%shtml" % extsep + self.root_pagename = self.parameters.get("root_pagename") or "FrontPage" # Convenience methods. + def ensure(self, pagename): + + "Ensure that the given 'pagename' exists." + + if not pagename: + return None + + self.dir.ensure(self.to_filename(pagename)) + + def ensure_attachments(self, pagename): + + "Ensure that attachment storage for the given 'pagename' exists." + + if not pagename: + return None + + self.dir.ensure(join(self.to_filename(pagename), "attachments")) + + def get_attachment_filename(self, pagename, filename): + + """ + Return the full path of an attachment file for the given 'pagename' + having the given 'filename'. + """ + + if not pagename: + return None + + return self.dir.get_filename(join(self.to_filename(pagename), "attachments", filename)) + def get_filename(self, filename): """ @@ -60,22 +91,18 @@ "Return the filename corresponding to 'pagename'." - return "%s%s" % (pagename, self.page_suffix) + # For the root page, use the top-level directory. + + if pagename == self.root_pagename: + return "" + else: + return pagename def to_pagename(self, filename): "Return the pagename corresponding to 'filename'." - # Take the leafname as the pagename from an arbitrary filename, removing - # any file extension. - - return splitext(split(filename)[-1])[0] - - def to_parent_filename(self, pagename): - - "Return the parent page filename corresponding to 'pagename'." - - return pagename + return self.within(filename) # Serialisation methods. @@ -102,39 +129,16 @@ the page is a parent of other pages. """ - dir = self.dir - parent = self.parent(pagename) - - # The page may have a parent. - - if parent: - parentfile = self.to_filename(parent) - parentdir = self.to_parent_filename(parent) - - # Relocate any file for the parent to an index file within a page - # directory. + filename = self.to_filename(pagename) - if dir.isfile(parentfile): - parent_tmp = "%s.tmp" % parentfile - dir.rename(parentfile, parent_tmp) - if not dir.exists(parentdir): - dir.makedirs(parentdir) - dir.rename(parent_tmp, join(parentdir, self.index_name)) + # Make a directory for the page. - # Or make a directory for the parent. - - elif not dir.exists(parentdir): - dir.makedirs(parentdir) + if not self.dir.exists(filename): + self.dir.makedirs(filename) # Write to an index filename within any existing directory. - dirname = self.to_parent_filename(pagename) - - if dir.isdir(dirname): - filename = join(dirname, self.index_name) - else: - filename = self.to_filename(pagename) - + filename = join(filename, self.index_name) self.writefile(text, filename, encoding) output = DirectoryOutput diff -r a20caaa18295 -r 3dd281615999 moinformat/output/standalone.py --- a/moinformat/output/standalone.py Mon Aug 06 15:45:11 2018 +0200 +++ b/moinformat/output/standalone.py Mon Aug 06 15:50:16 2018 +0200 @@ -27,6 +27,29 @@ name = "standalone" + # Convenience methods. + + def ensure(self, pagename): + + "Ensure that the given 'pagename' exists." + + pass + + def ensure_attachments(self, pagename): + + "Ensure that attachment storage for the given 'pagename' exists." + + pass + + def get_attachment_filename(self, pagename, filename): + + """ + Prevent independent output by returning a filename of None corresponding + to the given 'pagename' and any specified 'filename'. + """ + + return None + def get_filename(self, filename): """ diff -r a20caaa18295 -r 3dd281615999 moinformat/serialisers/html/graphviz.py --- a/moinformat/serialisers/html/graphviz.py Mon Aug 06 15:45:11 2018 +0200 +++ b/moinformat/serialisers/html/graphviz.py Mon Aug 06 15:50:16 2018 +0200 @@ -69,17 +69,17 @@ # Special methods for graph production. - def _tag(self, tagname, attrname, filename, attributes, closing): - l = ["%s='%s'" % (attrname, escape_attr(filename))] + def _tag(self, tagname, attrname, target, attributes, closing): + l = ["%s='%s'" % (attrname, escape_attr(target))] for key, value in attributes.items(): l.append("%s='%s'" % (key, value)) self.out("<%s %s%s>" % (tagname, " ".join(l), closing and " /")) - def image(self, filename, attributes): - self._tag("img", "src", filename, attributes, True) + def image(self, target, attributes): + self._tag("img", "src", target, attributes, True) - def object(self, filename, attributes): - self._tag("object", "data", filename, attributes, False) + def object(self, target, attributes): + self._tag("object", "data", target, attributes, False) self.out("") def raw(self, text): @@ -97,16 +97,27 @@ format = self.directives.get("format", ["svg"])[0] transforms = self.directives.get("transform", []) + # Graph output is stored for a known page only. + + if not self.pagename: + return + # Get an identifier and usable filename to store the output. - identifier = "%s.%s" % (get_output_identifier(text), format) - filename = self.output.get_filename(identifier) + identifier = get_output_identifier(text) + attachment = "%s.%s" % (identifier, format) + filename = self.output.get_attachment_filename(self.pagename, attachment) # Handle situations where no independent output is permitted. if not filename: return + # Make sure that page attachments can be stored. + + self.output.ensure_attachments(self.pagename) + target, label = self.linker.translate("attachment:%s" % attachment) + # Permit imagemaps only for image formats. if format in IMAGE_FORMATS: @@ -135,12 +146,12 @@ self.raw(graphviz.get_output()) attributes["usemap"] = "#%s" % im_attributes["id"] - self.image(identifier, attributes) + self.image(target, attributes) # For other output, create a file and embed the object. else: - self.object(identifier, attributes) + self.object(target, attributes) serialiser = HTMLGraphvizSerialiser