# HG changeset patch # User Paul Boddie # Date 1533485616 -7200 # Node ID 6bc36ce901802510a0dd406ab53ae7bca13e0aee # Parent df6611ecc1a5ebbcf1c9e5f4284cf03ffc714428 Added serialisation methods to the output contexts, with the directory context supporting parent pages as "index" documents within appropriately-named directories, with pages normally being represented by appropriately-named files until subpages of such pages are encountered. diff -r df6611ecc1a5 -r 6bc36ce90180 moinformat/output/common.py --- a/moinformat/output/common.py Sun Aug 05 18:07:02 2018 +0200 +++ b/moinformat/output/common.py Sun Aug 05 18:13:36 2018 +0200 @@ -19,6 +19,8 @@ this program. If not, see . """ +import codecs + class Output: "A common output context abstraction." @@ -48,12 +50,57 @@ self.output.append(self.encode(text)) + # Serialisation methods. + def to_string(self): "Return the output as a plain string." return "".join(self.output) + # Serialisation methods. + + def can_write(self): + + "Return whether this context supports page writing." + + return False + + def writefile(self, text, filename, encoding=None): + + """ + Write 'text' to the file having the given 'filename'. If the + optional 'encoding' is specified, override the general encoding. + + Subclasses need to override this method for it to have an effect. + """ + + pass + + def writepage(self, text, pagename, encoding=None): + + """ + Write 'text' to the file having the given 'pagename' and optional + 'encoding'. + """ + + return self.writefile(text, self.to_filename(pagename), encoding) + + # Output methods. + + def writepath(self, text, filename, encoding=None): + + """ + Write 'text' to the file having the given 'filename'. If the + optional 'encoding' is specified, override the general encoding. + """ + + f = codecs.open(filename, "w", encoding=encoding or self.encoding) + try: + f.write(text) + finally: + f.close() + def encode(s, encoding): "Encode 's' using 'encoding' if Unicode." diff -r df6611ecc1a5 -r 6bc36ce90180 moinformat/output/directory.py --- a/moinformat/output/directory.py Sun Aug 05 18:07:02 2018 +0200 +++ b/moinformat/output/directory.py Sun Aug 05 18:13:36 2018 +0200 @@ -21,6 +21,8 @@ from moinformat.output.common import Output from moinformat.utils.directory import Directory +from os import makedirs, rename +from os.path import exists, isdir, isfile, join, split class DirectoryOutput(Output, Directory): @@ -38,6 +40,85 @@ Output.__init__(self, parameters) Directory.__init__(self, parameters["filename"]) + if not exists(self.filename): + makedirs(self.filename) + + self.index_name = parameters and parameters.get("index_name") or "index" + + # Name translation methods. + + def to_filename(self, pagename): + + "Return the filename corresponding to 'pagename'." + + return pagename + + def to_pagename(self, filename): + + "Return the pagename corresponding to 'filename'." + + # Take the leafname as the pagename from an arbitrary filename. + + return split(filename)[-1] + + # Serialisation methods. + + def can_write(self): + + "Return whether this context supports page writing." + + return True + + def writefile(self, text, filename, encoding=None): + + """ + Write 'text' to the file having the given 'filename'. If the + optional 'encoding' is specified, override the general encoding. + """ + + return self.writepath(text, self.get_filename(filename), encoding) + + def writepage(self, text, pagename, encoding=None): + + """ + Write 'text' to the file having the given 'pagename' and optional + 'encoding'. If 'parent' is specified and a true value, it indicates that + the page is a parent of other pages. + """ + + filename = self.to_filename(pagename) + parent = split(filename)[0] + + # The page may have a parent. + + if parent and parent != filename: + dirpath = self.get_filename(parent) + + # Relocate any file for the parent to an index file within a page + # directory. + + if isfile(dirpath): + parent_tmp = "%s.tmp" % dirpath + rename(dirpath, parent_tmp) + makedirs(dirpath) + rename(parent_tmp, join(dirpath, self.index_name)) + + # Or make a directory for the parent. + + elif not exists(dirpath): + makedirs(dirpath) + + # Obtain a complete filename for the content. + + pathname = self.get_filename(filename) + + # Write to an index filename within any existing directory. + + if isdir(pathname): + pathname = join(pathname, self.index_name) + + self.writefile(text, pathname, encoding) + output = DirectoryOutput # vim: tabstop=4 expandtab shiftwidth=4