[Happydoc-checkins] CVS: HappyDoc3/happydoclib/docset base.py,1.9,1.10
Brought to you by:
doughellmann,
krlosaqp
From: Doug H. <dou...@us...> - 2002-12-27 18:35:59
|
Update of /cvsroot/happydoc/HappyDoc3/happydoclib/docset In directory sc8-pr-cvs1:/tmp/cvs-serv19277/happydoclib/docset Modified Files: base.py Log Message: Refactoring and docstrings to make the various API levels a bit more clear. Work may still need to be done on this. Index: base.py =================================================================== RCS file: /cvsroot/happydoc/HappyDoc3/happydoclib/docset/base.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** base.py 15 Dec 2002 17:02:14 -0000 1.9 --- base.py 27 Dec 2002 18:35:55 -0000 1.10 *************** *** 26,30 **** # ! """Base class for documentation sets. """ --- 26,30 ---- # ! """Base classes for documentation sets. """ *************** *** 56,59 **** --- 56,60 ---- # import os + import shutil # *************** *** 69,76 **** # ! class DocSet: """Basic Documentation Set. Parameters --- 70,155 ---- # + class DocSetBase: + """Base class for documentation sets. ! This is the base class for all documentation set classes. The ! methods defined here are required of all docset classes. Only the ! 'write' method is actually used by the main application. ! """ ! ! def __init__(self, scanner, ! title, ! outputDirectory, ! statusMessageFunc=None, ! extraParameters={}, ! ): ! """Basic Documentation Set ! ! Parameters ! ! scanner -- A directory tree scanner. ! ! title -- the title of the documentation set ! ! outputDirectory -- The base directory for writing the ! output files. ! ! statusMessageFunc -- function which will print a status ! message for the user ! ! extraParameters -- Dictionary containing parameters ! specified on the command line by ! the user. ! ! """ ! trace.into('DocSetBase', '__init__', ! scanner=scanner, ! title=title, ! outputDirectory=outputDirectory, ! statusMessageFunc=statusMessageFunc, ! extraParameters=extraParameters, ! ) ! # ! # Store parameters ! # ! self.scanner = scanner ! self.title = title ! self.output_directory = outputDirectory ! self.status_message_func = statusMessageFunc ! ! self.statusMessage('Initializing documentation set %s' % title) ! ! self.statusMessage('NEED TO HANDLE extraParameters in DocSetBase') ! ! trace.outof() ! return ! ! def statusMessage(self, message='', verboseLevel=1): ! "Print a status message for the user." ! if self.status_message_func: ! self.status_message_func(message, verboseLevel) ! return ! ! def write(self): ! """Called by the application to cause the docset to be written. ! """ ! raise NotImplementedError('%s.write' % self.__class__.__name__) ! ! ! ! ! ! class DocSet(DocSetBase): """Basic Documentation Set. + This class extends the DocSetBase with a few more convenience + methods. Most docsets will actually subclass from DocSet or one + of its descendants rather than from DocSet directly. + + The basic extension is that this class provides a 'write' method + which walks the scanner tree, determines the appropriate writer + method for each node, and calls the writer. Subclasses need only + provide writers and + Parameters *************** *** 84,87 **** --- 163,173 ---- """ + # + # Override this with a mapping from mime-type to the + # method name to be called to handle writing a node + # of that type. + # + mimetype_writer_mapping = {} + def __init__(self, scanner, title, *************** *** 119,123 **** """ ! trace.into('DocSet', '__init__', scanner=scanner, title=title, --- 205,209 ---- """ ! trace.into('DocSetBase', '__init__', scanner=scanner, title=title, *************** *** 125,180 **** includeComments=includeComments, includePrivateNames=includePrivateNames, - ## formatter=formatter, statusMessageFunc=statusMessageFunc, extraParameters=extraParameters, ) # # Store parameters # - self.scanner = scanner - self.title = title - self.output_directory = outputDirectory self.include_comments = includeComments self.include_private_names = includePrivateNames - ## self.formatter = formatter - self.status_message_func = statusMessageFunc - - self.statusMessage('Initializing documentation set %s' % title) - - self.statusMessage('NEED TO HANDLE extraParameters in DocSet') trace.outof() return ! def statusMessage(self, message='', verboseLevel=1): ! "Print a status message for the user." ! if self.status_message_func: ! self.status_message_func(message, verboseLevel) return - def writeCB(self, packageTreeNode): ! raise NotImplementedError('No writeCB defined for %s' % self.__class__.__name__) def write(self): self.scanner.walk(self.writeCB) return class MultiFileDocSet(DocSet): """Base class for documentation sets which write to multiple files. - """ ! mimetype_writer_mapping = { ! 'application/x-directory' : 'writeDirectory', ! 'text/x-python' : 'writePythonFile', ! 'text/plain' : 'writePlainTextFile', ! 'text/x-structured' : 'writePlainTextFile', ! 'text/html' : 'copyInputFileToOutput', ! 'image/gif' : 'copyInputFileToOutput', ! 'image/jpeg' : 'copyInputFileToOutput', ! 'image/png' : 'copyInputFileToOutput', ! } mimetype_extension_mapping = { --- 211,305 ---- includeComments=includeComments, includePrivateNames=includePrivateNames, statusMessageFunc=statusMessageFunc, extraParameters=extraParameters, ) + DocSetBase.__init__( + self, + scanner=scanner, + title=title, + outputDirectory=outputDirectory, + statusMessageFunc=statusMessageFunc, + extraParameters=extraParameters, + ) # # Store parameters # self.include_comments = includeComments self.include_private_names = includePrivateNames + self._initializeWriters() + trace.outof() return ! def _skipInputFile(self, packageTreeNode): ! """False writer method used to notify the user that a node is being ! skipped because the real writer is unknown. ! """ ! mimetype, encoding = packageTreeNode.getMimeType() ! filename = packageTreeNode.getInputFilename() ! self.statusMessage('Skiping unrecognized file %s with mimetype %s' % ( ! filename, ! mimetype, ! )) return + def getWriterForNode(self, packageTreeNode): + """Returns the writer to be used for the node. + """ + mimetype, encoding = packageTreeNode.getMimeType() + + writer_name = self.mimetype_writer_mapping.get(mimetype) + if writer_name: + writer = getattr(self, writer_name) + + else: + # + # Unrecognized file. + # + writer = self._skipInputFile + + return writer + def writeCB(self, packageTreeNode): ! """Callback used when walking the scanned package tree. ! """ ! trace.into('MultiHTMLFileDocSet', 'writeCB', ! packageTreeNode=packageTreeNode, ! ) ! ! writer = self.getWriterForNode(packageTreeNode) ! writer(packageTreeNode) ! trace.outof() ! return def write(self): + """Called by the application to cause the docset to be written. + """ self.scanner.walk(self.writeCB) return + def _initializeWriters(self): + """Hook to allow subclasses to register writers without having to + override __init__ with all of its arguments. + """ + return + + def registerWriter(self, mimetype, writerName): + """Register a writer for the specified mimetype. + """ + self.mimetype_writer_mapping[mimetype] = writerName + return + class MultiFileDocSet(DocSet): """Base class for documentation sets which write to multiple files. ! This class further extends the DocSet class by adding several ! convenience methods for handling files, as well as a few basic ! handlers. ! ! """ mimetype_extension_mapping = { *************** *** 185,188 **** --- 310,334 ---- } + def _initializeWriters(self): + """Hook to allow subclasses to register writers without having to + override __init__ with all of its arguments. + """ + + DocSet._initializeWriters(self) + + mimetype_writers = [ + ('application/x-directory' , 'writeDirectory'), + ('text/x-python' , 'writePythonFile'), + ('text/plain' , 'writePlainTextFile'), + ('text/x-structured' , 'writePlainTextFile'), + ('text/html' , 'copyInputFileToOutput'), + ('image/gif' , 'copyInputFileToOutput'), + ('image/jpeg' , 'copyInputFileToOutput'), + ('image/png' , 'copyInputFileToOutput'), + ] + for mimetype, writer_name in mimetype_writers: + self.registerWriter(mimetype, writer_name) + return + def getOutputFilenameForPackageTreeNode(self, packageTreeNode, includePath=1): """Returns a filename where documentation for packageTreeNode should be written. *************** *** 238,241 **** --- 384,389 ---- def copyInputFileToOutput(self, packageTreeNode): + """Copy the input file to the appropriate place in the output. + """ input_filename = packageTreeNode.getInputFilename() output_filename = self.getOutputFilenameForPackageTreeNode(packageTreeNode) *************** *** 243,278 **** input_filename, output_filename, ! )) ! input_file = open(input_filename, 'rb') ! output_file = open(output_filename, 'wb') ! output_file.write(input_file.read()) ! input_file.close() ! output_file.close() ! return ! ! def writeCB(self, packageTreeNode): ! trace.into('MultiHTMLFileDocSet', 'writeCB', ! packageTreeNode=packageTreeNode, ! ) ! ! mimetype, encoding = packageTreeNode.getMimeType() ! ! writer_name = self.mimetype_writer_mapping.get(mimetype) ! if writer_name: ! writer = getattr(self, writer_name) ! writer(packageTreeNode) ! ! else: ! # ! # Unrecognized file, skipped. ! # ! node_path = packageTreeNode.getPath() ! filename = apply(os.path.join, node_path) ! self.statusMessage('Skiping unrecognized file %s with mimetype %s' % ( ! filename, ! mimetype, ! )) ! ! trace.outof() return --- 391,396 ---- input_filename, output_filename, ! )) ! shutil.copyfile(input_filename, output_filename) return *************** *** 291,294 **** --- 409,417 ---- def writeDirectory(self, packageTreeNode): + """Handler for application/x-directory nodes. + + Creates the output directory and writes the table of contents + file. + """ trace.into('MultiFileDocSet', 'writeDirectory', packageTreeNode=packageTreeNode, *************** *** 317,329 **** def writeTOCFile(self, packageTreeNode): ! raise NotImplemented('writeTOCFile') def writeFileHeader(self, output, title='', subtitle=''): ! raise NotImplemented('writeFileHeader') def writeFileFooter(self, output): ! raise NotImplemented('writeFileFooter') def openOutput(self, name, title='', subtitle=''): f = open(name, 'wt') self.writeFileHeader(f, title=title, subtitle=subtitle) --- 440,472 ---- def writeTOCFile(self, packageTreeNode): ! """Write the table of contents for a directory. ! ! Subclasses must implement this method. ! ! The packageTreeNode is a directory, and the table of contents ! for that directory should be written as appropriate. ! """ ! raise NotImplementedError('writeTOCFile') def writeFileHeader(self, output, title='', subtitle=''): ! """Given an open output stream, write a header using the title and subtitle. ! ! Subclasses must implement this method. ! """ ! raise NotImplementedError('writeFileHeader') def writeFileFooter(self, output): ! """Given an open output stream, write a footer using the title and subtitle. ! ! Subclasses must implement this method. ! """ ! raise NotImplementedError('writeFileFooter') def openOutput(self, name, title='', subtitle=''): + """Open the output stream from the name. + + Opens the output stream and writes a header using title and + subtitle. Returns the stream. + """ f = open(name, 'wt') self.writeFileHeader(f, title=title, subtitle=subtitle) *************** *** 331,334 **** --- 474,481 ---- def closeOutput(self, output): + """Close the output stream. + + Writes a footer to the output stream and then closes it. + """ self.writeFileFooter(output) output.close() *************** *** 383,389 **** output.write(html) return ! def writePlainTextFile(self, packageTreeNode): trace.into('MultiFileDocSet', 'writePlainTextFile', packageTreeNode=packageTreeNode, --- 530,546 ---- output.write(html) return ! ! def writePythonFile(self, packageTreeNode): ! """Handler for text/x-python nodes. ! """ ! raise NotImplementedError('writePythonFile') def writePlainTextFile(self, packageTreeNode): + """Handler for text/x-structured and text/plain nodes. + + Converts the input file to the output file format and + generates the output. The output directory is assumed to + already exist. + """ trace.into('MultiFileDocSet', 'writePlainTextFile', packageTreeNode=packageTreeNode, *************** *** 406,409 **** --- 563,569 ---- raw_body = str(input_file) + # + # FIXME - This needs to be handled more abstractly! + # cooked_body = converter.convert(raw_body, 'html', level=3) |