Tue, 02 Oct 2012 19:53:31 +0200

Detlev Offenbach <>
Tue, 02 Oct 2012 19:53:31 +0200
changeset 2087
parent 1519
child 2302

Made the sixth set of Qt5 compatibility changes.

# -*- coding: utf-8 -*-

# Copyright (c) 2009 - 2012 Detlev Offenbach <>

Module implementing the QtHelp generator for the builtin documentation generator.

import sys
import os
import shutil
import subprocess

from Utilities import joinext, relpath, html_encode

HelpCollection = r"""<?xml version="1.0" encoding="utf-8" ?>
<QHelpCollectionProject version="1.0">

HelpProject = r"""<?xml version="1.0" encoding="UTF-8"?>
<QtHelpProject version="1.0">
  <customFilter name="{filter_name}">

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):
        @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)
            if udir:
                upackage = udir.replace(os.sep, ".")
                    elt = self.packages[upackage]
                except KeyError:
                    elt = self.packages["00index"]
                elt = self.packages["00index"]
            package = dir.replace(os.sep, ".")
            elt["subpackages"][package] =
            self.packages[package] = {
                "subpackages": {},
                "modules": {}
            kwEntry = ("{0} (Package)".format(package.split('.')[-1]),
                       joinext("index-{0}".format(package), ".html"))
            if kwEntry not in self.keywords:
            if moduleDocument.isEmpty():
        package = os.path.dirname(file).replace(os.sep, ".")
            elt = self.packages[package]
        except KeyError:
            elt = self.packages["00index"]
        elt["modules"][] =
        if "__init__" not in file:
            kwEntry = ("{0} (Module)".format('.')[-1]),
                       joinext(, ".html"))
            if kwEntry not in self.keywords:
        for kw in moduleDocument.getQtHelpKeywords():
            kwEntry = (kw[0], "{0}{1}".format(
                joinext(, ".html"), kw[1]))
            if kwEntry not in self.keywords:
    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="{0}" ref="{1}">\n'.format(
            package == "00index" and self.title or package,
             package == "00index" and \
                joinext("index", ".html") or \
                joinext("index-{0}".format(package), ".html"))
        for subpack in sorted(self.packages[package]["subpackages"]):
            s += self.__generateSections(subpack, level + 1)
            s += '\n'
        for mod in sorted(self.packages[package]["modules"]):
            s += indent1 + '<section title="{0}" ref="{1}" />\n'.format(
                mod, joinext(mod, ".html"))
        s += indent + '</section>'
        return s
    def __convertEol(self, txt, newline):
        Private method to convert the newline characters.
        @param txt text to be converted (string)
        @param newline newline character to be used (string)
        @return converted text (string)
        # step 1: normalize eol to '\n'
        txt = txt.replace("\r\n", "\n").replace("\r", "\n")
        # step 2: convert to the target eol
        if newline is None:
            return txt.replace("\n", os.linesep)
        elif newline in ["\r", "\r\n"]:
            return txt.replace("\n", newline)
            return txt
    def generateFiles(self, basename="", newline=None):
        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.
        @param newline newline character to be used (string)
        if not self.remembered:
            sys.stderr.write("No QtHelp to generate.\n")
        if basename:
            basename = basename.replace(os.sep, ".")
            if not basename.endswith("."):
                basename = "{0}.".format(basename)
        sections = self.__generateSections("00index", 3)
        filesList = sorted([e for e in os.listdir(self.htmlDir) if e.endswith('.html')])
        files = "\n".join(["      <file>{0}</file>".format(f) for f in filesList])
        filterAttribs = "\n".join(["    <filterAttribute>{0}</filterAttribute>".format(a) \
                                  for a in sorted(self.filterAttributes)])
        keywords = "\n".join(
            ['      <keyword name="{0}" id="{1}" ref="{2}" />'.format(
             html_encode(kw[0]), html_encode(kw[0]), html_encode(kw[1])) \
             for kw in sorted(self.keywords)])
        helpAttribs = {
            "namespace": self.namespace,
            "folder": self.virtualFolder,
            "filter_name": self.filterName,
            "filter_attributes": filterAttribs,
            "sections": sections,
            "keywords": keywords,
            "files": files,
        txt = self.__convertEol(HelpProject.format(**helpAttribs), newline)
        f = open(os.path.join(self.outputDir, HelpProjectFile), "w",
                 encoding="utf-8", newline=newline)
        if self.createCollection and \
           not os.path.exists(os.path.join(self.outputDir, HelpCollectionProjectFile)):
            collectionAttribs = {
                "helpfile": HelpHelpFile,
            txt = self.__convertEol(HelpCollection.format(**collectionAttribs), newline)
            f = open(os.path.join(self.outputDir, HelpCollectionProjectFile),
                     "w", encoding="utf-8", newline=newline)
        sys.stdout.write("QtHelp files written.\n")
        sys.stdout.write("Generating QtHelp documentation...\n")
        cwd = os.getcwd()
        # generate the compressed files
        shutil.copy(os.path.join(self.outputDir, HelpProjectFile), self.htmlDir)
        os.chdir(self.htmlDir)["qhelpgenerator", "source.qhp",
                         "-o", os.path.join(self.outputDir, HelpHelpFile)])
        if self.createCollection:
            sys.stdout.write("Generating QtHelp collection...\n")
  ["qcollectiongenerator", "source.qhcp", "-o", "collection.qhc"])

eric ide