|
1 |
|
2 /**************************************************************************** |
|
3 ** |
|
4 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
5 ** All rights reserved. |
|
6 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
7 ** |
|
8 ** This file is part of the tools applications of the Qt Toolkit. |
|
9 ** |
|
10 ** $QT_BEGIN_LICENSE:LGPL$ |
|
11 ** No Commercial Usage |
|
12 ** This file contains pre-release code and may not be distributed. |
|
13 ** You may use this file in accordance with the terms and conditions |
|
14 ** contained in the Technology Preview License Agreement accompanying |
|
15 ** this package. |
|
16 ** |
|
17 ** GNU Lesser General Public License Usage |
|
18 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
19 ** General Public License version 2.1 as published by the Free Software |
|
20 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
21 ** packaging of this file. Please review the following information to |
|
22 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
24 ** |
|
25 ** In addition, as a special exception, Nokia gives you certain additional |
|
26 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
28 ** |
|
29 ** If you have questions regarding the use of this file, please contact |
|
30 ** Nokia at qt-info@nokia.com. |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** |
|
39 ** $QT_END_LICENSE$ |
|
40 ** |
|
41 ****************************************************************************/ |
|
42 |
|
43 /* |
|
44 ditaxmlgenerator.cpp |
|
45 */ |
|
46 |
|
47 #include "codemarker.h" |
|
48 #include "codeparser.h" |
|
49 #include "ditaxmlgenerator.h" |
|
50 #include "node.h" |
|
51 #include "separator.h" |
|
52 #include "tree.h" |
|
53 #include <ctype.h> |
|
54 #include <qdebug.h> |
|
55 #include <qlist.h> |
|
56 #include <qiterator.h> |
|
57 #include <qtextcodec.h> |
|
58 #include <QUuid> |
|
59 |
|
60 QT_BEGIN_NAMESPACE |
|
61 |
|
62 #define COMMAND_VERSION Doc::alias("version") |
|
63 int DitaXmlGenerator::id = 0; |
|
64 |
|
65 #define cxxapi_d_xref Doc::alias("cxxapi-d-xref") |
|
66 #define cxxclass Doc::alias("cxxclass") |
|
67 #define cxxdefine Doc::alias("cxxdefine") |
|
68 #define cxxenumeration Doc::alias("cxxenumeration") |
|
69 #define cxxfile Doc::alias("cxxfile") |
|
70 #define cxxfunction Doc::alias("cxxfunction") |
|
71 #define cxxstruct Doc::alias("cxxstruct") |
|
72 #define cxxtypedef Doc::alias("cxxtypedef") |
|
73 #define cxxunion Doc::alias("cxxunion") |
|
74 #define cxxvariable Doc::alias("cxxvariable") |
|
75 |
|
76 #define CXXAPIMAP Doc::alias("cxxAPIMap") |
|
77 #define CXXCLASSREF Doc::alias("cxxClassRef") |
|
78 #define CXXDEFINEREF Doc::alias("cxxDefineRef") |
|
79 #define CXXENUMERATIONREF Doc::alias("cxxEnumerationRef") |
|
80 #define CXXFILEREF Doc::alias("cxxFileRef") |
|
81 #define CXXFUNCTIONREF Doc::alias("cxxFunctionRef") |
|
82 #define CXXSTRUCTREF Doc::alias("cxxStructRef") |
|
83 #define CXXTYPDEFREF Doc::alias("cxxTypedefRef") |
|
84 #define CXXUNIONREF Doc::alias("cxxUnionRef") |
|
85 #define CXXVARIABLEREF Doc::alias("cxxVariableRef") |
|
86 |
|
87 #define CXXCLASS Doc::alias("cxxClass") |
|
88 #define CXXCLASSABSTRACT Doc::alias("cxxClassAbstract") |
|
89 #define CXXCLASSACCESSSPECIFIER Doc::alias("cxxClassAccessSpecifier") |
|
90 #define CXXCLASSAPIITEMLOCATION Doc::alias("cxxClassAPIItemLocation") |
|
91 #define CXXCLASSBASECLASS Doc::alias("cxxClassBaseClass") |
|
92 #define CXXCLASSBASECLASSSTRUCT Doc::alias("cxxClassBaseStruct") |
|
93 #define CXXCLASSBASEUNION Doc::alias("cxxClassBaseUnion") |
|
94 #define CXXCLASSDECLARATIONFILE Doc::alias("cxxClassDeclarationFile") |
|
95 #define CXXCLASSDECLARATIONFILELINE Doc::alias("cxxClassDeclarationFileLine") |
|
96 #define CXXCLASSDEFINITION Doc::alias("cxxClassDefinition") |
|
97 #define CXXCLASSDEFINITIONFILE Doc::alias("cxxClassDefinitionFile") |
|
98 #define CXXCLASSDEFINITIONFILEEND Doc::alias("cxxClassDefinitionFileLineEnd") |
|
99 #define CXXCLASSDEFINITIONFILESTART Doc::alias("cxxClassDefinitionFileLineStart") |
|
100 #define CXXCLASSDERIVATION Doc::alias("cxxClassDerivation") |
|
101 #define CXXCLASSDERIVATIONACCESSSPECIFIER Doc::alias("cxxClassDerivationAccessSpecifier") |
|
102 #define CXXCLASSDERIVATIONS Doc::alias("cxxClassDerivations") |
|
103 #define CXXCLASSDERIVATIONVIRTUAL Doc::alias("cxxClassDerivationVirtual") |
|
104 #define CXXCLASSDETAIL Doc::alias("cxxClassDetail") |
|
105 #define CXXCLASSENUMERATIONINHERITED Doc::alias("cxxClassEnumerationInherited") |
|
106 #define CXXCLASSENUMERATORINHERITED Doc::alias("cxxClassEnumeratorInherited") |
|
107 #define CXXCLASSFUNCTIONINHERITED Doc::alias("cxxClassFunctionInherited") |
|
108 #define CXXCLASSINHERITS Doc::alias("cxxClassInherits") |
|
109 #define CXXCLASSINHERITSDETAIL Doc::alias("cxxClassInheritsDetail") |
|
110 #define CXXCLASSNESTED Doc::alias("cxxClassNested") |
|
111 #define CXXCLASSNESTEDCLASS Doc::alias("cxxClassNestedClass") |
|
112 #define CXXCLASSNESTEDDETAIL Doc::alias("cxxClassNestedDetail") |
|
113 #define CXXCLASSNESTEDSTRUCT Doc::alias("cxxClassNestedStruct") |
|
114 #define CXXCLASSNESTEDUNION Doc::alias("cxxClassNestedUnion") |
|
115 #define CXXCLASSTEMPLATEPARAMETER Doc::alias("cxxClassTemplateParameter") |
|
116 #define CXXCLASSTEMPLATEPARAMETERS Doc::alias("cxxClassTemplateParameters") |
|
117 #define CXXCLASSTEMPLATEPARAMETERTYPE Doc::alias("cxxClassTemplateParameterType") |
|
118 #define CXXCLASSVARIABLEINHERITED Doc::alias("cxxClassVariableInherited") |
|
119 |
|
120 #define CXXDEFINE Doc::alias("cxxDefine") |
|
121 #define CXXDEFINEACCESSSPECIFIER Doc::alias("cxxDefineAccessSpecifier") |
|
122 #define CXXDEFINEAPIITEMLOCATION Doc::alias("cxxDefineAPIItemLocation") |
|
123 #define CXXDEFINEDECLARATIONFILE Doc::alias("cxxDefineDeclarationFile") |
|
124 #define CXXDEFINEDECLARATIONFILELINE Doc::alias("cxxDefineDeclarationFileLine") |
|
125 #define CXXDEFINEDEFINITION Doc::alias("cxxDefineDefinition") |
|
126 #define CXXDEFINEDETAIL Doc::alias("cxxDefineDetail") |
|
127 #define CXXDEFINENAMELOOKUP Doc::alias("cxxDefineNameLookup") |
|
128 #define CXXDEFINEPARAMETER Doc::alias("cxxDefineParameter") |
|
129 #define CXXDEFINEPARAMETERDECLARATIONNAME Doc::alias("cxxDefineParameterDeclarationName") |
|
130 #define CXXDEFINEPARAMETERS Doc::alias("cxxDefineParameters") |
|
131 #define CXXDEFINEPROTOTYPE Doc::alias("cxxDefinePrototype") |
|
132 #define CXXDEFINEREIMPLEMENTED Doc::alias("cxxDefineReimplemented") |
|
133 |
|
134 #define CXXENUMERATION Doc::alias("cxxEnumeration") |
|
135 #define CXXENUMERATIONACCESSSPECIFIER Doc::alias("cxxEnumerationAccessSpecifier") |
|
136 #define CXXENUMERATIONAPIITEMLOCATION Doc::alias("cxxEnumerationAPIItemLocation") |
|
137 #define CXXENUMERATIONDECLARATIONFILE Doc::alias("cxxEnumerationDeclarationFile") |
|
138 #define CXXENUMERATIONDECLARATIONFILELINE Doc::alias("cxxEnumerationDeclarationFileLine") |
|
139 #define CXXENUMERATIONDEFINITION Doc::alias("cxxEnumerationDefinition") |
|
140 #define CXXENUMERATIONDEFINITIONFILE Doc::alias("cxxEnumerationDefinitionFile") |
|
141 #define CXXENUMERATIONDEFINITIONFILELINEEND Doc::alias("cxxEnumerationDefinitionFileLineEnd") |
|
142 #define CXXENUMERATIONDEFINITIONFILELINESTART Doc::alias("cxxEnumerationDefinitionFileLineStart") |
|
143 #define CXXENUMERATIONDETAIL Doc::alias("cxxEnumerationDetail") |
|
144 #define CXXENUMERATIONNAMELOOKUP Doc::alias("cxxEnumerationNameLookup") |
|
145 #define CXXENUMERATIONPROTOTYPE Doc::alias("cxxEnumerationPrototype") |
|
146 #define CXXENUMERATIONREIMPLEMENTED Doc::alias("cxxEnumerationReimplemented") |
|
147 #define CXXENUMERATIONSCOPEDNAME Doc::alias("cxxEnumerationScopedName") |
|
148 #define CXXENUMERATOR Doc::alias("cxxEnumerator") |
|
149 #define CXXENUMERATORAPIITEMLOCATION Doc::alias("cxxEnumeratorAPIItemLocation") |
|
150 #define CXXENUMERATORDECLARATIONFILE Doc::alias("cxxEnumeratorDeclarationFile") |
|
151 #define CXXENUMERATORDECLARATIONFILELINE Doc::alias("cxxEnumeratorDeclarationFileLine") |
|
152 #define CXXENUMERATORINITIALISER Doc::alias("cxxEnumeratorInitialiser") |
|
153 #define CXXENUMERATORNAMELOOKUP Doc::alias("cxxEnumeratorNameLookup") |
|
154 #define CXXENUMERATORPROTOTYPE Doc::alias("cxxEnumeratorPrototype") |
|
155 #define CXXENUMERATORS Doc::alias("cxxEnumerators") |
|
156 #define CXXENUMERATORSCOPEDNAME Doc::alias("cxxEnumeratorScopedName") |
|
157 |
|
158 #define CXXFILE_INFO_TYPES Doc::alias("cxxFile-info-types") |
|
159 #define CXXFILE_TYPES_DEFAULT Doc::alias("cxxFile-types-default") |
|
160 #define CXXFILE Doc::alias("cxxFile") |
|
161 #define CXXFILEAPIITMELOCATION Doc::alias("cxxFileAPIItemLocation") |
|
162 #define CXXFILEDECLARATIONFILE Doc::alias("cxxFileDeclarationFile") |
|
163 |
|
164 #define CXXFUNCTION Doc::alias("cxxFunction") |
|
165 #define CXXFUNCTIONACCESSSPECIFIER Doc::alias("cxxFunctionAccessSpecifier") |
|
166 #define CXXFUNCTIONAPIITEMLOCATION Doc::alias("cxxFunctionAPIItemLocation") |
|
167 #define CXXFUNCTIONCONST Doc::alias("cxxFunctionConst") |
|
168 #define CXXFUNCTIONCONSTRUCTOR Doc::alias("cxxFunctionConstructor") |
|
169 #define CXXFUNCTIONDECLARATIONFILE Doc::alias("cxxFunctionDeclarationFile") |
|
170 #define CXXFUNCTIONDECLARATIONFILELINE Doc::alias("cxxFunctionDeclarationFileLine") |
|
171 #define CXXFUNCTIONDECLAREDTYPE Doc::alias("cxxFunctionDeclaredType") |
|
172 #define CXXFUNCTIONDEFINITION Doc::alias("cxxFunctionDefinition") |
|
173 #define CXXFUNCTIONDEFINITIONFILE Doc::alias("cxxFunctionDefinitionFile") |
|
174 #define CXXFUNCTIONDEFINITIONFILELINEEND Doc::alias("cxxFunctionDefinitionFileLineEnd") |
|
175 #define CXXFUNCTIONDEFINITIONFILELINESTART Doc::alias("cxxFunctionDefinitionFileLineStart") |
|
176 #define CXXFUNCTIONDESTRUCTOR Doc::alias("cxxFunctionDestructor") |
|
177 #define CXXFUNCTIONDETAIL Doc::alias("cxxFunctionDetail") |
|
178 #define CXXFUNCTIONEXPLICIT Doc::alias("cxxFunctionExplicit") |
|
179 #define CXXFUNCTIONINLINE Doc::alias("cxxFunctionInline") |
|
180 #define CXXFUNCTIONNAMELOOKUP Doc::alias("cxxFunctionNameLookup") |
|
181 #define CXXFUNCTIONPARAMETER Doc::alias("cxxFunctionParameter") |
|
182 #define CXXFUNCTIONPARAMETERDECLARATIONNAME Doc::alias("cxxFunctionParameterDeclarationName") |
|
183 #define CXXFUNCTIONPARAMETERDECLAREDTYPE Doc::alias("cxxFunctionParameterDeclaredType") |
|
184 #define CXXFUNCTIONPARAMETERDEFAULTVALUE Doc::alias("cxxFunctionParameterDefaultValue") |
|
185 #define CXXFUNCTIONPARAMETERDEFINITIONNAME Doc::alias("cxxFunctionParameterDefinitionName") |
|
186 #define CXXFUNCTIONPARAMETERS Doc::alias("cxxFunctionParameters") |
|
187 #define CXXFUNCTIONPROTOTYPE Doc::alias("cxxFunctionPrototype") |
|
188 #define CXXFUNCTIONPUREVIRTUAL Doc::alias("cxxFunctionPureVirtual") |
|
189 #define CXXFUNCTIONREIMPLEMENTED Doc::alias("cxxFunctionReimplemented") |
|
190 #define CXXFUNCTIONRETURNTYPE Doc::alias("cxxFunctionReturnType") |
|
191 #define CXXFUNCTIONSCOPEDNAME Doc::alias("cxxFunctionScopedName") |
|
192 #define CXXFUNCTIONSTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxFunctionStorageClassSpecifierExtern") |
|
193 #define CXXFUNCTIONSTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxFunctionStorageClassSpecifierMutable") |
|
194 #define CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxFunctionStorageClassSpecifierStatic") |
|
195 #define CXXFUNCTIONTEMPLATEPARAMETER Doc::alias("cxxFunctionTemplateParameter") |
|
196 #define CXXFUNCTIONTEMPLATEPARAMETERS Doc::alias("cxxFunctionTemplateParameters") |
|
197 #define CXXFUNCTIONTEMPLATEPARAMETERTYPE Doc::alias("cxxFunctionTemplateParameterType") |
|
198 #define CXXFUNCTIONVIRTUAL Doc::alias("cxxFunctionVirtual") |
|
199 #define CXXFUNCTIONVOLATILE Doc::alias("cxxFunctionVolatile") |
|
200 |
|
201 #define CXXSTRUCT Doc::alias("cxxStruct") |
|
202 #define CXXSTRUCTABSTRACT Doc::alias("cxxStructAbstract") |
|
203 #define CXXSTRUCTACCESSSPECIFIER Doc::alias("cxxStructAccessSpecifier") |
|
204 #define CXXSTRUCTAPIITEMLOCATION Doc::alias("cxxStructAPIItemLocation") |
|
205 #define CXXSTRUCTBASECLASS Doc::alias("cxxStructBaseClass") |
|
206 #define CXXSTRUCTBASESTRUCT Doc::alias("cxxStructBaseStruct") |
|
207 #define CXXSTRUCTBASEUNION Doc::alias("cxxStructBaseUnion") |
|
208 #define CXXSTRUCTDECLARATIONFILE Doc::alias("cxxStructDeclarationFile") |
|
209 #define CXXSTRUCTDECLARATIONFILELINE Doc::alias("cxxStructDeclarationFileLine") |
|
210 #define CXXSTRUCTDEFINITION Doc::alias("cxxStructDefinition") |
|
211 #define CXXSTRUCTDEFINITIONFILE Doc::alias("cxxStructDefinitionFile") |
|
212 #define CXXSTRUCTDEFINITIONFILELINEEND Doc::alias("cxxStructDefinitionFileLineEnd") |
|
213 #define CXXSTRUCTDEFINITIONFILELINESTART Doc::alias("cxxStructDefinitionFileLineStart") |
|
214 #define CXXSTRUCTDERIVATION Doc::alias("cxxStructDerivation") |
|
215 #define CXXSTRUCTDERIVATIONACCESSSPECIFIER Doc::alias("cxxStructDerivationAccessSpecifier") |
|
216 #define CXXSTRUCTDERIVATIONS Doc::alias("cxxStructDerivations") |
|
217 #define CXXSTRUCTDERIVATIONVIRTUAL Doc::alias("cxxStructDerivationVirtual") |
|
218 #define CXXSTRUCTDETAIL Doc::alias("cxxStructDetail") |
|
219 #define CXXSTRUCTENUMERATIONINHERITED Doc::alias("cxxStructEnumerationInherited") |
|
220 #define CXXSTRUCTENUMERATORINHERITED Doc::alias("cxxStructEnumeratorInherited") |
|
221 #define CXXSTRUCTFUNCTIONINHERITED Doc::alias("cxxStructFunctionInherited") |
|
222 #define CXXSTRUCTINHERITS Doc::alias("cxxStructInherits") |
|
223 #define CXXSTRUCTINHERITSDETAIL Doc::alias("cxxStructInheritsDetail") |
|
224 #define CXXSTRUCTNESTED Doc::alias("cxxStructNested") |
|
225 #define CXXSTRUCTNESTEDCLASS Doc::alias("cxxStructNestedClass") |
|
226 #define CXXSTRUCTNESTEDDETAIL Doc::alias("cxxStructNestedDetail") |
|
227 #define CXXSTRUCTNESTEDSTRUCT Doc::alias("cxxStructNestedStruct") |
|
228 #define CXXSTRUCTNESTEDUNION Doc::alias("cxxStructNestedUnion") |
|
229 #define CXXSTRUCTTEMPLATEPARAMETER Doc::alias("cxxStructTemplateParameter") |
|
230 #define CXXSTRUCTTEMPLATEPARAMETERS Doc::alias("cxxStructTemplateParameters") |
|
231 #define CXXSTRUCTTEMPLATEPARAMETERTYPE Doc::alias("cxxStructTemplateParameterType") |
|
232 #define CXXSTRUCTVARIABLEINHERITED Doc::alias("cxxStructVariableInherited") |
|
233 |
|
234 #define CXXTYPEDEF Doc::alias("cxxTypedef") |
|
235 #define CXXTYPEDEFACCESSSPECIFIER Doc::alias("cxxTypedefAccessSpecifier") |
|
236 #define CXXTYPEDEFAPIITEMLOCATION Doc::alias("cxxTypedefAPIItemLocation") |
|
237 #define CXXTYPEDEFDECLARATIONFILE Doc::alias("cxxTypedefDeclarationFile") |
|
238 #define CXXTYPEDEFDECLARATIONFILELINE Doc::alias("cxxTypedefDeclarationFileLine") |
|
239 #define CXXTYPEDEFDECLAREDTYPE Doc::alias("cxxTypedefDeclaredType") |
|
240 #define CXXTYPEDEFDEFINITION Doc::alias("cxxTypedefDefinition") |
|
241 #define CXXTYPEDEFDETAIL Doc::alias("cxxTypedefDetail") |
|
242 #define CXXTYPEDEFNAMELOOKUP Doc::alias("cxxTypedefNameLookup") |
|
243 #define CXXTYPEDEFPROTOTYPE Doc::alias("cxxTypedefPrototype") |
|
244 #define CXXTYPEDEFREIMPLEMENTED Doc::alias("cxxTypedefReimplemented") |
|
245 #define CXXTYPEDEFSCOPEDNAME Doc::alias("cxxTypedefScopedName") |
|
246 |
|
247 #define CXXUNION Doc::alias("cxxUnion") |
|
248 #define CXXUNIONABSTRACT Doc::alias("cxxUnionAbstract") |
|
249 #define CXXUNIONACCESSSPECIFIER Doc::alias("cxxUnionAccessSpecifier") |
|
250 #define CXXUNIONAPIITEMLOCATION Doc::alias("cxxUnionAPIItemLocation") |
|
251 #define CXXUNIONDECLARATIONFILE Doc::alias("cxxUnionDeclarationFile") |
|
252 #define CXXUNIONDECLARATIONFILELINE Doc::alias("cxxUnionDeclarationFileLine") |
|
253 #define CXXUNIONDEFINITION Doc::alias("cxxUnionDefinition") |
|
254 #define CXXUNIONDEFINITIONFILE Doc::alias("cxxUnionDefinitionFile") |
|
255 #define CXXUNIONDEFINITIONFILELINEEND Doc::alias("cxxUnionDefinitionFileLineEnd") |
|
256 #define CXXUNIONDEFINITIONFILELINESTART Doc::alias("cxxUnionDefinitionFileLineStart") |
|
257 #define CXXUNIONDETAIL Doc::alias("cxxUnionDetail") |
|
258 #define CXXUNIONNESTED Doc::alias("cxxUnionNested") |
|
259 #define CXXUNIONNESTEDCLASS Doc::alias("cxxUnionNestedClass") |
|
260 #define CXXUNIONNESTEDDETAIL Doc::alias("cxxUnionNestedDetail") |
|
261 #define CXXUNIONNESTEDSTRUCT Doc::alias("cxxUnionNestedStruct") |
|
262 #define CXXUNIONNESTEDUNION Doc::alias("cxxUnionNestedUnion") |
|
263 #define CXXUNIONTEMPLATEPARAMETER Doc::alias("cxxUnionTemplateParameter") |
|
264 #define CXXUNIONTEMPLATEPARAMETERS Doc::alias("cxxUnionTemplateParameters") |
|
265 #define CXXUNIONTEMPLATEPARAMETERTYPE Doc::alias("cxxUnionTemplateParameterType") |
|
266 |
|
267 #define CXXVARIABLE Doc::alias("cxxVariable") |
|
268 #define CXXVARIABLEACCESSSPECIFIER Doc::alias("cxxVariableAccessSpecifier") |
|
269 #define CXXVARIABLEAPIITEMLOCATION Doc::alias("cxxVariableAPIItemLocation") |
|
270 #define CXXVARIABLECONST Doc::alias("cxxVariableConst") |
|
271 #define CXXVARIABLEDECLARATIONFILE Doc::alias("cxxVariableDeclarationFile") |
|
272 #define CXXVARIABLEDECLARATIONFILELINE Doc::alias("cxxVariableDeclarationFileLine") |
|
273 #define CXXVARIABLEDECLAREDTYPE Doc::alias("cxxVariableDeclaredType") |
|
274 #define CXXVARIABLEDEFINITION Doc::alias("cxxVariableDefinition") |
|
275 #define CXXVARIABLEDETAIL Doc::alias("cxxVariableDetail") |
|
276 #define CXXVARIABLENAMELOOKUP Doc::alias("cxxVariableNameLookup") |
|
277 #define CXXVARIABLEPROTOTYPE Doc::alias("cxxVariablePrototype") |
|
278 #define CXXVARIABLEREIMPLEMENTED Doc::alias("cxxVariableReimplemented") |
|
279 #define CXXVARIABLESCOPEDNAME Doc::alias("cxxVariableScopedName") |
|
280 #define CXXVARIABLESTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxVariableStorageClassSpecifierExtern") |
|
281 #define CXXVARIABLESTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxVariableStorageClassSpecifierMutable") |
|
282 #define CXXVARIABLESTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxVariableStorageClassSpecifierStatic") |
|
283 #define CXXVARIABLEVOLATILE Doc::alias("cxxVariableVolatile") |
|
284 |
|
285 #define APIREF Doc::alias("apiRef") |
|
286 #define APINAME Doc::alias("apiName") |
|
287 #define APIDETAIL Doc::alias("apiDetail") |
|
288 #define APISYNTAX Doc::alias("apiSyntax") |
|
289 #define APISYNTAXTEXT Doc::alias("apiSyntaxText") |
|
290 #define APISYNTAXITEM Doc::alias("apiSyntaxItem") |
|
291 #define APIDEF Doc::alias("apiDef") |
|
292 #define APIQUALIFIER Doc::alias("apiQualifier") |
|
293 #define APIRELATION Doc::alias("apiRelation") |
|
294 #define APITYPE Doc::alias("apiType") |
|
295 #define APIARRAY Doc::alias("apiArray") |
|
296 #define APIDATA Doc::alias("apiData") |
|
297 #define APIDEFNOTE Doc::alias("apiDefNote") |
|
298 #define APIDEFITEM Doc::alias("apiDefItem") |
|
299 #define APIITEMNAME Doc::alias("apiItemName") |
|
300 #define APIDESC Doc::alias("apiDesc") |
|
301 #define APIIMPL Doc::alias("apiImpl") |
|
302 |
|
303 #define APIPACKAGE Doc::alias("apiPackage") |
|
304 |
|
305 #define APICLASSIFIER Doc::alias("apiClassifier") |
|
306 #define APICLASSIFIERDETAIL Doc::alias("apiClassifierDetail") |
|
307 #define APICLASSIFIERDEF Doc::alias("apiClassifierDef") |
|
308 #define APICLASSIFIERMEMBER Doc::alias("apiClassifierMember") |
|
309 #define APIOTHERCLASSIFIER Doc::alias("apiOtherClassifier") |
|
310 #define APIBASECLASSIFIER Doc::alias("apiBaseClassifier") |
|
311 |
|
312 #define APIOPERATION Doc::alias("apiOperation") |
|
313 #define APIOPERATIONDETAIL Doc::alias("apiOperationDetail") |
|
314 #define APIOPERATIONDEF Doc::alias("apiOperationDef") |
|
315 #define APIRETURN Doc::alias("apiReturn") |
|
316 #define APIPARAM Doc::alias("apiParam") |
|
317 #define APIEVENT Doc::alias("apiEvent") |
|
318 #define APIOPERATIONDEFITEM Doc::alias("apiOperationDefItem") |
|
319 #define APIOPERATIONCLASSIFIER Doc::alias("apiOperationClassifier") |
|
320 #define APICONSTRUCTORDEF Doc::alias("apiConstructorDef") |
|
321 |
|
322 #define APIVALUE Doc::alias("apiValue") |
|
323 #define APIVALUEDETAIL Doc::alias("apiValueDetail") |
|
324 #define APIVALUEDEF Doc::alias("apiValueDef") |
|
325 #define APIVALUEMEMBER Doc::alias("apiValueMember") |
|
326 #define APIVALUECLASSIFIER Doc::alias("apiValueClassifier") |
|
327 |
|
328 #define APIclassifier Doc::alias("apiclassifier") |
|
329 #define APIoperation Doc::alias("apioperation") |
|
330 #define APIpackage Doc::alias("apipackage") |
|
331 #define APIvalue Doc::alias("apivalue") |
|
332 |
|
333 #define APIMAP Doc::alias("apiMap") |
|
334 #define APIITEMREF Doc::alias("apiItemRef") |
|
335 |
|
336 #define SHORTDESC Doc::alias("shortdesc") |
|
337 |
|
338 QString DitaXmlGenerator::sinceTitles[] = |
|
339 { |
|
340 " New Namespaces", |
|
341 " New Classes", |
|
342 " New Member Functions", |
|
343 " New Functions in Namespaces", |
|
344 " New Global Functions", |
|
345 " New Macros", |
|
346 " New Enum Types", |
|
347 " New Typedefs", |
|
348 " New Properties", |
|
349 " New Variables", |
|
350 " New QML Elements", |
|
351 " New Qml Properties", |
|
352 " New Qml Signals", |
|
353 " New Qml Methods", |
|
354 "" |
|
355 }; |
|
356 |
|
357 static bool showBrokenLinks = false; |
|
358 |
|
359 static void addLink(const QString &linkTarget, |
|
360 const QStringRef &nestedStuff, |
|
361 QString *res) |
|
362 { |
|
363 if (!linkTarget.isEmpty()) { |
|
364 *res += "<xref href=\""; |
|
365 *res += linkTarget; |
|
366 *res += "\">"; |
|
367 *res += nestedStuff; |
|
368 *res += "</xref>"; |
|
369 } |
|
370 else { |
|
371 *res += nestedStuff; |
|
372 } |
|
373 } |
|
374 |
|
375 |
|
376 DitaXmlGenerator::DitaXmlGenerator() |
|
377 : inLink(false), |
|
378 inContents(false), |
|
379 inSectionHeading(false), |
|
380 inTableHeader(false), |
|
381 numTableRows(0), |
|
382 threeColumnEnumValueTable(true), |
|
383 offlineDocs(true), |
|
384 funcLeftParen("\\S(\\()"), |
|
385 myTree(0), |
|
386 slow(false), |
|
387 obsoleteLinks(false), |
|
388 noLinks(0) |
|
389 { |
|
390 } |
|
391 |
|
392 DitaXmlGenerator::~DitaXmlGenerator() |
|
393 { |
|
394 // nothing yet. |
|
395 } |
|
396 |
|
397 void DitaXmlGenerator::initializeGenerator(const Config &config) |
|
398 { |
|
399 static const struct { |
|
400 const char *key; |
|
401 const char *tag; |
|
402 } defaults[] = { |
|
403 { ATOM_FORMATTING_BOLD, "b" }, |
|
404 { ATOM_FORMATTING_INDEX, "<!--" }, |
|
405 { ATOM_FORMATTING_ITALIC, "i" }, |
|
406 { ATOM_FORMATTING_PARAMETER, "i" }, |
|
407 { ATOM_FORMATTING_SUBSCRIPT, "sub" }, |
|
408 { ATOM_FORMATTING_SUPERSCRIPT, "sup" }, |
|
409 { ATOM_FORMATTING_TELETYPE, "tt", }, |
|
410 { ATOM_FORMATTING_UNDERLINE, "u", }, |
|
411 { 0, 0 } |
|
412 }; |
|
413 |
|
414 Generator::initializeGenerator(config); |
|
415 obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS)); |
|
416 setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif"); |
|
417 int i = 0; |
|
418 while (defaults[i].key) { |
|
419 formattingLeftMap().insert(defaults[i].key, defaults[i].tag); |
|
420 i++; |
|
421 } |
|
422 |
|
423 style = config.getString(DitaXmlGenerator::format() + |
|
424 Config::dot + |
|
425 DITAXMLGENERATOR_STYLE); |
|
426 postHeader = config.getString(DitaXmlGenerator::format() + |
|
427 Config::dot + |
|
428 DITAXMLGENERATOR_POSTHEADER); |
|
429 postPostHeader = config.getString(DitaXmlGenerator::format() + |
|
430 Config::dot + |
|
431 DITAXMLGENERATOR_POSTPOSTHEADER); |
|
432 footer = config.getString(DitaXmlGenerator::format() + |
|
433 Config::dot + |
|
434 DITAXMLGENERATOR_FOOTER); |
|
435 address = config.getString(DitaXmlGenerator::format() + |
|
436 Config::dot + |
|
437 DITAXMLGENERATOR_ADDRESS); |
|
438 pleaseGenerateMacRef = config.getBool(DitaXmlGenerator::format() + |
|
439 Config::dot + |
|
440 DITAXMLGENERATOR_GENERATEMACREFS); |
|
441 |
|
442 project = config.getString(CONFIG_PROJECT); |
|
443 offlineDocs = !config.getBool(CONFIG_ONLINE); |
|
444 projectDescription = config.getString(CONFIG_DESCRIPTION); |
|
445 if (projectDescription.isEmpty() && !project.isEmpty()) |
|
446 projectDescription = project + " Reference Documentation"; |
|
447 |
|
448 projectUrl = config.getString(CONFIG_URL); |
|
449 |
|
450 outputEncoding = config.getString(CONFIG_OUTPUTENCODING); |
|
451 if (outputEncoding.isEmpty()) |
|
452 outputEncoding = QLatin1String("ISO-8859-1"); |
|
453 outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit()); |
|
454 |
|
455 naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE); |
|
456 if (naturalLanguage.isEmpty()) |
|
457 naturalLanguage = QLatin1String("en"); |
|
458 |
|
459 QSet<QString> editionNames = config.subVars(CONFIG_EDITION); |
|
460 QSet<QString>::ConstIterator edition = editionNames.begin(); |
|
461 while (edition != editionNames.end()) { |
|
462 QString editionName = *edition; |
|
463 QStringList editionModules = config.getStringList(CONFIG_EDITION + |
|
464 Config::dot + |
|
465 editionName + |
|
466 Config::dot + |
|
467 "modules"); |
|
468 QStringList editionGroups = config.getStringList(CONFIG_EDITION + |
|
469 Config::dot + |
|
470 editionName + |
|
471 Config::dot + |
|
472 "groups"); |
|
473 |
|
474 if (!editionModules.isEmpty()) |
|
475 editionModuleMap[editionName] = editionModules; |
|
476 if (!editionGroups.isEmpty()) |
|
477 editionGroupMap[editionName] = editionGroups; |
|
478 |
|
479 ++edition; |
|
480 } |
|
481 |
|
482 slow = config.getBool(CONFIG_SLOW); |
|
483 |
|
484 stylesheets = config.getStringList(DitaXmlGenerator::format() + |
|
485 Config::dot + |
|
486 DITAXMLGENERATOR_STYLESHEETS); |
|
487 customHeadElements = config.getStringList(DitaXmlGenerator::format() + |
|
488 Config::dot + |
|
489 DITAXMLGENERATOR_CUSTOMHEADELEMENTS); |
|
490 codeIndent = config.getInt(CONFIG_CODEINDENT); |
|
491 |
|
492 } |
|
493 |
|
494 void DitaXmlGenerator::terminateGenerator() |
|
495 { |
|
496 Generator::terminateGenerator(); |
|
497 } |
|
498 |
|
499 QString DitaXmlGenerator::format() |
|
500 { |
|
501 return "DITAXML"; |
|
502 } |
|
503 |
|
504 /*! |
|
505 Calls lookupGuid() to get a GUID for \a text, then writes |
|
506 it to the XML stream as an "id" attribute, and returns it. |
|
507 */ |
|
508 QString DitaXmlGenerator::writeGuidAttribute(QString text) |
|
509 { |
|
510 QString guid = lookupGuid(text); |
|
511 writer.writeAttribute("id",guid); |
|
512 return guid; |
|
513 } |
|
514 |
|
515 /*! |
|
516 Looks up \a text in the GUID map. If it finds \a text, |
|
517 it returns the associated GUID. Otherwise it inserts |
|
518 \a text into the map with a new GUID, and it returns |
|
519 the new GUID. |
|
520 */ |
|
521 QString DitaXmlGenerator::lookupGuid(QString text) |
|
522 { |
|
523 QMap<QString, QString>::const_iterator i = name2guidMap.find(text); |
|
524 if (i != name2guidMap.end()) |
|
525 return i.value(); |
|
526 QString guid = QUuid::createUuid().toString(); |
|
527 name2guidMap.insert(text,guid); |
|
528 return guid; |
|
529 } |
|
530 |
|
531 /*! |
|
532 This is where the DITA XML files are written. |
|
533 \note The file generation is done in the base class, |
|
534 PageGenerator::generateTree(). |
|
535 */ |
|
536 void DitaXmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) |
|
537 { |
|
538 myTree = tree; |
|
539 nonCompatClasses.clear(); |
|
540 mainClasses.clear(); |
|
541 compatClasses.clear(); |
|
542 obsoleteClasses.clear(); |
|
543 moduleClassMap.clear(); |
|
544 moduleNamespaceMap.clear(); |
|
545 funcIndex.clear(); |
|
546 legaleseTexts.clear(); |
|
547 serviceClasses.clear(); |
|
548 findAllClasses(tree->root()); |
|
549 findAllFunctions(tree->root()); |
|
550 findAllLegaleseTexts(tree->root()); |
|
551 findAllNamespaces(tree->root()); |
|
552 findAllSince(tree->root()); |
|
553 |
|
554 PageGenerator::generateTree(tree, marker); |
|
555 } |
|
556 |
|
557 void DitaXmlGenerator::startText(const Node* /* relative */, |
|
558 CodeMarker* /* marker */) |
|
559 { |
|
560 inLink = false; |
|
561 inContents = false; |
|
562 inSectionHeading = false; |
|
563 inTableHeader = false; |
|
564 numTableRows = 0; |
|
565 threeColumnEnumValueTable = true; |
|
566 link.clear(); |
|
567 sectionNumber.clear(); |
|
568 } |
|
569 |
|
570 /*! |
|
571 Generate html from an instance of Atom. |
|
572 */ |
|
573 int DitaXmlGenerator::generateAtom(const Atom *atom, |
|
574 const Node *relative, |
|
575 CodeMarker *marker) |
|
576 { |
|
577 int skipAhead = 0; |
|
578 QString hx; |
|
579 static bool in_para = false; |
|
580 QString guid; |
|
581 |
|
582 switch (atom->type()) { |
|
583 case Atom::AbstractLeft: |
|
584 break; |
|
585 case Atom::AbstractRight: |
|
586 break; |
|
587 case Atom::AutoLink: |
|
588 if ((noLinks > 0) && !inLink && !inContents && !inSectionHeading) { |
|
589 const Node *node = 0; |
|
590 QString link = getLink(atom, relative, marker, &node); |
|
591 if (!link.isEmpty()) { |
|
592 beginLink(link, node, relative, marker); |
|
593 generateLink(atom, relative, marker); |
|
594 endLink(); |
|
595 } |
|
596 else { |
|
597 writer.writeCharacters(protectEnc(atom->string())); |
|
598 } |
|
599 } |
|
600 else { |
|
601 writer.writeCharacters(protectEnc(atom->string())); |
|
602 } |
|
603 break; |
|
604 case Atom::BaseName: |
|
605 break; |
|
606 case Atom::BriefLeft: |
|
607 if (relative->type() == Node::Fake) { |
|
608 skipAhead = skipAtoms(atom, Atom::BriefRight); |
|
609 break; |
|
610 } |
|
611 writer.writeStartElement(SHORTDESC); |
|
612 if (relative->type() == Node::Property || |
|
613 relative->type() == Node::Variable) { |
|
614 QString str; |
|
615 atom = atom->next(); |
|
616 while (atom != 0 && atom->type() != Atom::BriefRight) { |
|
617 if (atom->type() == Atom::String || |
|
618 atom->type() == Atom::AutoLink) |
|
619 str += atom->string(); |
|
620 skipAhead++; |
|
621 atom = atom->next(); |
|
622 } |
|
623 str[0] = str[0].toLower(); |
|
624 if (str.right(1) == ".") |
|
625 str.truncate(str.length() - 1); |
|
626 writer.writeCharacters("This "); |
|
627 if (relative->type() == Node::Property) |
|
628 writer.writeCharacters("property"); |
|
629 else |
|
630 writer.writeCharacters("variable"); |
|
631 QStringList words = str.split(" "); |
|
632 if (!(words.first() == "contains" || words.first() == "specifies" |
|
633 || words.first() == "describes" || words.first() == "defines" |
|
634 || words.first() == "holds" || words.first() == "determines")) |
|
635 writer.writeCharacters(" holds "); |
|
636 else |
|
637 writer.writeCharacters(" "); |
|
638 writer.writeCharacters(str + "."); |
|
639 } |
|
640 break; |
|
641 case Atom::BriefRight: |
|
642 if (relative->type() != Node::Fake) { |
|
643 writer.writeEndElement(); // </shortdesc> |
|
644 } |
|
645 break; |
|
646 case Atom::C: |
|
647 writer.writeStartElement(formattingLeftMap()[ATOM_FORMATTING_TELETYPE]); |
|
648 if (inLink) { |
|
649 writer.writeCharacters(protectEnc(plainCode(atom->string()))); |
|
650 } |
|
651 else { |
|
652 writer.writeCharacters(highlightedCode(atom->string(), marker, relative)); |
|
653 } |
|
654 writer.writeEndElement(); // sse writeStartElement() above |
|
655 break; |
|
656 case Atom::Code: |
|
657 writer.writeStartElement("pre"); |
|
658 writer.writeAttribute("outputclass","highlightedCode"); |
|
659 writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), |
|
660 marker, |
|
661 relative))); |
|
662 writer.writeEndElement(); // </pre> |
|
663 break; |
|
664 #ifdef QDOC_QML |
|
665 case Atom::Qml: |
|
666 writer.writeStartElement("pre"); |
|
667 writer.writeAttribute("outputclass","highlightedCode"); |
|
668 writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), |
|
669 marker, |
|
670 relative))); |
|
671 writer.writeEndElement(); // pre |
|
672 break; |
|
673 #endif |
|
674 case Atom::CodeNew: |
|
675 writer.writeStartElement("p"); |
|
676 writer.writeCharacters("you can rewrite it as"); |
|
677 writer.writeEndElement(); // </p> |
|
678 writer.writeStartElement("pre"); |
|
679 writer.writeAttribute("outputclass","highlightedCode"); |
|
680 writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), |
|
681 marker, |
|
682 relative))); |
|
683 writer.writeEndElement(); // </pre> |
|
684 break; |
|
685 case Atom::CodeOld: |
|
686 writer.writeStartElement("p"); |
|
687 writer.writeCharacters("For example, if you have code like"); |
|
688 writer.writeEndElement(); // </p> |
|
689 // fallthrough |
|
690 case Atom::CodeBad: |
|
691 writer.writeStartElement("pre"); |
|
692 writer.writeAttribute("outputclass","highlightedCode"); |
|
693 writer.writeCharacters(trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))); |
|
694 writer.writeEndElement(); // </pre> |
|
695 break; |
|
696 case Atom::FootnoteLeft: |
|
697 // ### For now |
|
698 if (in_para) { |
|
699 writer.writeEndElement(); // </p> |
|
700 in_para = false; |
|
701 } |
|
702 writer.writeCharacters("<!-- "); |
|
703 break; |
|
704 case Atom::FootnoteRight: |
|
705 // ### For now |
|
706 writer.writeCharacters("-->"); |
|
707 break; |
|
708 case Atom::FormatElse: |
|
709 case Atom::FormatEndif: |
|
710 case Atom::FormatIf: |
|
711 break; |
|
712 case Atom::FormattingLeft: |
|
713 writer.writeStartElement(formattingLeftMap()[atom->string()]); |
|
714 if (atom->string() == ATOM_FORMATTING_PARAMETER) { |
|
715 if (atom->next() != 0 && atom->next()->type() == Atom::String) { |
|
716 QRegExp subscriptRegExp("([a-z]+)_([0-9n])"); |
|
717 if (subscriptRegExp.exactMatch(atom->next()->string())) { |
|
718 writer.writeCharacters(subscriptRegExp.cap(1)); |
|
719 writer.writeStartElement("sub"); |
|
720 writer.writeCharacters(subscriptRegExp.cap(2)); |
|
721 writer.writeEndElement(); // </sub> |
|
722 skipAhead = 1; |
|
723 } |
|
724 } |
|
725 } |
|
726 break; |
|
727 case Atom::FormattingRight: |
|
728 if (atom->string() == ATOM_FORMATTING_LINK) { |
|
729 endLink(); |
|
730 } |
|
731 else { |
|
732 writer.writeEndElement(); // ? |
|
733 } |
|
734 break; |
|
735 case Atom::AnnotatedList: |
|
736 { |
|
737 QList<Node*> values = myTree->groups().values(atom->string()); |
|
738 NodeMap nodeMap; |
|
739 for (int i = 0; i < values.size(); ++i) { |
|
740 const Node* n = values.at(i); |
|
741 if ((n->status() != Node::Internal) && (n->access() != Node::Private)) { |
|
742 nodeMap.insert(n->nameForLists(),n); |
|
743 } |
|
744 } |
|
745 generateAnnotatedList(relative, marker, nodeMap); |
|
746 } |
|
747 break; |
|
748 case Atom::GeneratedList: |
|
749 if (atom->string() == "annotatedclasses") { |
|
750 generateAnnotatedList(relative, marker, nonCompatClasses); |
|
751 } |
|
752 else if (atom->string() == "classes") { |
|
753 generateCompactList(relative, marker, nonCompatClasses, true); |
|
754 } |
|
755 else if (atom->string().contains("classesbymodule")) { |
|
756 QString arg = atom->string().trimmed(); |
|
757 QString moduleName = atom->string().mid(atom->string().indexOf( |
|
758 "classesbymodule") + 15).trimmed(); |
|
759 if (moduleClassMap.contains(moduleName)) |
|
760 generateAnnotatedList(relative, marker, moduleClassMap[moduleName]); |
|
761 } |
|
762 else if (atom->string().contains("classesbyedition")) { |
|
763 |
|
764 QString arg = atom->string().trimmed(); |
|
765 QString editionName = atom->string().mid(atom->string().indexOf( |
|
766 "classesbyedition") + 16).trimmed(); |
|
767 |
|
768 if (editionModuleMap.contains(editionName)) { |
|
769 |
|
770 // Add all classes in the modules listed for that edition. |
|
771 NodeMap editionClasses; |
|
772 foreach (const QString &moduleName, editionModuleMap[editionName]) { |
|
773 if (moduleClassMap.contains(moduleName)) |
|
774 editionClasses.unite(moduleClassMap[moduleName]); |
|
775 } |
|
776 |
|
777 // Add additional groups and remove groups of classes that |
|
778 // should be excluded from the edition. |
|
779 |
|
780 QMultiMap <QString, Node *> groups = myTree->groups(); |
|
781 foreach (const QString &groupName, editionGroupMap[editionName]) { |
|
782 QList<Node *> groupClasses; |
|
783 if (groupName.startsWith("-")) { |
|
784 groupClasses = groups.values(groupName.mid(1)); |
|
785 foreach (const Node *node, groupClasses) |
|
786 editionClasses.remove(node->name()); |
|
787 } |
|
788 else { |
|
789 groupClasses = groups.values(groupName); |
|
790 foreach (const Node *node, groupClasses) |
|
791 editionClasses.insert(node->name(), node); |
|
792 } |
|
793 } |
|
794 generateAnnotatedList(relative, marker, editionClasses); |
|
795 } |
|
796 } |
|
797 else if (atom->string() == "classhierarchy") { |
|
798 generateClassHierarchy(relative, marker, nonCompatClasses); |
|
799 } |
|
800 else if (atom->string() == "compatclasses") { |
|
801 generateCompactList(relative, marker, compatClasses, false); |
|
802 } |
|
803 else if (atom->string() == "obsoleteclasses") { |
|
804 generateCompactList(relative, marker, obsoleteClasses, false); |
|
805 } |
|
806 else if (atom->string() == "functionindex") { |
|
807 generateFunctionIndex(relative, marker); |
|
808 } |
|
809 else if (atom->string() == "legalese") { |
|
810 generateLegaleseList(relative, marker); |
|
811 } |
|
812 else if (atom->string() == "mainclasses") { |
|
813 generateCompactList(relative, marker, mainClasses, true); |
|
814 } |
|
815 else if (atom->string() == "services") { |
|
816 generateCompactList(relative, marker, serviceClasses, false); |
|
817 } |
|
818 else if (atom->string() == "overviews") { |
|
819 generateOverviewList(relative, marker); |
|
820 } |
|
821 else if (atom->string() == "namespaces") { |
|
822 generateAnnotatedList(relative, marker, namespaceIndex); |
|
823 } |
|
824 else if (atom->string() == "related") { |
|
825 const FakeNode *fake = static_cast<const FakeNode *>(relative); |
|
826 if (fake && !fake->groupMembers().isEmpty()) { |
|
827 NodeMap groupMembersMap; |
|
828 foreach (const Node *node, fake->groupMembers()) { |
|
829 if (node->type() == Node::Fake) |
|
830 groupMembersMap[fullName(node, relative, marker)] = node; |
|
831 } |
|
832 generateAnnotatedList(fake, marker, groupMembersMap); |
|
833 } |
|
834 } |
|
835 else if (atom->string() == "relatedinline") { |
|
836 const FakeNode *fake = static_cast<const FakeNode *>(relative); |
|
837 if (fake && !fake->groupMembers().isEmpty()) { |
|
838 // Reverse the list into the original scan order. |
|
839 // Should be sorted. But on what? It may not be a |
|
840 // regular class or page definition. |
|
841 QList<const Node *> list; |
|
842 foreach (const Node *node, fake->groupMembers()) |
|
843 list.prepend(node); |
|
844 foreach (const Node *node, list) |
|
845 generateBody(node, marker); |
|
846 } |
|
847 } |
|
848 break; |
|
849 case Atom::SinceList: |
|
850 { |
|
851 NewSinceMaps::const_iterator nsmap; |
|
852 nsmap = newSinceMaps.find(atom->string()); |
|
853 NewClassMaps::const_iterator ncmap; |
|
854 ncmap = newClassMaps.find(atom->string()); |
|
855 NewClassMaps::const_iterator nqcmap; |
|
856 nqcmap = newQmlClassMaps.find(atom->string()); |
|
857 if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) { |
|
858 QList<Section> sections; |
|
859 QList<Section>::ConstIterator s; |
|
860 for (int i=0; i<LastSinceType; ++i) |
|
861 sections.append(Section(sinceTitle(i),QString(),QString(),QString())); |
|
862 |
|
863 NodeMultiMap::const_iterator n = nsmap.value().constBegin(); |
|
864 while (n != nsmap.value().constEnd()) { |
|
865 const Node* node = n.value(); |
|
866 switch (node->type()) { |
|
867 case Node::Fake: |
|
868 if (node->subType() == Node::QmlClass) { |
|
869 sections[QmlClass].appendMember((Node*)node); |
|
870 } |
|
871 break; |
|
872 case Node::Namespace: |
|
873 sections[Namespace].appendMember((Node*)node); |
|
874 break; |
|
875 case Node::Class: |
|
876 sections[Class].appendMember((Node*)node); |
|
877 break; |
|
878 case Node::Enum: |
|
879 sections[Enum].appendMember((Node*)node); |
|
880 break; |
|
881 case Node::Typedef: |
|
882 sections[Typedef].appendMember((Node*)node); |
|
883 break; |
|
884 case Node::Function: { |
|
885 const FunctionNode* fn = static_cast<const FunctionNode*>(node); |
|
886 if (fn->isMacro()) |
|
887 sections[Macro].appendMember((Node*)node); |
|
888 else { |
|
889 Node* p = fn->parent(); |
|
890 if (p) { |
|
891 if (p->type() == Node::Class) |
|
892 sections[MemberFunction].appendMember((Node*)node); |
|
893 else if (p->type() == Node::Namespace) { |
|
894 if (p->name().isEmpty()) |
|
895 sections[GlobalFunction].appendMember((Node*)node); |
|
896 else |
|
897 sections[NamespaceFunction].appendMember((Node*)node); |
|
898 } |
|
899 else |
|
900 sections[GlobalFunction].appendMember((Node*)node); |
|
901 } |
|
902 else |
|
903 sections[GlobalFunction].appendMember((Node*)node); |
|
904 } |
|
905 break; |
|
906 } |
|
907 case Node::Property: |
|
908 sections[Property].appendMember((Node*)node); |
|
909 break; |
|
910 case Node::Variable: |
|
911 sections[Variable].appendMember((Node*)node); |
|
912 break; |
|
913 case Node::QmlProperty: |
|
914 sections[QmlProperty].appendMember((Node*)node); |
|
915 break; |
|
916 case Node::QmlSignal: |
|
917 sections[QmlSignal].appendMember((Node*)node); |
|
918 break; |
|
919 case Node::QmlMethod: |
|
920 sections[QmlMethod].appendMember((Node*)node); |
|
921 break; |
|
922 default: |
|
923 break; |
|
924 } |
|
925 ++n; |
|
926 } |
|
927 |
|
928 /* |
|
929 First generate the table of contents. |
|
930 */ |
|
931 writer.writeStartElement("ul"); |
|
932 s = sections.constBegin(); |
|
933 while (s != sections.constEnd()) { |
|
934 if (!(*s).members.isEmpty()) { |
|
935 |
|
936 writer.writeStartElement("li"); |
|
937 writer.writeStartElement("xref"); |
|
938 writer.writeAttribute("href",QString("#" + Doc::canonicalTitle((*s).name))); |
|
939 writer.writeCharacters((*s).name); |
|
940 writer.writeEndElement(); // </xref> |
|
941 writer.writeEndElement(); // </li> |
|
942 } |
|
943 ++s; |
|
944 } |
|
945 writer.writeEndElement(); // </ul> |
|
946 |
|
947 int idx = 0; |
|
948 s = sections.constBegin(); |
|
949 while (s != sections.constEnd()) { |
|
950 if (!(*s).members.isEmpty()) { |
|
951 writer.writeStartElement("p"); |
|
952 writeGuidAttribute(Doc::canonicalTitle((*s).name)); |
|
953 writer.writeAttribute("outputclass","h3"); |
|
954 writer.writeCharacters(protectEnc((*s).name)); |
|
955 writer.writeEndElement(); // </p> |
|
956 if (idx == Class) |
|
957 generateCompactList(0, marker, ncmap.value(), false, QString("Q")); |
|
958 else if (idx == QmlClass) |
|
959 generateCompactList(0, marker, nqcmap.value(), false, QString("Q")); |
|
960 else if (idx == MemberFunction) { |
|
961 ParentMaps parentmaps; |
|
962 ParentMaps::iterator pmap; |
|
963 NodeList::const_iterator i = s->members.constBegin(); |
|
964 while (i != s->members.constEnd()) { |
|
965 Node* p = (*i)->parent(); |
|
966 pmap = parentmaps.find(p); |
|
967 if (pmap == parentmaps.end()) |
|
968 pmap = parentmaps.insert(p,NodeMultiMap()); |
|
969 pmap->insert((*i)->name(),(*i)); |
|
970 ++i; |
|
971 } |
|
972 pmap = parentmaps.begin(); |
|
973 while (pmap != parentmaps.end()) { |
|
974 NodeList nlist = pmap->values(); |
|
975 writer.writeStartElement("p"); |
|
976 writer.writeCharacters("Class "); |
|
977 writer.writeStartElement("xref"); |
|
978 writer.writeAttribute("href",linkForNode(pmap.key(), 0)); |
|
979 QStringList pieces = fullName(pmap.key(), 0, marker).split("::"); |
|
980 writer.writeCharacters(protectEnc(pieces.last())); |
|
981 writer.writeEndElement(); // </xref> |
|
982 writer.writeCharacters(":"); |
|
983 writer.writeEndElement(); // </p> |
|
984 |
|
985 generateSection(nlist, 0, marker, CodeMarker::Summary); |
|
986 writer.writeEmptyElement("br"); |
|
987 ++pmap; |
|
988 } |
|
989 } |
|
990 else |
|
991 generateSection(s->members, 0, marker, CodeMarker::Summary); |
|
992 } |
|
993 ++idx; |
|
994 ++s; |
|
995 } |
|
996 } |
|
997 } |
|
998 break; |
|
999 case Atom::Image: |
|
1000 case Atom::InlineImage: |
|
1001 { |
|
1002 QString fileName = imageFileName(relative, atom->string()); |
|
1003 QString text; |
|
1004 if (atom->next() != 0) |
|
1005 text = atom->next()->string(); |
|
1006 if (atom->type() == Atom::Image) { |
|
1007 writer.writeStartElement("p"); |
|
1008 writer.writeAttribute("outputclass","centerAlign"); |
|
1009 } |
|
1010 if (fileName.isEmpty()) { |
|
1011 writer.writeStartElement("font"); |
|
1012 writer.writeAttribute("color","red"); |
|
1013 writer.writeCharacters("[Missing image: "); |
|
1014 writer.writeCharacters(protectEnc(atom->string())); |
|
1015 writer.writeEndElement(); // </font> |
|
1016 } |
|
1017 else { |
|
1018 writer.writeStartElement("img"); |
|
1019 writer.writeAttribute("src",protectEnc(fileName)); |
|
1020 if (!text.isEmpty()) |
|
1021 writer.writeAttribute("alt",protectEnc(text)); |
|
1022 writer.writeEndElement(); // </img> |
|
1023 } |
|
1024 if (atom->type() == Atom::Image) |
|
1025 writer.writeEndElement(); // </p> |
|
1026 } |
|
1027 break; |
|
1028 case Atom::ImageText: |
|
1029 // nothing |
|
1030 break; |
|
1031 case Atom::LegaleseLeft: |
|
1032 writer.writeStartElement("p"); |
|
1033 writer.writeAttribute("outputclass","legalese"); |
|
1034 break; |
|
1035 case Atom::LegaleseRight: |
|
1036 writer.writeEndElement(); // </p> |
|
1037 break; |
|
1038 case Atom::LineBreak: |
|
1039 writer.writeEmptyElement("br"); |
|
1040 break; |
|
1041 case Atom::Link: |
|
1042 { |
|
1043 const Node *node = 0; |
|
1044 QString myLink = getLink(atom, relative, marker, &node); |
|
1045 if (myLink.isEmpty()) { |
|
1046 relative->doc().location().warning(tr("Cannot link to '%1' in %2") |
|
1047 .arg(atom->string()) |
|
1048 .arg(marker->plainFullName(relative))); |
|
1049 } |
|
1050 beginLink(myLink, node, relative, marker); |
|
1051 skipAhead = 1; |
|
1052 } |
|
1053 break; |
|
1054 case Atom::LinkNode: |
|
1055 { |
|
1056 const Node *node = CodeMarker::nodeForString(atom->string()); |
|
1057 beginLink(linkForNode(node, relative), node, relative, marker); |
|
1058 skipAhead = 1; |
|
1059 } |
|
1060 break; |
|
1061 case Atom::ListLeft: |
|
1062 if (in_para) { |
|
1063 writer.writeEndElement(); // </p> |
|
1064 in_para = false; |
|
1065 } |
|
1066 if (atom->string() == ATOM_LIST_BULLET) { |
|
1067 writer.writeStartElement("ul"); |
|
1068 } |
|
1069 else if (atom->string() == ATOM_LIST_TAG) { |
|
1070 writer.writeStartElement("dl"); |
|
1071 } |
|
1072 else if (atom->string() == ATOM_LIST_VALUE) { |
|
1073 threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom); |
|
1074 if (threeColumnEnumValueTable) { |
|
1075 writer.writeStartElement("table"); |
|
1076 writer.writeAttribute("outputclass","valuelist"); |
|
1077 writer.writeStartElement("tr"); |
|
1078 if (++numTableRows % 2 == 1) |
|
1079 writer.writeAttribute("outputclass","odd"); |
|
1080 else |
|
1081 writer.writeAttribute("outputclass","even"); |
|
1082 writer.writeStartElement("th"); |
|
1083 writer.writeCharacters("Constant"); |
|
1084 writer.writeEndElement(); // </th> |
|
1085 writer.writeStartElement("th"); |
|
1086 writer.writeCharacters("Value"); |
|
1087 writer.writeEndElement(); // </th> |
|
1088 writer.writeStartElement("th"); |
|
1089 writer.writeCharacters("Description"); |
|
1090 writer.writeEndElement(); // </th> |
|
1091 writer.writeEndElement(); // </tr> |
|
1092 } |
|
1093 else { |
|
1094 writer.writeStartElement("table"); |
|
1095 writer.writeAttribute("outputclass","valuelist"); |
|
1096 writer.writeStartElement("tr"); |
|
1097 writer.writeStartElement("th"); |
|
1098 writer.writeCharacters("Constant"); |
|
1099 writer.writeEndElement(); // </th> |
|
1100 writer.writeStartElement("th"); |
|
1101 writer.writeCharacters("Value"); |
|
1102 writer.writeEndElement(); // </th> |
|
1103 writer.writeEndElement(); // </tr> |
|
1104 } |
|
1105 } |
|
1106 else { |
|
1107 writer.writeStartElement("ol"); |
|
1108 if (atom->string() == ATOM_LIST_UPPERALPHA) |
|
1109 writer.writeAttribute("type","A"); |
|
1110 else if (atom->string() == ATOM_LIST_LOWERALPHA) |
|
1111 writer.writeAttribute("type","a"); |
|
1112 else if (atom->string() == ATOM_LIST_UPPERROMAN) |
|
1113 writer.writeAttribute("type","I"); |
|
1114 else if (atom->string() == ATOM_LIST_LOWERROMAN) |
|
1115 writer.writeAttribute("type","i"); |
|
1116 else // (atom->string() == ATOM_LIST_NUMERIC) |
|
1117 writer.writeAttribute("type","1"); |
|
1118 if (atom->next() != 0 && atom->next()->string().toInt() != 1) |
|
1119 writer.writeAttribute("start",atom->next()->string()); |
|
1120 } |
|
1121 break; |
|
1122 case Atom::ListItemNumber: |
|
1123 // nothing |
|
1124 break; |
|
1125 case Atom::ListTagLeft: |
|
1126 if (atom->string() == ATOM_LIST_TAG) { |
|
1127 writer.writeStartElement("dt"); |
|
1128 } |
|
1129 else { // (atom->string() == ATOM_LIST_VALUE) |
|
1130 writer.writeStartElement("tr"); |
|
1131 writer.writeStartElement("td"); |
|
1132 writer.writeAttribute("outputclass","topAlign"); |
|
1133 writer.writeStartElement("tt"); |
|
1134 writer.writeCharacters(protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(), |
|
1135 relative)))); |
|
1136 writer.writeEndElement(); // </tt> |
|
1137 writer.writeEndElement(); // </td> |
|
1138 writer.writeStartElement("td"); |
|
1139 writer.writeAttribute("outputclass","topAlign"); |
|
1140 |
|
1141 QString itemValue; |
|
1142 if (relative->type() == Node::Enum) { |
|
1143 const EnumNode *enume = static_cast<const EnumNode *>(relative); |
|
1144 itemValue = enume->itemValue(atom->next()->string()); |
|
1145 } |
|
1146 |
|
1147 if (itemValue.isEmpty()) |
|
1148 writer.writeCharacters("?"); |
|
1149 else { |
|
1150 writer.writeStartElement("tt"); |
|
1151 writer.writeCharacters(protectEnc(itemValue)); |
|
1152 writer.writeEndElement(); // </tt> |
|
1153 } |
|
1154 skipAhead = 1; |
|
1155 } |
|
1156 break; |
|
1157 case Atom::ListTagRight: |
|
1158 if (atom->string() == ATOM_LIST_TAG) |
|
1159 writer.writeEndElement(); // </dt> |
|
1160 break; |
|
1161 case Atom::ListItemLeft: |
|
1162 if (atom->string() == ATOM_LIST_TAG) { |
|
1163 writer.writeStartElement("dd"); |
|
1164 } |
|
1165 else if (atom->string() == ATOM_LIST_VALUE) { |
|
1166 if (threeColumnEnumValueTable) { |
|
1167 writer.writeEndElement(); // </td> |
|
1168 writer.writeStartElement("td"); |
|
1169 writer.writeAttribute("outputclass","topAlign"); |
|
1170 if (matchAhead(atom, Atom::ListItemRight)) |
|
1171 writer.writeCharacters(" "); |
|
1172 } |
|
1173 } |
|
1174 else { |
|
1175 writer.writeStartElement("li"); |
|
1176 } |
|
1177 if (matchAhead(atom, Atom::ParaLeft)) |
|
1178 skipAhead = 1; |
|
1179 break; |
|
1180 case Atom::ListItemRight: |
|
1181 if (atom->string() == ATOM_LIST_TAG) { |
|
1182 writer.writeEndElement(); // </dd> |
|
1183 } |
|
1184 else if (atom->string() == ATOM_LIST_VALUE) { |
|
1185 writer.writeEndElement(); // </td> |
|
1186 writer.writeEndElement(); // </tr> |
|
1187 } |
|
1188 else { |
|
1189 writer.writeEndElement(); // </li> |
|
1190 } |
|
1191 break; |
|
1192 case Atom::ListRight: |
|
1193 if (atom->string() == ATOM_LIST_BULLET) { |
|
1194 writer.writeEndElement(); // </ul> |
|
1195 } |
|
1196 else if (atom->string() == ATOM_LIST_TAG) { |
|
1197 writer.writeEndElement(); // </dl> |
|
1198 } |
|
1199 else if (atom->string() == ATOM_LIST_VALUE) { |
|
1200 writer.writeEndElement(); // </table> |
|
1201 } |
|
1202 else { |
|
1203 writer.writeEndElement(); // </ol> |
|
1204 } |
|
1205 break; |
|
1206 case Atom::Nop: |
|
1207 // nothing |
|
1208 break; |
|
1209 case Atom::ParaLeft: |
|
1210 writer.writeStartElement("p"); |
|
1211 in_para = true; |
|
1212 break; |
|
1213 case Atom::ParaRight: |
|
1214 endLink(); |
|
1215 if (in_para) { |
|
1216 writer.writeEndElement(); // </p? |
|
1217 in_para = false; |
|
1218 } |
|
1219 break; |
|
1220 case Atom::QuotationLeft: |
|
1221 writer.writeStartElement("blockquote"); |
|
1222 break; |
|
1223 case Atom::QuotationRight: |
|
1224 writer.writeEndElement(); // </blockquote> |
|
1225 break; |
|
1226 case Atom::RawString: |
|
1227 writer.writeCharacters(atom->string()); |
|
1228 break; |
|
1229 case Atom::SectionLeft: |
|
1230 writer.writeStartElement("p"); |
|
1231 writeGuidAttribute(Doc::canonicalTitle(Text::sectionHeading(atom).toString())); |
|
1232 writer.writeAttribute("outputclass","target"); |
|
1233 writer.writeCharacters(protectEnc(Text::sectionHeading(atom).toString())); |
|
1234 writer.writeEndElement(); // </p> |
|
1235 break; |
|
1236 case Atom::SectionRight: |
|
1237 // nothing |
|
1238 break; |
|
1239 case Atom::SectionHeadingLeft: |
|
1240 writer.writeStartElement("p"); |
|
1241 hx = "h" + QString::number(atom->string().toInt() + hOffset(relative)); |
|
1242 writer.writeAttribute("outputclass",hx); |
|
1243 inSectionHeading = true; |
|
1244 break; |
|
1245 case Atom::SectionHeadingRight: |
|
1246 writer.writeEndElement(); // </p> (see case Atom::SectionHeadingLeft) |
|
1247 inSectionHeading = false; |
|
1248 break; |
|
1249 case Atom::SidebarLeft: |
|
1250 // nothing |
|
1251 break; |
|
1252 case Atom::SidebarRight: |
|
1253 // nothing |
|
1254 break; |
|
1255 case Atom::String: |
|
1256 if (inLink && !inContents && !inSectionHeading) { |
|
1257 generateLink(atom, relative, marker); |
|
1258 } |
|
1259 else { |
|
1260 writer.writeCharacters(protectEnc(atom->string())); |
|
1261 } |
|
1262 break; |
|
1263 case Atom::TableLeft: |
|
1264 if (in_para) { |
|
1265 writer.writeEndElement(); // </p> |
|
1266 in_para = false; |
|
1267 } |
|
1268 writer.writeStartElement("table"); |
|
1269 writer.writeAttribute("outputclass","generic"); |
|
1270 numTableRows = 0; |
|
1271 break; |
|
1272 case Atom::TableRight: |
|
1273 writer.writeEndElement(); // </table> |
|
1274 break; |
|
1275 case Atom::TableHeaderLeft: |
|
1276 writer.writeStartElement("thead"); |
|
1277 writer.writeStartElement("tr"); |
|
1278 writer.writeAttribute("outputclass","qt-style topAlign"); |
|
1279 inTableHeader = true; |
|
1280 break; |
|
1281 case Atom::TableHeaderRight: |
|
1282 writer.writeEndElement(); // </tr> |
|
1283 if (matchAhead(atom, Atom::TableHeaderLeft)) { |
|
1284 skipAhead = 1; |
|
1285 writer.writeStartElement("tr"); |
|
1286 writer.writeAttribute("outputclass","qt-style topAlign"); |
|
1287 } |
|
1288 else { |
|
1289 writer.writeEndElement(); // </thead> |
|
1290 inTableHeader = false; |
|
1291 } |
|
1292 break; |
|
1293 case Atom::TableRowLeft: |
|
1294 writer.writeStartElement("tr"); |
|
1295 if (++numTableRows % 2 == 1) |
|
1296 writer.writeAttribute("outputclass","odd topAlign"); |
|
1297 else |
|
1298 writer.writeAttribute("outputclass","even topAlign"); |
|
1299 break; |
|
1300 case Atom::TableRowRight: |
|
1301 writer.writeEndElement(); // </tr>\n"; |
|
1302 break; |
|
1303 case Atom::TableItemLeft: |
|
1304 { |
|
1305 if (inTableHeader) |
|
1306 writer.writeStartElement("th"); |
|
1307 else |
|
1308 writer.writeStartElement("td"); |
|
1309 |
|
1310 QStringList spans = atom->string().split(","); |
|
1311 if (spans.size() == 2) { |
|
1312 #if zzz |
|
1313 |
|
1314 if (spans.at(0) != "1") |
|
1315 out() << " colspan=\"" << spans.at(0) << "\""; |
|
1316 if (spans.at(1) != "1") |
|
1317 out() << " rowspan=\"" << spans.at(1) << "\""; |
|
1318 #endif |
|
1319 if (!inTableHeader) |
|
1320 writer.writeStartElement("p"); |
|
1321 } |
|
1322 if (matchAhead(atom, Atom::ParaLeft)) |
|
1323 skipAhead = 1; |
|
1324 } |
|
1325 break; |
|
1326 case Atom::TableItemRight: |
|
1327 if (inTableHeader) |
|
1328 writer.writeEndElement(); // </th> |
|
1329 else { |
|
1330 writer.writeEndElement(); // </p> |
|
1331 writer.writeEndElement(); // </td> |
|
1332 } |
|
1333 if (matchAhead(atom, Atom::ParaLeft)) |
|
1334 skipAhead = 1; |
|
1335 break; |
|
1336 case Atom::TableOfContents: |
|
1337 { |
|
1338 int numColumns = 1; |
|
1339 const Node *node = relative; |
|
1340 |
|
1341 Doc::SectioningUnit sectioningUnit = Doc::Section4; |
|
1342 QStringList params = atom->string().split(","); |
|
1343 QString columnText = params.at(0); |
|
1344 QStringList pieces = columnText.split(" ", QString::SkipEmptyParts); |
|
1345 if (pieces.size() >= 2) { |
|
1346 columnText = pieces.at(0); |
|
1347 pieces.pop_front(); |
|
1348 QString path = pieces.join(" ").trimmed(); |
|
1349 node = findNodeForTarget(path, relative, marker, atom); |
|
1350 } |
|
1351 |
|
1352 if (params.size() == 2) { |
|
1353 numColumns = qMax(columnText.toInt(), numColumns); |
|
1354 sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt(); |
|
1355 } |
|
1356 |
|
1357 if (node) |
|
1358 generateTableOfContents(node, |
|
1359 marker, |
|
1360 sectioningUnit, |
|
1361 numColumns, |
|
1362 relative); |
|
1363 } |
|
1364 break; |
|
1365 case Atom::Target: |
|
1366 writer.writeStartElement("p"); |
|
1367 writeGuidAttribute(Doc::canonicalTitle(atom->string())); |
|
1368 writer.writeAttribute("outputclass","target"); |
|
1369 writer.writeCharacters(protectEnc(atom->string())); |
|
1370 writer.writeEndElement(); // </p> |
|
1371 break; |
|
1372 case Atom::UnhandledFormat: |
|
1373 writer.writeStartElement("b"); |
|
1374 writer.writeAttribute("outputclass","redFont"); |
|
1375 writer.writeCharacters("<Missing DITAXML>"); |
|
1376 writer.writeEndElement(); // </b> |
|
1377 break; |
|
1378 case Atom::UnknownCommand: |
|
1379 writer.writeStartElement("b"); |
|
1380 writer.writeAttribute("outputclass","redFont code"); |
|
1381 writer.writeCharacters(protectEnc(atom->string())); |
|
1382 writer.writeEndElement(); // </b> |
|
1383 break; |
|
1384 #ifdef QDOC_QML |
|
1385 case Atom::QmlText: |
|
1386 case Atom::EndQmlText: |
|
1387 // don't do anything with these. They are just tags. |
|
1388 break; |
|
1389 #endif |
|
1390 default: |
|
1391 // unknownAtom(atom); |
|
1392 break; |
|
1393 } |
|
1394 return skipAhead; |
|
1395 } |
|
1396 |
|
1397 /*! |
|
1398 Generate a reference page for a C++ class. |
|
1399 */ |
|
1400 void |
|
1401 DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* marker) |
|
1402 { |
|
1403 QList<Section> sections; |
|
1404 QList<Section>::ConstIterator s; |
|
1405 |
|
1406 const ClassNode* cn = 0; |
|
1407 const NamespaceNode* namespasse = 0; |
|
1408 |
|
1409 QString title; |
|
1410 QString rawTitle; |
|
1411 QString fullTitle; |
|
1412 if (inner->type() == Node::Namespace) { |
|
1413 namespasse = const_cast<NamespaceNode*>(static_cast<const NamespaceNode*>(inner)); |
|
1414 rawTitle = marker->plainName(inner); |
|
1415 fullTitle = marker->plainFullName(inner); |
|
1416 title = rawTitle + " Namespace"; |
|
1417 } |
|
1418 else if (inner->type() == Node::Class) { |
|
1419 cn = const_cast<ClassNode*>(static_cast<const ClassNode*>(inner)); |
|
1420 rawTitle = marker->plainName(inner); |
|
1421 fullTitle = marker->plainFullName(inner); |
|
1422 title = rawTitle + " Class Reference"; |
|
1423 |
|
1424 generateHeader(inner); |
|
1425 |
|
1426 writer.writeStartElement(CXXCLASS); |
|
1427 writer.writeAttribute("id",cn->guid()); |
|
1428 writer.writeStartElement(APINAME); |
|
1429 writer.writeCharacters(fullTitle); |
|
1430 writer.writeEndElement(); // </apiName> |
|
1431 |
|
1432 generateBrief(inner, marker); |
|
1433 |
|
1434 writer.writeStartElement(CXXCLASSDETAIL); |
|
1435 writer.writeStartElement(CXXCLASSDEFINITION); |
|
1436 writer.writeStartElement(CXXCLASSACCESSSPECIFIER); |
|
1437 writer.writeAttribute("value",inner->accessString()); |
|
1438 writer.writeEndElement(); // <cxxClassAccessSpecifier> |
|
1439 if (cn->isAbstract()) { |
|
1440 writer.writeStartElement(CXXCLASSABSTRACT); |
|
1441 writer.writeAttribute("name","abstract"); |
|
1442 writer.writeAttribute("value","abstract"); |
|
1443 writer.writeEndElement(); // </cxxClassAbstract> |
|
1444 } |
|
1445 writeDerivations(cn, marker); |
|
1446 writeLocation(cn); |
|
1447 writer.writeEndElement(); // <cxxClassDefinition> |
|
1448 writer.writeStartElement(APIDESC); |
|
1449 |
|
1450 if (!inner->doc().isEmpty()) { |
|
1451 writer.writeStartElement("p"); |
|
1452 writer.writeAttribute("outputclass","h2"); |
|
1453 writer.writeCharacters("Detailed Description"); |
|
1454 writer.writeEndElement(); // </p> |
|
1455 generateBody(inner, marker); |
|
1456 // generateAlsoList(inner, marker); |
|
1457 } |
|
1458 |
|
1459 writer.writeEndElement(); // </apiDesc> |
|
1460 writer.writeEndElement(); // </cxxClassDetail> |
|
1461 |
|
1462 sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay); |
|
1463 s = sections.begin(); |
|
1464 while (s != sections.end()) { |
|
1465 if ((*s).name == "Member Function Documentation") { |
|
1466 writeFunctions((*s),cn,marker); |
|
1467 } |
|
1468 else if ((*s).name == "Member Type Documentation") { |
|
1469 writeEnumerations((*s),cn,marker); |
|
1470 writeTypedefs((*s),cn,marker); |
|
1471 } |
|
1472 else if ((*s).name == "Member Variable Documentation") { |
|
1473 writeDataMembers((*s),cn,marker); |
|
1474 } |
|
1475 else if ((*s).name == "Property Documentation") { |
|
1476 writeProperties((*s),cn,marker); |
|
1477 } |
|
1478 else if ((*s).name == "Macro Documentation") { |
|
1479 writeMacros((*s),cn,marker); |
|
1480 } |
|
1481 ++s; |
|
1482 } |
|
1483 writer.writeEndElement(); // </cxxClass> |
|
1484 } |
|
1485 |
|
1486 #ifdef WRITE_HTML |
|
1487 Text subtitleText; |
|
1488 if (rawTitle != fullTitle) |
|
1489 subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")" |
|
1490 << Atom(Atom::LineBreak); |
|
1491 |
|
1492 QString shortVersion; |
|
1493 shortVersion = project + " " + shortVersion + ": "; |
|
1494 shortVersion = myTree->version(); |
|
1495 if (shortVersion.count(QChar('.')) == 2) |
|
1496 shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); |
|
1497 if (!shortVersion.isEmpty()) { |
|
1498 if (project == "QSA") |
|
1499 shortVersion = "QSA " + shortVersion + ": "; |
|
1500 else |
|
1501 shortVersion = "Qt " + shortVersion + ": "; |
|
1502 } |
|
1503 |
|
1504 out() << " <title>" << shortVersion << protectEnc(title) << "</title>\n"; |
|
1505 |
|
1506 #if 0 |
|
1507 out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); |
|
1508 generateBreadCrumbs(title,node,marker); |
|
1509 out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); |
|
1510 #endif |
|
1511 |
|
1512 sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); |
|
1513 generateTableOfContents(inner,marker,§ions); |
|
1514 generateTitle(title, subtitleText, SmallSubTitle, inner, marker); |
|
1515 |
|
1516 #ifdef QDOC_QML |
|
1517 if (cn && !cn->qmlElement().isEmpty()) { |
|
1518 generateInstantiatedBy(cn,marker); |
|
1519 } |
|
1520 #endif |
|
1521 |
|
1522 generateBrief(inner, marker); |
|
1523 generateIncludes(inner, marker); |
|
1524 generateStatus(inner, marker); |
|
1525 if (cn) { |
|
1526 generateInherits(cn, marker); |
|
1527 generateInheritedBy(cn, marker); |
|
1528 } |
|
1529 generateThreadSafeness(inner, marker); |
|
1530 generateSince(inner, marker); |
|
1531 |
|
1532 out() << "<ul>\n"; |
|
1533 |
|
1534 QString membersLink = generateListOfAllMemberFile(inner, marker); |
|
1535 if (!membersLink.isEmpty()) |
|
1536 out() << "<li><xref href=\"" << membersLink << "\">" |
|
1537 << "List of all members, including inherited members</xref></li>\n"; |
|
1538 |
|
1539 QString obsoleteLink = generateLowStatusMemberFile(inner, |
|
1540 marker, |
|
1541 CodeMarker::Obsolete); |
|
1542 if (!obsoleteLink.isEmpty()) |
|
1543 out() << "<li><xref href=\"" << obsoleteLink << "\">" |
|
1544 << "Obsolete members</xref></li>\n"; |
|
1545 |
|
1546 QString compatLink = generateLowStatusMemberFile(inner, |
|
1547 marker, |
|
1548 CodeMarker::Compat); |
|
1549 if (!compatLink.isEmpty()) |
|
1550 out() << "<li><xref href=\"" << compatLink << "\">" |
|
1551 << "Qt 3 support members</xref></li>\n"; |
|
1552 |
|
1553 out() << "</ul>\n"; |
|
1554 |
|
1555 bool needOtherSection = false; |
|
1556 |
|
1557 /* |
|
1558 sections is built above for the call to generateTableOfContents(). |
|
1559 */ |
|
1560 s = sections.begin(); |
|
1561 while (s != sections.end()) { |
|
1562 if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { |
|
1563 if (!s->inherited.isEmpty()) |
|
1564 needOtherSection = true; |
|
1565 } |
|
1566 else { |
|
1567 if (!s->members.isEmpty()) { |
|
1568 out() << "<hr />\n"; |
|
1569 out() << "<a name=\"" |
|
1570 << registerRef((*s).name.toLower()) |
|
1571 << "\"></a>\n"; |
|
1572 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1573 generateSection(s->members, inner, marker, CodeMarker::Summary); |
|
1574 } |
|
1575 if (!s->reimpMembers.isEmpty()) { |
|
1576 QString name = QString("Reimplemented ") + (*s).name; |
|
1577 out() << "<hr />\n"; |
|
1578 out() << "<a name=\"" |
|
1579 << registerRef(name.toLower()) |
|
1580 << "\"></a>\n"; |
|
1581 out() << "<h2>" << protectEnc(name) << "</h2>\n"; |
|
1582 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); |
|
1583 } |
|
1584 |
|
1585 if (!s->inherited.isEmpty()) { |
|
1586 out() << "<ul>\n"; |
|
1587 generateSectionInheritedList(*s, inner, marker, true); |
|
1588 out() << "</ul>\n"; |
|
1589 } |
|
1590 } |
|
1591 ++s; |
|
1592 } |
|
1593 |
|
1594 if (needOtherSection) { |
|
1595 out() << "<h3>Additional Inherited Members</h3>\n" |
|
1596 "<ul>\n"; |
|
1597 |
|
1598 s = sections.begin(); |
|
1599 while (s != sections.end()) { |
|
1600 if (s->members.isEmpty() && !s->inherited.isEmpty()) |
|
1601 generateSectionInheritedList(*s, inner, marker); |
|
1602 ++s; |
|
1603 } |
|
1604 out() << "</ul>\n"; |
|
1605 } |
|
1606 |
|
1607 out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; |
|
1608 |
|
1609 if (!inner->doc().isEmpty()) { |
|
1610 out() << "<hr />\n" |
|
1611 << "<div class=\"descr\"/>\n" // QTBUG-9504 |
|
1612 << "<h2>" << "Detailed Description" << "</h2>\n"; |
|
1613 generateBody(inner, marker); |
|
1614 out() << "</div>\n"; // QTBUG-9504 |
|
1615 generateAlsoList(inner, marker); |
|
1616 } |
|
1617 |
|
1618 sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay); |
|
1619 s = sections.begin(); |
|
1620 while (s != sections.end()) { |
|
1621 out() << "<hr />\n"; |
|
1622 if (!(*s).divClass.isEmpty()) |
|
1623 out() << "<div class=\"" << (*s).divClass << "\"/>\n"; // QTBUG-9504 |
|
1624 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1625 |
|
1626 NodeList::ConstIterator m = (*s).members.begin(); |
|
1627 while (m != (*s).members.end()) { |
|
1628 if ((*m)->access() != Node::Private) { // ### check necessary? |
|
1629 if ((*m)->type() != Node::Class) |
|
1630 generateDetailedMember(*m, inner, marker); |
|
1631 else { |
|
1632 out() << "<h3> class "; |
|
1633 generateFullName(*m, inner, marker); |
|
1634 out() << "</h3>"; |
|
1635 generateBrief(*m, marker, inner); |
|
1636 } |
|
1637 |
|
1638 QStringList names; |
|
1639 names << (*m)->name(); |
|
1640 if ((*m)->type() == Node::Function) { |
|
1641 const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m); |
|
1642 if (func->metaness() == FunctionNode::Ctor || |
|
1643 func->metaness() == FunctionNode::Dtor || |
|
1644 func->overloadNumber() != 1) |
|
1645 names.clear(); |
|
1646 } |
|
1647 else if ((*m)->type() == Node::Property) { |
|
1648 const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m); |
|
1649 if (!prop->getters().isEmpty() && |
|
1650 !names.contains(prop->getters().first()->name())) |
|
1651 names << prop->getters().first()->name(); |
|
1652 if (!prop->setters().isEmpty()) |
|
1653 names << prop->setters().first()->name(); |
|
1654 if (!prop->resetters().isEmpty()) |
|
1655 names << prop->resetters().first()->name(); |
|
1656 } |
|
1657 else if ((*m)->type() == Node::Enum) { |
|
1658 const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m); |
|
1659 if (enume->flagsType()) |
|
1660 names << enume->flagsType()->name(); |
|
1661 |
|
1662 foreach (const QString &enumName, |
|
1663 enume->doc().enumItemNames().toSet() - |
|
1664 enume->doc().omitEnumItemNames().toSet()) |
|
1665 names << plainCode(marker->markedUpEnumValue(enumName, |
|
1666 enume)); |
|
1667 } |
|
1668 } |
|
1669 ++m; |
|
1670 } |
|
1671 if (!(*s).divClass.isEmpty()) |
|
1672 out() << "</div>\n"; // QTBUG-9504 |
|
1673 ++s; |
|
1674 } |
|
1675 #endif |
|
1676 } |
|
1677 |
|
1678 /*! |
|
1679 Generate the html page for a qdoc file that doesn't map |
|
1680 to an underlying c++ file. |
|
1681 */ |
|
1682 void DitaXmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) |
|
1683 { |
|
1684 return; // zzz |
|
1685 |
|
1686 SubTitleSize subTitleSize = LargeSubTitle; |
|
1687 QList<Section> sections; |
|
1688 QList<Section>::const_iterator s; |
|
1689 QString fullTitle = fake->fullTitle(); |
|
1690 QString htmlTitle = fullTitle; |
|
1691 |
|
1692 if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) { |
|
1693 subTitleSize = SmallSubTitle; |
|
1694 htmlTitle += " (" + fake->subTitle() + ")"; |
|
1695 } |
|
1696 else if (fake->subType() == Node::QmlBasicType) { |
|
1697 fullTitle = "QML Basic Type: " + fullTitle; |
|
1698 htmlTitle = fullTitle; |
|
1699 } |
|
1700 |
|
1701 generateHeader(fake); |
|
1702 |
|
1703 /* |
|
1704 Generate the TOC for the new doc format. |
|
1705 Don't generate a TOC for the home page. |
|
1706 */ |
|
1707 if (fake->name() != QString("index.html")) |
|
1708 generateTableOfContents(fake,marker,0); |
|
1709 |
|
1710 generateTitle(fullTitle, |
|
1711 Text() << fake->subTitle(), |
|
1712 subTitleSize, |
|
1713 fake, |
|
1714 marker); |
|
1715 |
|
1716 if (fake->subType() == Node::Module) { |
|
1717 // Generate brief text and status for modules. |
|
1718 generateBrief(fake, marker); |
|
1719 generateStatus(fake, marker); |
|
1720 |
|
1721 if (moduleNamespaceMap.contains(fake->name())) { |
|
1722 out() << "<a name=\"" << registerRef("namespaces") << "\"></a>\n"; |
|
1723 out() << "<h2>Namespaces</h2>\n"; |
|
1724 generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]); |
|
1725 } |
|
1726 if (moduleClassMap.contains(fake->name())) { |
|
1727 out() << "<a name=\"" << registerRef("classes") << "\"></a>\n"; |
|
1728 out() << "<h2>Classes</h2>\n"; |
|
1729 generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]); |
|
1730 } |
|
1731 } |
|
1732 else if (fake->subType() == Node::HeaderFile) { |
|
1733 // Generate brief text and status for modules. |
|
1734 generateBrief(fake, marker); |
|
1735 generateStatus(fake, marker); |
|
1736 |
|
1737 out() << "<ul>\n"; |
|
1738 |
|
1739 QString membersLink = generateListOfAllMemberFile(fake, marker); |
|
1740 if (!membersLink.isEmpty()) |
|
1741 out() << "<li><xref href=\"" << membersLink << "\">" |
|
1742 << "List of all members, including inherited members</xref></li>\n"; |
|
1743 |
|
1744 QString obsoleteLink = generateLowStatusMemberFile(fake, |
|
1745 marker, |
|
1746 CodeMarker::Obsolete); |
|
1747 if (!obsoleteLink.isEmpty()) |
|
1748 out() << "<li><xref href=\"" << obsoleteLink << "\">" |
|
1749 << "Obsolete members</xref></li>\n"; |
|
1750 |
|
1751 QString compatLink = generateLowStatusMemberFile(fake, |
|
1752 marker, |
|
1753 CodeMarker::Compat); |
|
1754 if (!compatLink.isEmpty()) |
|
1755 out() << "<li><xref href=\"" << compatLink << "\">" |
|
1756 << "Qt 3 support members</xref></li>\n"; |
|
1757 |
|
1758 out() << "</ul>\n"; |
|
1759 } |
|
1760 #ifdef QDOC_QML |
|
1761 else if (fake->subType() == Node::QmlClass) { |
|
1762 const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake); |
|
1763 const ClassNode* cn = qml_cn->classNode(); |
|
1764 generateQmlInherits(qml_cn, marker); |
|
1765 generateQmlInstantiates(qml_cn, marker); |
|
1766 generateBrief(qml_cn, marker); |
|
1767 generateQmlInheritedBy(qml_cn, marker); |
|
1768 sections = marker->qmlSections(qml_cn,CodeMarker::Summary); |
|
1769 s = sections.begin(); |
|
1770 while (s != sections.end()) { |
|
1771 out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; |
|
1772 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1773 generateQmlSummary(*s,fake,marker); |
|
1774 ++s; |
|
1775 } |
|
1776 |
|
1777 out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; |
|
1778 out() << "<h2>" << "Detailed Description" << "</h2>\n"; |
|
1779 generateBody(fake, marker); |
|
1780 if (cn) |
|
1781 generateQmlText(cn->doc().body(), cn, marker, fake->name()); |
|
1782 generateAlsoList(fake, marker); |
|
1783 out() << "<hr />\n"; |
|
1784 |
|
1785 sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); |
|
1786 s = sections.begin(); |
|
1787 while (s != sections.end()) { |
|
1788 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1789 NodeList::ConstIterator m = (*s).members.begin(); |
|
1790 while (m != (*s).members.end()) { |
|
1791 generateDetailedQmlMember(*m, fake, marker); |
|
1792 out() << "<br/>\n"; |
|
1793 ++m; |
|
1794 } |
|
1795 ++s; |
|
1796 } |
|
1797 return; |
|
1798 } |
|
1799 #endif |
|
1800 |
|
1801 sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay); |
|
1802 s = sections.begin(); |
|
1803 while (s != sections.end()) { |
|
1804 out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; |
|
1805 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1806 generateSectionList(*s, fake, marker, CodeMarker::Summary); |
|
1807 ++s; |
|
1808 } |
|
1809 |
|
1810 Text brief = fake->doc().briefText(); |
|
1811 if (fake->subType() == Node::Module && !brief.isEmpty()) { |
|
1812 out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; |
|
1813 out() << "<div class=\"descr\"/>\n"; // QTBUG-9504 |
|
1814 out() << "<h2>" << "Detailed Description" << "</h2>\n"; |
|
1815 } |
|
1816 else |
|
1817 out() << "<div class=\"descr\"/>\n"; // QTBUG-9504 |
|
1818 |
|
1819 generateBody(fake, marker); |
|
1820 out() << "</div>\n"; // QTBUG-9504 |
|
1821 generateAlsoList(fake, marker); |
|
1822 |
|
1823 if (!fake->groupMembers().isEmpty()) { |
|
1824 NodeMap groupMembersMap; |
|
1825 foreach (const Node *node, fake->groupMembers()) { |
|
1826 if (node->type() == Node::Class || node->type() == Node::Namespace) |
|
1827 groupMembersMap[node->name()] = node; |
|
1828 } |
|
1829 generateAnnotatedList(fake, marker, groupMembersMap); |
|
1830 } |
|
1831 |
|
1832 sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay); |
|
1833 s = sections.begin(); |
|
1834 while (s != sections.end()) { |
|
1835 out() << "<hr />\n"; |
|
1836 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; |
|
1837 |
|
1838 NodeList::ConstIterator m = (*s).members.begin(); |
|
1839 while (m != (*s).members.end()) { |
|
1840 generateDetailedMember(*m, fake, marker); |
|
1841 ++m; |
|
1842 } |
|
1843 ++s; |
|
1844 } |
|
1845 } |
|
1846 |
|
1847 /*! |
|
1848 Returns "xml" for this subclass of Generator. |
|
1849 */ |
|
1850 QString DitaXmlGenerator::fileExtension(const Node * /* node */) const |
|
1851 { |
|
1852 return "xml"; |
|
1853 } |
|
1854 |
|
1855 /*! |
|
1856 Output breadcrumb list in the html file. |
|
1857 */ |
|
1858 void DitaXmlGenerator::generateBreadCrumbs(const QString& title, |
|
1859 const Node *node, |
|
1860 CodeMarker *marker) |
|
1861 { |
|
1862 Text breadcrumb; |
|
1863 if (node->type() == Node::Class) { |
|
1864 const ClassNode* cn = static_cast<const ClassNode*>(node); |
|
1865 QString name = node->moduleName(); |
|
1866 out() << " <li><xref href=\"modules.html\">All Modules</xref></li>"; |
|
1867 if (!name.isEmpty()) { |
|
1868 out() << " <li>"; |
|
1869 breadcrumb << Atom(Atom::AutoLink,name); |
|
1870 generateText(breadcrumb, node, marker); |
|
1871 out() << "</li>\n"; |
|
1872 } |
|
1873 breadcrumb.clear(); |
|
1874 if (!cn->name().isEmpty()) { |
|
1875 out() << " <li>"; |
|
1876 breadcrumb << Atom(Atom::AutoLink,cn->name()); |
|
1877 generateText(breadcrumb, 0, marker); |
|
1878 out() << "</li>\n"; |
|
1879 } |
|
1880 } |
|
1881 else if (node->type() == Node::Fake) { |
|
1882 const FakeNode* fn = static_cast<const FakeNode*>(node); |
|
1883 if (node->subType() == Node::Module) { |
|
1884 out() << " <li><xref href=\"modules.html\">All Modules</xref></li>"; |
|
1885 QString name = node->name(); |
|
1886 if (!name.isEmpty()) { |
|
1887 out() << " <li>"; |
|
1888 breadcrumb << Atom(Atom::AutoLink,name); |
|
1889 generateText(breadcrumb, 0, marker); |
|
1890 out() << "</li>\n"; |
|
1891 } |
|
1892 } |
|
1893 else if (node->subType() == Node::Group) { |
|
1894 if (fn->name() == QString("modules")) |
|
1895 out() << " <li><xref href=\"modules.html\">All Modules</xref></li>"; |
|
1896 else { |
|
1897 out() << " <li><xref href=\"" << fn->name() << "\">" << title |
|
1898 << "</xref></li>"; |
|
1899 } |
|
1900 } |
|
1901 else if (node->subType() == Node::Page) { |
|
1902 if (fn->name() == QString("examples.html")) { |
|
1903 out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>"; |
|
1904 } |
|
1905 else if (fn->name().startsWith("examples-")) { |
|
1906 out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>"; |
|
1907 out() << " <li><xref href=\"" << fn->name() << "\">" << title |
|
1908 << "</xref></li>"; |
|
1909 } |
|
1910 else if (fn->name() == QString("namespaces.html")) { |
|
1911 out() << " <li><xref href=\"namespaces.html\">All Namespaces</xref></li>"; |
|
1912 } |
|
1913 else { |
|
1914 out() << " <li><xref href=\"" << fn->name() << "\">" << title |
|
1915 << "</xref></li>"; |
|
1916 } |
|
1917 } |
|
1918 else if (node->subType() == Node::QmlClass) { |
|
1919 out() << " <li><xref href=\"qdeclarativeelements.html\">QML Elements</xref></li>"; |
|
1920 out() << " <li><xref href=\"" << fn->name() << "\">" << title |
|
1921 << "</xref></li>"; |
|
1922 } |
|
1923 else if (node->subType() == Node::Example) { |
|
1924 out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>"; |
|
1925 QStringList sl = fn->name().split('/'); |
|
1926 QString name = "examples-" + sl.at(0) + ".html"; |
|
1927 QString t = CodeParser::titleFromName(name); |
|
1928 out() << " <li><xref href=\"" << name << "\">" |
|
1929 << t << "</xref></li>"; |
|
1930 out() << " <li><xref href=\"" << sl.at(0) |
|
1931 << "-" << sl.at(sl.size()-1) << ".html\">" |
|
1932 << title << "</xref></li>"; |
|
1933 } |
|
1934 } |
|
1935 else if (node->type() == Node::Namespace) { |
|
1936 const NamespaceNode* nsn = static_cast<const NamespaceNode*>(node); |
|
1937 out() << " <li><xref href=\"namespaces.html\">All Namespaces</xref></li>"; |
|
1938 out() << " <li><xref href=\"" << fileName(nsn) << "\">" << title |
|
1939 << "</xref></li>"; |
|
1940 } |
|
1941 } |
|
1942 |
|
1943 void DitaXmlGenerator::generateHeader(const Node* node) |
|
1944 { |
|
1945 writer.setDevice(out().device()); |
|
1946 writer.setAutoFormatting(true); |
|
1947 writer.setAutoFormattingIndent(4); |
|
1948 writer.writeStartDocument(); |
|
1949 |
|
1950 if (!node) |
|
1951 return; |
|
1952 |
|
1953 QString docType; |
|
1954 QString dtd; |
|
1955 QString version; |
|
1956 if (node->type() == Node::Class) { |
|
1957 docType = "cxxClass"; |
|
1958 dtd = "dtd/cxxClass.dtd"; |
|
1959 version = "0.6.0"; |
|
1960 } |
|
1961 |
|
1962 QString doctype = "<!DOCTYPE " + docType + |
|
1963 " PUBLIC \"-//NOKIA//DTD DITA C++ API Class Reference Type v" + |
|
1964 version + "//EN\" \"" + dtd + "\">"; |
|
1965 writer.writeDTD(doctype); |
|
1966 writer.writeComment(node->doc().location().fileName()); |
|
1967 } |
|
1968 |
|
1969 void DitaXmlGenerator::generateTitle(const QString& title, |
|
1970 const Text &subTitle, |
|
1971 SubTitleSize subTitleSize, |
|
1972 const Node *relative, |
|
1973 CodeMarker *marker) |
|
1974 { |
|
1975 if (!title.isEmpty()) |
|
1976 out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n"; |
|
1977 if (!subTitle.isEmpty()) { |
|
1978 out() << "<span"; |
|
1979 if (subTitleSize == SmallSubTitle) |
|
1980 out() << " class=\"small-subtitle\">"; |
|
1981 else |
|
1982 out() << " class=\"subtitle\">"; |
|
1983 generateText(subTitle, relative, marker); |
|
1984 out() << "</span>\n"; |
|
1985 } |
|
1986 } |
|
1987 |
|
1988 /*! |
|
1989 Outputs the brief command as a <shortdesc" element. |
|
1990 */ |
|
1991 void DitaXmlGenerator::generateBrief(const Node* node, CodeMarker* marker) |
|
1992 { |
|
1993 Text brief = node->doc().briefText(); |
|
1994 if (!brief.isEmpty()) { |
|
1995 ++noLinks; |
|
1996 writer.writeStartElement(SHORTDESC); |
|
1997 generateText(brief, node, marker); |
|
1998 writer.writeEndElement(); // shortdesc |
|
1999 --noLinks; |
|
2000 } |
|
2001 } |
|
2002 |
|
2003 void DitaXmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker) |
|
2004 { |
|
2005 if (!inner->includes().isEmpty()) { |
|
2006 out() << "<pre class=\"highlightedCode\">" |
|
2007 << trimmedTrailing(highlightedCode(indent(codeIndent, |
|
2008 marker->markedUpIncludes(inner->includes())), |
|
2009 marker,inner)) |
|
2010 << "</pre>"; |
|
2011 } |
|
2012 } |
|
2013 |
|
2014 /*! |
|
2015 Generates a table of contents begining at \a node. |
|
2016 */ |
|
2017 void DitaXmlGenerator::generateTableOfContents(const Node *node, |
|
2018 CodeMarker *marker, |
|
2019 Doc::SectioningUnit sectioningUnit, |
|
2020 int numColumns, |
|
2021 const Node *relative) |
|
2022 |
|
2023 { |
|
2024 return; |
|
2025 if (!node->doc().hasTableOfContents()) |
|
2026 return; |
|
2027 QList<Atom *> toc = node->doc().tableOfContents(); |
|
2028 if (toc.isEmpty()) |
|
2029 return; |
|
2030 |
|
2031 QString nodeName = ""; |
|
2032 if (node != relative) |
|
2033 nodeName = node->name(); |
|
2034 |
|
2035 QStringList sectionNumber; |
|
2036 int columnSize = 0; |
|
2037 |
|
2038 QString tdTag; |
|
2039 if (numColumns > 1) { |
|
2040 tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/ |
|
2041 out() << "<table class=\"toc\">\n<tr class=\"topAlign\">" |
|
2042 << tdTag << "\n"; |
|
2043 } |
|
2044 |
|
2045 // disable nested links in table of contents |
|
2046 inContents = true; |
|
2047 inLink = true; |
|
2048 |
|
2049 for (int i = 0; i < toc.size(); ++i) { |
|
2050 Atom *atom = toc.at(i); |
|
2051 |
|
2052 int nextLevel = atom->string().toInt(); |
|
2053 if (nextLevel > (int)sectioningUnit) |
|
2054 continue; |
|
2055 |
|
2056 if (sectionNumber.size() < nextLevel) { |
|
2057 do { |
|
2058 out() << "<ul>"; |
|
2059 sectionNumber.append("1"); |
|
2060 } while (sectionNumber.size() < nextLevel); |
|
2061 } |
|
2062 else { |
|
2063 while (sectionNumber.size() > nextLevel) { |
|
2064 out() << "</ul>\n"; |
|
2065 sectionNumber.removeLast(); |
|
2066 } |
|
2067 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); |
|
2068 } |
|
2069 int numAtoms; |
|
2070 Text headingText = Text::sectionHeading(atom); |
|
2071 |
|
2072 if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) { |
|
2073 out() << "</ul></td>" << tdTag << "<ul>\n"; |
|
2074 columnSize = 0; |
|
2075 } |
|
2076 out() << "<li>"; |
|
2077 out() << "<xref href=\"" |
|
2078 << nodeName |
|
2079 << "#" |
|
2080 << Doc::canonicalTitle(headingText.toString()) |
|
2081 << "\">"; |
|
2082 generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); |
|
2083 out() << "</xref></li>\n"; |
|
2084 |
|
2085 ++columnSize; |
|
2086 } |
|
2087 while (!sectionNumber.isEmpty()) { |
|
2088 out() << "</ul>\n"; |
|
2089 sectionNumber.removeLast(); |
|
2090 } |
|
2091 |
|
2092 if (numColumns > 1) |
|
2093 out() << "</td></tr></table>\n"; |
|
2094 |
|
2095 inContents = false; |
|
2096 inLink = false; |
|
2097 } |
|
2098 |
|
2099 /*! |
|
2100 Revised for the new doc format. |
|
2101 Generates a table of contents begining at \a node. |
|
2102 */ |
|
2103 void DitaXmlGenerator::generateTableOfContents(const Node *node, |
|
2104 CodeMarker *marker, |
|
2105 QList<Section>* sections) |
|
2106 { |
|
2107 QList<Atom*> toc; |
|
2108 if (node->doc().hasTableOfContents()) |
|
2109 toc = node->doc().tableOfContents(); |
|
2110 if (toc.isEmpty() && !sections && (node->subType() != Node::Module)) |
|
2111 return; |
|
2112 |
|
2113 QStringList sectionNumber; |
|
2114 int detailsBase = 0; |
|
2115 |
|
2116 // disable nested links in table of contents |
|
2117 inContents = true; |
|
2118 inLink = true; |
|
2119 |
|
2120 out() << "<div class=\"toc\">\n"; |
|
2121 out() << "<h3>Contents</h3>\n"; |
|
2122 sectionNumber.append("1"); |
|
2123 out() << "<ul>\n"; |
|
2124 |
|
2125 if (node->subType() == Node::Module) { |
|
2126 if (moduleNamespaceMap.contains(node->name())) { |
|
2127 out() << "<li class=\"level" |
|
2128 << sectionNumber.size() |
|
2129 << "\"><xref href=\"#" |
|
2130 << registerRef("namespaces") |
|
2131 << "\">Namespaces</xref></li>\n"; |
|
2132 } |
|
2133 if (moduleClassMap.contains(node->name())) { |
|
2134 out() << "<li class=\"level" |
|
2135 << sectionNumber.size() |
|
2136 << "\"><xref href=\"#" |
|
2137 << registerRef("classes") |
|
2138 << "\">Classes</xref></li>\n"; |
|
2139 } |
|
2140 out() << "<li class=\"level" |
|
2141 << sectionNumber.size() |
|
2142 << "\"><xref href=\"#" |
|
2143 << registerRef("details") |
|
2144 << "\">Detailed Description</xref></li>\n"; |
|
2145 for (int i = 0; i < toc.size(); ++i) { |
|
2146 if (toc.at(i)->string().toInt() == 1) { |
|
2147 detailsBase = 1; |
|
2148 break; |
|
2149 } |
|
2150 } |
|
2151 } |
|
2152 else if (sections && (node->type() == Node::Class)) { |
|
2153 QList<Section>::ConstIterator s = sections->begin(); |
|
2154 while (s != sections->end()) { |
|
2155 if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) { |
|
2156 out() << "<li class=\"level" |
|
2157 << sectionNumber.size() |
|
2158 << "\"><xref href=\"#" |
|
2159 << registerRef((*s).pluralMember) |
|
2160 << "\">" << (*s).name |
|
2161 << "</xref></li>\n"; |
|
2162 } |
|
2163 ++s; |
|
2164 } |
|
2165 out() << "<li class=\"level" |
|
2166 << sectionNumber.size() |
|
2167 << "\"><xref href=\"#" |
|
2168 << registerRef("details") |
|
2169 << "\">Detailed Description</xref></li>\n"; |
|
2170 for (int i = 0; i < toc.size(); ++i) { |
|
2171 if (toc.at(i)->string().toInt() == 1) { |
|
2172 detailsBase = 1; |
|
2173 break; |
|
2174 } |
|
2175 } |
|
2176 } |
|
2177 |
|
2178 for (int i = 0; i < toc.size(); ++i) { |
|
2179 Atom *atom = toc.at(i); |
|
2180 int nextLevel = atom->string().toInt() + detailsBase; |
|
2181 if (sectionNumber.size() < nextLevel) { |
|
2182 do { |
|
2183 sectionNumber.append("1"); |
|
2184 } while (sectionNumber.size() < nextLevel); |
|
2185 } |
|
2186 else { |
|
2187 while (sectionNumber.size() > nextLevel) { |
|
2188 sectionNumber.removeLast(); |
|
2189 } |
|
2190 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); |
|
2191 } |
|
2192 int numAtoms; |
|
2193 Text headingText = Text::sectionHeading(atom); |
|
2194 QString s = headingText.toString(); |
|
2195 out() << "<li class=\"level" |
|
2196 << sectionNumber.size() |
|
2197 << "\">"; |
|
2198 out() << "<xref href=\"" |
|
2199 << "#" |
|
2200 << Doc::canonicalTitle(s) |
|
2201 << "\">"; |
|
2202 generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); |
|
2203 out() << "</xref></li>\n"; |
|
2204 } |
|
2205 while (!sectionNumber.isEmpty()) { |
|
2206 sectionNumber.removeLast(); |
|
2207 } |
|
2208 out() << "</ul>\n"; |
|
2209 out() << "</div>\n"; |
|
2210 inContents = false; |
|
2211 inLink = false; |
|
2212 } |
|
2213 |
|
2214 QString DitaXmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, |
|
2215 CodeMarker *marker) |
|
2216 { |
|
2217 QList<Section> sections; |
|
2218 QList<Section>::ConstIterator s; |
|
2219 |
|
2220 sections = marker->sections(inner, |
|
2221 CodeMarker::SeparateList, |
|
2222 CodeMarker::Okay); |
|
2223 if (sections.isEmpty()) |
|
2224 return QString(); |
|
2225 |
|
2226 QString fileName = fileBase(inner) + "-members." + fileExtension(inner); |
|
2227 beginSubPage(inner->location(), fileName); |
|
2228 QString title = "List of All Members for " + inner->name(); |
|
2229 generateHeader(inner); |
|
2230 generateTitle(title, Text(), SmallSubTitle, inner, marker); |
|
2231 out() << "<p>This is the complete list of members for "; |
|
2232 generateFullName(inner, 0, marker); |
|
2233 out() << ", including inherited members.</p>\n"; |
|
2234 |
|
2235 Section section = sections.first(); |
|
2236 generateSectionList(section, 0, marker, CodeMarker::SeparateList); |
|
2237 |
|
2238 endSubPage(); |
|
2239 return fileName; |
|
2240 } |
|
2241 |
|
2242 QString DitaXmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, |
|
2243 CodeMarker *marker, |
|
2244 CodeMarker::Status status) |
|
2245 { |
|
2246 QList<Section> sections = marker->sections(inner, |
|
2247 CodeMarker::Summary, |
|
2248 status); |
|
2249 QMutableListIterator<Section> j(sections); |
|
2250 while (j.hasNext()) { |
|
2251 if (j.next().members.size() == 0) |
|
2252 j.remove(); |
|
2253 } |
|
2254 if (sections.isEmpty()) |
|
2255 return QString(); |
|
2256 |
|
2257 int i; |
|
2258 |
|
2259 QString title; |
|
2260 QString fileName; |
|
2261 |
|
2262 if (status == CodeMarker::Compat) { |
|
2263 title = "Qt 3 Support Members for " + inner->name(); |
|
2264 fileName = fileBase(inner) + "-qt3." + fileExtension(inner); |
|
2265 } |
|
2266 else { |
|
2267 title = "Obsolete Members for " + inner->name(); |
|
2268 fileName = fileBase(inner) + "-obsolete." + fileExtension(inner); |
|
2269 } |
|
2270 |
|
2271 beginSubPage(inner->location(), fileName); |
|
2272 generateHeader(inner); |
|
2273 generateTitle(title, Text(), SmallSubTitle, inner, marker); |
|
2274 |
|
2275 if (status == CodeMarker::Compat) { |
|
2276 out() << "<p><b>The following class members are part of the " |
|
2277 "<xref href=\"qt3support.html\">Qt 3 support layer</xref>.</b> " |
|
2278 "They are provided to help you port old code to Qt 4. We advise against " |
|
2279 "using them in new code.</p>\n"; |
|
2280 } |
|
2281 else { |
|
2282 out() << "<p><b>The following class members are obsolete.</b> " |
|
2283 << "They are provided to keep old source code working. " |
|
2284 << "We strongly advise against using them in new code.</p>\n"; |
|
2285 } |
|
2286 |
|
2287 out() << "<p><ul><li><xref href=\"" |
|
2288 << linkForNode(inner, 0) << "\">" |
|
2289 << protectEnc(inner->name()) |
|
2290 << " class reference</xref></li></ul></p>\n"; |
|
2291 |
|
2292 for (i = 0; i < sections.size(); ++i) { |
|
2293 out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; |
|
2294 generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary); |
|
2295 } |
|
2296 |
|
2297 sections = marker->sections(inner, CodeMarker::Detailed, status); |
|
2298 for (i = 0; i < sections.size(); ++i) { |
|
2299 out() << "<hr />\n"; |
|
2300 out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; |
|
2301 |
|
2302 NodeList::ConstIterator m = sections.at(i).members.begin(); |
|
2303 while (m != sections.at(i).members.end()) { |
|
2304 if ((*m)->access() != Node::Private) |
|
2305 generateDetailedMember(*m, inner, marker); |
|
2306 ++m; |
|
2307 } |
|
2308 } |
|
2309 |
|
2310 endSubPage(); |
|
2311 return fileName; |
|
2312 } |
|
2313 |
|
2314 void DitaXmlGenerator::generateClassHierarchy(const Node *relative, |
|
2315 CodeMarker *marker, |
|
2316 const QMap<QString,const Node*> &classMap) |
|
2317 { |
|
2318 if (classMap.isEmpty()) |
|
2319 return; |
|
2320 |
|
2321 NodeMap topLevel; |
|
2322 NodeMap::ConstIterator c = classMap.begin(); |
|
2323 while (c != classMap.end()) { |
|
2324 const ClassNode *classe = static_cast<const ClassNode *>(*c); |
|
2325 if (classe->baseClasses().isEmpty()) |
|
2326 topLevel.insert(classe->name(), classe); |
|
2327 ++c; |
|
2328 } |
|
2329 |
|
2330 QStack<NodeMap > stack; |
|
2331 stack.push(topLevel); |
|
2332 |
|
2333 out() << "<ul>\n"; |
|
2334 while (!stack.isEmpty()) { |
|
2335 if (stack.top().isEmpty()) { |
|
2336 stack.pop(); |
|
2337 out() << "</ul>\n"; |
|
2338 } |
|
2339 else { |
|
2340 const ClassNode *child = |
|
2341 static_cast<const ClassNode *>(*stack.top().begin()); |
|
2342 out() << "<li>"; |
|
2343 generateFullName(child, relative, marker); |
|
2344 out() << "</li>\n"; |
|
2345 stack.top().erase(stack.top().begin()); |
|
2346 |
|
2347 NodeMap newTop; |
|
2348 foreach (const RelatedClass &d, child->derivedClasses()) { |
|
2349 if (d.access != Node::Private) |
|
2350 newTop.insert(d.node->name(), d.node); |
|
2351 } |
|
2352 if (!newTop.isEmpty()) { |
|
2353 stack.push(newTop); |
|
2354 out() << "<ul>\n"; |
|
2355 } |
|
2356 } |
|
2357 } |
|
2358 } |
|
2359 |
|
2360 void DitaXmlGenerator::generateAnnotatedList(const Node *relative, |
|
2361 CodeMarker *marker, |
|
2362 const NodeMap &nodeMap) |
|
2363 { |
|
2364 out() << "<table class=\"annotated\">\n"; |
|
2365 |
|
2366 int row = 0; |
|
2367 foreach (const QString &name, nodeMap.keys()) { |
|
2368 const Node *node = nodeMap[name]; |
|
2369 |
|
2370 if (node->status() == Node::Obsolete) |
|
2371 continue; |
|
2372 |
|
2373 if (++row % 2 == 1) |
|
2374 out() << "<tr class=\"odd topAlign\">"; |
|
2375 else |
|
2376 out() << "<tr class=\"even topAlign\">"; |
|
2377 out() << "<td><p>"; |
|
2378 generateFullName(node, relative, marker); |
|
2379 out() << "</p></td>"; |
|
2380 |
|
2381 if (!(node->type() == Node::Fake)) { |
|
2382 Text brief = node->doc().trimmedBriefText(name); |
|
2383 if (!brief.isEmpty()) { |
|
2384 out() << "<td><p>"; |
|
2385 generateText(brief, node, marker); |
|
2386 out() << "</p></td>"; |
|
2387 } |
|
2388 } |
|
2389 else { |
|
2390 out() << "<td><p>"; |
|
2391 out() << protectEnc(node->doc().briefText().toString()); |
|
2392 out() << "</p></td>"; |
|
2393 } |
|
2394 out() << "</tr>\n"; |
|
2395 } |
|
2396 out() << "</table>\n"; |
|
2397 } |
|
2398 |
|
2399 /*! |
|
2400 This function finds the common prefix of the names of all |
|
2401 the classes in \a classMap and then generates a compact |
|
2402 list of the class names alphabetized on the part of the |
|
2403 name not including the common prefix. You can tell the |
|
2404 function to use \a comonPrefix as the common prefix, but |
|
2405 normally you let it figure it out itself by looking at |
|
2406 the name of the first and last classes in \a classMap. |
|
2407 */ |
|
2408 void DitaXmlGenerator::generateCompactList(const Node *relative, |
|
2409 CodeMarker *marker, |
|
2410 const NodeMap &classMap, |
|
2411 bool includeAlphabet, |
|
2412 QString commonPrefix) |
|
2413 { |
|
2414 const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' |
|
2415 |
|
2416 if (classMap.isEmpty()) |
|
2417 return; |
|
2418 |
|
2419 /* |
|
2420 If commonPrefix is not empty, then the caller knows what |
|
2421 the common prefix is and has passed it in, so just use that |
|
2422 one. |
|
2423 */ |
|
2424 int commonPrefixLen = commonPrefix.length(); |
|
2425 if (commonPrefixLen == 0) { |
|
2426 QString first; |
|
2427 QString last; |
|
2428 |
|
2429 /* |
|
2430 The caller didn't pass in a common prefix, so get the common |
|
2431 prefix by looking at the class names of the first and last |
|
2432 classes in the class map. Discard any namespace names and |
|
2433 just use the bare class names. For Qt, the prefix is "Q". |
|
2434 |
|
2435 Note that the algorithm used here to derive the common prefix |
|
2436 from the first and last classes in alphabetical order (QAccel |
|
2437 and QXtWidget in Qt 2.1), fails if either class name does not |
|
2438 begin with Q. |
|
2439 */ |
|
2440 |
|
2441 NodeMap::const_iterator iter = classMap.begin(); |
|
2442 while (iter != classMap.end()) { |
|
2443 if (!iter.key().contains("::")) { |
|
2444 first = iter.key(); |
|
2445 break; |
|
2446 } |
|
2447 ++iter; |
|
2448 } |
|
2449 |
|
2450 if (first.isEmpty()) |
|
2451 first = classMap.begin().key(); |
|
2452 |
|
2453 iter = classMap.end(); |
|
2454 while (iter != classMap.begin()) { |
|
2455 --iter; |
|
2456 if (!iter.key().contains("::")) { |
|
2457 last = iter.key(); |
|
2458 break; |
|
2459 } |
|
2460 } |
|
2461 |
|
2462 if (last.isEmpty()) |
|
2463 last = classMap.begin().key(); |
|
2464 |
|
2465 if (classMap.size() > 1) { |
|
2466 while (commonPrefixLen < first.length() + 1 && |
|
2467 commonPrefixLen < last.length() + 1 && |
|
2468 first[commonPrefixLen] == last[commonPrefixLen]) |
|
2469 ++commonPrefixLen; |
|
2470 } |
|
2471 |
|
2472 commonPrefix = first.left(commonPrefixLen); |
|
2473 } |
|
2474 |
|
2475 /* |
|
2476 Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z, |
|
2477 underscore (_). QAccel will fall in paragraph 10 (A) and |
|
2478 QXtWidget in paragraph 33 (X). This is the only place where we |
|
2479 assume that NumParagraphs is 37. Each paragraph is a NodeMap. |
|
2480 */ |
|
2481 NodeMap paragraph[NumParagraphs+1]; |
|
2482 QString paragraphName[NumParagraphs+1]; |
|
2483 QSet<char> usedParagraphNames; |
|
2484 |
|
2485 NodeMap::ConstIterator c = classMap.begin(); |
|
2486 while (c != classMap.end()) { |
|
2487 QStringList pieces = c.key().split("::"); |
|
2488 QString key; |
|
2489 int idx = commonPrefixLen; |
|
2490 if (!pieces.last().startsWith(commonPrefix)) |
|
2491 idx = 0; |
|
2492 if (pieces.size() == 1) |
|
2493 key = pieces.last().mid(idx).toLower(); |
|
2494 else |
|
2495 key = pieces.last().toLower(); |
|
2496 |
|
2497 int paragraphNr = NumParagraphs - 1; |
|
2498 |
|
2499 if (key[0].digitValue() != -1) { |
|
2500 paragraphNr = key[0].digitValue(); |
|
2501 } |
|
2502 else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) { |
|
2503 paragraphNr = 10 + key[0].unicode() - 'a'; |
|
2504 } |
|
2505 |
|
2506 paragraphName[paragraphNr] = key[0].toUpper(); |
|
2507 usedParagraphNames.insert(key[0].toLower().cell()); |
|
2508 paragraph[paragraphNr].insert(key, c.value()); |
|
2509 ++c; |
|
2510 } |
|
2511 |
|
2512 /* |
|
2513 Each paragraph j has a size: paragraph[j].count(). In the |
|
2514 discussion, we will assume paragraphs 0 to 5 will have sizes |
|
2515 3, 1, 4, 1, 5, 9. |
|
2516 |
|
2517 We now want to compute the paragraph offset. Paragraphs 0 to 6 |
|
2518 start at offsets 0, 3, 4, 8, 9, 14, 23. |
|
2519 */ |
|
2520 int paragraphOffset[NumParagraphs + 1]; // 37 + 1 |
|
2521 paragraphOffset[0] = 0; |
|
2522 for (int i=0; i<NumParagraphs; i++) // i = 0..36 |
|
2523 paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count(); |
|
2524 |
|
2525 int curParNr = 0; |
|
2526 int curParOffset = 0; |
|
2527 |
|
2528 /* |
|
2529 Output the alphabet as a row of links. |
|
2530 */ |
|
2531 if (includeAlphabet) { |
|
2532 out() << "<p class=\"centerAlign functionIndex\"><b>"; |
|
2533 for (int i = 0; i < 26; i++) { |
|
2534 QChar ch('a' + i); |
|
2535 if (usedParagraphNames.contains(char('a' + i))) |
|
2536 out() << QString("<xref href=\"#%1\">%2</xref> ").arg(ch).arg(ch.toUpper()); |
|
2537 } |
|
2538 out() << "</b></p>\n"; |
|
2539 } |
|
2540 |
|
2541 /* |
|
2542 Output a <div> element to contain all the <dl> elements. |
|
2543 */ |
|
2544 out() << "<div class=\"flowListDiv\">\n"; |
|
2545 |
|
2546 for (int i=0; i<classMap.count()-1; i++) { |
|
2547 while ((curParNr < NumParagraphs) && |
|
2548 (curParOffset == paragraph[curParNr].count())) { |
|
2549 ++curParNr; |
|
2550 curParOffset = 0; |
|
2551 } |
|
2552 |
|
2553 /* |
|
2554 Starting a new paragraph means starting a new <dl>. |
|
2555 */ |
|
2556 if (curParOffset == 0) { |
|
2557 if (i > 0) |
|
2558 out() << "</dl>\n"; |
|
2559 if (++numTableRows % 2 == 1) |
|
2560 out() << "<dl class=\"flowList odd\">"; |
|
2561 else |
|
2562 out() << "<dl class=\"flowList even\">"; |
|
2563 out() << "<dt class=\"alphaChar\">"; |
|
2564 if (includeAlphabet) { |
|
2565 QChar c = paragraphName[curParNr][0].toLower(); |
|
2566 out() << QString("<a name=\"%1\"></a>").arg(c); |
|
2567 } |
|
2568 out() << "<b>" |
|
2569 << paragraphName[curParNr] |
|
2570 << "</b>"; |
|
2571 out() << "</dt>\n"; |
|
2572 } |
|
2573 |
|
2574 /* |
|
2575 Output a <dd> for the current offset in the current paragraph. |
|
2576 */ |
|
2577 out() << "<dd>"; |
|
2578 if ((curParNr < NumParagraphs) && |
|
2579 !paragraphName[curParNr].isEmpty()) { |
|
2580 NodeMap::Iterator it; |
|
2581 it = paragraph[curParNr].begin(); |
|
2582 for (int i=0; i<curParOffset; i++) |
|
2583 ++it; |
|
2584 |
|
2585 /* |
|
2586 Previously, we used generateFullName() for this, but we |
|
2587 require some special formatting. |
|
2588 */ |
|
2589 out() << "<xref href=\"" << linkForNode(it.value(), relative) << "\">"; |
|
2590 |
|
2591 QStringList pieces; |
|
2592 if (it.value()->subType() == Node::QmlClass) |
|
2593 pieces << it.value()->name(); |
|
2594 else |
|
2595 pieces = fullName(it.value(), relative, marker).split("::"); |
|
2596 out() << protectEnc(pieces.last()); |
|
2597 out() << "</xref>"; |
|
2598 if (pieces.size() > 1) { |
|
2599 out() << " ("; |
|
2600 generateFullName(it.value()->parent(), relative, marker); |
|
2601 out() << ")"; |
|
2602 } |
|
2603 } |
|
2604 out() << "</dd>\n"; |
|
2605 curParOffset++; |
|
2606 } |
|
2607 out() << "</dl>\n"; |
|
2608 out() << "</div>\n"; |
|
2609 } |
|
2610 |
|
2611 void DitaXmlGenerator::generateFunctionIndex(const Node *relative, |
|
2612 CodeMarker *marker) |
|
2613 { |
|
2614 out() << "<p class=\"centerAlign functionIndex\"><b>"; |
|
2615 for (int i = 0; i < 26; i++) { |
|
2616 QChar ch('a' + i); |
|
2617 out() << QString("<xref href=\"#%1\">%2</xref> ").arg(ch).arg(ch.toUpper()); |
|
2618 } |
|
2619 out() << "</b></p>\n"; |
|
2620 |
|
2621 char nextLetter = 'a'; |
|
2622 char currentLetter; |
|
2623 |
|
2624 #if 1 |
|
2625 out() << "<ul>\n"; |
|
2626 #endif |
|
2627 QMap<QString, NodeMap >::ConstIterator f = funcIndex.begin(); |
|
2628 while (f != funcIndex.end()) { |
|
2629 #if 1 |
|
2630 out() << "<li>"; |
|
2631 #else |
|
2632 out() << "<p>"; |
|
2633 #endif |
|
2634 out() << protectEnc(f.key()) << ":"; |
|
2635 |
|
2636 currentLetter = f.key()[0].unicode(); |
|
2637 while (islower(currentLetter) && currentLetter >= nextLetter) { |
|
2638 out() << QString("<a name=\"%1\"></a>").arg(nextLetter); |
|
2639 nextLetter++; |
|
2640 } |
|
2641 |
|
2642 NodeMap::ConstIterator s = (*f).begin(); |
|
2643 while (s != (*f).end()) { |
|
2644 out() << " "; |
|
2645 generateFullName((*s)->parent(), relative, marker, *s); |
|
2646 ++s; |
|
2647 } |
|
2648 #if 1 |
|
2649 out() << "</li>"; |
|
2650 #else |
|
2651 out() << "</p>"; |
|
2652 #endif |
|
2653 out() << "\n"; |
|
2654 ++f; |
|
2655 } |
|
2656 #if 1 |
|
2657 out() << "</ul>\n"; |
|
2658 #endif |
|
2659 } |
|
2660 |
|
2661 void DitaXmlGenerator::generateLegaleseList(const Node *relative, |
|
2662 CodeMarker *marker) |
|
2663 { |
|
2664 QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin(); |
|
2665 while (it != legaleseTexts.end()) { |
|
2666 Text text = it.key(); |
|
2667 out() << "<hr />\n"; |
|
2668 generateText(text, relative, marker); |
|
2669 out() << "<ul>\n"; |
|
2670 do { |
|
2671 out() << "<li>"; |
|
2672 generateFullName(it.value(), relative, marker); |
|
2673 out() << "</li>\n"; |
|
2674 ++it; |
|
2675 } while (it != legaleseTexts.end() && it.key() == text); |
|
2676 out() << "</ul>\n"; |
|
2677 } |
|
2678 } |
|
2679 |
|
2680 /*void DitaXmlGenerator::generateSynopsis(const Node *node, |
|
2681 const Node *relative, |
|
2682 CodeMarker *marker, |
|
2683 CodeMarker::SynopsisStyle style) |
|
2684 { |
|
2685 QString marked = marker->markedUpSynopsis(node, relative, style); |
|
2686 QRegExp templateTag("(<[^@>]*>)"); |
|
2687 if (marked.indexOf(templateTag) != -1) { |
|
2688 QString contents = protectEnc(marked.mid(templateTag.pos(1), |
|
2689 templateTag.cap(1).length())); |
|
2690 marked.replace(templateTag.pos(1), templateTag.cap(1).length(), |
|
2691 contents); |
|
2692 } |
|
2693 marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), |
|
2694 "<i>\\1<sub>\\2</sub></i>"); |
|
2695 marked.replace("<@param>", "<i>"); |
|
2696 marked.replace("</@param>", "</i>"); |
|
2697 |
|
2698 if (style == CodeMarker::Summary) |
|
2699 marked.replace("@name>", "b>"); |
|
2700 |
|
2701 if (style == CodeMarker::SeparateList) { |
|
2702 QRegExp extraRegExp("<@extra>.*</@extra>"); |
|
2703 extraRegExp.setMinimal(true); |
|
2704 marked.replace(extraRegExp, ""); |
|
2705 } |
|
2706 else { |
|
2707 marked.replace("<@extra>", " <tt>"); |
|
2708 marked.replace("</@extra>", "</tt>"); |
|
2709 } |
|
2710 |
|
2711 if (style != CodeMarker::Detailed) { |
|
2712 marked.replace("<@type>", ""); |
|
2713 marked.replace("</@type>", ""); |
|
2714 } |
|
2715 out() << highlightedCode(marked, marker, relative); |
|
2716 }*/ |
|
2717 |
|
2718 #ifdef QDOC_QML |
|
2719 void DitaXmlGenerator::generateQmlItem(const Node *node, |
|
2720 const Node *relative, |
|
2721 CodeMarker *marker, |
|
2722 bool summary) |
|
2723 { |
|
2724 QString marked = marker->markedUpQmlItem(node,summary); |
|
2725 QRegExp templateTag("(<[^@>]*>)"); |
|
2726 if (marked.indexOf(templateTag) != -1) { |
|
2727 QString contents = protectEnc(marked.mid(templateTag.pos(1), |
|
2728 templateTag.cap(1).length())); |
|
2729 marked.replace(templateTag.pos(1), templateTag.cap(1).length(), |
|
2730 contents); |
|
2731 } |
|
2732 marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), |
|
2733 "<i>\\1<sub>\\2</sub></i>"); |
|
2734 marked.replace("<@param>", "<i>"); |
|
2735 marked.replace("</@param>", "</i>"); |
|
2736 |
|
2737 if (summary) |
|
2738 marked.replace("@name>", "b>"); |
|
2739 |
|
2740 marked.replace("<@extra>", "<tt>"); |
|
2741 marked.replace("</@extra>", "</tt>"); |
|
2742 |
|
2743 if (summary) { |
|
2744 marked.replace("<@type>", ""); |
|
2745 marked.replace("</@type>", ""); |
|
2746 } |
|
2747 out() << highlightedCode(marked, marker, relative); |
|
2748 } |
|
2749 #endif |
|
2750 |
|
2751 void DitaXmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */) |
|
2752 { |
|
2753 QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap; |
|
2754 QMap<QString, const FakeNode *> groupTitlesMap; |
|
2755 QMap<QString, FakeNode *> uncategorizedNodeMap; |
|
2756 QRegExp singleDigit("\\b([0-9])\\b"); |
|
2757 |
|
2758 const NodeList children = myTree->root()->childNodes(); |
|
2759 foreach (Node *child, children) { |
|
2760 if (child->type() == Node::Fake && child != relative) { |
|
2761 FakeNode *fakeNode = static_cast<FakeNode *>(child); |
|
2762 |
|
2763 // Check whether the page is part of a group or is the group |
|
2764 // definition page. |
|
2765 QString group; |
|
2766 bool isGroupPage = false; |
|
2767 if (fakeNode->doc().metaCommandsUsed().contains("group")) { |
|
2768 group = fakeNode->doc().metaCommandArgs("group")[0]; |
|
2769 isGroupPage = true; |
|
2770 } |
|
2771 |
|
2772 // there are too many examples; they would clutter the list |
|
2773 if (fakeNode->subType() == Node::Example) |
|
2774 continue; |
|
2775 |
|
2776 // not interested either in individual (Qt Designer etc.) manual chapters |
|
2777 if (fakeNode->links().contains(Node::ContentsLink)) |
|
2778 continue; |
|
2779 |
|
2780 // Discard external nodes. |
|
2781 if (fakeNode->subType() == Node::ExternalPage) |
|
2782 continue; |
|
2783 |
|
2784 QString sortKey = fakeNode->fullTitle().toLower(); |
|
2785 if (sortKey.startsWith("the ")) |
|
2786 sortKey.remove(0, 4); |
|
2787 sortKey.replace(singleDigit, "0\\1"); |
|
2788 |
|
2789 if (!group.isEmpty()) { |
|
2790 if (isGroupPage) { |
|
2791 // If we encounter a group definition page, we add all |
|
2792 // the pages in that group to the list for that group. |
|
2793 foreach (Node *member, fakeNode->groupMembers()) { |
|
2794 if (member->type() != Node::Fake) |
|
2795 continue; |
|
2796 FakeNode *page = static_cast<FakeNode *>(member); |
|
2797 if (page) { |
|
2798 QString sortKey = page->fullTitle().toLower(); |
|
2799 if (sortKey.startsWith("the ")) |
|
2800 sortKey.remove(0, 4); |
|
2801 sortKey.replace(singleDigit, "0\\1"); |
|
2802 fakeNodeMap[const_cast<const FakeNode *>(fakeNode)].insert(sortKey, page); |
|
2803 groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode); |
|
2804 } |
|
2805 } |
|
2806 } |
|
2807 else if (!isGroupPage) { |
|
2808 // If we encounter a page that belongs to a group then |
|
2809 // we add that page to the list for that group. |
|
2810 const FakeNode *groupNode = static_cast<const FakeNode *>(myTree->root()->findNode(group, Node::Fake)); |
|
2811 if (groupNode) |
|
2812 fakeNodeMap[groupNode].insert(sortKey, fakeNode); |
|
2813 //else |
|
2814 // uncategorizedNodeMap.insert(sortKey, fakeNode); |
|
2815 }// else |
|
2816 // uncategorizedNodeMap.insert(sortKey, fakeNode); |
|
2817 }// else |
|
2818 // uncategorizedNodeMap.insert(sortKey, fakeNode); |
|
2819 } |
|
2820 } |
|
2821 |
|
2822 // We now list all the pages found that belong to groups. |
|
2823 // If only certain pages were found for a group, but the definition page |
|
2824 // for that group wasn't listed, the list of pages will be intentionally |
|
2825 // incomplete. However, if the group definition page was listed, all the |
|
2826 // pages in that group are listed for completeness. |
|
2827 |
|
2828 if (!fakeNodeMap.isEmpty()) { |
|
2829 foreach (const QString &groupTitle, groupTitlesMap.keys()) { |
|
2830 const FakeNode *groupNode = groupTitlesMap[groupTitle]; |
|
2831 out() << QString("<h3><xref href=\"%1\">%2</xref></h3>\n").arg( |
|
2832 linkForNode(groupNode, relative)).arg( |
|
2833 protectEnc(groupNode->fullTitle())); |
|
2834 |
|
2835 if (fakeNodeMap[groupNode].count() == 0) |
|
2836 continue; |
|
2837 |
|
2838 out() << "<ul>\n"; |
|
2839 |
|
2840 foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) { |
|
2841 QString title = fakeNode->fullTitle(); |
|
2842 if (title.startsWith("The ")) |
|
2843 title.remove(0, 4); |
|
2844 out() << "<li><xref href=\"" << linkForNode(fakeNode, relative) << "\">" |
|
2845 << protectEnc(title) << "</xref></li>\n"; |
|
2846 } |
|
2847 out() << "</ul>\n"; |
|
2848 } |
|
2849 } |
|
2850 |
|
2851 if (!uncategorizedNodeMap.isEmpty()) { |
|
2852 out() << QString("<h3>Miscellaneous</h3>\n"); |
|
2853 out() << "<ul>\n"; |
|
2854 foreach (const FakeNode *fakeNode, uncategorizedNodeMap) { |
|
2855 QString title = fakeNode->fullTitle(); |
|
2856 if (title.startsWith("The ")) |
|
2857 title.remove(0, 4); |
|
2858 out() << "<li><xref href=\"" << linkForNode(fakeNode, relative) << "\">" |
|
2859 << protectEnc(title) << "</xref></li>\n"; |
|
2860 } |
|
2861 out() << "</ul>\n"; |
|
2862 } |
|
2863 } |
|
2864 |
|
2865 void DitaXmlGenerator::generateSection(const NodeList& nl, |
|
2866 const Node *relative, |
|
2867 CodeMarker *marker, |
|
2868 CodeMarker::SynopsisStyle style) |
|
2869 { |
|
2870 bool name_alignment = true; |
|
2871 if (!nl.isEmpty()) { |
|
2872 bool twoColumn = false; |
|
2873 if (style == CodeMarker::SeparateList) { |
|
2874 name_alignment = false; |
|
2875 twoColumn = (nl.count() >= 16); |
|
2876 } |
|
2877 else if (nl.first()->type() == Node::Property) { |
|
2878 twoColumn = (nl.count() >= 5); |
|
2879 name_alignment = false; |
|
2880 } |
|
2881 if (name_alignment) { |
|
2882 out() << "<table class=\"alignedsummary\">\n"; |
|
2883 } |
|
2884 else { |
|
2885 if (twoColumn) |
|
2886 out() << "<table class=\"propsummary\">\n" |
|
2887 << "<tr><td class=\"topAlign\">"; |
|
2888 out() << "<ul>\n"; |
|
2889 } |
|
2890 |
|
2891 int i = 0; |
|
2892 NodeList::ConstIterator m = nl.begin(); |
|
2893 while (m != nl.end()) { |
|
2894 if ((*m)->access() == Node::Private) { |
|
2895 ++m; |
|
2896 continue; |
|
2897 } |
|
2898 |
|
2899 if (name_alignment) { |
|
2900 out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> "; |
|
2901 } |
|
2902 else { |
|
2903 if (twoColumn && i == (int) (nl.count() + 1) / 2) |
|
2904 out() << "</ul></td><td class=\"topAlign\"><ul>\n"; |
|
2905 out() << "<li class=\"fn\">"; |
|
2906 } |
|
2907 |
|
2908 generateSynopsis(*m, relative, marker, style, name_alignment); |
|
2909 if (name_alignment) |
|
2910 out() << "</td></tr>\n"; |
|
2911 else |
|
2912 out() << "</li>\n"; |
|
2913 i++; |
|
2914 ++m; |
|
2915 } |
|
2916 if (name_alignment) |
|
2917 out() << "</table>\n"; |
|
2918 else { |
|
2919 out() << "</ul>\n"; |
|
2920 if (twoColumn) |
|
2921 out() << "</td></tr>\n</table>\n"; |
|
2922 } |
|
2923 } |
|
2924 } |
|
2925 |
|
2926 void DitaXmlGenerator::generateSectionList(const Section& section, |
|
2927 const Node *relative, |
|
2928 CodeMarker *marker, |
|
2929 CodeMarker::SynopsisStyle style) |
|
2930 { |
|
2931 bool name_alignment = true; |
|
2932 if (!section.members.isEmpty()) { |
|
2933 bool twoColumn = false; |
|
2934 if (style == CodeMarker::SeparateList) { |
|
2935 name_alignment = false; |
|
2936 twoColumn = (section.members.count() >= 16); |
|
2937 } |
|
2938 else if (section.members.first()->type() == Node::Property) { |
|
2939 twoColumn = (section.members.count() >= 5); |
|
2940 name_alignment = false; |
|
2941 } |
|
2942 if (name_alignment) { |
|
2943 out() << "<table class=\"alignedsummary\">\n"; |
|
2944 } |
|
2945 else { |
|
2946 if (twoColumn) |
|
2947 out() << "<table class=\"propsummary\">\n" |
|
2948 << "<tr><td class=\"topAlign\">"; |
|
2949 out() << "<ul>\n"; |
|
2950 } |
|
2951 |
|
2952 int i = 0; |
|
2953 NodeList::ConstIterator m = section.members.begin(); |
|
2954 while (m != section.members.end()) { |
|
2955 if ((*m)->access() == Node::Private) { |
|
2956 ++m; |
|
2957 continue; |
|
2958 } |
|
2959 |
|
2960 if (name_alignment) { |
|
2961 out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> "; |
|
2962 } |
|
2963 else { |
|
2964 if (twoColumn && i == (int) (section.members.count() + 1) / 2) |
|
2965 out() << "</ul></td><td class=\"topAlign\"><ul>\n"; |
|
2966 out() << "<li class=\"fn\">"; |
|
2967 } |
|
2968 |
|
2969 generateSynopsis(*m, relative, marker, style, name_alignment); |
|
2970 if (name_alignment) |
|
2971 out() << "</td></tr>\n"; |
|
2972 else |
|
2973 out() << "</li>\n"; |
|
2974 i++; |
|
2975 ++m; |
|
2976 } |
|
2977 if (name_alignment) |
|
2978 out() << "</table>\n"; |
|
2979 else { |
|
2980 out() << "</ul>\n"; |
|
2981 if (twoColumn) |
|
2982 out() << "</td></tr>\n</table>\n"; |
|
2983 } |
|
2984 } |
|
2985 |
|
2986 if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { |
|
2987 out() << "<ul>\n"; |
|
2988 generateSectionInheritedList(section, relative, marker, name_alignment); |
|
2989 out() << "</ul>\n"; |
|
2990 } |
|
2991 } |
|
2992 |
|
2993 void DitaXmlGenerator::generateSectionInheritedList(const Section& section, |
|
2994 const Node *relative, |
|
2995 CodeMarker *marker, |
|
2996 bool nameAlignment) |
|
2997 { |
|
2998 QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin(); |
|
2999 while (p != section.inherited.end()) { |
|
3000 if (nameAlignment) |
|
3001 out() << "<li class=\"fn\">"; |
|
3002 else |
|
3003 out() << "<li class=\"fn\">"; |
|
3004 out() << (*p).second << " "; |
|
3005 if ((*p).second == 1) { |
|
3006 out() << section.singularMember; |
|
3007 } |
|
3008 else { |
|
3009 out() << section.pluralMember; |
|
3010 } |
|
3011 out() << " inherited from <xref href=\"" << fileName((*p).first) |
|
3012 << "#" << DitaXmlGenerator::cleanRef(section.name.toLower()) << "\">" |
|
3013 << protectEnc(marker->plainFullName((*p).first, relative)) |
|
3014 << "</xref></li>\n"; |
|
3015 ++p; |
|
3016 } |
|
3017 } |
|
3018 |
|
3019 void DitaXmlGenerator::generateSynopsis(const Node *node, |
|
3020 const Node *relative, |
|
3021 CodeMarker *marker, |
|
3022 CodeMarker::SynopsisStyle style, |
|
3023 bool nameAlignment) |
|
3024 { |
|
3025 QString marked = marker->markedUpSynopsis(node, relative, style); |
|
3026 QRegExp templateTag("(<[^@>]*>)"); |
|
3027 if (marked.indexOf(templateTag) != -1) { |
|
3028 QString contents = protectEnc(marked.mid(templateTag.pos(1), |
|
3029 templateTag.cap(1).length())); |
|
3030 marked.replace(templateTag.pos(1), templateTag.cap(1).length(), |
|
3031 contents); |
|
3032 } |
|
3033 marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), |
|
3034 "<i>\\1<sub>\\2</sub></i>"); |
|
3035 marked.replace("<@param>", "<i>"); |
|
3036 marked.replace("</@param>", "</i>"); |
|
3037 |
|
3038 if (style == CodeMarker::Summary) { |
|
3039 marked.replace("<@name>", ""); // was "<b>" |
|
3040 marked.replace("</@name>", ""); // was "</b>" |
|
3041 } |
|
3042 |
|
3043 if (style == CodeMarker::SeparateList) { |
|
3044 QRegExp extraRegExp("<@extra>.*</@extra>"); |
|
3045 extraRegExp.setMinimal(true); |
|
3046 marked.replace(extraRegExp, ""); |
|
3047 } else { |
|
3048 marked.replace("<@extra>", "<tt>"); |
|
3049 marked.replace("</@extra>", "</tt>"); |
|
3050 } |
|
3051 |
|
3052 if (style != CodeMarker::Detailed) { |
|
3053 marked.replace("<@type>", ""); |
|
3054 marked.replace("</@type>", ""); |
|
3055 } |
|
3056 out() << highlightedCode(marked, marker, relative, style, nameAlignment); |
|
3057 } |
|
3058 |
|
3059 QString DitaXmlGenerator::highlightedCode(const QString& markedCode, |
|
3060 CodeMarker *marker, |
|
3061 const Node *relative, |
|
3062 CodeMarker::SynopsisStyle , |
|
3063 bool nameAlignment) |
|
3064 { |
|
3065 QString src = markedCode; |
|
3066 QString html; |
|
3067 QStringRef arg; |
|
3068 QStringRef par1; |
|
3069 |
|
3070 const QChar charLangle = '<'; |
|
3071 const QChar charAt = '@'; |
|
3072 |
|
3073 // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" |
|
3074 static const QString linkTag("link"); |
|
3075 bool done = false; |
|
3076 for (int i = 0, n = src.size(); i < n;) { |
|
3077 if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') { |
|
3078 if (nameAlignment && !done) {// && (i != 0)) Why was this here? |
|
3079 html += "</td><td class=\"memItemRight bottomAlign\">"; |
|
3080 done = true; |
|
3081 } |
|
3082 i += 2; |
|
3083 if (parseArg(src, linkTag, &i, n, &arg, &par1)) { |
|
3084 html += "<b>"; |
|
3085 QString link = linkForNode( |
|
3086 CodeMarker::nodeForString(par1.toString()), relative); |
|
3087 addLink(link, arg, &html); |
|
3088 html += "</b>"; |
|
3089 } |
|
3090 else { |
|
3091 html += charLangle; |
|
3092 html += charAt; |
|
3093 } |
|
3094 } |
|
3095 else { |
|
3096 html += src.at(i++); |
|
3097 } |
|
3098 } |
|
3099 |
|
3100 |
|
3101 if (slow) { |
|
3102 // is this block ever used at all? |
|
3103 // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" |
|
3104 src = html; |
|
3105 html = QString(); |
|
3106 static const QString funcTag("func"); |
|
3107 for (int i = 0, n = src.size(); i < n;) { |
|
3108 if (src.at(i) == charLangle && src.at(i + 1) == charAt) { |
|
3109 i += 2; |
|
3110 if (parseArg(src, funcTag, &i, n, &arg, &par1)) { |
|
3111 QString link = linkForNode( |
|
3112 marker->resolveTarget(par1.toString(), |
|
3113 myTree, |
|
3114 relative), |
|
3115 relative); |
|
3116 addLink(link, arg, &html); |
|
3117 par1 = QStringRef(); |
|
3118 } |
|
3119 else { |
|
3120 html += charLangle; |
|
3121 html += charAt; |
|
3122 } |
|
3123 } |
|
3124 else { |
|
3125 html += src.at(i++); |
|
3126 } |
|
3127 } |
|
3128 } |
|
3129 |
|
3130 // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags |
|
3131 src = html; |
|
3132 html = QString(); |
|
3133 static const QString typeTags[] = { "type", "headerfile", "func" }; |
|
3134 for (int i = 0, n = src.size(); i < n;) { |
|
3135 if (src.at(i) == charLangle && src.at(i + 1) == charAt) { |
|
3136 i += 2; |
|
3137 bool handled = false; |
|
3138 for (int k = 0; k != 3; ++k) { |
|
3139 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) { |
|
3140 par1 = QStringRef(); |
|
3141 QString link = linkForNode( |
|
3142 marker->resolveTarget(arg.toString(), myTree, relative), |
|
3143 relative); |
|
3144 addLink(link, arg, &html); |
|
3145 handled = true; |
|
3146 break; |
|
3147 } |
|
3148 } |
|
3149 if (!handled) { |
|
3150 html += charLangle; |
|
3151 html += charAt; |
|
3152 } |
|
3153 } |
|
3154 else { |
|
3155 html += src.at(i++); |
|
3156 } |
|
3157 } |
|
3158 |
|
3159 // replace all |
|
3160 // "<@comment>" -> "<span class=\"comment\">"; |
|
3161 // "<@preprocessor>" -> "<span class=\"preprocessor\">"; |
|
3162 // "<@string>" -> "<span class=\"string\">"; |
|
3163 // "<@char>" -> "<span class=\"char\">"; |
|
3164 // "</@(?:comment|preprocessor|string|char)>" -> "</span>" |
|
3165 src = html; |
|
3166 html = QString(); |
|
3167 static const QString spanTags[] = { |
|
3168 "<@comment>", "<span class=\"comment\">", |
|
3169 "<@preprocessor>", "<span class=\"preprocessor\">", |
|
3170 "<@string>", "<span class=\"string\">", |
|
3171 "<@char>", "<span class=\"char\">", |
|
3172 "</@comment>", "</span>", |
|
3173 "</@preprocessor>","</span>", |
|
3174 "</@string>", "</span>", |
|
3175 "</@char>", "</span>" |
|
3176 // "<@char>", "<font color=blue>", |
|
3177 // "</@char>", "</font>", |
|
3178 // "<@func>", "<font color=green>", |
|
3179 // "</@func>", "</font>", |
|
3180 // "<@id>", "<i>", |
|
3181 // "</@id>", "</i>", |
|
3182 // "<@keyword>", "<b>", |
|
3183 // "</@keyword>", "</b>", |
|
3184 // "<@number>", "<font color=yellow>", |
|
3185 // "</@number>", "</font>", |
|
3186 // "<@op>", "<b>", |
|
3187 // "</@op>", "</b>", |
|
3188 // "<@param>", "<i>", |
|
3189 // "</@param>", "</i>", |
|
3190 // "<@string>", "<font color=green>", |
|
3191 // "</@string>", "</font>", |
|
3192 }; |
|
3193 for (int i = 0, n = src.size(); i < n;) { |
|
3194 if (src.at(i) == charLangle) { |
|
3195 bool handled = false; |
|
3196 for (int k = 0; k != 8; ++k) { |
|
3197 const QString & tag = spanTags[2 * k]; |
|
3198 if (tag == QStringRef(&src, i, tag.length())) { |
|
3199 html += spanTags[2 * k + 1]; |
|
3200 i += tag.length(); |
|
3201 handled = true; |
|
3202 break; |
|
3203 } |
|
3204 } |
|
3205 if (!handled) { |
|
3206 ++i; |
|
3207 if (src.at(i) == charAt || |
|
3208 (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { |
|
3209 // drop 'our' unknown tags (the ones still containing '@') |
|
3210 while (i < n && src.at(i) != QLatin1Char('>')) |
|
3211 ++i; |
|
3212 ++i; |
|
3213 } |
|
3214 else { |
|
3215 // retain all others |
|
3216 html += charLangle; |
|
3217 } |
|
3218 } |
|
3219 } |
|
3220 else { |
|
3221 html += src.at(i); |
|
3222 ++i; |
|
3223 } |
|
3224 } |
|
3225 |
|
3226 return html; |
|
3227 } |
|
3228 |
|
3229 void DitaXmlGenerator::generateLink(const Atom* atom, |
|
3230 const Node* /* relative */, |
|
3231 CodeMarker* marker) |
|
3232 { |
|
3233 static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_"); |
|
3234 |
|
3235 if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) { |
|
3236 // hack for C++: move () outside of link |
|
3237 int k = funcLeftParen.pos(1); |
|
3238 writer.writeCharacters(protectEnc(atom->string().left(k))); |
|
3239 if (link.isEmpty()) { |
|
3240 if (showBrokenLinks) |
|
3241 writer.writeEndElement(); // </i> |
|
3242 } |
|
3243 else { |
|
3244 writer.writeEndElement(); // </xref> |
|
3245 } |
|
3246 inLink = false; |
|
3247 writer.writeCharacters(protectEnc(atom->string().mid(k))); |
|
3248 } else if (marker->recognizeLanguage("Java")) { |
|
3249 // hack for Java: remove () and use <tt> when appropriate |
|
3250 bool func = atom->string().endsWith("()"); |
|
3251 bool tt = (func || atom->string().contains(camelCase)); |
|
3252 if (tt) |
|
3253 writer.writeStartElement("tt"); |
|
3254 if (func) { |
|
3255 writer.writeCharacters(protectEnc(atom->string().left(atom->string().length() - 2))); |
|
3256 } |
|
3257 else { |
|
3258 writer.writeCharacters(protectEnc(atom->string())); |
|
3259 } |
|
3260 writer.writeEndElement(); // </tt> |
|
3261 } |
|
3262 else { |
|
3263 writer.writeCharacters(protectEnc(atom->string())); |
|
3264 } |
|
3265 } |
|
3266 |
|
3267 QString DitaXmlGenerator::cleanRef(const QString& ref) |
|
3268 { |
|
3269 QString clean; |
|
3270 |
|
3271 if (ref.isEmpty()) |
|
3272 return clean; |
|
3273 |
|
3274 clean.reserve(ref.size() + 20); |
|
3275 const QChar c = ref[0]; |
|
3276 const uint u = c.unicode(); |
|
3277 |
|
3278 if ((u >= 'a' && u <= 'z') || |
|
3279 (u >= 'A' && u <= 'Z') || |
|
3280 (u >= '0' && u <= '9')) { |
|
3281 clean += c; |
|
3282 } else if (u == '~') { |
|
3283 clean += "dtor."; |
|
3284 } else if (u == '_') { |
|
3285 clean += "underscore."; |
|
3286 } else { |
|
3287 clean += "A"; |
|
3288 } |
|
3289 |
|
3290 for (int i = 1; i < (int) ref.length(); i++) { |
|
3291 const QChar c = ref[i]; |
|
3292 const uint u = c.unicode(); |
|
3293 if ((u >= 'a' && u <= 'z') || |
|
3294 (u >= 'A' && u <= 'Z') || |
|
3295 (u >= '0' && u <= '9') || u == '-' || |
|
3296 u == '_' || u == ':' || u == '.') { |
|
3297 clean += c; |
|
3298 } else if (c.isSpace()) { |
|
3299 clean += "-"; |
|
3300 } else if (u == '!') { |
|
3301 clean += "-not"; |
|
3302 } else if (u == '&') { |
|
3303 clean += "-and"; |
|
3304 } else if (u == '<') { |
|
3305 clean += "-lt"; |
|
3306 } else if (u == '=') { |
|
3307 clean += "-eq"; |
|
3308 } else if (u == '>') { |
|
3309 clean += "-gt"; |
|
3310 } else if (u == '#') { |
|
3311 clean += "#"; |
|
3312 } else { |
|
3313 clean += "-"; |
|
3314 clean += QString::number((int)u, 16); |
|
3315 } |
|
3316 } |
|
3317 return clean; |
|
3318 } |
|
3319 |
|
3320 QString DitaXmlGenerator::registerRef(const QString& ref) |
|
3321 { |
|
3322 QString clean = DitaXmlGenerator::cleanRef(ref); |
|
3323 |
|
3324 for (;;) { |
|
3325 QString& prevRef = refMap[clean.toLower()]; |
|
3326 if (prevRef.isEmpty()) { |
|
3327 prevRef = ref; |
|
3328 break; |
|
3329 } else if (prevRef == ref) { |
|
3330 break; |
|
3331 } |
|
3332 clean += "x"; |
|
3333 } |
|
3334 return clean; |
|
3335 } |
|
3336 |
|
3337 QString DitaXmlGenerator::protectEnc(const QString &string) |
|
3338 { |
|
3339 return protect(string, outputEncoding); |
|
3340 } |
|
3341 |
|
3342 QString DitaXmlGenerator::protect(const QString &string, const QString &outputEncoding) |
|
3343 { |
|
3344 #define APPEND(x) \ |
|
3345 if (xml.isEmpty()) { \ |
|
3346 xml = string; \ |
|
3347 xml.truncate(i); \ |
|
3348 } \ |
|
3349 xml += (x); |
|
3350 |
|
3351 QString xml; |
|
3352 int n = string.length(); |
|
3353 |
|
3354 for (int i = 0; i < n; ++i) { |
|
3355 QChar ch = string.at(i); |
|
3356 |
|
3357 if (ch == QLatin1Char('&')) { |
|
3358 APPEND("&"); |
|
3359 } else if (ch == QLatin1Char('<')) { |
|
3360 APPEND("<"); |
|
3361 } else if (ch == QLatin1Char('>')) { |
|
3362 APPEND(">"); |
|
3363 } else if (ch == QLatin1Char('"')) { |
|
3364 APPEND("""); |
|
3365 } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) |
|
3366 || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) |
|
3367 || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { |
|
3368 // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator |
|
3369 APPEND("&#x"); |
|
3370 xml += QString::number(ch.unicode(), 16); |
|
3371 xml += QLatin1Char(';'); |
|
3372 } else { |
|
3373 if (!xml.isEmpty()) |
|
3374 xml += ch; |
|
3375 } |
|
3376 } |
|
3377 |
|
3378 if (!xml.isEmpty()) |
|
3379 return xml; |
|
3380 return string; |
|
3381 |
|
3382 #undef APPEND |
|
3383 } |
|
3384 |
|
3385 QString DitaXmlGenerator::fileBase(const Node *node) |
|
3386 { |
|
3387 QString result; |
|
3388 |
|
3389 result = PageGenerator::fileBase(node); |
|
3390 |
|
3391 if (!node->isInnerNode()) { |
|
3392 switch (node->status()) { |
|
3393 case Node::Compat: |
|
3394 result += "-qt3"; |
|
3395 break; |
|
3396 case Node::Obsolete: |
|
3397 result += "-obsolete"; |
|
3398 break; |
|
3399 default: |
|
3400 ; |
|
3401 } |
|
3402 } |
|
3403 return result; |
|
3404 } |
|
3405 |
|
3406 #if 0 |
|
3407 QString DitaXmlGenerator::fileBase(const Node *node, |
|
3408 const SectionIterator& section) |
|
3409 { |
|
3410 QStringList::ConstIterator s = section.sectionNumber().end(); |
|
3411 QStringList::ConstIterator b = section.baseNameStack().end(); |
|
3412 |
|
3413 QString suffix; |
|
3414 QString base = fileBase(node); |
|
3415 |
|
3416 while (s != section.sectionNumber().begin()) { |
|
3417 --s; |
|
3418 --b; |
|
3419 if (!(*b).isEmpty()) { |
|
3420 base = *b; |
|
3421 break; |
|
3422 } |
|
3423 suffix.prepend("-" + *s); |
|
3424 } |
|
3425 return base + suffix; |
|
3426 } |
|
3427 #endif |
|
3428 |
|
3429 QString DitaXmlGenerator::fileName(const Node *node) |
|
3430 { |
|
3431 if (node->type() == Node::Fake) { |
|
3432 if (static_cast<const FakeNode *>(node)->subType() == Node::ExternalPage) |
|
3433 return node->name(); |
|
3434 if (static_cast<const FakeNode *>(node)->subType() == Node::Image) |
|
3435 return node->name(); |
|
3436 } |
|
3437 return PageGenerator::fileName(node); |
|
3438 } |
|
3439 |
|
3440 QString DitaXmlGenerator::refForNode(const Node *node) |
|
3441 { |
|
3442 const FunctionNode *func; |
|
3443 const TypedefNode *typedeffe; |
|
3444 QString ref; |
|
3445 |
|
3446 switch (node->type()) { |
|
3447 case Node::Namespace: |
|
3448 case Node::Class: |
|
3449 default: |
|
3450 break; |
|
3451 case Node::Enum: |
|
3452 ref = node->name() + "-enum"; |
|
3453 break; |
|
3454 case Node::Typedef: |
|
3455 typedeffe = static_cast<const TypedefNode *>(node); |
|
3456 if (typedeffe->associatedEnum()) { |
|
3457 return refForNode(typedeffe->associatedEnum()); |
|
3458 } |
|
3459 else { |
|
3460 ref = node->name() + "-typedef"; |
|
3461 } |
|
3462 break; |
|
3463 case Node::Function: |
|
3464 func = static_cast<const FunctionNode *>(node); |
|
3465 if (func->associatedProperty()) { |
|
3466 return refForNode(func->associatedProperty()); |
|
3467 } |
|
3468 else { |
|
3469 ref = func->name(); |
|
3470 if (func->overloadNumber() != 1) |
|
3471 ref += "-" + QString::number(func->overloadNumber()); |
|
3472 } |
|
3473 break; |
|
3474 #ifdef QDOC_QML |
|
3475 case Node::Fake: |
|
3476 if (node->subType() != Node::QmlPropertyGroup) |
|
3477 break; |
|
3478 case Node::QmlProperty: |
|
3479 #endif |
|
3480 case Node::Property: |
|
3481 ref = node->name() + "-prop"; |
|
3482 break; |
|
3483 #ifdef QDOC_QML |
|
3484 case Node::QmlSignal: |
|
3485 ref = node->name() + "-signal"; |
|
3486 break; |
|
3487 case Node::QmlMethod: |
|
3488 ref = node->name() + "-method"; |
|
3489 break; |
|
3490 #endif |
|
3491 case Node::Variable: |
|
3492 ref = node->name() + "-var"; |
|
3493 break; |
|
3494 case Node::Target: |
|
3495 return protectEnc(node->name()); |
|
3496 } |
|
3497 return registerRef(ref); |
|
3498 } |
|
3499 |
|
3500 QString DitaXmlGenerator::linkForNode(const Node *node, const Node *relative) |
|
3501 { |
|
3502 QString link; |
|
3503 QString fn; |
|
3504 QString ref; |
|
3505 |
|
3506 if (node == 0 || node == relative) |
|
3507 return QString(); |
|
3508 if (!node->url().isEmpty()) |
|
3509 return node->url(); |
|
3510 if (fileBase(node).isEmpty()) |
|
3511 return QString(); |
|
3512 if (node->access() == Node::Private) |
|
3513 return QString(); |
|
3514 |
|
3515 fn = fileName(node); |
|
3516 link += fn; |
|
3517 |
|
3518 if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) { |
|
3519 ref = refForNode(node); |
|
3520 if (relative && fn == fileName(relative) && ref == refForNode(relative)) |
|
3521 return QString(); |
|
3522 |
|
3523 link += "#"; |
|
3524 link += ref; |
|
3525 } |
|
3526 return link; |
|
3527 } |
|
3528 |
|
3529 QString DitaXmlGenerator::refForAtom(Atom *atom, const Node * /* node */) |
|
3530 { |
|
3531 if (atom->type() == Atom::SectionLeft) { |
|
3532 return Doc::canonicalTitle(Text::sectionHeading(atom).toString()); |
|
3533 } |
|
3534 else if (atom->type() == Atom::Target) { |
|
3535 return Doc::canonicalTitle(atom->string()); |
|
3536 } |
|
3537 else { |
|
3538 return QString(); |
|
3539 } |
|
3540 } |
|
3541 |
|
3542 void DitaXmlGenerator::generateFullName(const Node *apparentNode, |
|
3543 const Node *relative, |
|
3544 CodeMarker *marker, |
|
3545 const Node *actualNode) |
|
3546 { |
|
3547 if (actualNode == 0) |
|
3548 actualNode = apparentNode; |
|
3549 out() << "<xref href=\"" << linkForNode(actualNode, relative); |
|
3550 if (true || relative == 0 || relative->status() != actualNode->status()) { |
|
3551 switch (actualNode->status()) { |
|
3552 case Node::Obsolete: |
|
3553 out() << "\" class=\"obsolete"; |
|
3554 break; |
|
3555 case Node::Compat: |
|
3556 out() << "\" class=\"compat"; |
|
3557 break; |
|
3558 default: |
|
3559 ; |
|
3560 } |
|
3561 } |
|
3562 out() << "\">"; |
|
3563 out() << protectEnc(fullName(apparentNode, relative, marker)); |
|
3564 out() << "</xref>"; |
|
3565 } |
|
3566 |
|
3567 void DitaXmlGenerator::generateDetailedMember(const Node *node, |
|
3568 const InnerNode *relative, |
|
3569 CodeMarker *marker) |
|
3570 { |
|
3571 const EnumNode *enume; |
|
3572 |
|
3573 #ifdef GENERATE_MAC_REFS |
|
3574 generateMacRef(node, marker); |
|
3575 #endif |
|
3576 if (node->type() == Node::Enum |
|
3577 && (enume = static_cast<const EnumNode *>(node))->flagsType()) { |
|
3578 #ifdef GENERATE_MAC_REFS |
|
3579 generateMacRef(enume->flagsType(), marker); |
|
3580 #endif |
|
3581 out() << "<h3 class=\"flags\">"; |
|
3582 out() << "<a name=\"" + refForNode(node) + "\"></a>"; |
|
3583 generateSynopsis(enume, relative, marker, CodeMarker::Detailed); |
|
3584 out() << "<br/>"; |
|
3585 generateSynopsis(enume->flagsType(), |
|
3586 relative, |
|
3587 marker, |
|
3588 CodeMarker::Detailed); |
|
3589 out() << "</h3>\n"; |
|
3590 } |
|
3591 else { |
|
3592 out() << "<h3 class=\"fn\">"; |
|
3593 out() << "<a name=\"" + refForNode(node) + "\"></a>"; |
|
3594 generateSynopsis(node, relative, marker, CodeMarker::Detailed); |
|
3595 out() << "</h3>\n"; |
|
3596 } |
|
3597 |
|
3598 generateStatus(node, marker); |
|
3599 generateBody(node, marker); |
|
3600 generateThreadSafeness(node, marker); |
|
3601 generateSince(node, marker); |
|
3602 |
|
3603 if (node->type() == Node::Property) { |
|
3604 const PropertyNode *property = static_cast<const PropertyNode *>(node); |
|
3605 Section section; |
|
3606 |
|
3607 section.members += property->getters(); |
|
3608 section.members += property->setters(); |
|
3609 section.members += property->resetters(); |
|
3610 |
|
3611 if (!section.members.isEmpty()) { |
|
3612 out() << "<p><b>Access functions:</b></p>\n"; |
|
3613 generateSectionList(section, node, marker, CodeMarker::Accessors); |
|
3614 } |
|
3615 |
|
3616 Section notifiers; |
|
3617 notifiers.members += property->notifiers(); |
|
3618 |
|
3619 if (!notifiers.members.isEmpty()) { |
|
3620 out() << "<p><b>Notifier signal:</b></p>\n"; |
|
3621 //out() << "<p>This signal is emitted when the property value is changed.</p>\n"; |
|
3622 generateSectionList(notifiers, node, marker, CodeMarker::Accessors); |
|
3623 } |
|
3624 } |
|
3625 else if (node->type() == Node::Enum) { |
|
3626 const EnumNode *enume = static_cast<const EnumNode *>(node); |
|
3627 if (enume->flagsType()) { |
|
3628 out() << "<p>The " << protectEnc(enume->flagsType()->name()) |
|
3629 << " type is a typedef for " |
|
3630 << "<xref href=\"qflags.html\">QFlags</xref><" |
|
3631 << protectEnc(enume->name()) |
|
3632 << ">. It stores an OR combination of " |
|
3633 << protectEnc(enume->name()) |
|
3634 << " values.</p>\n"; |
|
3635 } |
|
3636 } |
|
3637 generateAlsoList(node, marker); |
|
3638 } |
|
3639 |
|
3640 void DitaXmlGenerator::findAllClasses(const InnerNode *node) |
|
3641 { |
|
3642 NodeList::const_iterator c = node->childNodes().constBegin(); |
|
3643 while (c != node->childNodes().constEnd()) { |
|
3644 if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) { |
|
3645 if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) { |
|
3646 QString className = (*c)->name(); |
|
3647 if ((*c)->parent() && |
|
3648 (*c)->parent()->type() == Node::Namespace && |
|
3649 !(*c)->parent()->name().isEmpty()) |
|
3650 className = (*c)->parent()->name()+"::"+className; |
|
3651 |
|
3652 if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) { |
|
3653 if ((*c)->status() == Node::Compat) { |
|
3654 compatClasses.insert(className, *c); |
|
3655 } |
|
3656 else if ((*c)->status() == Node::Obsolete) { |
|
3657 obsoleteClasses.insert(className, *c); |
|
3658 } |
|
3659 else { |
|
3660 nonCompatClasses.insert(className, *c); |
|
3661 if ((*c)->status() == Node::Main) |
|
3662 mainClasses.insert(className, *c); |
|
3663 } |
|
3664 } |
|
3665 |
|
3666 QString moduleName = (*c)->moduleName(); |
|
3667 if (moduleName == "Qt3SupportLight") { |
|
3668 moduleClassMap[moduleName].insert((*c)->name(), *c); |
|
3669 moduleName = "Qt3Support"; |
|
3670 } |
|
3671 if (!moduleName.isEmpty()) |
|
3672 moduleClassMap[moduleName].insert((*c)->name(), *c); |
|
3673 |
|
3674 QString serviceName = |
|
3675 (static_cast<const ClassNode *>(*c))->serviceName(); |
|
3676 if (!serviceName.isEmpty()) |
|
3677 serviceClasses.insert(serviceName, *c); |
|
3678 } |
|
3679 else if ((*c)->isInnerNode()) { |
|
3680 findAllClasses(static_cast<InnerNode *>(*c)); |
|
3681 } |
|
3682 } |
|
3683 ++c; |
|
3684 } |
|
3685 } |
|
3686 |
|
3687 /*! |
|
3688 For generating the "New Classes... in 4.6" section on the |
|
3689 What's New in 4.6" page. |
|
3690 */ |
|
3691 void DitaXmlGenerator::findAllSince(const InnerNode *node) |
|
3692 { |
|
3693 NodeList::const_iterator child = node->childNodes().constBegin(); |
|
3694 while (child != node->childNodes().constEnd()) { |
|
3695 QString sinceVersion = (*child)->since(); |
|
3696 if (((*child)->access() != Node::Private) && !sinceVersion.isEmpty()) { |
|
3697 NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceVersion); |
|
3698 if (nsmap == newSinceMaps.end()) |
|
3699 nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap()); |
|
3700 NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion); |
|
3701 if (ncmap == newClassMaps.end()) |
|
3702 ncmap = newClassMaps.insert(sinceVersion,NodeMap()); |
|
3703 NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); |
|
3704 if (nqcmap == newQmlClassMaps.end()) |
|
3705 nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); |
|
3706 |
|
3707 if ((*child)->type() == Node::Function) { |
|
3708 FunctionNode *func = static_cast<FunctionNode *>(*child); |
|
3709 if ((func->status() > Node::Obsolete) && |
|
3710 (func->metaness() != FunctionNode::Ctor) && |
|
3711 (func->metaness() != FunctionNode::Dtor)) { |
|
3712 nsmap.value().insert(func->name(),(*child)); |
|
3713 } |
|
3714 } |
|
3715 else if ((*child)->url().isEmpty()) { |
|
3716 if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) { |
|
3717 QString className = (*child)->name(); |
|
3718 if ((*child)->parent() && |
|
3719 (*child)->parent()->type() == Node::Namespace && |
|
3720 !(*child)->parent()->name().isEmpty()) |
|
3721 className = (*child)->parent()->name()+"::"+className; |
|
3722 nsmap.value().insert(className,(*child)); |
|
3723 ncmap.value().insert(className,(*child)); |
|
3724 } |
|
3725 else if ((*child)->subType() == Node::QmlClass) { |
|
3726 QString className = (*child)->name(); |
|
3727 if ((*child)->parent() && |
|
3728 (*child)->parent()->type() == Node::Namespace && |
|
3729 !(*child)->parent()->name().isEmpty()) |
|
3730 className = (*child)->parent()->name()+"::"+className; |
|
3731 nsmap.value().insert(className,(*child)); |
|
3732 nqcmap.value().insert(className,(*child)); |
|
3733 } |
|
3734 } |
|
3735 else { |
|
3736 QString name = (*child)->name(); |
|
3737 if ((*child)->parent() && |
|
3738 (*child)->parent()->type() == Node::Namespace && |
|
3739 !(*child)->parent()->name().isEmpty()) |
|
3740 name = (*child)->parent()->name()+"::"+name; |
|
3741 nsmap.value().insert(name,(*child)); |
|
3742 } |
|
3743 if ((*child)->isInnerNode()) { |
|
3744 findAllSince(static_cast<InnerNode *>(*child)); |
|
3745 } |
|
3746 } |
|
3747 ++child; |
|
3748 } |
|
3749 } |
|
3750 |
|
3751 #if 0 |
|
3752 const QRegExp versionSeparator("[\\-\\.]"); |
|
3753 const int minorIndex = version.indexOf(versionSeparator); |
|
3754 const int patchIndex = version.indexOf(versionSeparator, minorIndex+1); |
|
3755 version = version.left(patchIndex); |
|
3756 #endif |
|
3757 |
|
3758 void DitaXmlGenerator::findAllFunctions(const InnerNode *node) |
|
3759 { |
|
3760 NodeList::ConstIterator c = node->childNodes().begin(); |
|
3761 while (c != node->childNodes().end()) { |
|
3762 if ((*c)->access() != Node::Private) { |
|
3763 if ((*c)->isInnerNode() && (*c)->url().isEmpty()) { |
|
3764 findAllFunctions(static_cast<const InnerNode *>(*c)); |
|
3765 } |
|
3766 else if ((*c)->type() == Node::Function) { |
|
3767 const FunctionNode *func = static_cast<const FunctionNode *>(*c); |
|
3768 if ((func->status() > Node::Obsolete) && |
|
3769 (func->metaness() != FunctionNode::Ctor) && |
|
3770 (func->metaness() != FunctionNode::Dtor)) { |
|
3771 funcIndex[(*c)->name()].insert(myTree->fullDocumentName((*c)->parent()), *c); |
|
3772 } |
|
3773 } |
|
3774 } |
|
3775 ++c; |
|
3776 } |
|
3777 } |
|
3778 |
|
3779 void DitaXmlGenerator::findAllLegaleseTexts(const InnerNode *node) |
|
3780 { |
|
3781 NodeList::ConstIterator c = node->childNodes().begin(); |
|
3782 while (c != node->childNodes().end()) { |
|
3783 if ((*c)->access() != Node::Private) { |
|
3784 if (!(*c)->doc().legaleseText().isEmpty()) |
|
3785 legaleseTexts.insertMulti((*c)->doc().legaleseText(), *c); |
|
3786 if ((*c)->isInnerNode()) |
|
3787 findAllLegaleseTexts(static_cast<const InnerNode *>(*c)); |
|
3788 } |
|
3789 ++c; |
|
3790 } |
|
3791 } |
|
3792 |
|
3793 void DitaXmlGenerator::findAllNamespaces(const InnerNode *node) |
|
3794 { |
|
3795 NodeList::ConstIterator c = node->childNodes().begin(); |
|
3796 while (c != node->childNodes().end()) { |
|
3797 if ((*c)->access() != Node::Private) { |
|
3798 if ((*c)->isInnerNode() && (*c)->url().isEmpty()) { |
|
3799 findAllNamespaces(static_cast<const InnerNode *>(*c)); |
|
3800 if ((*c)->type() == Node::Namespace) { |
|
3801 const NamespaceNode *nspace = static_cast<const NamespaceNode *>(*c); |
|
3802 // Ensure that the namespace's name is not empty (the root |
|
3803 // namespace has no name). |
|
3804 if (!nspace->name().isEmpty()) { |
|
3805 namespaceIndex.insert(nspace->name(), *c); |
|
3806 QString moduleName = (*c)->moduleName(); |
|
3807 if (moduleName == "Qt3SupportLight") { |
|
3808 moduleNamespaceMap[moduleName].insert((*c)->name(), *c); |
|
3809 moduleName = "Qt3Support"; |
|
3810 } |
|
3811 if (!moduleName.isEmpty()) |
|
3812 moduleNamespaceMap[moduleName].insert((*c)->name(), *c); |
|
3813 } |
|
3814 } |
|
3815 } |
|
3816 } |
|
3817 ++c; |
|
3818 } |
|
3819 } |
|
3820 |
|
3821 int DitaXmlGenerator::hOffset(const Node *node) |
|
3822 { |
|
3823 switch (node->type()) { |
|
3824 case Node::Namespace: |
|
3825 case Node::Class: |
|
3826 return 2; |
|
3827 case Node::Fake: |
|
3828 return 1; |
|
3829 #if 0 |
|
3830 if (node->doc().briefText().isEmpty()) |
|
3831 return 1; |
|
3832 else |
|
3833 return 2; |
|
3834 #endif |
|
3835 case Node::Enum: |
|
3836 case Node::Typedef: |
|
3837 case Node::Function: |
|
3838 case Node::Property: |
|
3839 default: |
|
3840 return 3; |
|
3841 } |
|
3842 } |
|
3843 |
|
3844 bool DitaXmlGenerator::isThreeColumnEnumValueTable(const Atom *atom) |
|
3845 { |
|
3846 while (atom != 0 && !(atom->type() == Atom::ListRight && atom->string() == ATOM_LIST_VALUE)) { |
|
3847 if (atom->type() == Atom::ListItemLeft && !matchAhead(atom, Atom::ListItemRight)) |
|
3848 return true; |
|
3849 atom = atom->next(); |
|
3850 } |
|
3851 return false; |
|
3852 } |
|
3853 |
|
3854 const Node *DitaXmlGenerator::findNodeForTarget(const QString &target, |
|
3855 const Node *relative, |
|
3856 CodeMarker *marker, |
|
3857 const Atom *atom) |
|
3858 { |
|
3859 const Node *node = 0; |
|
3860 |
|
3861 if (target.isEmpty()) { |
|
3862 node = relative; |
|
3863 } |
|
3864 else if (target.endsWith(".html")) { |
|
3865 node = myTree->root()->findNode(target, Node::Fake); |
|
3866 } |
|
3867 else if (marker) { |
|
3868 node = marker->resolveTarget(target, myTree, relative); |
|
3869 if (!node) |
|
3870 node = myTree->findFakeNodeByTitle(target); |
|
3871 if (!node && atom) { |
|
3872 node = myTree->findUnambiguousTarget(target, |
|
3873 *const_cast<Atom**>(&atom)); |
|
3874 } |
|
3875 } |
|
3876 |
|
3877 if (!node) |
|
3878 relative->doc().location().warning(tr("Cannot link to '%1'").arg(target)); |
|
3879 |
|
3880 return node; |
|
3881 } |
|
3882 |
|
3883 const QPair<QString,QString> DitaXmlGenerator::anchorForNode(const Node *node) |
|
3884 { |
|
3885 QPair<QString,QString> anchorPair; |
|
3886 |
|
3887 anchorPair.first = PageGenerator::fileName(node); |
|
3888 if (node->type() == Node::Fake) { |
|
3889 const FakeNode *fakeNode = static_cast<const FakeNode*>(node); |
|
3890 anchorPair.second = fakeNode->title(); |
|
3891 } |
|
3892 |
|
3893 return anchorPair; |
|
3894 } |
|
3895 |
|
3896 QString DitaXmlGenerator::getLink(const Atom *atom, |
|
3897 const Node *relative, |
|
3898 CodeMarker *marker, |
|
3899 const Node** node) |
|
3900 { |
|
3901 QString link; |
|
3902 *node = 0; |
|
3903 inObsoleteLink = false; |
|
3904 |
|
3905 if (atom->string().contains(":") && |
|
3906 (atom->string().startsWith("file:") |
|
3907 || atom->string().startsWith("http:") |
|
3908 || atom->string().startsWith("https:") |
|
3909 || atom->string().startsWith("ftp:") |
|
3910 || atom->string().startsWith("mailto:"))) { |
|
3911 |
|
3912 link = atom->string(); |
|
3913 } |
|
3914 else { |
|
3915 QStringList path; |
|
3916 if (atom->string().contains('#')) { |
|
3917 path = atom->string().split('#'); |
|
3918 } |
|
3919 else { |
|
3920 path.append(atom->string()); |
|
3921 } |
|
3922 |
|
3923 Atom *targetAtom = 0; |
|
3924 |
|
3925 QString first = path.first().trimmed(); |
|
3926 if (first.isEmpty()) { |
|
3927 *node = relative; |
|
3928 } |
|
3929 else if (first.endsWith(".html")) { |
|
3930 *node = myTree->root()->findNode(first, Node::Fake); |
|
3931 } |
|
3932 else { |
|
3933 *node = marker->resolveTarget(first, myTree, relative); |
|
3934 if (!*node) { |
|
3935 *node = myTree->findFakeNodeByTitle(first); |
|
3936 } |
|
3937 if (!*node) { |
|
3938 *node = myTree->findUnambiguousTarget(first, targetAtom); |
|
3939 } |
|
3940 } |
|
3941 |
|
3942 if (*node) { |
|
3943 if (!(*node)->url().isEmpty()) |
|
3944 return (*node)->url(); |
|
3945 else |
|
3946 path.removeFirst(); |
|
3947 } |
|
3948 else { |
|
3949 *node = relative; |
|
3950 } |
|
3951 |
|
3952 if (*node) { |
|
3953 if ((*node)->status() == Node::Obsolete) { |
|
3954 if (relative) { |
|
3955 if (relative->parent() != *node) { |
|
3956 if (relative->status() != Node::Obsolete) { |
|
3957 bool porting = false; |
|
3958 if (relative->type() == Node::Fake) { |
|
3959 const FakeNode* fake = static_cast<const FakeNode*>(relative); |
|
3960 if (fake->title().startsWith("Porting")) |
|
3961 porting = true; |
|
3962 } |
|
3963 QString name = marker->plainFullName(relative); |
|
3964 if (!porting && !name.startsWith("Q3")) { |
|
3965 if (obsoleteLinks) { |
|
3966 relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") |
|
3967 .arg(atom->string()) |
|
3968 .arg(name)); |
|
3969 } |
|
3970 inObsoleteLink = true; |
|
3971 } |
|
3972 } |
|
3973 } |
|
3974 } |
|
3975 else { |
|
3976 qDebug() << "Link to Obsolete entity" |
|
3977 << (*node)->name() << "no relative"; |
|
3978 } |
|
3979 } |
|
3980 #if 0 |
|
3981 else if ((*node)->status() == Node::Deprecated) { |
|
3982 qDebug() << "Link to Deprecated entity"; |
|
3983 } |
|
3984 else if ((*node)->status() == Node::Internal) { |
|
3985 qDebug() << "Link to Internal entity"; |
|
3986 } |
|
3987 #endif |
|
3988 } |
|
3989 |
|
3990 while (!path.isEmpty()) { |
|
3991 targetAtom = myTree->findTarget(path.first(), *node); |
|
3992 if (targetAtom == 0) |
|
3993 break; |
|
3994 path.removeFirst(); |
|
3995 } |
|
3996 |
|
3997 if (path.isEmpty()) { |
|
3998 link = linkForNode(*node, relative); |
|
3999 if (*node && (*node)->subType() == Node::Image) |
|
4000 link = "images/used-in-examples/" + link; |
|
4001 if (targetAtom) |
|
4002 link += "#" + refForAtom(targetAtom, *node); |
|
4003 } |
|
4004 } |
|
4005 return link; |
|
4006 } |
|
4007 |
|
4008 void DitaXmlGenerator::generateIndex(const QString &fileBase, |
|
4009 const QString &url, |
|
4010 const QString &title) |
|
4011 { |
|
4012 myTree->generateIndex(outputDir() + "/" + fileBase + ".index", url, title); |
|
4013 } |
|
4014 |
|
4015 void DitaXmlGenerator::generateStatus(const Node *node, CodeMarker *marker) |
|
4016 { |
|
4017 Text text; |
|
4018 |
|
4019 switch (node->status()) { |
|
4020 case Node::Obsolete: |
|
4021 if (node->isInnerNode()) |
|
4022 Generator::generateStatus(node, marker); |
|
4023 break; |
|
4024 case Node::Compat: |
|
4025 if (node->isInnerNode()) { |
|
4026 text << Atom::ParaLeft |
|
4027 << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) |
|
4028 << "This " |
|
4029 << typeString(node) |
|
4030 << " is part of the Qt 3 support library." |
|
4031 << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) |
|
4032 << " It is provided to keep old source code working. " |
|
4033 << "We strongly advise against " |
|
4034 << "using it in new code. See "; |
|
4035 |
|
4036 const FakeNode *fakeNode = myTree->findFakeNodeByTitle("Porting To Qt 4"); |
|
4037 Atom *targetAtom = 0; |
|
4038 if (fakeNode && node->type() == Node::Class) { |
|
4039 QString oldName(node->name()); |
|
4040 targetAtom = myTree->findTarget(oldName.replace("3", ""), |
|
4041 fakeNode); |
|
4042 } |
|
4043 |
|
4044 if (targetAtom) { |
|
4045 text << Atom(Atom::Link, linkForNode(fakeNode, node) + "#" + |
|
4046 refForAtom(targetAtom, fakeNode)); |
|
4047 } |
|
4048 else |
|
4049 text << Atom(Atom::Link, "Porting to Qt 4"); |
|
4050 |
|
4051 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) |
|
4052 << Atom(Atom::String, "Porting to Qt 4") |
|
4053 << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) |
|
4054 << " for more information." |
|
4055 << Atom::ParaRight; |
|
4056 } |
|
4057 generateText(text, node, marker); |
|
4058 break; |
|
4059 default: |
|
4060 Generator::generateStatus(node, marker); |
|
4061 } |
|
4062 } |
|
4063 |
|
4064 #ifdef GENERATE_MAC_REFS |
|
4065 /* |
|
4066 No longer valid. |
|
4067 */ |
|
4068 void DitaXmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) |
|
4069 { |
|
4070 if (!pleaseGenerateMacRef || marker == 0) |
|
4071 return; |
|
4072 |
|
4073 QStringList macRefs = marker->macRefsForNode(node); |
|
4074 foreach (const QString &macRef, macRefs) |
|
4075 out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n"; |
|
4076 } |
|
4077 #endif |
|
4078 |
|
4079 void DitaXmlGenerator::beginLink(const QString &link, |
|
4080 const Node *node, |
|
4081 const Node *relative, |
|
4082 CodeMarker *marker) |
|
4083 { |
|
4084 Q_UNUSED(marker) |
|
4085 Q_UNUSED(relative) |
|
4086 |
|
4087 this->link = link; |
|
4088 if (link.isEmpty()) { |
|
4089 if (showBrokenLinks) |
|
4090 writer.writeStartElement("i"); |
|
4091 } |
|
4092 else if (node == 0 || (relative != 0 && |
|
4093 node->status() == relative->status())) { |
|
4094 writer.writeStartElement("xref"); |
|
4095 writer.writeAttribute("href",link); |
|
4096 } |
|
4097 else { |
|
4098 switch (node->status()) { |
|
4099 case Node::Obsolete: |
|
4100 writer.writeStartElement("xref"); |
|
4101 writer.writeAttribute("href",link); |
|
4102 writer.writeAttribute("outputclass","obsolete"); |
|
4103 break; |
|
4104 case Node::Compat: |
|
4105 writer.writeStartElement("xref"); |
|
4106 writer.writeAttribute("href",link); |
|
4107 writer.writeAttribute("outputclass","compat"); |
|
4108 break; |
|
4109 default: |
|
4110 writer.writeStartElement("xref"); |
|
4111 writer.writeAttribute("href",link); |
|
4112 } |
|
4113 } |
|
4114 inLink = true; |
|
4115 } |
|
4116 |
|
4117 void DitaXmlGenerator::endLink() |
|
4118 { |
|
4119 if (inLink) { |
|
4120 if (link.isEmpty()) { |
|
4121 if (showBrokenLinks) |
|
4122 writer.writeEndElement(); // i |
|
4123 } |
|
4124 else { |
|
4125 if (inObsoleteLink) { |
|
4126 writer.writeStartElement("sup"); |
|
4127 writer.writeCharacters("(obsolete)"); |
|
4128 writer.writeEndElement(); // sup |
|
4129 } |
|
4130 writer.writeEndElement(); // xref |
|
4131 } |
|
4132 } |
|
4133 inLink = false; |
|
4134 inObsoleteLink = false; |
|
4135 } |
|
4136 |
|
4137 #ifdef QDOC_QML |
|
4138 |
|
4139 /*! |
|
4140 Generates the summary for the \a section. Only used for |
|
4141 sections of QML element documentation. |
|
4142 |
|
4143 Currently handles only the QML property group. |
|
4144 */ |
|
4145 void DitaXmlGenerator::generateQmlSummary(const Section& section, |
|
4146 const Node *relative, |
|
4147 CodeMarker *marker) |
|
4148 { |
|
4149 if (!section.members.isEmpty()) { |
|
4150 NodeList::ConstIterator m; |
|
4151 int count = section.members.size(); |
|
4152 bool twoColumn = false; |
|
4153 if (section.members.first()->type() == Node::QmlProperty) { |
|
4154 twoColumn = (count >= 5); |
|
4155 } |
|
4156 if (twoColumn) |
|
4157 out() << "<table class=\"qmlsummary\">\n"; |
|
4158 if (++numTableRows % 2 == 1) |
|
4159 out() << "<tr class=\"odd topAlign\">"; |
|
4160 else |
|
4161 out() << "<tr class=\"even topAlign\">"; |
|
4162 // << "<tr><td class=\"topAlign\">"; |
|
4163 out() << "<ul>\n"; |
|
4164 |
|
4165 int row = 0; |
|
4166 m = section.members.begin(); |
|
4167 while (m != section.members.end()) { |
|
4168 if (twoColumn && row == (int) (count + 1) / 2) |
|
4169 out() << "</ul></td><td class=\"topAlign\"><ul>\n"; |
|
4170 out() << "<li class=\"fn\">"; |
|
4171 generateQmlItem(*m,relative,marker,true); |
|
4172 out() << "</li>\n"; |
|
4173 row++; |
|
4174 ++m; |
|
4175 } |
|
4176 out() << "</ul>\n"; |
|
4177 if (twoColumn) |
|
4178 out() << "</td></tr>\n</table>\n"; |
|
4179 } |
|
4180 } |
|
4181 |
|
4182 /*! |
|
4183 Outputs the html detailed documentation for a section |
|
4184 on a QML element reference page. |
|
4185 */ |
|
4186 void DitaXmlGenerator::generateDetailedQmlMember(const Node *node, |
|
4187 const InnerNode *relative, |
|
4188 CodeMarker *marker) |
|
4189 { |
|
4190 const QmlPropertyNode* qpn = 0; |
|
4191 #ifdef GENERATE_MAC_REFS |
|
4192 generateMacRef(node, marker); |
|
4193 #endif |
|
4194 out() << "<div class=\"qmlitem\">"; |
|
4195 if (node->subType() == Node::QmlPropertyGroup) { |
|
4196 const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node); |
|
4197 NodeList::ConstIterator p = qpgn->childNodes().begin(); |
|
4198 out() << "<div class=\"qmlproto\">"; |
|
4199 out() << "<table class=\"qmlname\">"; |
|
4200 |
|
4201 while (p != qpgn->childNodes().end()) { |
|
4202 if ((*p)->type() == Node::QmlProperty) { |
|
4203 qpn = static_cast<const QmlPropertyNode*>(*p); |
|
4204 |
|
4205 if (++numTableRows % 2 == 1) |
|
4206 out() << "<tr class=\"odd\">"; |
|
4207 else |
|
4208 out() << "<tr class=\"even\">"; |
|
4209 |
|
4210 out() << "<td><p>"; |
|
4211 //out() << "<tr><td>"; // old |
|
4212 out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; |
|
4213 if (!qpn->isWritable(myTree)) |
|
4214 out() << "<span class=\"qmlreadonly\">read-only</span>"; |
|
4215 if (qpgn->isDefault()) |
|
4216 out() << "<span class=\"qmldefault\">default</span>"; |
|
4217 generateQmlItem(qpn, relative, marker, false); |
|
4218 out() << "</td></tr>"; |
|
4219 } |
|
4220 ++p; |
|
4221 } |
|
4222 out() << "</table>"; |
|
4223 out() << "</div>"; |
|
4224 } |
|
4225 else if (node->type() == Node::QmlSignal) { |
|
4226 const FunctionNode* qsn = static_cast<const FunctionNode*>(node); |
|
4227 out() << "<div class=\"qmlproto\">"; |
|
4228 out() << "<table class=\"qmlname\">"; |
|
4229 //out() << "<tr>"; |
|
4230 if (++numTableRows % 2 == 1) |
|
4231 out() << "<tr class=\"odd\">"; |
|
4232 else |
|
4233 out() << "<tr class=\"even\">"; |
|
4234 out() << "<td><p>"; |
|
4235 out() << "<a name=\"" + refForNode(qsn) + "\"></a>"; |
|
4236 generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); |
|
4237 //generateQmlItem(qsn,relative,marker,false); |
|
4238 out() << "</p></td></tr>"; |
|
4239 out() << "</table>"; |
|
4240 out() << "</div>"; |
|
4241 } |
|
4242 else if (node->type() == Node::QmlMethod) { |
|
4243 const FunctionNode* qmn = static_cast<const FunctionNode*>(node); |
|
4244 out() << "<div class=\"qmlproto\">"; |
|
4245 out() << "<table class=\"qmlname\">"; |
|
4246 //out() << "<tr>"; |
|
4247 if (++numTableRows % 2 == 1) |
|
4248 out() << "<tr class=\"odd\">"; |
|
4249 else |
|
4250 out() << "<tr class=\"even\">"; |
|
4251 out() << "<td><p>"; |
|
4252 out() << "<a name=\"" + refForNode(qmn) + "\"></a>"; |
|
4253 generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); |
|
4254 out() << "</p></td></tr>"; |
|
4255 out() << "</table>"; |
|
4256 out() << "</div>"; |
|
4257 } |
|
4258 out() << "<div class=\"qmldoc\">"; |
|
4259 generateStatus(node, marker); |
|
4260 generateBody(node, marker); |
|
4261 generateThreadSafeness(node, marker); |
|
4262 generateSince(node, marker); |
|
4263 generateAlsoList(node, marker); |
|
4264 out() << "</div>"; |
|
4265 out() << "</div>"; |
|
4266 } |
|
4267 |
|
4268 /*! |
|
4269 Output the "Inherits" line for the QML element, |
|
4270 if there should be one. |
|
4271 */ |
|
4272 void DitaXmlGenerator::generateQmlInherits(const QmlClassNode* cn, |
|
4273 CodeMarker* marker) |
|
4274 { |
|
4275 if (cn && !cn->links().empty()) { |
|
4276 if (cn->links().contains(Node::InheritsLink)) { |
|
4277 QPair<QString,QString> linkPair; |
|
4278 linkPair = cn->links()[Node::InheritsLink]; |
|
4279 QStringList strList(linkPair.first); |
|
4280 const Node* n = myTree->findNode(strList,Node::Fake); |
|
4281 if (n && n->subType() == Node::QmlClass) { |
|
4282 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n); |
|
4283 out() << "<p class=\"centerAlign\">"; |
|
4284 Text text; |
|
4285 text << "[Inherits "; |
|
4286 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); |
|
4287 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); |
|
4288 text << Atom(Atom::String, linkPair.second); |
|
4289 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); |
|
4290 text << "]"; |
|
4291 generateText(text, cn, marker); |
|
4292 out() << "</p>"; |
|
4293 } |
|
4294 } |
|
4295 } |
|
4296 } |
|
4297 |
|
4298 /*! |
|
4299 Output the "Inherit by" list for the QML element, |
|
4300 if it is inherited by any other elements. |
|
4301 */ |
|
4302 void DitaXmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, |
|
4303 CodeMarker* marker) |
|
4304 { |
|
4305 if (cn) { |
|
4306 NodeList subs; |
|
4307 QmlClassNode::subclasses(cn->name(),subs); |
|
4308 if (!subs.isEmpty()) { |
|
4309 Text text; |
|
4310 text << Atom::ParaLeft << "Inherited by "; |
|
4311 appendSortedQmlNames(text,cn,subs,marker); |
|
4312 text << Atom::ParaRight; |
|
4313 generateText(text, cn, marker); |
|
4314 } |
|
4315 } |
|
4316 } |
|
4317 |
|
4318 /*! |
|
4319 Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" |
|
4320 line for the QML element, if there should be one. |
|
4321 |
|
4322 If there is no class node, or if the class node status |
|
4323 is set to Node::Internal, do nothing. |
|
4324 */ |
|
4325 void DitaXmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, |
|
4326 CodeMarker* marker) |
|
4327 { |
|
4328 const ClassNode* cn = qcn->classNode(); |
|
4329 if (cn && (cn->status() != Node::Internal)) { |
|
4330 out() << "<p class=\"centerAlign\">"; |
|
4331 Text text; |
|
4332 text << "["; |
|
4333 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); |
|
4334 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); |
|
4335 text << Atom(Atom::String, qcn->name()); |
|
4336 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); |
|
4337 text << " instantiates the C++ class "; |
|
4338 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); |
|
4339 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); |
|
4340 text << Atom(Atom::String, cn->name()); |
|
4341 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); |
|
4342 text << "]"; |
|
4343 generateText(text, qcn, marker); |
|
4344 out() << "</p>"; |
|
4345 } |
|
4346 } |
|
4347 |
|
4348 /*! |
|
4349 Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]" |
|
4350 line for the class, if there should be one. |
|
4351 |
|
4352 If there is no QML element, or if the class node status |
|
4353 is set to Node::Internal, do nothing. |
|
4354 */ |
|
4355 void DitaXmlGenerator::generateInstantiatedBy(const ClassNode* cn, |
|
4356 CodeMarker* marker) |
|
4357 { |
|
4358 if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) { |
|
4359 const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake); |
|
4360 if (n && n->subType() == Node::QmlClass) { |
|
4361 out() << "<p class=\"centerAlign\">"; |
|
4362 Text text; |
|
4363 text << "["; |
|
4364 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); |
|
4365 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); |
|
4366 text << Atom(Atom::String, cn->name()); |
|
4367 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); |
|
4368 text << " is instantiated by QML element "; |
|
4369 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n)); |
|
4370 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); |
|
4371 text << Atom(Atom::String, n->name()); |
|
4372 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); |
|
4373 text << "]"; |
|
4374 generateText(text, cn, marker); |
|
4375 out() << "</p>"; |
|
4376 } |
|
4377 } |
|
4378 } |
|
4379 |
|
4380 /*! |
|
4381 Generate the <page> element for the given \a node using the \a writer. |
|
4382 Return true if a <page> element was written; otherwise return false. |
|
4383 */ |
|
4384 bool DitaXmlGenerator::generatePageElement(QXmlStreamWriter& writer, |
|
4385 const Node* node, |
|
4386 CodeMarker* marker) const |
|
4387 { |
|
4388 if (node->pageType() == Node::NoPageType) |
|
4389 return false; |
|
4390 if (node->name().isEmpty()) |
|
4391 return true; |
|
4392 if (node->access() == Node::Private) |
|
4393 return false; |
|
4394 if (!node->isInnerNode()) |
|
4395 return false; |
|
4396 |
|
4397 QString title; |
|
4398 QString rawTitle; |
|
4399 QString fullTitle; |
|
4400 const InnerNode* inner = static_cast<const InnerNode*>(node); |
|
4401 |
|
4402 writer.writeStartElement("page"); |
|
4403 QXmlStreamAttributes attributes; |
|
4404 QString t; |
|
4405 t.setNum(id++); |
|
4406 switch (node->type()) { |
|
4407 case Node::Fake: |
|
4408 { |
|
4409 const FakeNode* fake = static_cast<const FakeNode*>(node); |
|
4410 title = fake->fullTitle(); |
|
4411 break; |
|
4412 } |
|
4413 case Node::Class: |
|
4414 { |
|
4415 title = node->name() + " Class Reference"; |
|
4416 break; |
|
4417 } |
|
4418 case Node::Namespace: |
|
4419 { |
|
4420 rawTitle = marker->plainName(inner); |
|
4421 fullTitle = marker->plainFullName(inner); |
|
4422 title = rawTitle + " Namespace Reference"; |
|
4423 break; |
|
4424 } |
|
4425 default: |
|
4426 title = node->name(); |
|
4427 break; |
|
4428 } |
|
4429 writer.writeAttribute("id",t); |
|
4430 writer.writeStartElement("pageWords"); |
|
4431 writer.writeCharacters(title); |
|
4432 if (!inner->pageKeywords().isEmpty()) { |
|
4433 const QStringList& w = inner->pageKeywords(); |
|
4434 for (int i = 0; i < w.size(); ++i) { |
|
4435 writer.writeCharacters(" "); |
|
4436 writer.writeCharacters(w.at(i).toLocal8Bit().constData()); |
|
4437 } |
|
4438 } |
|
4439 writer.writeEndElement(); |
|
4440 writer.writeStartElement("pageTitle"); |
|
4441 writer.writeCharacters(title); |
|
4442 writer.writeEndElement(); |
|
4443 writer.writeStartElement("pageUrl"); |
|
4444 writer.writeCharacters(PageGenerator::fileName(node)); |
|
4445 writer.writeEndElement(); |
|
4446 writer.writeStartElement("pageType"); |
|
4447 switch (node->pageType()) { |
|
4448 case Node::ApiPage: |
|
4449 writer.writeCharacters("APIPage"); |
|
4450 break; |
|
4451 case Node::ArticlePage: |
|
4452 writer.writeCharacters("Article"); |
|
4453 break; |
|
4454 case Node::ExamplePage: |
|
4455 writer.writeCharacters("Example"); |
|
4456 break; |
|
4457 default: |
|
4458 break; |
|
4459 } |
|
4460 writer.writeEndElement(); |
|
4461 writer.writeEndElement(); |
|
4462 return true; |
|
4463 } |
|
4464 |
|
4465 /*! |
|
4466 Traverse the tree recursively and generate the <keyword> |
|
4467 elements. |
|
4468 */ |
|
4469 void DitaXmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const |
|
4470 { |
|
4471 if (generatePageElement(writer, node, marker)) { |
|
4472 |
|
4473 if (node->isInnerNode()) { |
|
4474 const InnerNode *inner = static_cast<const InnerNode *>(node); |
|
4475 |
|
4476 // Recurse to write an element for this child node and all its children. |
|
4477 foreach (const Node *child, inner->childNodes()) |
|
4478 generatePageElements(writer, child, marker); |
|
4479 } |
|
4480 } |
|
4481 } |
|
4482 |
|
4483 /*! |
|
4484 Outputs the file containing the index used for searching the html docs. |
|
4485 */ |
|
4486 void DitaXmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const |
|
4487 { |
|
4488 QFile file(fileName); |
|
4489 if (!file.open(QFile::WriteOnly | QFile::Text)) |
|
4490 return ; |
|
4491 |
|
4492 QXmlStreamWriter writer(&file); |
|
4493 writer.setAutoFormatting(true); |
|
4494 writer.writeStartDocument(); |
|
4495 writer.writeStartElement("qtPageIndex"); |
|
4496 |
|
4497 generatePageElements(writer, myTree->root(), marker); |
|
4498 |
|
4499 writer.writeEndElement(); // qtPageIndex |
|
4500 writer.writeEndDocument(); |
|
4501 file.close(); |
|
4502 } |
|
4503 |
|
4504 #endif |
|
4505 |
|
4506 /*! |
|
4507 Return the full qualification of the node \a n, but without |
|
4508 the name of \a n itself. e.g. A::B::C |
|
4509 */ |
|
4510 QString DitaXmlGenerator::fullQualification(const Node* n) |
|
4511 { |
|
4512 QString fq; |
|
4513 InnerNode* in = n->parent(); |
|
4514 while (in) { |
|
4515 if ((in->type() == Node::Class) || |
|
4516 (in->type() == Node::Namespace)) { |
|
4517 if (in->name().isEmpty()) |
|
4518 break; |
|
4519 if (fq.isEmpty()) |
|
4520 fq = in->name(); |
|
4521 else |
|
4522 fq = in->name() + "::" + fq; |
|
4523 } |
|
4524 else |
|
4525 break; |
|
4526 in = in->parent(); |
|
4527 } |
|
4528 return fq; |
|
4529 } |
|
4530 |
|
4531 void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker) |
|
4532 { |
|
4533 QList<RelatedClass>::ConstIterator r; |
|
4534 int index; |
|
4535 |
|
4536 if (!cn->baseClasses().isEmpty()) { |
|
4537 writer.writeStartElement(CXXCLASSDERIVATIONS); |
|
4538 r = cn->baseClasses().begin(); |
|
4539 index = 0; |
|
4540 while (r != cn->baseClasses().end()) { |
|
4541 writer.writeStartElement(CXXCLASSDERIVATION); |
|
4542 writer.writeStartElement(CXXCLASSDERIVATIONACCESSSPECIFIER); |
|
4543 writer.writeAttribute("value",(*r).accessString()); |
|
4544 writer.writeEndElement(); // </cxxClassDerivationAccessSpecifier> |
|
4545 writer.writeStartElement(CXXCLASSBASECLASS); |
|
4546 writer.writeAttribute("href",(*r).node->ditaXmlHref()); |
|
4547 writer.writeCharacters(marker->plainFullName((*r).node)); |
|
4548 writer.writeEndElement(); // </cxxClassBaseClass> |
|
4549 writer.writeEndElement(); // </cxxClassDerivation> |
|
4550 ++r; |
|
4551 } |
|
4552 writer.writeEndElement(); // </cxxClassDerivations> |
|
4553 } |
|
4554 } |
|
4555 |
|
4556 void DitaXmlGenerator::writeLocation(const Node* n) |
|
4557 { |
|
4558 QString s1, s2, s3; |
|
4559 if (n->type() == Node::Class) { |
|
4560 s1 = CXXCLASSAPIITEMLOCATION; |
|
4561 s2 = CXXCLASSDECLARATIONFILE; |
|
4562 s3 = CXXCLASSDECLARATIONFILELINE; |
|
4563 } |
|
4564 else if (n->type() == Node::Function) { |
|
4565 s1 = CXXFUNCTIONAPIITEMLOCATION; |
|
4566 s2 = CXXFUNCTIONDECLARATIONFILE; |
|
4567 s3 = CXXFUNCTIONDECLARATIONFILELINE; |
|
4568 } |
|
4569 else if (n->type() == Node::Enum) { |
|
4570 s1 = CXXENUMERATIONAPIITEMLOCATION; |
|
4571 s2 = CXXENUMERATIONDECLARATIONFILE; |
|
4572 s3 = CXXENUMERATIONDECLARATIONFILELINE; |
|
4573 } |
|
4574 else if (n->type() == Node::Typedef) { |
|
4575 s1 = CXXTYPEDEFAPIITEMLOCATION; |
|
4576 s2 = CXXTYPEDEFDECLARATIONFILE; |
|
4577 s3 = CXXTYPEDEFDECLARATIONFILELINE; |
|
4578 } |
|
4579 else if ((n->type() == Node::Property) || |
|
4580 (n->type() == Node::Variable)) { |
|
4581 s1 = CXXVARIABLEAPIITEMLOCATION; |
|
4582 s2 = CXXVARIABLEDECLARATIONFILE; |
|
4583 s3 = CXXVARIABLEDECLARATIONFILELINE; |
|
4584 } |
|
4585 writer.writeStartElement(s1); |
|
4586 writer.writeStartElement(s2); |
|
4587 writer.writeAttribute("name","filePath"); |
|
4588 writer.writeAttribute("value",n->location().filePath()); |
|
4589 writer.writeEndElement(); // </cxx<s2>DeclarationFile> |
|
4590 writer.writeStartElement(s3); |
|
4591 writer.writeAttribute("name","lineNumber"); |
|
4592 QString lineNr; |
|
4593 writer.writeAttribute("value",lineNr.setNum(n->location().lineNo())); |
|
4594 writer.writeEndElement(); // </cxx<s3>DeclarationFileLine> |
|
4595 writer.writeEndElement(); // </cxx<s1>ApiItemLocation> |
|
4596 } |
|
4597 |
|
4598 void DitaXmlGenerator::writeFunctions(const Section& s, |
|
4599 const ClassNode* cn, |
|
4600 CodeMarker* marker) |
|
4601 { |
|
4602 NodeList::ConstIterator m = s.members.begin(); |
|
4603 while (m != s.members.end()) { |
|
4604 if ((*m)->type() == Node::Function) { |
|
4605 FunctionNode* fn = const_cast<FunctionNode*>(static_cast<const FunctionNode*>(*m)); |
|
4606 writer.writeStartElement(CXXFUNCTION); |
|
4607 writer.writeAttribute("id",fn->guid()); |
|
4608 writer.writeStartElement(APINAME); |
|
4609 writer.writeCharacters(fn->name()); |
|
4610 writer.writeEndElement(); // </apiName> |
|
4611 generateBrief(fn,marker); |
|
4612 writer.writeStartElement(CXXFUNCTIONDETAIL); |
|
4613 writer.writeStartElement(CXXFUNCTIONDEFINITION); |
|
4614 writer.writeStartElement(CXXFUNCTIONACCESSSPECIFIER); |
|
4615 writer.writeAttribute("value",fn->accessString()); |
|
4616 writer.writeEndElement(); // <cxxFunctionAccessSpecifier> |
|
4617 |
|
4618 if (fn->isStatic()) { |
|
4619 writer.writeStartElement(CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC); |
|
4620 writer.writeAttribute("name","static"); |
|
4621 writer.writeAttribute("value","static"); |
|
4622 writer.writeEndElement(); // <cxxFunctionStorageClassSpecifierStatic> |
|
4623 } |
|
4624 |
|
4625 if (fn->isConst()) { |
|
4626 writer.writeStartElement(CXXFUNCTIONCONST); |
|
4627 writer.writeAttribute("name","const"); |
|
4628 writer.writeAttribute("value","const"); |
|
4629 writer.writeEndElement(); // <cxxFunctionConst> |
|
4630 } |
|
4631 |
|
4632 if (fn->virtualness() != FunctionNode::NonVirtual) { |
|
4633 writer.writeStartElement(CXXFUNCTIONVIRTUAL); |
|
4634 writer.writeAttribute("name","virtual"); |
|
4635 writer.writeAttribute("value","virtual"); |
|
4636 writer.writeEndElement(); // <cxxFunctionVirtual> |
|
4637 if (fn->virtualness() == FunctionNode::PureVirtual) { |
|
4638 writer.writeStartElement(CXXFUNCTIONPUREVIRTUAL); |
|
4639 writer.writeAttribute("name","pure virtual"); |
|
4640 writer.writeAttribute("value","pure virtual"); |
|
4641 writer.writeEndElement(); // <cxxFunctionPureVirtual> |
|
4642 } |
|
4643 } |
|
4644 |
|
4645 if (fn->name() == cn->name()) { |
|
4646 writer.writeStartElement(CXXFUNCTIONCONSTRUCTOR); |
|
4647 writer.writeAttribute("name","constructor"); |
|
4648 writer.writeAttribute("value","constructor"); |
|
4649 writer.writeEndElement(); // <cxxFunctionConstructor> |
|
4650 } |
|
4651 else if (fn->name()[0] == QChar('~')) { |
|
4652 writer.writeStartElement(CXXFUNCTIONDESTRUCTOR); |
|
4653 writer.writeAttribute("name","destructor"); |
|
4654 writer.writeAttribute("value","destructor"); |
|
4655 writer.writeEndElement(); // <cxxFunctionDestructor> |
|
4656 } |
|
4657 else { |
|
4658 writer.writeStartElement(CXXFUNCTIONDECLAREDTYPE); |
|
4659 writer.writeCharacters(fn->returnType()); |
|
4660 writer.writeEndElement(); // <cxxFunctionDeclaredType> |
|
4661 } |
|
4662 QString fq = fullQualification(fn); |
|
4663 if (!fq.isEmpty()) { |
|
4664 writer.writeStartElement(CXXFUNCTIONSCOPEDNAME); |
|
4665 writer.writeCharacters(fq); |
|
4666 writer.writeEndElement(); // <cxxFunctionScopedName> |
|
4667 } |
|
4668 writer.writeStartElement(CXXFUNCTIONPROTOTYPE); |
|
4669 writer.writeCharacters(fn->signature(true)); |
|
4670 writer.writeEndElement(); // <cxxFunctionPrototype> |
|
4671 |
|
4672 QString fnl = fn->signature(false); |
|
4673 int idx = fnl.indexOf(' '); |
|
4674 if (idx < 0) |
|
4675 idx = 0; |
|
4676 else |
|
4677 ++idx; |
|
4678 fnl = fn->parent()->name() + "::" + fnl.mid(idx); |
|
4679 writer.writeStartElement(CXXFUNCTIONNAMELOOKUP); |
|
4680 writer.writeCharacters(fnl); |
|
4681 writer.writeEndElement(); // <cxxFunctionNameLookup> |
|
4682 |
|
4683 if (fn->isReimp() && fn->reimplementedFrom() != 0) { |
|
4684 FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom(); |
|
4685 writer.writeStartElement(CXXFUNCTIONREIMPLEMENTED); |
|
4686 writer.writeAttribute("href",rfn->ditaXmlHref()); |
|
4687 writer.writeCharacters(marker->plainFullName(rfn)); |
|
4688 writer.writeEndElement(); // </cxxFunctionReimplemented> |
|
4689 } |
|
4690 writeParameters(fn,marker); |
|
4691 writeLocation(fn); |
|
4692 writer.writeEndElement(); // <cxxFunctionDefinition> |
|
4693 writer.writeStartElement(APIDESC); |
|
4694 |
|
4695 if (!fn->doc().isEmpty()) { |
|
4696 generateBody(fn, marker); |
|
4697 // generateAlsoList(inner, marker); |
|
4698 } |
|
4699 |
|
4700 writer.writeEndElement(); // </apiDesc> |
|
4701 writer.writeEndElement(); // </cxxFunctionDetail> |
|
4702 writer.writeEndElement(); // </cxxFunction> |
|
4703 |
|
4704 if (fn->metaness() == FunctionNode::Ctor || |
|
4705 fn->metaness() == FunctionNode::Dtor || |
|
4706 fn->overloadNumber() != 1) { |
|
4707 } |
|
4708 } |
|
4709 ++m; |
|
4710 } |
|
4711 } |
|
4712 |
|
4713 void DitaXmlGenerator::writeParameters(const FunctionNode* fn, CodeMarker* marker) |
|
4714 { |
|
4715 const QList<Parameter>& parameters = fn->parameters(); |
|
4716 if (!parameters.isEmpty()) { |
|
4717 writer.writeStartElement(CXXFUNCTIONPARAMETERS); |
|
4718 QList<Parameter>::ConstIterator p = parameters.begin(); |
|
4719 while (p != parameters.end()) { |
|
4720 writer.writeStartElement(CXXFUNCTIONPARAMETER); |
|
4721 writer.writeStartElement(CXXFUNCTIONPARAMETERDECLAREDTYPE); |
|
4722 writer.writeCharacters((*p).leftType()); |
|
4723 if (!(*p).rightType().isEmpty()) |
|
4724 writer.writeCharacters((*p).rightType()); |
|
4725 writer.writeEndElement(); // <cxxFunctionParameterDeclaredType> |
|
4726 writer.writeStartElement(CXXFUNCTIONPARAMETERDECLARATIONNAME); |
|
4727 writer.writeCharacters((*p).name()); |
|
4728 writer.writeEndElement(); // <cxxFunctionParameterDeclarationName> |
|
4729 if (!(*p).defaultValue().isEmpty()) { |
|
4730 writer.writeStartElement(CXXFUNCTIONPARAMETERDEFAULTVALUE); |
|
4731 writer.writeCharacters((*p).defaultValue()); |
|
4732 writer.writeEndElement(); // <cxxFunctionParameterDefaultValue> |
|
4733 } |
|
4734 writer.writeEndElement(); // <cxxFunctionParameter> |
|
4735 ++p; |
|
4736 } |
|
4737 writer.writeEndElement(); // <cxxFunctionParameters> |
|
4738 } |
|
4739 } |
|
4740 |
|
4741 void DitaXmlGenerator::writeEnumerations(const Section& s, |
|
4742 const ClassNode* cn, |
|
4743 CodeMarker* marker) |
|
4744 { |
|
4745 NodeList::ConstIterator m = s.members.begin(); |
|
4746 while (m != s.members.end()) { |
|
4747 if ((*m)->type() == Node::Enum) { |
|
4748 const EnumNode* en = static_cast<const EnumNode*>(*m); |
|
4749 writer.writeStartElement(CXXENUMERATION); |
|
4750 writer.writeAttribute("id",en->guid()); |
|
4751 writer.writeStartElement(APINAME); |
|
4752 writer.writeCharacters(en->name()); |
|
4753 writer.writeEndElement(); // </apiName> |
|
4754 generateBrief(en,marker); |
|
4755 writer.writeStartElement(CXXENUMERATIONDETAIL); |
|
4756 writer.writeStartElement(CXXENUMERATIONDEFINITION); |
|
4757 writer.writeStartElement(CXXENUMERATIONACCESSSPECIFIER); |
|
4758 writer.writeAttribute("value",en->accessString()); |
|
4759 writer.writeEndElement(); // <cxxEnumerationAccessSpecifier> |
|
4760 |
|
4761 QString fq = fullQualification(en); |
|
4762 if (!fq.isEmpty()) { |
|
4763 writer.writeStartElement(CXXENUMERATIONSCOPEDNAME); |
|
4764 writer.writeCharacters(fq); |
|
4765 writer.writeEndElement(); // <cxxEnumerationScopedName> |
|
4766 } |
|
4767 const QList<EnumItem>& items = en->items(); |
|
4768 if (!items.isEmpty()) { |
|
4769 writer.writeStartElement(CXXENUMERATIONPROTOTYPE); |
|
4770 writer.writeCharacters(en->name()); |
|
4771 writer.writeCharacters(" = { "); |
|
4772 QList<EnumItem>::ConstIterator i = items.begin(); |
|
4773 while (i != items.end()) { |
|
4774 writer.writeCharacters((*i).name()); |
|
4775 if (!(*i).value().isEmpty()) { |
|
4776 writer.writeCharacters(" = "); |
|
4777 writer.writeCharacters((*i).value()); |
|
4778 } |
|
4779 ++i; |
|
4780 if (i != items.end()) |
|
4781 writer.writeCharacters(", "); |
|
4782 } |
|
4783 writer.writeCharacters(" }"); |
|
4784 writer.writeEndElement(); // <cxxEnumerationPrototype> |
|
4785 } |
|
4786 |
|
4787 writer.writeStartElement(CXXENUMERATIONNAMELOOKUP); |
|
4788 writer.writeCharacters(en->parent()->name() + "::" + en->name()); |
|
4789 writer.writeEndElement(); // <cxxEnumerationNameLookup> |
|
4790 |
|
4791 if (!items.isEmpty()) { |
|
4792 writer.writeStartElement(CXXENUMERATORS); |
|
4793 QList<EnumItem>::ConstIterator i = items.begin(); |
|
4794 while (i != items.end()) { |
|
4795 writer.writeStartElement(CXXENUMERATOR); |
|
4796 writer.writeStartElement(APINAME); |
|
4797 writer.writeCharacters((*i).name()); |
|
4798 writer.writeEndElement(); // </apiName> |
|
4799 |
|
4800 QString fq = fullQualification(en->parent()); |
|
4801 if (!fq.isEmpty()) { |
|
4802 writer.writeStartElement(CXXENUMERATORSCOPEDNAME); |
|
4803 writer.writeCharacters(fq + "::" + (*i).name()); |
|
4804 writer.writeEndElement(); // <cxxEnumeratorScopedName> |
|
4805 } |
|
4806 writer.writeStartElement(CXXENUMERATORPROTOTYPE); |
|
4807 writer.writeCharacters((*i).name()); |
|
4808 writer.writeEndElement(); // <cxxEnumeratorPrototype> |
|
4809 writer.writeStartElement(CXXENUMERATORNAMELOOKUP); |
|
4810 writer.writeCharacters(en->parent()->name() + "::" + (*i).name()); |
|
4811 writer.writeEndElement(); // <cxxEnumeratorNameLookup> |
|
4812 |
|
4813 if (!(*i).value().isEmpty()) { |
|
4814 writer.writeStartElement(CXXENUMERATORINITIALISER); |
|
4815 writer.writeAttribute("value", (*i).value()); |
|
4816 writer.writeEndElement(); // <cxxEnumeratorInitialiser> |
|
4817 } |
|
4818 if (!(*i).text().isEmpty()) { |
|
4819 writer.writeStartElement(APIDESC); |
|
4820 generateText((*i).text(), en, marker); |
|
4821 writer.writeEndElement(); // </apiDesc> |
|
4822 } |
|
4823 writer.writeEndElement(); // <cxxEnumerator> |
|
4824 ++i; |
|
4825 } |
|
4826 writer.writeEndElement(); // <cxxEnumerators> |
|
4827 } |
|
4828 |
|
4829 writeLocation(en); |
|
4830 writer.writeEndElement(); // <cxxEnumerationDefinition> |
|
4831 writer.writeStartElement(APIDESC); |
|
4832 |
|
4833 if (!en->doc().isEmpty()) { |
|
4834 generateBody(en, marker); |
|
4835 } |
|
4836 |
|
4837 writer.writeEndElement(); // </apiDesc> |
|
4838 writer.writeEndElement(); // </cxxEnumerationDetail> |
|
4839 writer.writeEndElement(); // </cxxEnumeration> |
|
4840 } |
|
4841 ++m; |
|
4842 } |
|
4843 } |
|
4844 |
|
4845 void DitaXmlGenerator::writeTypedefs(const Section& s, |
|
4846 const ClassNode* cn, |
|
4847 CodeMarker* marker) |
|
4848 { |
|
4849 NodeList::ConstIterator m = s.members.begin(); |
|
4850 while (m != s.members.end()) { |
|
4851 if ((*m)->type() == Node::Typedef) { |
|
4852 const TypedefNode* tn = static_cast<const TypedefNode*>(*m); |
|
4853 writer.writeStartElement(CXXTYPEDEF); |
|
4854 writer.writeAttribute("id",tn->guid()); |
|
4855 writer.writeStartElement(APINAME); |
|
4856 writer.writeCharacters(tn->name()); |
|
4857 writer.writeEndElement(); // </apiName> |
|
4858 generateBrief(tn,marker); |
|
4859 writer.writeStartElement(CXXTYPEDEFDETAIL); |
|
4860 writer.writeStartElement(CXXTYPEDEFDEFINITION); |
|
4861 writer.writeStartElement(CXXTYPEDEFACCESSSPECIFIER); |
|
4862 writer.writeAttribute("value",tn->accessString()); |
|
4863 writer.writeEndElement(); // <cxxTypedefAccessSpecifier> |
|
4864 |
|
4865 QString fq = fullQualification(tn); |
|
4866 if (!fq.isEmpty()) { |
|
4867 writer.writeStartElement(CXXTYPEDEFSCOPEDNAME); |
|
4868 writer.writeCharacters(fq); |
|
4869 writer.writeEndElement(); // <cxxTypedefScopedName> |
|
4870 } |
|
4871 writer.writeStartElement(CXXTYPEDEFNAMELOOKUP); |
|
4872 writer.writeCharacters(tn->parent()->name() + "::" + tn->name()); |
|
4873 writer.writeEndElement(); // <cxxTypedefNameLookup> |
|
4874 |
|
4875 writeLocation(tn); |
|
4876 writer.writeEndElement(); // <cxxTypedefDefinition> |
|
4877 writer.writeStartElement(APIDESC); |
|
4878 |
|
4879 if (!tn->doc().isEmpty()) { |
|
4880 generateBody(tn, marker); |
|
4881 } |
|
4882 |
|
4883 writer.writeEndElement(); // </apiDesc> |
|
4884 writer.writeEndElement(); // </cxxTypedefDetail> |
|
4885 writer.writeEndElement(); // </cxxTypedef> |
|
4886 } |
|
4887 ++m; |
|
4888 } |
|
4889 } |
|
4890 |
|
4891 void DitaXmlGenerator::writeProperties(const Section& s, |
|
4892 const ClassNode* cn, |
|
4893 CodeMarker* marker) |
|
4894 { |
|
4895 NodeList::ConstIterator m = s.members.begin(); |
|
4896 while (m != s.members.end()) { |
|
4897 if ((*m)->type() == Node::Property) { |
|
4898 const PropertyNode* pn = static_cast<const PropertyNode*>(*m); |
|
4899 writer.writeStartElement(CXXVARIABLE); |
|
4900 writer.writeAttribute("id",pn->guid()); |
|
4901 writer.writeStartElement(APINAME); |
|
4902 writer.writeCharacters(pn->name()); |
|
4903 writer.writeEndElement(); // </apiName> |
|
4904 generateBrief(pn,marker); |
|
4905 writer.writeStartElement(CXXVARIABLEDETAIL); |
|
4906 writer.writeStartElement(CXXVARIABLEDEFINITION); |
|
4907 writer.writeStartElement(CXXVARIABLEACCESSSPECIFIER); |
|
4908 writer.writeAttribute("value",pn->accessString()); |
|
4909 writer.writeEndElement(); // <cxxVariableAccessSpecifier> |
|
4910 |
|
4911 if (!pn->qualifiedDataType().isEmpty()) { |
|
4912 writer.writeStartElement(CXXVARIABLEDECLAREDTYPE); |
|
4913 writer.writeCharacters(pn->qualifiedDataType()); |
|
4914 writer.writeEndElement(); // <cxxVariableDeclaredType> |
|
4915 } |
|
4916 QString fq = fullQualification(pn); |
|
4917 if (!fq.isEmpty()) { |
|
4918 writer.writeStartElement(CXXVARIABLESCOPEDNAME); |
|
4919 writer.writeCharacters(fq); |
|
4920 writer.writeEndElement(); // <cxxVariableScopedName> |
|
4921 } |
|
4922 |
|
4923 writer.writeStartElement(CXXVARIABLEPROTOTYPE); |
|
4924 writer.writeCharacters("Q_PROPERTY("); |
|
4925 writer.writeCharacters(pn->qualifiedDataType()); |
|
4926 writer.writeCharacters(" "); |
|
4927 writer.writeCharacters(pn->name()); |
|
4928 writePropParams("READ",pn->getters()); |
|
4929 writePropParams("WRITE",pn->setters()); |
|
4930 writePropParams("RESET",pn->resetters()); |
|
4931 writePropParams("NOTIFY",pn->notifiers()); |
|
4932 if (pn->isDesignable() != pn->designableDefault()) { |
|
4933 writer.writeCharacters(" DESIGNABLE "); |
|
4934 if (!pn->runtimeDesignabilityFunction().isEmpty()) |
|
4935 writer.writeCharacters(pn->runtimeDesignabilityFunction()); |
|
4936 else |
|
4937 writer.writeCharacters(pn->isDesignable() ? "true" : "false"); |
|
4938 } |
|
4939 if (pn->isScriptable() != pn->scriptableDefault()) { |
|
4940 writer.writeCharacters(" SCRIPTABLE "); |
|
4941 if (!pn->runtimeScriptabilityFunction().isEmpty()) |
|
4942 writer.writeCharacters(pn->runtimeScriptabilityFunction()); |
|
4943 else |
|
4944 writer.writeCharacters(pn->isScriptable() ? "true" : "false"); |
|
4945 } |
|
4946 if (pn->isWritable() != pn->writableDefault()) { |
|
4947 writer.writeCharacters(" STORED "); |
|
4948 writer.writeCharacters(pn->isStored() ? "true" : "false"); |
|
4949 } |
|
4950 if (pn->isUser() != pn->userDefault()) { |
|
4951 writer.writeCharacters(" USER "); |
|
4952 writer.writeCharacters(pn->isUser() ? "true" : "false"); |
|
4953 } |
|
4954 if (pn->isConstant()) |
|
4955 writer.writeCharacters(" CONSTANT"); |
|
4956 if (pn->isFinal()) |
|
4957 writer.writeCharacters(" FINAL"); |
|
4958 writer.writeCharacters(")"); |
|
4959 writer.writeEndElement(); // <cxxVariablePrototype> |
|
4960 |
|
4961 writer.writeStartElement(CXXVARIABLENAMELOOKUP); |
|
4962 writer.writeCharacters(pn->parent()->name() + "::" + pn->name()); |
|
4963 writer.writeEndElement(); // <cxxVariableNameLookup> |
|
4964 |
|
4965 if (pn->overriddenFrom() != 0) { |
|
4966 PropertyNode* opn = (PropertyNode*)pn->overriddenFrom(); |
|
4967 writer.writeStartElement(CXXVARIABLEREIMPLEMENTED); |
|
4968 writer.writeAttribute("href",opn->ditaXmlHref()); |
|
4969 writer.writeCharacters(marker->plainFullName(opn)); |
|
4970 writer.writeEndElement(); // </cxxVariableReimplemented> |
|
4971 } |
|
4972 |
|
4973 writeLocation(pn); |
|
4974 writer.writeEndElement(); // <cxxVariableDefinition> |
|
4975 writer.writeStartElement(APIDESC); |
|
4976 |
|
4977 if (!pn->doc().isEmpty()) { |
|
4978 generateBody(pn, marker); |
|
4979 } |
|
4980 |
|
4981 writer.writeEndElement(); // </apiDesc> |
|
4982 writer.writeEndElement(); // </cxxVariableDetail> |
|
4983 writer.writeEndElement(); // </cxxVariable> |
|
4984 } |
|
4985 ++m; |
|
4986 } |
|
4987 } |
|
4988 |
|
4989 void DitaXmlGenerator::writeDataMembers(const Section& s, |
|
4990 const ClassNode* cn, |
|
4991 CodeMarker* marker) |
|
4992 { |
|
4993 NodeList::ConstIterator m = s.members.begin(); |
|
4994 while (m != s.members.end()) { |
|
4995 if ((*m)->type() == Node::Variable) { |
|
4996 const VariableNode* vn = static_cast<const VariableNode*>(*m); |
|
4997 writer.writeStartElement(CXXVARIABLE); |
|
4998 writer.writeAttribute("id",vn->guid()); |
|
4999 writer.writeStartElement(APINAME); |
|
5000 writer.writeCharacters(vn->name()); |
|
5001 writer.writeEndElement(); // </apiName> |
|
5002 generateBrief(vn,marker); |
|
5003 writer.writeStartElement(CXXVARIABLEDETAIL); |
|
5004 writer.writeStartElement(CXXVARIABLEDEFINITION); |
|
5005 writer.writeStartElement(CXXVARIABLEACCESSSPECIFIER); |
|
5006 writer.writeAttribute("value",vn->accessString()); |
|
5007 writer.writeEndElement(); // <cxxVariableAccessSpecifier> |
|
5008 |
|
5009 if (vn->isStatic()) { |
|
5010 writer.writeStartElement(CXXVARIABLESTORAGECLASSSPECIFIERSTATIC); |
|
5011 writer.writeAttribute("name","static"); |
|
5012 writer.writeAttribute("value","static"); |
|
5013 writer.writeEndElement(); // <cxxVariableStorageClassSpecifierStatic> |
|
5014 } |
|
5015 |
|
5016 writer.writeStartElement(CXXVARIABLEDECLAREDTYPE); |
|
5017 writer.writeCharacters(vn->leftType()); |
|
5018 if (!vn->rightType().isEmpty()) |
|
5019 writer.writeCharacters(vn->rightType()); |
|
5020 writer.writeEndElement(); // <cxxVariableDeclaredType> |
|
5021 |
|
5022 QString fq = fullQualification(vn); |
|
5023 if (!fq.isEmpty()) { |
|
5024 writer.writeStartElement(CXXVARIABLESCOPEDNAME); |
|
5025 writer.writeCharacters(fq); |
|
5026 writer.writeEndElement(); // <cxxVariableScopedName> |
|
5027 } |
|
5028 |
|
5029 writer.writeStartElement(CXXVARIABLEPROTOTYPE); |
|
5030 writer.writeCharacters(vn->leftType() + " "); |
|
5031 //writer.writeCharacters(vn->parent()->name() + "::" + vn->name()); |
|
5032 writer.writeCharacters(vn->name()); |
|
5033 if (!vn->rightType().isEmpty()) |
|
5034 writer.writeCharacters(vn->rightType()); |
|
5035 writer.writeEndElement(); // <cxxVariablePrototype> |
|
5036 |
|
5037 writer.writeStartElement(CXXVARIABLENAMELOOKUP); |
|
5038 writer.writeCharacters(vn->parent()->name() + "::" + vn->name()); |
|
5039 writer.writeEndElement(); // <cxxVariableNameLookup> |
|
5040 |
|
5041 writeLocation(vn); |
|
5042 writer.writeEndElement(); // <cxxVariableDefinition> |
|
5043 writer.writeStartElement(APIDESC); |
|
5044 |
|
5045 if (!vn->doc().isEmpty()) { |
|
5046 generateBody(vn, marker); |
|
5047 } |
|
5048 |
|
5049 writer.writeEndElement(); // </apiDesc> |
|
5050 writer.writeEndElement(); // </cxxVariableDetail> |
|
5051 writer.writeEndElement(); // </cxxVariable> |
|
5052 } |
|
5053 ++m; |
|
5054 } |
|
5055 } |
|
5056 |
|
5057 void DitaXmlGenerator::writeMacros(const Section& s, |
|
5058 const ClassNode* cn, |
|
5059 CodeMarker* marker) |
|
5060 { |
|
5061 NodeList::ConstIterator m = s.members.begin(); |
|
5062 while (m != s.members.end()) { |
|
5063 if ((*m)->type() == Node::Function) { |
|
5064 const FunctionNode* fn = static_cast<const FunctionNode*>(*m); |
|
5065 if (fn->isMacro()) { |
|
5066 writer.writeStartElement(CXXDEFINE); |
|
5067 writer.writeAttribute("id",fn->guid()); |
|
5068 writer.writeStartElement(APINAME); |
|
5069 writer.writeCharacters(fn->name()); |
|
5070 writer.writeEndElement(); // </apiName> |
|
5071 generateBrief(fn,marker); |
|
5072 writer.writeStartElement(CXXDEFINEDETAIL); |
|
5073 writer.writeStartElement(CXXDEFINEDEFINITION); |
|
5074 writer.writeStartElement(CXXDEFINEACCESSSPECIFIER); |
|
5075 writer.writeAttribute("value",fn->accessString()); |
|
5076 writer.writeEndElement(); // <cxxDefineAccessSpecifier> |
|
5077 |
|
5078 writer.writeStartElement(CXXDEFINEPROTOTYPE); |
|
5079 writer.writeCharacters("#define "); |
|
5080 writer.writeCharacters(fn->name()); |
|
5081 if (fn->metaness() == FunctionNode::MacroWithParams) { |
|
5082 QStringList params = fn->parameterNames(); |
|
5083 if (!params.isEmpty()) { |
|
5084 writer.writeCharacters("("); |
|
5085 for (int i = 0; i < params.size(); ++i) { |
|
5086 if (params[i].isEmpty()) |
|
5087 writer.writeCharacters("..."); |
|
5088 else |
|
5089 writer.writeCharacters(params[i]); |
|
5090 if ((i+1) < params.size()) |
|
5091 writer.writeCharacters(", "); |
|
5092 } |
|
5093 writer.writeCharacters(")"); |
|
5094 } |
|
5095 } |
|
5096 writer.writeEndElement(); // <cxxDefinePrototype> |
|
5097 |
|
5098 writer.writeStartElement(CXXDEFINENAMELOOKUP); |
|
5099 writer.writeCharacters(fn->name()); |
|
5100 writer.writeEndElement(); // <cxxDefineNameLookup> |
|
5101 |
|
5102 if (fn->reimplementedFrom() != 0) { |
|
5103 FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom(); |
|
5104 writer.writeStartElement(CXXDEFINEREIMPLEMENTED); |
|
5105 writer.writeAttribute("href",rfn->ditaXmlHref()); |
|
5106 writer.writeCharacters(marker->plainFullName(rfn)); |
|
5107 writer.writeEndElement(); // </cxxDefineReimplemented> |
|
5108 } |
|
5109 |
|
5110 if (fn->metaness() == FunctionNode::MacroWithParams) { |
|
5111 QStringList params = fn->parameterNames(); |
|
5112 if (!params.isEmpty()) { |
|
5113 writer.writeStartElement(CXXDEFINEPARAMETERS); |
|
5114 for (int i = 0; i < params.size(); ++i) { |
|
5115 writer.writeStartElement(CXXDEFINEPARAMETER); |
|
5116 writer.writeStartElement(CXXDEFINEPARAMETERDECLARATIONNAME); |
|
5117 writer.writeCharacters(params[i]); |
|
5118 writer.writeEndElement(); // <cxxDefineParameterDeclarationName> |
|
5119 writer.writeEndElement(); // <cxxDefineParameter> |
|
5120 } |
|
5121 writer.writeEndElement(); // <cxxDefineParameters> |
|
5122 } |
|
5123 } |
|
5124 |
|
5125 writeLocation(fn); |
|
5126 writer.writeEndElement(); // <cxxDefineDefinition> |
|
5127 writer.writeStartElement(APIDESC); |
|
5128 |
|
5129 if (!fn->doc().isEmpty()) { |
|
5130 generateBody(fn, marker); |
|
5131 } |
|
5132 |
|
5133 writer.writeEndElement(); // </apiDesc> |
|
5134 writer.writeEndElement(); // </cxxDefineDetail> |
|
5135 writer.writeEndElement(); // </cxxDefine> |
|
5136 } |
|
5137 } |
|
5138 ++m; |
|
5139 } |
|
5140 } |
|
5141 |
|
5142 void DitaXmlGenerator::writePropParams(const QString& tag, const NodeList& nlist) |
|
5143 { |
|
5144 NodeList::const_iterator n = nlist.begin(); |
|
5145 while (n != nlist.end()) { |
|
5146 writer.writeCharacters(" "); |
|
5147 writer.writeCharacters(tag); |
|
5148 writer.writeCharacters(" "); |
|
5149 writer.writeCharacters((*n)->name()); |
|
5150 ++n; |
|
5151 } |
|
5152 } |
|
5153 |
|
5154 QT_END_NAMESPACE |