DocumentationTools/QtHelpGenerator.py

changeset 0
de9c2efb9d02
child 13
1af94a91f439
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the QtHelp generator for the builtin documentation generator.
8 """
9
10 import sys
11 import os
12 import shutil
13 import codecs
14 import subprocess
15
16 from Utilities import joinext, relpath, html_encode
17
18 HelpCollection = r"""<?xml version="1.0" encoding="utf-8" ?>
19 <QHelpCollectionProject version="1.0">
20 <docFiles>
21 <register>
22 <file>%(helpfile)s</file>
23 </register>
24 </docFiles>
25 </QHelpCollectionProject>
26 """
27
28 HelpProject = r"""<?xml version="1.0" encoding="UTF-8"?>
29 <QtHelpProject version="1.0">
30 <namespace>%(namespace)s</namespace>
31 <virtualFolder>%(folder)s</virtualFolder>
32 <customFilter name="%(filter_name)s">
33 %(filter_attributes)s
34 </customFilter>
35 <filterSection>
36 %(filter_attributes)s
37 <toc>
38 %(sections)s
39 </toc>
40 <keywords>
41 %(keywords)s
42 </keywords>
43 <files>
44 %(files)s
45 </files>
46 </filterSection>
47 </QtHelpProject>
48 """
49
50 HelpProjectFile = 'source.qhp'
51 HelpHelpFile = 'source.qch'
52 HelpCollectionProjectFile = 'source.qhcp'
53 HelpCollectionFile = 'collection.qhc'
54
55 class QtHelpGenerator(object):
56 """
57 Class implementing the QtHelp generator for the builtin documentation generator.
58 """
59 def __init__(self, htmlDir,
60 outputDir, namespace, virtualFolder, filterName, filterAttributes,
61 title, createCollection):
62 """
63 Constructor
64
65 @param htmlDir directory containing the HTML files (string)
66 @param outputDir output directory for the files (string)
67 @param namespace namespace to be used (string)
68 @param virtualFolder virtual folder to be used (string)
69 @param filterName name of the custom filter (string)
70 @param filterAttributes ':' separated list of filter attributes (string)
71 @param title title to be used for the generated help (string)
72 @param createCollection flag indicating the generation of the collection
73 files (boolean)
74 """
75 self.htmlDir = htmlDir
76 self.outputDir = outputDir
77 self.namespace = namespace
78 self.virtualFolder = virtualFolder
79 self.filterName = filterName
80 self.filterAttributes = filterAttributes and filterAttributes.split(':') or []
81 self.relPath = relpath(self.htmlDir, self.outputDir)
82 self.title = title
83 self.createCollection = createCollection
84
85 self.packages = {
86 "00index" : {
87 "subpackages" : {},
88 "modules" : {}
89 }
90 }
91 self.remembered = False
92 self.keywords = []
93
94 def remember(self, file, moduleDocument, basename=""):
95 """
96 Public method to remember a documentation file.
97
98 @param file The filename to be remembered. (string)
99 @param moduleDocument The ModuleDocument object containing the
100 information for the file.
101 @param basename The basename of the file hierarchy to be documented.
102 The basename is stripped off the filename if it starts with
103 the basename.
104 """
105 self.remembered = True
106 if basename:
107 file = file.replace(basename, "")
108
109 if "__init__" in file:
110 dir = os.path.dirname(file)
111 udir = os.path.dirname(dir)
112 base = os.path.basename(dir)
113 if udir:
114 upackage = udir.replace(os.sep, ".")
115 try:
116 elt = self.packages[upackage]
117 except KeyError:
118 elt = self.packages["00index"]
119 else:
120 elt = self.packages["00index"]
121 package = dir.replace(os.sep, ".")
122 elt["subpackages"][package] = moduleDocument.name()
123
124 self.packages[package] = {
125 "subpackages" : {},
126 "modules" : {}
127 }
128
129 kwEntry = ("%s (Package)" % package.split('.')[-1],
130 joinext("index-%s" % package, ".html"))
131 if kwEntry not in self.keywords:
132 self.keywords.append(kwEntry)
133
134 if moduleDocument.isEmpty():
135 return
136
137 package = os.path.dirname(file).replace(os.sep, ".")
138 try:
139 elt = self.packages[package]
140 except KeyError:
141 elt = self.packages["00index"]
142 elt["modules"][moduleDocument.name()] = moduleDocument.name()
143
144 if "__init__" not in file:
145 kwEntry = ("%s (Module)" % moduleDocument.name().split('.')[-1],
146 joinext(moduleDocument.name(), ".html"))
147 if kwEntry not in self.keywords:
148 self.keywords.append(kwEntry)
149 for kw in moduleDocument.getQtHelpKeywords():
150 kwEntry = (kw[0], "%s%s" % (joinext(moduleDocument.name(), ".html"), kw[1]))
151 if kwEntry not in self.keywords:
152 self.keywords.append(kwEntry)
153
154 def __generateSections(self, package, level):
155 """
156 Private method to generate the sections part.
157
158 @param package name of the package to process (string)
159 @param level indentation level (integer)
160 @return sections part (string)
161 """
162 indent = level * ' '
163 indent1 = indent + ' '
164 s = indent + '<section title="%s" ref="%s">\n' % \
165 (package == "00index" and self.title or package,
166 package == "00index" and \
167 joinext("index", ".html") or \
168 joinext("index-%s" % package, ".html"))
169 for subpack in sorted(self.packages[package]["subpackages"]):
170 s += self.__generateSections(subpack, level + 1)
171 for mod in sorted(self.packages[package]["modules"]):
172 s += indent1 + '<section title="%s" ref="%s" />\n' % \
173 (mod, joinext(mod, ".html"))
174 s += indent + '</section>\n'
175 return s
176
177 def __generateKeywords(self):
178 """
179 Private method to generate the keywords section.
180
181 @return keywords section (string)
182 """
183 indent = level * ' '
184 return "\n".join([])
185
186 def generateFiles(self, basename = ""):
187 """
188 Public method to generate all index files.
189
190 @param basename The basename of the file hierarchy to be documented.
191 The basename is stripped off the filename if it starts with
192 the basename.
193 """
194 if not self.remembered:
195 sys.stderr.write("No QtHelp to generate.\n")
196 return
197
198 if basename:
199 basename = basename.replace(os.sep, ".")
200 if not basename.endswith("."):
201 basename = "%s." % basename
202
203 sections = self.__generateSections("00index", 3)
204 filesList = sorted([e for e in os.listdir(self.htmlDir) if e.endswith('.html')])
205 files = "\n".join([" <file>%s</file>" % f for f in filesList])
206 filterAttribs = "\n".join([" <filterAttribute>%s</filterAttribute>" % a \
207 for a in self.filterAttributes])
208 keywords = "\n".join(
209 [' <keyword name="%s" id="%s" ref="%s" />' % \
210 (html_encode(kw[0]), html_encode(kw[0]), html_encode(kw[1])) \
211 for kw in self.keywords])
212
213 helpAttribs = {
214 "namespace" : self.namespace,
215 "folder" : self.virtualFolder,
216 "filter_name" : self.filterName,
217 "filter_attributes" : filterAttribs,
218 "sections" : sections,
219 "keywords" : keywords,
220 "files" : files,
221 }
222
223 f = codecs.open(os.path.join(self.outputDir, HelpProjectFile), 'w', 'utf-8')
224 f.write(HelpProject % helpAttribs)
225 f.close()
226
227 if self.createCollection and \
228 not os.path.exists(os.path.join(self.outputDir, HelpCollectionProjectFile)):
229 collectionAttribs = {
230 "helpfile" : HelpHelpFile,
231 }
232
233 f = codecs.open(os.path.join(self.outputDir, HelpCollectionProjectFile),
234 'w', 'utf-8')
235 f.write(HelpCollection % collectionAttribs)
236 f.close()
237
238 sys.stdout.write("QtHelp files written.\n")
239 sys.stdout.write("Generating QtHelp documentation...\n")
240 sys.stdout.flush()
241 sys.stderr.flush()
242
243 cwd = os.getcwd()
244 # generate the compressed files
245 shutil.copy(os.path.join(self.outputDir, HelpProjectFile), self.htmlDir)
246 os.chdir(self.htmlDir)
247 subprocess.call(["qhelpgenerator", "source.qhp",
248 "-o", os.path.join(self.outputDir, HelpHelpFile)])
249 os.remove(HelpProjectFile)
250
251 if self.createCollection:
252 sys.stdout.write("Generating QtHelp collection...\n")
253 sys.stdout.flush()
254 sys.stderr.flush()
255 os.chdir(self.outputDir)
256 subprocess.call(["qcollectiongenerator", "source.qhcp", "-o", "collection.qhc"])
257
258 os.chdir(cwd)

eric ide

mercurial