DocumentationTools/QtHelpGenerator.py

changeset 0
de9c2efb9d02
child 13
1af94a91f439
diff -r 000000000000 -r de9c2efb9d02 DocumentationTools/QtHelpGenerator.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DocumentationTools/QtHelpGenerator.py	Mon Dec 28 16:03:33 2009 +0000
@@ -0,0 +1,258 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the QtHelp generator for the builtin documentation generator.
+"""
+
+import sys
+import os
+import shutil
+import codecs
+import subprocess
+
+from Utilities import joinext, relpath, html_encode
+
+HelpCollection = r"""<?xml version="1.0" encoding="utf-8" ?>
+<QHelpCollectionProject version="1.0">
+  <docFiles>
+    <register>
+      <file>%(helpfile)s</file>
+    </register>
+  </docFiles>
+</QHelpCollectionProject>
+"""
+
+HelpProject = r"""<?xml version="1.0" encoding="UTF-8"?>
+<QtHelpProject version="1.0">
+  <namespace>%(namespace)s</namespace>
+  <virtualFolder>%(folder)s</virtualFolder>
+  <customFilter name="%(filter_name)s">
+%(filter_attributes)s
+  </customFilter>
+  <filterSection>
+%(filter_attributes)s
+    <toc>
+%(sections)s
+    </toc>
+    <keywords>
+%(keywords)s
+    </keywords>
+    <files>
+%(files)s
+    </files>
+  </filterSection>
+</QtHelpProject>
+"""
+
+HelpProjectFile = 'source.qhp'
+HelpHelpFile = 'source.qch'
+HelpCollectionProjectFile = 'source.qhcp'
+HelpCollectionFile = 'collection.qhc'
+
+class QtHelpGenerator(object):
+    """
+    Class implementing the QtHelp generator for the builtin documentation generator.
+    """
+    def __init__(self, htmlDir, 
+                 outputDir, namespace, virtualFolder, filterName, filterAttributes, 
+                 title, createCollection):
+        """
+        Constructor
+        
+        @param htmlDir directory containing the HTML files (string)
+        @param outputDir output directory for the files (string)
+        @param namespace namespace to be used (string)
+        @param virtualFolder virtual folder to be used (string)
+        @param filterName name of the custom filter (string)
+        @param filterAttributes ':' separated list of filter attributes (string)
+        @param title title to be used for the generated help (string)
+        @param createCollection flag indicating the generation of the collection
+            files (boolean)
+        """
+        self.htmlDir = htmlDir
+        self.outputDir = outputDir
+        self.namespace = namespace
+        self.virtualFolder = virtualFolder
+        self.filterName = filterName
+        self.filterAttributes = filterAttributes and filterAttributes.split(':') or []
+        self.relPath = relpath(self.htmlDir, self.outputDir)
+        self.title = title
+        self.createCollection = createCollection
+        
+        self.packages = {
+            "00index" : {
+                "subpackages" : {},
+                "modules" : {}
+            }
+        }
+        self.remembered = False
+        self.keywords = []
+    
+    def remember(self, file, moduleDocument, basename=""):
+        """
+        Public method to remember a documentation file.
+        
+        @param file The filename to be remembered. (string)
+        @param moduleDocument The ModuleDocument object containing the 
+            information for the file.
+        @param basename The basename of the file hierarchy to be documented.
+            The basename is stripped off the filename if it starts with
+            the basename.
+        """
+        self.remembered = True
+        if basename:
+            file = file.replace(basename, "")
+        
+        if "__init__" in file:
+            dir = os.path.dirname(file)
+            udir = os.path.dirname(dir)
+            base = os.path.basename(dir)
+            if udir:
+                upackage = udir.replace(os.sep, ".")
+                try:
+                    elt = self.packages[upackage]
+                except KeyError:
+                    elt = self.packages["00index"]
+            else:
+                elt = self.packages["00index"]
+            package = dir.replace(os.sep, ".")
+            elt["subpackages"][package] = moduleDocument.name()
+            
+            self.packages[package] = {
+                "subpackages" : {},
+                "modules" : {}
+            }
+            
+            kwEntry = ("%s (Package)" % package.split('.')[-1], 
+                       joinext("index-%s" % package, ".html"))
+            if kwEntry not in self.keywords:
+                self.keywords.append(kwEntry)
+            
+            if moduleDocument.isEmpty():
+                return
+        
+        package = os.path.dirname(file).replace(os.sep, ".")
+        try:
+            elt = self.packages[package]
+        except KeyError:
+            elt = self.packages["00index"]
+        elt["modules"][moduleDocument.name()] = moduleDocument.name()
+        
+        if "__init__" not in file:
+            kwEntry = ("%s (Module)" % moduleDocument.name().split('.')[-1], 
+                       joinext(moduleDocument.name(), ".html"))
+            if kwEntry not in self.keywords:
+                self.keywords.append(kwEntry)
+        for kw in moduleDocument.getQtHelpKeywords():
+            kwEntry = (kw[0], "%s%s" % (joinext(moduleDocument.name(), ".html"), kw[1]))
+            if kwEntry not in self.keywords:
+                self.keywords.append(kwEntry)
+    
+    def __generateSections(self, package, level):
+        """
+        Private method to generate the sections part.
+        
+        @param package name of the package to process (string)
+        @param level indentation level (integer)
+        @return sections part (string)
+        """
+        indent = level * '  '
+        indent1 = indent + '  '
+        s  = indent + '<section title="%s" ref="%s">\n' % \
+            (package == "00index" and self.title or package, 
+             package == "00index" and \
+                joinext("index", ".html") or \
+                joinext("index-%s" % package, ".html"))
+        for subpack in sorted(self.packages[package]["subpackages"]):
+            s += self.__generateSections(subpack, level + 1)
+        for mod in sorted(self.packages[package]["modules"]):
+            s += indent1 + '<section title="%s" ref="%s" />\n' % \
+                (mod, joinext(mod, ".html"))
+        s += indent + '</section>\n'
+        return s
+    
+    def __generateKeywords(self):
+        """
+        Private method to generate the keywords section.
+        
+        @return keywords section (string)
+        """
+        indent = level * '  '
+        return "\n".join([])
+    
+    def generateFiles(self, basename = ""):
+        """
+        Public method to generate all index files.
+        
+        @param basename The basename of the file hierarchy to be documented.
+            The basename is stripped off the filename if it starts with
+            the basename.
+        """
+        if not self.remembered:
+            sys.stderr.write("No QtHelp to generate.\n")
+            return
+        
+        if basename:
+            basename = basename.replace(os.sep, ".")
+            if not basename.endswith("."):
+                basename = "%s." % basename
+        
+        sections = self.__generateSections("00index", 3)
+        filesList = sorted([e for e in os.listdir(self.htmlDir) if e.endswith('.html')])
+        files = "\n".join(["      <file>%s</file>" % f for f in filesList])
+        filterAttribs = "\n".join(["    <filterAttribute>%s</filterAttribute>" % a \
+                                  for a in self.filterAttributes])
+        keywords = "\n".join(
+            ['      <keyword name="%s" id="%s" ref="%s" />' % \
+             (html_encode(kw[0]), html_encode(kw[0]), html_encode(kw[1])) \
+             for kw in self.keywords])
+        
+        helpAttribs = {
+            "namespace" : self.namespace, 
+            "folder" : self.virtualFolder, 
+            "filter_name" : self.filterName, 
+            "filter_attributes" : filterAttribs, 
+            "sections" : sections, 
+            "keywords" : keywords, 
+            "files" : files, 
+        }
+        
+        f = codecs.open(os.path.join(self.outputDir, HelpProjectFile), 'w', 'utf-8')
+        f.write(HelpProject % helpAttribs)
+        f.close()
+        
+        if self.createCollection and \
+           not os.path.exists(os.path.join(self.outputDir, HelpCollectionProjectFile)):
+            collectionAttribs = {
+                "helpfile" : HelpHelpFile, 
+            }
+        
+            f = codecs.open(os.path.join(self.outputDir, HelpCollectionProjectFile), 
+                            'w', 'utf-8')
+            f.write(HelpCollection % collectionAttribs)
+            f.close()
+        
+        sys.stdout.write("QtHelp files written.\n")
+        sys.stdout.write("Generating QtHelp documentation...\n")
+        sys.stdout.flush()
+        sys.stderr.flush()
+        
+        cwd = os.getcwd()
+        # generate the compressed files
+        shutil.copy(os.path.join(self.outputDir, HelpProjectFile), self.htmlDir)
+        os.chdir(self.htmlDir)
+        subprocess.call(["qhelpgenerator", "source.qhp", 
+                         "-o", os.path.join(self.outputDir, HelpHelpFile)])
+        os.remove(HelpProjectFile)
+        
+        if self.createCollection:
+            sys.stdout.write("Generating QtHelp collection...\n")
+            sys.stdout.flush()
+            sys.stderr.flush()
+            os.chdir(self.outputDir)
+            subprocess.call(["qcollectiongenerator", "source.qhcp", "-o", "collection.qhc"])
+        
+        os.chdir(cwd)

eric ide

mercurial