/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
ditaxmlgenerator.cpp
*/
#include "codemarker.h"
#include "codeparser.h"
#include "ditaxmlgenerator.h"
#include "node.h"
#include "quoter.h"
#include "separator.h"
#include "tree.h"
#include
#include
#include
#include
#include
#include
QT_BEGIN_NAMESPACE
#define COMMAND_VERSION Doc::alias("version")
int DitaXmlGenerator::id = 0;
bool DitaXmlGenerator::inApiDesc = false;
bool DitaXmlGenerator::inSection = false;
bool DitaXmlGenerator::inDetailedDescription = false;
bool DitaXmlGenerator::inLegaleseText = false;
#define cxxapi_d_xref Doc::alias("cxxapi-d-xref")
#define cxxclass Doc::alias("cxxclass")
#define cxxdefine Doc::alias("cxxdefine")
#define cxxenumeration Doc::alias("cxxenumeration")
#define cxxfile Doc::alias("cxxfile")
#define cxxfunction Doc::alias("cxxfunction")
#define cxxstruct Doc::alias("cxxstruct")
#define cxxtypedef Doc::alias("cxxtypedef")
#define cxxunion Doc::alias("cxxunion")
#define cxxvariable Doc::alias("cxxvariable")
#define CXXAPIMAP Doc::alias("cxxAPIMap")
#define CXXCLASSREF Doc::alias("cxxClassRef")
#define CXXDEFINEREF Doc::alias("cxxDefineRef")
#define CXXENUMERATIONREF Doc::alias("cxxEnumerationRef")
#define CXXFILEREF Doc::alias("cxxFileRef")
#define CXXFUNCTIONREF Doc::alias("cxxFunctionRef")
#define CXXSTRUCTREF Doc::alias("cxxStructRef")
#define CXXTYPDEFREF Doc::alias("cxxTypedefRef")
#define CXXUNIONREF Doc::alias("cxxUnionRef")
#define CXXVARIABLEREF Doc::alias("cxxVariableRef")
#define CXXCLASS Doc::alias("cxxClass")
#define CXXCLASSABSTRACT Doc::alias("cxxClassAbstract")
#define CXXCLASSACCESSSPECIFIER Doc::alias("cxxClassAccessSpecifier")
#define CXXCLASSAPIITEMLOCATION Doc::alias("cxxClassAPIItemLocation")
#define CXXCLASSBASECLASS Doc::alias("cxxClassBaseClass")
#define CXXCLASSBASECLASSSTRUCT Doc::alias("cxxClassBaseStruct")
#define CXXCLASSBASEUNION Doc::alias("cxxClassBaseUnion")
#define CXXCLASSDECLARATIONFILE Doc::alias("cxxClassDeclarationFile")
#define CXXCLASSDECLARATIONFILELINE Doc::alias("cxxClassDeclarationFileLine")
#define CXXCLASSDEFINITION Doc::alias("cxxClassDefinition")
#define CXXCLASSDEFINITIONFILE Doc::alias("cxxClassDefinitionFile")
#define CXXCLASSDEFINITIONFILEEND Doc::alias("cxxClassDefinitionFileLineEnd")
#define CXXCLASSDEFINITIONFILESTART Doc::alias("cxxClassDefinitionFileLineStart")
#define CXXCLASSDERIVATION Doc::alias("cxxClassDerivation")
#define CXXCLASSDERIVATIONACCESSSPECIFIER Doc::alias("cxxClassDerivationAccessSpecifier")
#define CXXCLASSDERIVATIONS Doc::alias("cxxClassDerivations")
#define CXXCLASSDERIVATIONVIRTUAL Doc::alias("cxxClassDerivationVirtual")
#define CXXCLASSDETAIL Doc::alias("cxxClassDetail")
#define CXXCLASSENUMERATIONINHERITED Doc::alias("cxxClassEnumerationInherited")
#define CXXCLASSENUMERATORINHERITED Doc::alias("cxxClassEnumeratorInherited")
#define CXXCLASSFUNCTIONINHERITED Doc::alias("cxxClassFunctionInherited")
#define CXXCLASSINHERITS Doc::alias("cxxClassInherits")
#define CXXCLASSINHERITSDETAIL Doc::alias("cxxClassInheritsDetail")
#define CXXCLASSNESTED Doc::alias("cxxClassNested")
#define CXXCLASSNESTEDCLASS Doc::alias("cxxClassNestedClass")
#define CXXCLASSNESTEDDETAIL Doc::alias("cxxClassNestedDetail")
#define CXXCLASSNESTEDSTRUCT Doc::alias("cxxClassNestedStruct")
#define CXXCLASSNESTEDUNION Doc::alias("cxxClassNestedUnion")
#define CXXCLASSTEMPLATEPARAMETER Doc::alias("cxxClassTemplateParameter")
#define CXXCLASSTEMPLATEPARAMETERS Doc::alias("cxxClassTemplateParameters")
#define CXXCLASSTEMPLATEPARAMETERTYPE Doc::alias("cxxClassTemplateParameterType")
#define CXXCLASSVARIABLEINHERITED Doc::alias("cxxClassVariableInherited")
#define CXXDEFINE Doc::alias("cxxDefine")
#define CXXDEFINEACCESSSPECIFIER Doc::alias("cxxDefineAccessSpecifier")
#define CXXDEFINEAPIITEMLOCATION Doc::alias("cxxDefineAPIItemLocation")
#define CXXDEFINEDECLARATIONFILE Doc::alias("cxxDefineDeclarationFile")
#define CXXDEFINEDECLARATIONFILELINE Doc::alias("cxxDefineDeclarationFileLine")
#define CXXDEFINEDEFINITION Doc::alias("cxxDefineDefinition")
#define CXXDEFINEDETAIL Doc::alias("cxxDefineDetail")
#define CXXDEFINENAMELOOKUP Doc::alias("cxxDefineNameLookup")
#define CXXDEFINEPARAMETER Doc::alias("cxxDefineParameter")
#define CXXDEFINEPARAMETERDECLARATIONNAME Doc::alias("cxxDefineParameterDeclarationName")
#define CXXDEFINEPARAMETERS Doc::alias("cxxDefineParameters")
#define CXXDEFINEPROTOTYPE Doc::alias("cxxDefinePrototype")
#define CXXDEFINEREIMPLEMENTED Doc::alias("cxxDefineReimplemented")
#define CXXENUMERATION Doc::alias("cxxEnumeration")
#define CXXENUMERATIONACCESSSPECIFIER Doc::alias("cxxEnumerationAccessSpecifier")
#define CXXENUMERATIONAPIITEMLOCATION Doc::alias("cxxEnumerationAPIItemLocation")
#define CXXENUMERATIONDECLARATIONFILE Doc::alias("cxxEnumerationDeclarationFile")
#define CXXENUMERATIONDECLARATIONFILELINE Doc::alias("cxxEnumerationDeclarationFileLine")
#define CXXENUMERATIONDEFINITION Doc::alias("cxxEnumerationDefinition")
#define CXXENUMERATIONDEFINITIONFILE Doc::alias("cxxEnumerationDefinitionFile")
#define CXXENUMERATIONDEFINITIONFILELINEEND Doc::alias("cxxEnumerationDefinitionFileLineEnd")
#define CXXENUMERATIONDEFINITIONFILELINESTART Doc::alias("cxxEnumerationDefinitionFileLineStart")
#define CXXENUMERATIONDETAIL Doc::alias("cxxEnumerationDetail")
#define CXXENUMERATIONNAMELOOKUP Doc::alias("cxxEnumerationNameLookup")
#define CXXENUMERATIONPROTOTYPE Doc::alias("cxxEnumerationPrototype")
#define CXXENUMERATIONREIMPLEMENTED Doc::alias("cxxEnumerationReimplemented")
#define CXXENUMERATIONSCOPEDNAME Doc::alias("cxxEnumerationScopedName")
#define CXXENUMERATOR Doc::alias("cxxEnumerator")
#define CXXENUMERATORAPIITEMLOCATION Doc::alias("cxxEnumeratorAPIItemLocation")
#define CXXENUMERATORDECLARATIONFILE Doc::alias("cxxEnumeratorDeclarationFile")
#define CXXENUMERATORDECLARATIONFILELINE Doc::alias("cxxEnumeratorDeclarationFileLine")
#define CXXENUMERATORINITIALISER Doc::alias("cxxEnumeratorInitialiser")
#define CXXENUMERATORNAMELOOKUP Doc::alias("cxxEnumeratorNameLookup")
#define CXXENUMERATORPROTOTYPE Doc::alias("cxxEnumeratorPrototype")
#define CXXENUMERATORS Doc::alias("cxxEnumerators")
#define CXXENUMERATORSCOPEDNAME Doc::alias("cxxEnumeratorScopedName")
#define CXXFILE_INFO_TYPES Doc::alias("cxxFile-info-types")
#define CXXFILE_TYPES_DEFAULT Doc::alias("cxxFile-types-default")
#define CXXFILE Doc::alias("cxxFile")
#define CXXFILEAPIITMELOCATION Doc::alias("cxxFileAPIItemLocation")
#define CXXFILEDECLARATIONFILE Doc::alias("cxxFileDeclarationFile")
#define CXXFUNCTION Doc::alias("cxxFunction")
#define CXXFUNCTIONACCESSSPECIFIER Doc::alias("cxxFunctionAccessSpecifier")
#define CXXFUNCTIONAPIITEMLOCATION Doc::alias("cxxFunctionAPIItemLocation")
#define CXXFUNCTIONCONST Doc::alias("cxxFunctionConst")
#define CXXFUNCTIONCONSTRUCTOR Doc::alias("cxxFunctionConstructor")
#define CXXFUNCTIONDECLARATIONFILE Doc::alias("cxxFunctionDeclarationFile")
#define CXXFUNCTIONDECLARATIONFILELINE Doc::alias("cxxFunctionDeclarationFileLine")
#define CXXFUNCTIONDECLAREDTYPE Doc::alias("cxxFunctionDeclaredType")
#define CXXFUNCTIONDEFINITION Doc::alias("cxxFunctionDefinition")
#define CXXFUNCTIONDEFINITIONFILE Doc::alias("cxxFunctionDefinitionFile")
#define CXXFUNCTIONDEFINITIONFILELINEEND Doc::alias("cxxFunctionDefinitionFileLineEnd")
#define CXXFUNCTIONDEFINITIONFILELINESTART Doc::alias("cxxFunctionDefinitionFileLineStart")
#define CXXFUNCTIONDESTRUCTOR Doc::alias("cxxFunctionDestructor")
#define CXXFUNCTIONDETAIL Doc::alias("cxxFunctionDetail")
#define CXXFUNCTIONEXPLICIT Doc::alias("cxxFunctionExplicit")
#define CXXFUNCTIONINLINE Doc::alias("cxxFunctionInline")
#define CXXFUNCTIONNAMELOOKUP Doc::alias("cxxFunctionNameLookup")
#define CXXFUNCTIONPARAMETER Doc::alias("cxxFunctionParameter")
#define CXXFUNCTIONPARAMETERDECLARATIONNAME Doc::alias("cxxFunctionParameterDeclarationName")
#define CXXFUNCTIONPARAMETERDECLAREDTYPE Doc::alias("cxxFunctionParameterDeclaredType")
#define CXXFUNCTIONPARAMETERDEFAULTVALUE Doc::alias("cxxFunctionParameterDefaultValue")
#define CXXFUNCTIONPARAMETERDEFINITIONNAME Doc::alias("cxxFunctionParameterDefinitionName")
#define CXXFUNCTIONPARAMETERS Doc::alias("cxxFunctionParameters")
#define CXXFUNCTIONPROTOTYPE Doc::alias("cxxFunctionPrototype")
#define CXXFUNCTIONPUREVIRTUAL Doc::alias("cxxFunctionPureVirtual")
#define CXXFUNCTIONREIMPLEMENTED Doc::alias("cxxFunctionReimplemented")
#define CXXFUNCTIONRETURNTYPE Doc::alias("cxxFunctionReturnType")
#define CXXFUNCTIONSCOPEDNAME Doc::alias("cxxFunctionScopedName")
#define CXXFUNCTIONSTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxFunctionStorageClassSpecifierExtern")
#define CXXFUNCTIONSTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxFunctionStorageClassSpecifierMutable")
#define CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxFunctionStorageClassSpecifierStatic")
#define CXXFUNCTIONTEMPLATEPARAMETER Doc::alias("cxxFunctionTemplateParameter")
#define CXXFUNCTIONTEMPLATEPARAMETERS Doc::alias("cxxFunctionTemplateParameters")
#define CXXFUNCTIONTEMPLATEPARAMETERTYPE Doc::alias("cxxFunctionTemplateParameterType")
#define CXXFUNCTIONVIRTUAL Doc::alias("cxxFunctionVirtual")
#define CXXFUNCTIONVOLATILE Doc::alias("cxxFunctionVolatile")
#define CXXSTRUCT Doc::alias("cxxStruct")
#define CXXSTRUCTABSTRACT Doc::alias("cxxStructAbstract")
#define CXXSTRUCTACCESSSPECIFIER Doc::alias("cxxStructAccessSpecifier")
#define CXXSTRUCTAPIITEMLOCATION Doc::alias("cxxStructAPIItemLocation")
#define CXXSTRUCTBASECLASS Doc::alias("cxxStructBaseClass")
#define CXXSTRUCTBASESTRUCT Doc::alias("cxxStructBaseStruct")
#define CXXSTRUCTBASEUNION Doc::alias("cxxStructBaseUnion")
#define CXXSTRUCTDECLARATIONFILE Doc::alias("cxxStructDeclarationFile")
#define CXXSTRUCTDECLARATIONFILELINE Doc::alias("cxxStructDeclarationFileLine")
#define CXXSTRUCTDEFINITION Doc::alias("cxxStructDefinition")
#define CXXSTRUCTDEFINITIONFILE Doc::alias("cxxStructDefinitionFile")
#define CXXSTRUCTDEFINITIONFILELINEEND Doc::alias("cxxStructDefinitionFileLineEnd")
#define CXXSTRUCTDEFINITIONFILELINESTART Doc::alias("cxxStructDefinitionFileLineStart")
#define CXXSTRUCTDERIVATION Doc::alias("cxxStructDerivation")
#define CXXSTRUCTDERIVATIONACCESSSPECIFIER Doc::alias("cxxStructDerivationAccessSpecifier")
#define CXXSTRUCTDERIVATIONS Doc::alias("cxxStructDerivations")
#define CXXSTRUCTDERIVATIONVIRTUAL Doc::alias("cxxStructDerivationVirtual")
#define CXXSTRUCTDETAIL Doc::alias("cxxStructDetail")
#define CXXSTRUCTENUMERATIONINHERITED Doc::alias("cxxStructEnumerationInherited")
#define CXXSTRUCTENUMERATORINHERITED Doc::alias("cxxStructEnumeratorInherited")
#define CXXSTRUCTFUNCTIONINHERITED Doc::alias("cxxStructFunctionInherited")
#define CXXSTRUCTINHERITS Doc::alias("cxxStructInherits")
#define CXXSTRUCTINHERITSDETAIL Doc::alias("cxxStructInheritsDetail")
#define CXXSTRUCTNESTED Doc::alias("cxxStructNested")
#define CXXSTRUCTNESTEDCLASS Doc::alias("cxxStructNestedClass")
#define CXXSTRUCTNESTEDDETAIL Doc::alias("cxxStructNestedDetail")
#define CXXSTRUCTNESTEDSTRUCT Doc::alias("cxxStructNestedStruct")
#define CXXSTRUCTNESTEDUNION Doc::alias("cxxStructNestedUnion")
#define CXXSTRUCTTEMPLATEPARAMETER Doc::alias("cxxStructTemplateParameter")
#define CXXSTRUCTTEMPLATEPARAMETERS Doc::alias("cxxStructTemplateParameters")
#define CXXSTRUCTTEMPLATEPARAMETERTYPE Doc::alias("cxxStructTemplateParameterType")
#define CXXSTRUCTVARIABLEINHERITED Doc::alias("cxxStructVariableInherited")
#define CXXTYPEDEF Doc::alias("cxxTypedef")
#define CXXTYPEDEFACCESSSPECIFIER Doc::alias("cxxTypedefAccessSpecifier")
#define CXXTYPEDEFAPIITEMLOCATION Doc::alias("cxxTypedefAPIItemLocation")
#define CXXTYPEDEFDECLARATIONFILE Doc::alias("cxxTypedefDeclarationFile")
#define CXXTYPEDEFDECLARATIONFILELINE Doc::alias("cxxTypedefDeclarationFileLine")
#define CXXTYPEDEFDECLAREDTYPE Doc::alias("cxxTypedefDeclaredType")
#define CXXTYPEDEFDEFINITION Doc::alias("cxxTypedefDefinition")
#define CXXTYPEDEFDETAIL Doc::alias("cxxTypedefDetail")
#define CXXTYPEDEFNAMELOOKUP Doc::alias("cxxTypedefNameLookup")
#define CXXTYPEDEFPROTOTYPE Doc::alias("cxxTypedefPrototype")
#define CXXTYPEDEFREIMPLEMENTED Doc::alias("cxxTypedefReimplemented")
#define CXXTYPEDEFSCOPEDNAME Doc::alias("cxxTypedefScopedName")
#define CXXUNION Doc::alias("cxxUnion")
#define CXXUNIONABSTRACT Doc::alias("cxxUnionAbstract")
#define CXXUNIONACCESSSPECIFIER Doc::alias("cxxUnionAccessSpecifier")
#define CXXUNIONAPIITEMLOCATION Doc::alias("cxxUnionAPIItemLocation")
#define CXXUNIONDECLARATIONFILE Doc::alias("cxxUnionDeclarationFile")
#define CXXUNIONDECLARATIONFILELINE Doc::alias("cxxUnionDeclarationFileLine")
#define CXXUNIONDEFINITION Doc::alias("cxxUnionDefinition")
#define CXXUNIONDEFINITIONFILE Doc::alias("cxxUnionDefinitionFile")
#define CXXUNIONDEFINITIONFILELINEEND Doc::alias("cxxUnionDefinitionFileLineEnd")
#define CXXUNIONDEFINITIONFILELINESTART Doc::alias("cxxUnionDefinitionFileLineStart")
#define CXXUNIONDETAIL Doc::alias("cxxUnionDetail")
#define CXXUNIONNESTED Doc::alias("cxxUnionNested")
#define CXXUNIONNESTEDCLASS Doc::alias("cxxUnionNestedClass")
#define CXXUNIONNESTEDDETAIL Doc::alias("cxxUnionNestedDetail")
#define CXXUNIONNESTEDSTRUCT Doc::alias("cxxUnionNestedStruct")
#define CXXUNIONNESTEDUNION Doc::alias("cxxUnionNestedUnion")
#define CXXUNIONTEMPLATEPARAMETER Doc::alias("cxxUnionTemplateParameter")
#define CXXUNIONTEMPLATEPARAMETERS Doc::alias("cxxUnionTemplateParameters")
#define CXXUNIONTEMPLATEPARAMETERTYPE Doc::alias("cxxUnionTemplateParameterType")
#define CXXVARIABLE Doc::alias("cxxVariable")
#define CXXVARIABLEACCESSSPECIFIER Doc::alias("cxxVariableAccessSpecifier")
#define CXXVARIABLEAPIITEMLOCATION Doc::alias("cxxVariableAPIItemLocation")
#define CXXVARIABLECONST Doc::alias("cxxVariableConst")
#define CXXVARIABLEDECLARATIONFILE Doc::alias("cxxVariableDeclarationFile")
#define CXXVARIABLEDECLARATIONFILELINE Doc::alias("cxxVariableDeclarationFileLine")
#define CXXVARIABLEDECLAREDTYPE Doc::alias("cxxVariableDeclaredType")
#define CXXVARIABLEDEFINITION Doc::alias("cxxVariableDefinition")
#define CXXVARIABLEDETAIL Doc::alias("cxxVariableDetail")
#define CXXVARIABLENAMELOOKUP Doc::alias("cxxVariableNameLookup")
#define CXXVARIABLEPROTOTYPE Doc::alias("cxxVariablePrototype")
#define CXXVARIABLEREIMPLEMENTED Doc::alias("cxxVariableReimplemented")
#define CXXVARIABLESCOPEDNAME Doc::alias("cxxVariableScopedName")
#define CXXVARIABLESTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxVariableStorageClassSpecifierExtern")
#define CXXVARIABLESTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxVariableStorageClassSpecifierMutable")
#define CXXVARIABLESTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxVariableStorageClassSpecifierStatic")
#define CXXVARIABLEVOLATILE Doc::alias("cxxVariableVolatile")
QString DitaXmlGenerator::sinceTitles[] =
{
" New Namespaces",
" New Classes",
" New Member Functions",
" New Functions in Namespaces",
" New Global Functions",
" New Macros",
" New Enum Types",
" New Typedefs",
" New Properties",
" New Variables",
" New QML Elements",
" New Qml Properties",
" New Qml Signals",
" New Qml Methods",
""
};
static bool showBrokenLinks = false;
/*!
Quick, dirty, and very ugly. Unescape \a text
so QXmlStreamWriter::writeCharacters() can put
the escapes back in again!
*/
void DitaXmlGenerator::writeCharacters(const QString& text)
{
QString t = text;
t = t.replace("<","<");
t = t.replace(">",">");
t = t.replace("&","&");
t = t.replace(""","\"");
xmlWriter().writeCharacters(t);
}
/*!
Appends an element to the current XML stream
with the \a href attribute and the \a text.
*/
void DitaXmlGenerator::addLink(const QString& href,
const QStringRef& text)
{
if (!href.isEmpty()) {
xmlWriter().writeStartElement("xref");
xmlWriter().writeAttribute("href", href);
writeCharacters(text.toString());
xmlWriter().writeEndElement(); //
}
else {
writeCharacters(text.toString());
}
}
/*!
The default constructor.
*/
DitaXmlGenerator::DitaXmlGenerator()
: inLink(false),
inContents(false),
inSectionHeading(false),
inTableHeader(false),
inTableBody(false),
numTableRows(0),
threeColumnEnumValueTable(true),
offlineDocs(true),
funcLeftParen("\\S(\\()"),
myTree(0),
slow(false),
obsoleteLinks(false),
noLinks(false),
tableColumnCount(0)
{
// nothing yet.
}
/*!
The destructor has nothing to do.
*/
DitaXmlGenerator::~DitaXmlGenerator()
{
GuidMaps::iterator i = guidMaps.begin();
while (i != guidMaps.end()) {
delete i.value();
++i;
}
}
/*!
A lot of internal structures are initialized.
*/
void DitaXmlGenerator::initializeGenerator(const Config &config)
{
static const struct {
const char *key;
const char *tag;
} defaults[] = {
{ ATOM_FORMATTING_BOLD, "b" },
{ ATOM_FORMATTING_INDEX, "");
break;
case Atom::FormatElse:
case Atom::FormatEndif:
case Atom::FormatIf:
break;
case Atom::FormattingLeft:
xmlWriter().writeStartElement(formattingLeftMap()[atom->string()]);
if (atom->string() == ATOM_FORMATTING_PARAMETER) {
if (atom->next() != 0 && atom->next()->type() == Atom::String) {
QRegExp subscriptRegExp("([a-z]+)_([0-9n])");
if (subscriptRegExp.exactMatch(atom->next()->string())) {
xmlWriter().writeCharacters(subscriptRegExp.cap(1));
xmlWriter().writeStartElement("sub");
xmlWriter().writeCharacters(subscriptRegExp.cap(2));
xmlWriter().writeEndElement(); //
skipAhead = 1;
}
}
}
break;
case Atom::FormattingRight:
if (atom->string() == ATOM_FORMATTING_LINK) {
endLink();
}
else {
xmlWriter().writeEndElement(); // ?
}
break;
case Atom::AnnotatedList:
{
QList values = myTree->groups().values(atom->string());
NodeMap nodeMap;
for (int i = 0; i < values.size(); ++i) {
const Node* n = values.at(i);
if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
nodeMap.insert(n->nameForLists(),n);
}
}
generateAnnotatedList(relative, marker, nodeMap);
}
break;
case Atom::GeneratedList:
if (atom->string() == "annotatedclasses") {
generateAnnotatedList(relative, marker, nonCompatClasses);
}
else if (atom->string() == "classes") {
generateCompactList(relative, marker, nonCompatClasses, true);
}
else if (atom->string() == "qmlclasses") {
generateCompactList(relative, marker, qmlClasses, true);
}
else if (atom->string().contains("classesbymodule")) {
QString arg = atom->string().trimmed();
QString moduleName = atom->string().mid(atom->string().indexOf(
"classesbymodule") + 15).trimmed();
if (moduleClassMap.contains(moduleName))
generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
}
else if (atom->string().contains("classesbyedition")) {
QString arg = atom->string().trimmed();
QString editionName = atom->string().mid(atom->string().indexOf(
"classesbyedition") + 16).trimmed();
if (editionModuleMap.contains(editionName)) {
// Add all classes in the modules listed for that edition.
NodeMap editionClasses;
foreach (const QString &moduleName, editionModuleMap[editionName]) {
if (moduleClassMap.contains(moduleName))
editionClasses.unite(moduleClassMap[moduleName]);
}
// Add additional groups and remove groups of classes that
// should be excluded from the edition.
QMultiMap groups = myTree->groups();
foreach (const QString &groupName, editionGroupMap[editionName]) {
QList groupClasses;
if (groupName.startsWith("-")) {
groupClasses = groups.values(groupName.mid(1));
foreach (const Node *node, groupClasses)
editionClasses.remove(node->name());
}
else {
groupClasses = groups.values(groupName);
foreach (const Node *node, groupClasses)
editionClasses.insert(node->name(), node);
}
}
generateAnnotatedList(relative, marker, editionClasses);
}
}
else if (atom->string() == "classhierarchy") {
generateClassHierarchy(relative, marker, nonCompatClasses);
}
else if (atom->string() == "compatclasses") {
generateCompactList(relative, marker, compatClasses, false);
}
else if (atom->string() == "obsoleteclasses") {
generateCompactList(relative, marker, obsoleteClasses, false);
}
else if (atom->string() == "functionindex") {
generateFunctionIndex(relative, marker);
}
else if (atom->string() == "legalese") {
generateLegaleseList(relative, marker);
}
else if (atom->string() == "mainclasses") {
generateCompactList(relative, marker, mainClasses, true);
}
else if (atom->string() == "services") {
generateCompactList(relative, marker, serviceClasses, false);
}
else if (atom->string() == "overviews") {
generateOverviewList(relative, marker);
}
else if (atom->string() == "namespaces") {
generateAnnotatedList(relative, marker, namespaceIndex);
}
else if (atom->string() == "related") {
const FakeNode *fake = static_cast(relative);
if (fake && !fake->groupMembers().isEmpty()) {
NodeMap groupMembersMap;
foreach (const Node *node, fake->groupMembers()) {
if (node->type() == Node::Fake)
groupMembersMap[fullName(node, relative, marker)] = node;
}
generateAnnotatedList(fake, marker, groupMembersMap);
}
}
break;
case Atom::SinceList:
{
NewSinceMaps::const_iterator nsmap;
nsmap = newSinceMaps.find(atom->string());
NewClassMaps::const_iterator ncmap;
ncmap = newClassMaps.find(atom->string());
NewClassMaps::const_iterator nqcmap;
nqcmap = newQmlClassMaps.find(atom->string());
if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
QList sections;
QList::ConstIterator s;
for (int i=0; itype()) {
case Node::Fake:
if (node->subType() == Node::QmlClass) {
sections[QmlClass].appendMember((Node*)node);
}
break;
case Node::Namespace:
sections[Namespace].appendMember((Node*)node);
break;
case Node::Class:
sections[Class].appendMember((Node*)node);
break;
case Node::Enum:
sections[Enum].appendMember((Node*)node);
break;
case Node::Typedef:
sections[Typedef].appendMember((Node*)node);
break;
case Node::Function: {
const FunctionNode* fn = static_cast(node);
if (fn->isMacro())
sections[Macro].appendMember((Node*)node);
else {
Node* p = fn->parent();
if (p) {
if (p->type() == Node::Class)
sections[MemberFunction].appendMember((Node*)node);
else if (p->type() == Node::Namespace) {
if (p->name().isEmpty())
sections[GlobalFunction].appendMember((Node*)node);
else
sections[NamespaceFunction].appendMember((Node*)node);
}
else
sections[GlobalFunction].appendMember((Node*)node);
}
else
sections[GlobalFunction].appendMember((Node*)node);
}
break;
}
case Node::Property:
sections[Property].appendMember((Node*)node);
break;
case Node::Variable:
sections[Variable].appendMember((Node*)node);
break;
case Node::QmlProperty:
sections[QmlProperty].appendMember((Node*)node);
break;
case Node::QmlSignal:
sections[QmlSignal].appendMember((Node*)node);
break;
case Node::QmlMethod:
sections[QmlMethod].appendMember((Node*)node);
break;
default:
break;
}
++n;
}
/*
First generate the table of contents.
*/
xmlWriter().writeStartElement("ul");
s = sections.constBegin();
while (s != sections.constEnd()) {
if (!(*s).members.isEmpty()) {
QString li = outFileName() + "#" + Doc::canonicalTitle((*s).name);
writeXrefListItem(li, (*s).name);
}
++s;
}
xmlWriter().writeEndElement(); //
int idx = 0;
s = sections.constBegin();
while (s != sections.constEnd()) {
if (!(*s).members.isEmpty()) {
xmlWriter().writeStartElement("p");
writeGuidAttribute(Doc::canonicalTitle((*s).name));
xmlWriter().writeAttribute("outputclass","h3");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
if (idx == Class)
generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
else if (idx == QmlClass)
generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
else if (idx == MemberFunction) {
ParentMaps parentmaps;
ParentMaps::iterator pmap;
NodeList::const_iterator i = s->members.constBegin();
while (i != s->members.constEnd()) {
Node* p = (*i)->parent();
pmap = parentmaps.find(p);
if (pmap == parentmaps.end())
pmap = parentmaps.insert(p,NodeMultiMap());
pmap->insert((*i)->name(),(*i));
++i;
}
pmap = parentmaps.begin();
while (pmap != parentmaps.end()) {
NodeList nlist = pmap->values();
xmlWriter().writeStartElement("p");
xmlWriter().writeCharacters("Class ");
xmlWriter().writeStartElement("xref");
xmlWriter().writeAttribute("href",linkForNode(pmap.key(), 0));
QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
writeCharacters(protectEnc(pieces.last()));
xmlWriter().writeEndElement(); //
xmlWriter().writeCharacters(":");
xmlWriter().writeEndElement(); //
generateSection(nlist, 0, marker, CodeMarker::Summary);
++pmap;
}
}
else {
generateSection(s->members, 0, marker, CodeMarker::Summary);
}
}
++idx;
++s;
}
}
}
break;
case Atom::Image:
case Atom::InlineImage:
{
QString fileName = imageFileName(relative, atom->string());
QString text;
if (atom->next() != 0)
text = atom->next()->string();
if (fileName.isEmpty()) {
/*
Don't bother outputting an error message.
Just output the href as if the image is in
the images directory...
*/
fileName = QLatin1String("images/") + protectEnc(atom->string());
}
xmlWriter().writeStartElement("fig");
xmlWriter().writeStartElement("image");
xmlWriter().writeAttribute("href",protectEnc(fileName));
if (atom->type() == Atom::InlineImage)
xmlWriter().writeAttribute("placement","inline");
else {
xmlWriter().writeAttribute("placement","break");
xmlWriter().writeAttribute("align","center");
}
if (!text.isEmpty()) {
xmlWriter().writeStartElement("alt");
writeCharacters(protectEnc(text));
xmlWriter().writeEndElement(); //
}
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
break;
case Atom::ImageText:
// nothing
break;
case Atom::LegaleseLeft:
inLegaleseText = true;
break;
case Atom::LegaleseRight:
inLegaleseText = false;
break;
case Atom::LineBreak:
//xmlWriter().writeEmptyElement("br");
break;
case Atom::Link:
{
const Node *node = 0;
QString myLink = getLink(atom, relative, marker, &node);
if (myLink.isEmpty()) {
relative->doc().location().warning(tr("Can't link to '%1' in %2")
.arg(atom->string())
.arg(marker->plainFullName(relative)));
}
else if (!inSectionHeading) {
beginLink(myLink);
}
#if 0
else {
//xmlWriter().writeCharacters(atom->string());
//qDebug() << "MYLINK:" << myLink << outFileName() << atom->string();
}
#endif
skipAhead = 1;
}
break;
case Atom::GuidLink:
{
#if 0
qDebug() << "GUID LINK:" << atom->string() << outFileName();
#endif
beginLink(atom->string());
skipAhead = 1;
}
break;
case Atom::LinkNode:
{
const Node* node = CodeMarker::nodeForString(atom->string());
beginLink(linkForNode(node, relative));
skipAhead = 1;
}
break;
case Atom::ListLeft:
if (in_para) {
xmlWriter().writeEndElement(); //
in_para = false;
}
if (atom->string() == ATOM_LIST_BULLET) {
xmlWriter().writeStartElement("ul");
}
else if (atom->string() == ATOM_LIST_TAG) {
xmlWriter().writeStartElement("dl");
}
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
xmlWriter().writeStartElement("simpletable");
xmlWriter().writeAttribute("outputclass","valuelist");
xmlWriter().writeStartElement("sthead");
xmlWriter().writeStartElement("stentry");
xmlWriter().writeCharacters("Constant");
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("stentry");
xmlWriter().writeCharacters("Value");
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("stentry");
xmlWriter().writeCharacters("Description");
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
else {
xmlWriter().writeStartElement("simpletable");
xmlWriter().writeAttribute("outputclass","valuelist");
xmlWriter().writeStartElement("sthead");
xmlWriter().writeStartElement("stentry");
xmlWriter().writeCharacters("Constant");
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("stentry");
xmlWriter().writeCharacters("Value");
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
}
else {
xmlWriter().writeStartElement("ol");
if (atom->string() == ATOM_LIST_UPPERALPHA)
xmlWriter().writeAttribute("outputclass","upperalpha");
else if (atom->string() == ATOM_LIST_LOWERALPHA)
xmlWriter().writeAttribute("outputclass","loweralpha");
else if (atom->string() == ATOM_LIST_UPPERROMAN)
xmlWriter().writeAttribute("outputclass","upperroman");
else if (atom->string() == ATOM_LIST_LOWERROMAN)
xmlWriter().writeAttribute("outputclass","lowerroman");
else // (atom->string() == ATOM_LIST_NUMERIC)
xmlWriter().writeAttribute("outputclass","numeric");
if (atom->next() != 0 && atom->next()->string().toInt() != 1) {
// I don't think this attribute is supported.
xmlWriter().writeAttribute("start",atom->next()->string());
}
}
break;
case Atom::ListItemNumber:
// nothing
break;
case Atom::ListTagLeft:
if (atom->string() == ATOM_LIST_TAG) {
xmlWriter().writeStartElement("dt");
}
else { // (atom->string() == ATOM_LIST_VALUE)
xmlWriter().writeStartElement("strow");
xmlWriter().writeStartElement("stentry");
xmlWriter().writeStartElement("tt");
writeCharacters(protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
relative))));
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("stentry");
QString itemValue;
if (relative->type() == Node::Enum) {
const EnumNode *enume = static_cast(relative);
itemValue = enume->itemValue(atom->next()->string());
}
if (itemValue.isEmpty())
xmlWriter().writeCharacters("?");
else {
xmlWriter().writeStartElement("tt");
writeCharacters(protectEnc(itemValue));
xmlWriter().writeEndElement(); //
}
skipAhead = 1;
}
break;
case Atom::ListTagRight:
if (atom->string() == ATOM_LIST_TAG)
xmlWriter().writeEndElement(); //
break;
case Atom::ListItemLeft:
if (atom->string() == ATOM_LIST_TAG) {
xmlWriter().writeStartElement("dd");
}
else if (atom->string() == ATOM_LIST_VALUE) {
if (threeColumnEnumValueTable) {
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("stentry");
}
}
else {
xmlWriter().writeStartElement("li");
}
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
break;
case Atom::ListItemRight:
if (atom->string() == ATOM_LIST_TAG) {
xmlWriter().writeEndElement(); //
}
else if (atom->string() == ATOM_LIST_VALUE) {
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
else {
xmlWriter().writeEndElement(); //
}
break;
case Atom::ListRight:
if (atom->string() == ATOM_LIST_BULLET) {
xmlWriter().writeEndElement(); //
}
else if (atom->string() == ATOM_LIST_TAG) {
xmlWriter().writeEndElement(); //
}
else if (atom->string() == ATOM_LIST_VALUE) {
xmlWriter().writeEndElement(); //
}
else {
xmlWriter().writeEndElement(); //
}
break;
case Atom::Nop:
// nothing
break;
case Atom::ParaLeft:
xmlWriter().writeStartElement("p");
if (inLegaleseText)
xmlWriter().writeAttribute("outputclass","legalese");
in_para = true;
break;
case Atom::ParaRight:
endLink();
if (in_para) {
xmlWriter().writeEndElement(); //
in_para = false;
}
break;
case Atom::QuotationLeft:
xmlWriter().writeStartElement("lq");
break;
case Atom::QuotationRight:
xmlWriter().writeEndElement(); //
break;
case Atom::RawString:
if (atom->string() == " ")
break;
if (atom->string().startsWith("&"))
writeCharacters(atom->string());
else if (atom->string() == "*") {
xmlWriter().writeStartElement("sup");
writeCharacters("*");
xmlWriter().writeEndElement(); //
}
else {
xmlWriter().writeStartElement("pre");
xmlWriter().writeAttribute("outputclass","raw-html");
writeCharacters(atom->string());
xmlWriter().writeEndElement(); //
}
break;
case Atom::SectionLeft:
if (inSection || inApiDesc) {
inApiDesc = false;
xmlWriter().writeEndElement(); // or
}
inSection = true;
xmlWriter().writeStartElement("section");
writeGuidAttribute(Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
xmlWriter().writeAttribute("outputclass","details");
break;
case Atom::SectionRight:
if (inSection) {
inSection = false;
xmlWriter().writeEndElement(); //
}
break;
case Atom::SectionHeadingLeft:
xmlWriter().writeStartElement("title");
hx = "h" + QString::number(atom->string().toInt() + hOffset(relative));
xmlWriter().writeAttribute("outputclass",hx);
inSectionHeading = true;
break;
case Atom::SectionHeadingRight:
xmlWriter().writeEndElement(); // (see case Atom::SectionHeadingLeft)
inSectionHeading = false;
break;
case Atom::SidebarLeft:
// nothing
break;
case Atom::SidebarRight:
// nothing
break;
case Atom::String:
if (inLink && !inContents && !inSectionHeading) {
generateLink(atom, relative, marker);
}
else {
writeCharacters(protectEnc(atom->string()));
}
break;
case Atom::TableLeft:
{
if (in_para) {
xmlWriter().writeEndElement(); //
in_para = false;
}
xmlWriter().writeStartElement("table");
numTableRows = 0;
if (tableColumnCount != 0) {
qDebug() << "ERROR: Nested tables!";
tableColumnCount = 0;
}
tableColumnCount = countTableColumns(atom->next());
xmlWriter().writeStartElement("tgroup");
xmlWriter().writeAttribute("cols",QString::number(tableColumnCount));
inTableHeader = false;
inTableBody = false;
}
break;
case Atom::TableRight:
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
inTableHeader = false;
inTableBody = false;
tableColumnCount = 0;
break;
case Atom::TableHeaderLeft:
if (inTableBody) {
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
inTableHeader = false;
inTableBody = false;
tableColumnCount = 0;
xmlWriter().writeStartElement("table");
numTableRows = 0;
tableColumnCount = countTableColumns(atom);
xmlWriter().writeStartElement("tgroup");
xmlWriter().writeAttribute("cols",QString::number(tableColumnCount));
}
xmlWriter().writeStartElement("thead");
xmlWriter().writeAttribute("valign","top");
xmlWriter().writeStartElement("row");
xmlWriter().writeAttribute("valign","top");
inTableHeader = true;
inTableBody = false;
break;
case Atom::TableHeaderRight:
xmlWriter().writeEndElement(); //
if (matchAhead(atom, Atom::TableHeaderLeft)) {
skipAhead = 1;
xmlWriter().writeStartElement("row");
xmlWriter().writeAttribute("valign","top");
}
else {
xmlWriter().writeEndElement(); //
inTableHeader = false;
inTableBody = true;
xmlWriter().writeStartElement("tbody");
}
break;
case Atom::TableRowLeft:
if (!inTableHeader && !inTableBody) {
inTableBody = true;
xmlWriter().writeStartElement("tbody");
}
xmlWriter().writeStartElement("row");
xmlWriter().writeAttribute("valign","top");
break;
case Atom::TableRowRight:
xmlWriter().writeEndElement(); //
break;
case Atom::TableItemLeft:
{
xmlWriter().writeStartElement("entry");
QStringList spans = atom->string().split(",");
if (spans.size() == 2) {
if (inTableHeader ||
(spans[0].toInt() != 1) ||
(spans[1].toInt() != 1)) {
QString s = "span(" + spans[0] + "," + spans[1] + ")";
xmlWriter().writeAttribute("outputclass",s);
}
}
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
}
break;
case Atom::TableItemRight:
if (inTableHeader)
xmlWriter().writeEndElement(); //
else {
xmlWriter().writeEndElement(); //
}
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
break;
case Atom::TableOfContents:
{
int numColumns = 1;
const Node* node = relative;
Doc::SectioningUnit sectioningUnit = Doc::Section4;
QStringList params = atom->string().split(",");
QString columnText = params.at(0);
QStringList pieces = columnText.split(" ", QString::SkipEmptyParts);
if (pieces.size() >= 2) {
columnText = pieces.at(0);
pieces.pop_front();
QString path = pieces.join(" ").trimmed();
node = findNodeForTarget(path, relative, marker, atom);
}
if (params.size() == 2) {
numColumns = qMax(columnText.toInt(), numColumns);
sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt();
}
if (node)
generateTableOfContents(node,
marker,
sectioningUnit,
numColumns,
relative);
}
break;
case Atom::Target:
if (in_para) {
xmlWriter().writeEndElement(); //
in_para = false;
}
xmlWriter().writeStartElement("p");
writeGuidAttribute(Doc::canonicalTitle(atom->string()));
xmlWriter().writeAttribute("outputclass","target");
//xmlWriter().writeCharacters(protectEnc(atom->string()));
xmlWriter().writeEndElement(); //
break;
case Atom::UnhandledFormat:
xmlWriter().writeStartElement("b");
xmlWriter().writeAttribute("outputclass","error");
xmlWriter().writeCharacters("");
xmlWriter().writeEndElement(); //
break;
case Atom::UnknownCommand:
xmlWriter().writeStartElement("b");
xmlWriter().writeAttribute("outputclass","error unknown-command");
writeCharacters(protectEnc(atom->string()));
xmlWriter().writeEndElement(); //
break;
case Atom::QmlText:
case Atom::EndQmlText:
// don't do anything with these. They are just tags.
break;
default:
// unknownAtom(atom);
break;
}
return skipAhead;
}
/*!
Generate a element (and all the stuff inside it)
for the C++ class represented by \a innerNode. \a marker is
for marking up the code. I don't know what that means exactly.
*/
void
DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* marker)
{
QList::ConstIterator s;
QString title;
QString rawTitle;
QString fullTitle;
if (inner->type() == Node::Namespace) {
const NamespaceNode* nsn = const_cast(static_cast(inner));
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
title = rawTitle + " Namespace";
/*
Note: Because the C++ specialization we are using
has no element, we are using the
element with an outputclass attribute
set to "namespace" .
*/
generateHeader(inner, fullTitle);
generateBrief(inner, marker); //
// not included:
xmlWriter().writeStartElement(CXXCLASSDETAIL);
xmlWriter().writeStartElement(CXXCLASSDEFINITION);
writeLocation(nsn);
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("apiDesc");
xmlWriter().writeAttribute("spectitle",title);
Text brief = nsn->doc().briefText(); // zzz
if (!brief.isEmpty()) {
xmlWriter().writeStartElement("p");
generateText(brief, nsn, marker);
xmlWriter().writeEndElement(); //
}
generateIncludes(nsn, marker);
generateStatus(nsn, marker);
generateThreadSafeness(nsn, marker);
generateSince(nsn, marker);
xmlWriter().writeEndElement(); //
bool needOtherSection = false;
QList summarySections;
summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
if (!s->inherited.isEmpty())
needOtherSection = true;
}
else {
QString attr;
if (!s->members.isEmpty()) {
xmlWriter().writeStartElement("section");
attr = cleanRef((*s).name).toLower() + " redundant";
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
generateSection(s->members, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
attr = cleanRef(name).toLower() + " redundant";
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc(name));
xmlWriter().writeEndElement(); //
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
}
++s;
}
if (needOtherSection) {
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass","additional-inherited-members redundant");
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h3");
xmlWriter().writeCharacters("Additional Inherited Members");
xmlWriter().writeEndElement(); //
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty())
generateSectionInheritedList(*s, inner, marker);
++s;
}
xmlWriter().writeEndElement(); //
}
writeDetailedDescription(nsn, marker, false, QString("Detailed Description"));
xmlWriter().writeEndElement(); //
// not included:
// not included:
QList detailSections;
detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
s = detailSections.begin();
while (s != detailSections.end()) {
if ((*s).name == "Classes") {
writeNestedClasses((*s),nsn);
break;
}
++s;
}
s = detailSections.begin();
while (s != detailSections.end()) {
if ((*s).name == "Function Documentation") {
writeFunctions((*s),nsn,marker);
}
else if ((*s).name == "Type Documentation") {
writeEnumerations((*s),marker);
writeTypedefs((*s),marker);
}
else if ((*s).name == "Namespaces") {
qDebug() << "Nested namespaces" << outFileName();
}
else if ((*s).name == "Macro Documentation") {
writeMacros((*s),marker);
}
++s;
}
generateLowStatusMembers(inner,marker,CodeMarker::Obsolete);
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
xmlWriter().writeEndElement(); //
}
else if (inner->type() == Node::Class) {
const ClassNode* cn = const_cast(static_cast(inner));
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
title = rawTitle + " Class Reference";
generateHeader(inner, fullTitle);
generateBrief(inner, marker); //
// not included:
xmlWriter().writeStartElement(CXXCLASSDETAIL);
xmlWriter().writeStartElement(CXXCLASSDEFINITION);
xmlWriter().writeStartElement(CXXCLASSACCESSSPECIFIER);
xmlWriter().writeAttribute("value",inner->accessString());
xmlWriter().writeEndElement(); //
if (cn->isAbstract()) {
xmlWriter().writeStartElement(CXXCLASSABSTRACT);
xmlWriter().writeAttribute("name","abstract");
xmlWriter().writeAttribute("value","abstract");
xmlWriter().writeEndElement(); //
}
writeDerivations(cn, marker); //
// not included:
writeLocation(cn);
xmlWriter().writeEndElement(); //
xmlWriter().writeStartElement("apiDesc");
xmlWriter().writeAttribute("spectitle",title);
Text brief = cn->doc().briefText(); // zzz
if (!brief.isEmpty()) {
xmlWriter().writeStartElement("p");
generateText(brief, cn, marker);
xmlWriter().writeEndElement(); //
}
generateIncludes(cn, marker);
generateStatus(cn, marker);
generateInherits(cn, marker);
generateInheritedBy(cn, marker);
generateThreadSafeness(cn, marker);
generateSince(cn, marker);
xmlWriter().writeEndElement(); //
bool needOtherSection = false;
QList summarySections;
summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
if (!s->inherited.isEmpty())
needOtherSection = true;
}
else {
QString attr;
if (!s->members.isEmpty()) {
xmlWriter().writeStartElement("section");
attr = cleanRef((*s).name).toLower() + " redundant";
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
generateSection(s->members, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
attr = cleanRef(name).toLower() + " redundant";
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc(name));
xmlWriter().writeEndElement(); //
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
}
++s;
}
if (needOtherSection) {
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass","additional-inherited-members redundant");
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h3");
xmlWriter().writeCharacters("Additional Inherited Members");
xmlWriter().writeEndElement(); //
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty())
generateSectionInheritedList(*s, inner, marker);
++s;
}
xmlWriter().writeEndElement(); //
}
writeDetailedDescription(cn, marker, false, QString("Detailed Description"));
// not included: or
xmlWriter().writeEndElement(); //
// not included:
// not included:
QList detailSections;
detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
s = detailSections.begin();
while (s != detailSections.end()) {
if ((*s).name == "Member Function Documentation") {
writeFunctions((*s),cn,marker);
}
else if ((*s).name == "Member Type Documentation") {
writeEnumerations((*s),marker);
writeTypedefs((*s),marker);
}
else if ((*s).name == "Member Variable Documentation") {
writeDataMembers((*s),marker);
}
else if ((*s).name == "Property Documentation") {
writeProperties((*s),marker);
}
else if ((*s).name == "Macro Documentation") {
writeMacros((*s),marker);
}
++s;
}
generateLowStatusMembers(inner,marker,CodeMarker::Obsolete);
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
xmlWriter().writeEndElement(); //
}
else if ((inner->type() == Node::Fake) && (inner->subType() == Node::HeaderFile)) {
const FakeNode* fn = const_cast(static_cast(inner));
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
title = rawTitle;
/*
Note: Because the C++ specialization we are using
has no element, we are using the
element with an outputclass attribute
set to "headerfile" .
*/
generateHeader(inner, fullTitle);
generateBrief(inner, marker); //
xmlWriter().writeStartElement(CXXCLASSDETAIL);
xmlWriter().writeStartElement("apiDesc");
xmlWriter().writeAttribute("spectitle",title);
Text brief = fn->doc().briefText(); // zzz
if (!brief.isEmpty()) {
xmlWriter().writeStartElement("p");
generateText(brief, fn, marker);
xmlWriter().writeEndElement(); //
}
generateIncludes(fn, marker);
generateStatus(fn, marker);
generateThreadSafeness(fn, marker);
generateSince(fn, marker);
xmlWriter().writeEndElement(); //
bool needOtherSection = false;
QList summarySections;
summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
if (!s->inherited.isEmpty())
needOtherSection = true;
}
else {
QString attr;
if (!s->members.isEmpty()) {
xmlWriter().writeStartElement("section");
attr = cleanRef((*s).name).toLower() + " redundant";
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
generateSection(s->members, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
attr = cleanRef(name).toLower() + " redundant";
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc(name));
xmlWriter().writeEndElement(); //
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
}
++s;
}
if (needOtherSection) {
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass","additional-inherited-members redundant");
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h3");
xmlWriter().writeCharacters("Additional Inherited Members");
xmlWriter().writeEndElement(); //
s = summarySections.begin();
while (s != summarySections.end()) {
if (s->members.isEmpty())
generateSectionInheritedList(*s, inner, marker);
++s;
}
xmlWriter().writeEndElement(); //
}
writeDetailedDescription(fn, marker, false, QString("Detailed Description"));
xmlWriter().writeEndElement(); //
// not included:
// not included:
QList detailSections;
detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
s = detailSections.begin();
while (s != detailSections.end()) {
if ((*s).name == "Classes") {
writeNestedClasses((*s),fn);
break;
}
++s;
}
s = detailSections.begin();
while (s != detailSections.end()) {
if ((*s).name == "Function Documentation") {
writeFunctions((*s),fn,marker);
}
else if ((*s).name == "Type Documentation") {
writeEnumerations((*s),marker);
writeTypedefs((*s),marker);
}
else if ((*s).name == "Namespaces") {
qDebug() << "Nested namespaces" << outFileName();
}
else if ((*s).name == "Macro Documentation") {
writeMacros((*s),marker);
}
++s;
}
generateLowStatusMembers(inner,marker,CodeMarker::Obsolete);
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
xmlWriter().writeEndElement(); //
}
else if ((inner->type() == Node::Fake) && (inner->subType() == Node::QmlClass)) {
const QmlClassNode* qcn = const_cast(static_cast(inner));
const ClassNode* cn = qcn->classNode();
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
title = rawTitle + " Element Reference";
//QString fullTitle = fake->fullTitle();
//QString htmlTitle = fullTitle;
generateHeader(inner, fullTitle);
generateBrief(inner, marker); //
// not included:
xmlWriter().writeStartElement(CXXCLASSDETAIL);
xmlWriter().writeStartElement("apiDesc");
xmlWriter().writeAttribute("spectitle",title);
Text brief = qcn->doc().briefText(); // zzz
if (!brief.isEmpty()) {
xmlWriter().writeStartElement("p");
generateText(brief, qcn, marker);
xmlWriter().writeEndElement(); //
}
generateQmlInstantiates(qcn, marker);
generateQmlInherits(qcn, marker);
generateQmlInheritedBy(qcn, marker);
generateSince(qcn, marker);
xmlWriter().writeEndElement(); //
QList summarySections;
summarySections = marker->qmlSections(qcn,CodeMarker::Summary,0);
s = summarySections.begin();
while (s != summarySections.end()) {
QString attr;
if (!s->members.isEmpty()) {
xmlWriter().writeStartElement("section");
attr = cleanRef((*s).name).toLower() + " redundant";
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
generateQmlSummary(*s,qcn,marker);
//generateSection(s->members, inner, marker, CodeMarker::Summary);
//generateSectionInheritedList(*s, inner, marker);
xmlWriter().writeEndElement(); //
}
++s;
}
writeDetailedDescription(qcn, marker, false, QString("Detailed Description"));
if (cn)
generateQmlText(cn->doc().body(), cn, marker, qcn->name());
QList detailSections;
detailSections = marker->qmlSections(qcn,CodeMarker::Detailed,0);
s = detailSections.begin();
while (s != detailSections.end()) {
if (!s->members.isEmpty()) {
QString attr;
inSection = true;
xmlWriter().writeStartElement("section");
attr = cleanRef((*s).name).toLower();
xmlWriter().writeAttribute("outputclass",attr);
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
writeCharacters(protectEnc((*s).name));
xmlWriter().writeEndElement(); //
NodeList::ConstIterator m = (*s).members.begin();
while (m != (*s).members.end()) {
generateDetailedQmlMember(*m, qcn, marker);
++m;
}
xmlWriter().writeEndElement(); //
inSection = false;
}
++s;
}
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
}
/*!
Write a list item for a \a link with the given \a text.
*/
void DitaXmlGenerator::writeXrefListItem(const QString& link, const QString& text)
{
xmlWriter().writeStartElement("li");
xmlWriter().writeStartElement("xref");
xmlWriter().writeAttribute("href",link);
writeCharacters(text);
xmlWriter().writeEndElement(); //
xmlWriter().writeEndElement(); //
}
/*!
Generate the html page for a qdoc file that doesn't map
to an underlying c++ file.
*/
void DitaXmlGenerator::generateFakeNode(const FakeNode* fake, CodeMarker* marker)
{
SubTitleSize subTitleSize = LargeSubTitle;
QList sections;
QList::const_iterator s;
QString fullTitle = fake->fullTitle();
QString htmlTitle = fullTitle;
if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
subTitleSize = SmallSubTitle;
htmlTitle += " (" + fake->subTitle() + ")";
}
else if (fake->subType() == Node::QmlBasicType) {
fullTitle = "QML Basic Type: " + fullTitle;
htmlTitle = fullTitle;
}
generateHeader(fake, fullTitle);
generateBrief(fake, marker); //
xmlWriter().writeStartElement("body");
if (fake->subType() == Node::Module) {
generateStatus(fake, marker);
if (moduleNamespaceMap.contains(fake->name())) {
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass","namespaces");
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
xmlWriter().writeCharacters("Namespaces");
xmlWriter().writeEndElement(); //
generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
xmlWriter().writeEndElement(); //
}
if (moduleClassMap.contains(fake->name())) {
xmlWriter().writeStartElement("section");
xmlWriter().writeAttribute("outputclass","classes");
xmlWriter().writeStartElement("title");
xmlWriter().writeAttribute("outputclass","h2");
xmlWriter().writeCharacters("Classes");
xmlWriter().writeEndElement(); //
generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
xmlWriter().writeEndElement(); //
}
}
if (fake->doc().isEmpty()) {
if (fake->subType() == Node::File) {
Text text;
Quoter quoter;
xmlWriter().writeStartElement("p");
xmlWriter().writeAttribute("outputclass", "small-subtitle");
text << fake->subTitle();
generateText(text, fake, marker);
xmlWriter().writeEndElement(); //
Doc::quoteFromFile(fake->doc().location(), quoter, fake->name());
QString code = quoter.quoteTo(fake->location(), "", "");
text.clear();
text << Atom(Atom::Code, code);
generateText(text, fake, marker);
}
}
else {
if (fake->subType() == Node::Module) {
writeDetailedDescription(fake, marker, false, QString("Detailed Description"));
}
else
writeDetailedDescription(fake, marker, false, QString());
generateAlsoList(fake, marker);
if (!fake->groupMembers().isEmpty()) {
NodeMap groupMembersMap;
foreach (const Node *node, fake->groupMembers()) {
if (node->type() == Node::Class || node->type() == Node::Namespace)
groupMembersMap[node->name()] = node;
}
generateAnnotatedList(fake, marker, groupMembersMap);
}
}
xmlWriter().writeEndElement(); //