From b45db5480d8bf4682ab3d203f0c56f1e3f1f7d00 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 8 Dec 2014 14:07:01 +0100 Subject: qdoc: Remove support for DITA XML This update makes removes Qdoc's DITA XML generator. Change-Id: Ibcfd013ace00e56a23268a2a5d850e6c9ea093d0 Task-number: QTBUG-43174 Reviewed-by: Martin Smith --- src/tools/qdoc/ditaxmlgenerator.cpp | 5993 ----------------------------------- src/tools/qdoc/ditaxmlgenerator.h | 520 --- src/tools/qdoc/generator.cpp | 1 - src/tools/qdoc/main.cpp | 3 +- src/tools/qdoc/qdoc.pro | 2 - 5 files changed, 1 insertion(+), 6518 deletions(-) delete mode 100644 src/tools/qdoc/ditaxmlgenerator.cpp delete mode 100644 src/tools/qdoc/ditaxmlgenerator.h (limited to 'src/tools') diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp deleted file mode 100644 index 54b358e170..0000000000 --- a/src/tools/qdoc/ditaxmlgenerator.cpp +++ /dev/null @@ -1,5993 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - ditaxmlgenerator.cpp -*/ - -#include -#include -#include -#include -#include -#include "codemarker.h" -#include "codeparser.h" -#include "ditaxmlgenerator.h" -#include "node.h" -#include "quoter.h" -#include "separator.h" -#include "tree.h" -#include -#include "qdocdatabase.h" - -QT_BEGIN_NAMESPACE - -#define COMMAND_VERSION Doc::alias("version") -int DitaXmlGenerator::id = 0; - -/* - The strings in this array must appear in the same order as - the values in enum DitaXmlGenerator::DitaTag. - */ -QString DitaXmlGenerator::ditaTags[] = -{ - "", - "alt", - "apiData", - "apiDef", - "apiDefItem", - "apiDesc", - "apiDetail", - "apiItemName", - "APIMap", - "apiName", - "apiRef", - "apiRelation", - "audience", - "author", - "b", - "body", - "bodydiv", - "brand", - "category", - "codeblock", - "colspec", - "comment", - "component", - "copyrholder", - "copyright", - "copyryear", - "created", - "critdates", - "cxxAPIMap", - "cxxClass", - "cxxClassAbstract", - "cxxClassAccessSpecifier", - "cxxClassAPIItemLocation", - "cxxClassBaseClass", - "cxxClassDeclarationFile", - "cxxClassDeclarationFileLine", - "cxxClassDeclarationFileLineStart", - "cxxClassDeclarationFileLineEnd", - "cxxClassDefinition", - "cxxClassDerivation", - "cxxClassDerivationAccessSpecifier", - "cxxClassDerivations", - "cxxClassDetail", - "cxxClassNested", - "cxxClassNestedClass", - "cxxClassNestedDetail", - "cxxDefine", - "cxxDefineAccessSpecifier", - "cxxDefineAPIItemLocation", - "cxxDefineDeclarationFile", - "cxxDefineDeclarationFileLine", - "cxxDefineDefinition", - "cxxDefineDetail", - "cxxDefineNameLookup", - "cxxDefineParameter", - "cxxDefineParameterDeclarationName", - "cxxDefineParameters", - "cxxDefinePrototype", - "cxxDefineReimplemented", - "cxxEnumeration", - "cxxEnumerationAccessSpecifier", - "cxxEnumerationAPIItemLocation", - "cxxEnumerationDeclarationFile", - "cxxEnumerationDeclarationFileLine", - "cxxEnumerationDeclarationFileLineStart", - "cxxEnumerationDeclarationFileLineEnd", - "cxxEnumerationDefinition", - "cxxEnumerationDetail", - "cxxEnumerationNameLookup", - "cxxEnumerationPrototype", - "cxxEnumerationScopedName", - "cxxEnumerator", - "cxxEnumeratorInitialiser", - "cxxEnumeratorNameLookup", - "cxxEnumeratorPrototype", - "cxxEnumerators", - "cxxEnumeratorScopedName", - "cxxFunction", - "cxxFunctionAccessSpecifier", - "cxxFunctionAPIItemLocation", - "cxxFunctionConst", - "cxxFunctionConstructor", - "cxxFunctionDeclarationFile", - "cxxFunctionDeclarationFileLine", - "cxxFunctionDeclaredType", - "cxxFunctionDefinition", - "cxxFunctionDestructor", - "cxxFunctionDetail", - "cxxFunctionNameLookup", - "cxxFunctionParameter", - "cxxFunctionParameterDeclarationName", - "cxxFunctionParameterDeclaredType", - "cxxFunctionParameterDefaultValue", - "cxxFunctionParameters", - "cxxFunctionPrototype", - "cxxFunctionPureVirtual", - "cxxFunctionReimplemented", - "cxxFunctionScopedName", - "cxxFunctionStorageClassSpecifierStatic", - "cxxFunctionVirtual", - "cxxTypedef", - "cxxTypedefAccessSpecifier", - "cxxTypedefAPIItemLocation", - "cxxTypedefDeclarationFile", - "cxxTypedefDeclarationFileLine", - "cxxTypedefDefinition", - "cxxTypedefDetail", - "cxxTypedefNameLookup", - "cxxTypedefScopedName", - "cxxVariable", - "cxxVariableAccessSpecifier", - "cxxVariableAPIItemLocation", - "cxxVariableDeclarationFile", - "cxxVariableDeclarationFileLine", - "cxxVariableDeclaredType", - "cxxVariableDefinition", - "cxxVariableDetail", - "cxxVariableNameLookup", - "cxxVariablePrototype", - "cxxVariableReimplemented", - "cxxVariableScopedName", - "cxxVariableStorageClassSpecifierStatic", - "data", - "data-about", - "dd", - "dl", - "dlentry", - "dt", - "entry", - "fig", - "i", - "image", - "keyword", - "keywords", - "li", - "link", - "linktext", - "lq", - "map", - "mapref", - "metadata", - "note", - "ol", - "othermeta", - "p", - "parameter", - "permissions", - "ph", - "platform", - "pre", - "prodinfo", - "prodname", - "prolog", - "publisher", - "qmlAttached", - "qmlDetail", - "qmlImportModule", - "qmlInheritedBy", - "qmlInherits", - "qmlInstantiates", - "qmlMethod", - "qmlMethodDef", - "qmlMethodDetail", - "qmlName", - "qmlProperty", - "qmlPropertyDef", - "qmlPropertyDetail", - "qmlPropertyGroup", - "qmlPropertyGroupDef", - "qmlPropertyGroupDetail", - "qmlQualifier", - "qmlSignal", - "qmlSignalDef", - "qmlSignalDetail", - "qmlSignalHandler", - "qmlSignalHandlerDef", - "qmlSignalHandlerDetail", - "qmlSignature", - "qmlSince", - "qmlType", - "qmlTypeDef", - "qmlTypeDetail", - "related-links", - "resourceid", - "revised", - "row", - "section", - "sectiondiv", - "shortdesc", - "simpletable", - "source", - "stentry", - "sthead", - "strow", - "sub", - "sup", - "table", - "tbody", - "tgroup", - "thead", - "title", - "tm", - "topic", - "topicmeta", - "topicref", - "tt", - "u", - "uicontrol", - "ul", - "unknown", - "vrm", - "vrmlist", - "xref", - "" -}; - -/*! - Composes a string to be used as an href attribute in DITA - XML. It is composed of the file name and the UUID separated - by a '#'. If this node is a class node, the file name is - taken from this node; if this node is a function node, the - file name is taken from the parent node of this node. - */ -QString DitaXmlGenerator::ditaXmlHref(Node* n) -{ - QString href; - if ((n->type() == Node::Function) || - (n->type() == Node::Property) || - (n->type() == Node::Variable)) { - href = fileBase(n->parent()); - } - else { - href = fileBase(n); - } - if (!href.endsWith(".xml") && !href.endsWith(".dita")) - href += ".dita"; - return href + QLatin1Char('#') + n->guid(); -} - -void DitaXmlGenerator::debugPara(const QString& t) -{ - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass",t); - xmlWriter().writeCharacters(t); - writeEndTag(); //

-} - -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, - DitaTag t) -{ - if (!href.isEmpty()) { - writeStartTag(t); - // formathtml - writeHrefAttribute(href); - writeCharacters(text.toString()); - writeEndTag(); // - } - else { - writeCharacters(text.toString()); - } -} - -/*! - Push \a t onto the dita tag stack and write the appropriate - start tag to the DITA XML file. - */ -void DitaXmlGenerator::writeStartTag(DitaTag t) -{ - xmlWriter().writeStartElement(ditaTags[t]); - tagStack.push(t); -} - -/*! - Pop the current DITA tag off the stack, and write the - appropriate end tag to the DITA XML file. If \a t is - not \e DT_NONE (default), then \a t contains the enum - value of the tag that should be on top of the stack. - - If the stack is empty, no end tag is written and false - is returned. Otherwise, an end tag is written and true - is returned. - */ -bool DitaXmlGenerator::writeEndTag(DitaTag t) -{ - if (tagStack.isEmpty()) - return false; - DitaTag top = tagStack.pop(); - if (t > DT_NONE && top != t) - qDebug() << "Expected:" << t << "ACTUAL:" << top; - xmlWriter().writeEndElement(); - return true; -} - -/*! - Return the current DITA element tag, the one - on top of the stack. - */ -DitaXmlGenerator::DitaTag DitaXmlGenerator::currentTag() -{ - return tagStack.top(); -} - -/*! - Write the start \a tag. if \a title is not empty, generate - a GUID from it and write the GUID as the value of the \e{id} - attribute. - - Then if \a outputclass is not empty, write it as the value - of the \a outputclass attribute. - - Fiunally, set the section nesting level to 1 and return 1. - */ -int DitaXmlGenerator::enterDesc(DitaTag tag, const QString& outputclass, const QString& title) -{ - writeStartTag(tag); - if (!title.isEmpty()) { - writeGuidAttribute(title); - //Are there cases where the spectitle is required? - //xmlWriter().writeAttribute("spectitle",title); - } - if (!outputclass.isEmpty()) - xmlWriter().writeAttribute("outputclass",outputclass); - sectionNestingLevel = 1; - return sectionNestingLevel; -} - -/*! - If the section nesting level is 0, output a \c{
} - element with an \e id attribute generated from \a title and - an \e outputclass attribute set to \a outputclass. - If \a title is null, no \e id attribute is output. - If \a outputclass is empty, no \e outputclass attribute - is output. - - Finally, increment the section nesting level and return - the new value. - */ -int DitaXmlGenerator::enterSection(const QString& outputclass, const QString& title) -{ - if (sectionNestingLevel == 0) { - writeStartTag(DT_section); - if (!title.isEmpty()) - writeGuidAttribute(title); - if (!outputclass.isEmpty()) - xmlWriter().writeAttribute("outputclass",outputclass); - } - else if (!title.isEmpty()) { - writeStartTag(DT_p); - writeGuidAttribute(title); - if (!outputclass.isEmpty()) - xmlWriter().writeAttribute("outputclass",outputclass); - writeCharacters(title); - writeEndTag(); //

- } - return ++sectionNestingLevel; -} - -/*! - If the section nesting level is greater than 0, decrement - it. If it becomes 0, output a \c {
}. Return the - decremented section nesting level. - */ -int DitaXmlGenerator::leaveSection() -{ - if (sectionNestingLevel > 0) { - --sectionNestingLevel; - if (sectionNestingLevel == 0) - writeEndTag(); // or - } - return sectionNestingLevel; -} - -/*! - Constructs the DITA XML output generator. - */ -DitaXmlGenerator::DitaXmlGenerator() - : inDetailedDescription(false), - inLegaleseText(false), - inObsoleteLink(false), - inTableBody(false), - noLinks(false), - obsoleteLinks(false), - divNestingLevel(0), - sectionNestingLevel(0), - tableColumnCount(0), - funcLeftParen("\\S(\\()"), - nodeTypeMaps(Node::LastType,0), - nodeSubtypeMaps(Node::LastSubtype,0), - pageTypeMaps(Node::OnBeyondZebra,0) -{ -} - -/*! - Destroys the DITA XML output generator. - */ -DitaXmlGenerator::~DitaXmlGenerator() -{ - GuidMaps::iterator i = guidMaps.begin(); - while (i != guidMaps.end()) { - delete i.value(); - ++i; - } -} - -/*! - Initializes the DITA XML output generator's data structures - from the configuration class \a config. - */ -void DitaXmlGenerator::initializeGenerator(const Config &config) -{ - Generator::initializeGenerator(config); - obsoleteLinks = config.getBool(CONFIG_OBSOLETELINKS); - setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif"); - - style = config.getString(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_STYLE); - postHeader = config.getString(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_POSTHEADER); - postPostHeader = config.getString(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_POSTPOSTHEADER); - footer = config.getString(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_FOOTER); - address = config.getString(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_ADDRESS); - pleaseGenerateMacRef = config.getBool(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_GENERATEMACREFS); - - project = config.getString(CONFIG_PROJECT); - projectDescription = config.getString(CONFIG_DESCRIPTION); - if (projectDescription.isEmpty() && !project.isEmpty()) - projectDescription = project + " Reference Documentation"; - - projectUrl = config.getString(CONFIG_URL); - tagFile_ = config.getString(CONFIG_TAGFILE); - -#ifndef QT_NO_TEXTCODEC - outputEncoding = config.getString(CONFIG_OUTPUTENCODING); - if (outputEncoding.isEmpty()) - outputEncoding = QLatin1String("ISO-8859-1"); - outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit()); -#endif - - naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE); - if (naturalLanguage.isEmpty()) - naturalLanguage = QLatin1String("en"); - - config.subVarsAndValues("dita.metadata.default",metadataDefaults); - QSet editionNames = config.subVars(CONFIG_EDITION); - QSet::ConstIterator edition = editionNames.constBegin(); - while (edition != editionNames.constEnd()) { - QString editionName = *edition; - QStringList editionModules = config.getStringList(CONFIG_EDITION + - Config::dot + - editionName + - Config::dot + - "modules"); - QStringList editionGroups = config.getStringList(CONFIG_EDITION + - Config::dot + - editionName + - Config::dot + - "groups"); - - if (!editionModules.isEmpty()) - editionModuleMap[editionName] = editionModules; - if (!editionGroups.isEmpty()) - editionGroupMap[editionName] = editionGroups; - - ++edition; - } - - stylesheets = config.getStringList(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_STYLESHEETS); - customHeadElements = config.getStringList(DitaXmlGenerator::format() + - Config::dot + - DITAXMLGENERATOR_CUSTOMHEADELEMENTS); - version = config.getString(CONFIG_VERSION); - vrm = version.split(QLatin1Char('.')); -} - -/*! - Gracefully terminates the DITA XML output generator. - */ -void DitaXmlGenerator::terminateGenerator() -{ - Generator::terminateGenerator(); -} - -/*! - Returns "DITAXML". - */ -QString DitaXmlGenerator::format() -{ - return "DITAXML"; -} - -/*! - Calls lookupGuid() to get a GUID for \a text, then writes - it to the XML stream as an "id" attribute, and returns it. - */ -QString DitaXmlGenerator::writeGuidAttribute(QString text) -{ - QString guid = lookupGuid(outFileName(),text); - xmlWriter().writeAttribute("id",guid); - return guid; -} - - -/*! - Write's the GUID for the \a node to the current XML stream - as an "id" attribute. If the \a node doesn't yet have a GUID, - one is generated. - */ -void DitaXmlGenerator::writeGuidAttribute(Node* node) -{ - xmlWriter().writeAttribute("id",node->guid()); -} - -/*! - Looks up \a text in the GUID map. If it finds \a text, - it returns the associated GUID. Otherwise it inserts - \a text into the map with a new GUID, and it returns - the new GUID. - */ -QString DitaXmlGenerator::lookupGuid(QString text) -{ - QMap::const_iterator i = name2guidMap.constFind(text); - if (i != name2guidMap.constEnd()) - return i.value(); - QString guid = Node::cleanId(text); - name2guidMap.insert(text,guid); - return guid; -} - -/*! - First, look up the GUID map for \a fileName. If there isn't - a GUID map for \a fileName, create one and insert it into - the map of GUID maps. Then look up \a text in that GUID map. - If \a text is found, return the associated GUID. Otherwise, - insert \a text into the GUID map with a new GUID, and return - the new GUID. - */ -QString DitaXmlGenerator::lookupGuid(const QString& fileName, const QString& text) -{ - GuidMap* gm = lookupGuidMap(fileName); - GuidMap::const_iterator i = gm->constFind(text); - if (i != gm->constEnd()) - return i.value(); - QString guid = Node::cleanId(text); - gm->insert(text,guid); - return guid; -} - -/*! - Looks up \a fileName in the map of GUID maps. If it finds - \a fileName, it returns a pointer to the associated GUID - map. Otherwise it creates a new GUID map and inserts it - into the map of GUID maps with \a fileName as its key. - */ -GuidMap* DitaXmlGenerator::lookupGuidMap(const QString& fileName) -{ - GuidMaps::const_iterator i = guidMaps.constFind(fileName); - if (i != guidMaps.constEnd()) - return i.value(); - GuidMap* gm = new GuidMap; - guidMaps.insert(fileName,gm); - return gm; -} - -/*! - Traverses the current tree generating all the DITA XML documentation. - */ -void DitaXmlGenerator::generateDocs() -{ - if (!preparing()) - Generator::generateDocs(); - - if (!generating()) { - QString fileBase = project.toLower().simplified().replace(QLatin1Char(' '), QLatin1Char('-')); - qdb_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", - projectUrl, - projectDescription, - this, - true); - } - - if (!preparing()) { - writeDitaMap(); - /* - Generate the XML tag file, if it was requested. - */ - qdb_->generateTagFile(tagFile_, this); - } -} - -static int countTableColumns(const Atom* t) -{ - int result = 0; - if (t->type() == Atom::TableHeaderLeft) { - while (t->type() == Atom::TableHeaderLeft) { - int count = 0; - t = t->next(); - while (t->type() != Atom::TableHeaderRight) { - if (t->type() == Atom::TableItemLeft) { - for (int i=0; icount(); ++i) { - QString attr = t->string(i); - if (!attr.contains('=')) { - QStringList spans = attr.split(QLatin1Char(',')); - if (spans.size() == 2) { - count += spans[0].toInt(); - } - else { - ++count; - } - } - } - } - t = t->next(); - } - if (count > result) - result = count; - t = t->next(); - } - } - else if (t->type() == Atom::TableRowLeft) { - while (t->type() != Atom::TableRowRight) { - if (t->type() == Atom::TableItemLeft) { - for (int i=0; icount(); ++i) { - QString attr = t->string(i); - if (!attr.contains('=')) { - QStringList spans = attr.split(QLatin1Char(',')); - if (spans.size() == 2) { - result += spans[0].toInt(); - } - else { - ++result; - } - } - } - } - t = t->next(); - } - } - return result; -} - -/*! - Generate html from an instance of Atom. - */ -int DitaXmlGenerator::generateAtom(const Atom *atom, - const Node *relative, - CodeMarker *marker) -{ - int skipAhead = 0; - QString hx, str; - static bool in_para = false; - QString guid, hc, attr; - - switch (atom->type()) { - case Atom::AbstractLeft: - break; - case Atom::AbstractRight: - break; - case Atom::AutoLink: - if (!noLinks && !inLink_ && !inContents_ && !inSectionHeading_) { - const Node* node = 0; - QString link = getAutoLink(atom, relative, &node); - if (!link.isEmpty()) { - beginLink(link); - generateLink(atom, marker); - endLink(); - } - else { - writeCharacters(protectEnc(atom->string())); - } - } - else { - writeCharacters(protectEnc(atom->string())); - } - break; - case Atom::BaseName: - break; - case Atom::BriefLeft: - { - Node::Type t = relative->type(); - if (inSection()) { - in_para = true; - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","brief"); - } - else { - noLinks = true; - writeStartTag(DT_shortdesc); - } - if (t == Node::Property || t == Node::Variable) { - xmlWriter().writeCharacters("This "); - if (relative->type() == Node::Property) - xmlWriter().writeCharacters("property"); - else if (relative->type() == Node::Variable) - xmlWriter().writeCharacters("variable"); - xmlWriter().writeCharacters(" holds "); - } - if (noLinks) { - atom = atom->next(); - while (atom != 0 && atom->type() != Atom::BriefRight) { - if (atom->type() == Atom::String || - atom->type() == Atom::AutoLink) - str += atom->string(); - skipAhead++; - atom = atom->next(); - } - if (t == Node::Property || t == Node::Variable) - str[0] = str[0].toLower(); - if (str.endsWith(QLatin1Char('.'))) - str.truncate(str.length() - 1); - writeCharacters(str + QLatin1Char('.')); - } - } - break; - case Atom::BriefRight: - writeEndTag(); // or

- if (in_para) - in_para = false; - noLinks = false; - break; - case Atom::C: - writeStartTag(DT_tt); - if (inLink_) { - writeCharacters(protectEnc(plainCode(atom->string()))); - } - else { - writeText(atom->string(), relative); - } - writeEndTag(); // see writeStartElement() above - break; - case Atom::Code: - { - writeStartTag(DT_codeblock); - xmlWriter().writeAttribute("outputclass","cpp"); - writeCharacters("\n"); - writeText(trimmedTrailing(atom->string()), relative); - writeEndTag(); // - } - break; - case Atom::Qml: - writeStartTag(DT_codeblock); - xmlWriter().writeAttribute("outputclass","qml"); - writeCharacters("\n"); - writeText(trimmedTrailing(atom->string()), relative); - writeEndTag(); // - break; - case Atom::CodeNew: - writeStartTag(DT_p); - xmlWriter().writeCharacters("you can rewrite it as"); - writeEndTag(); //

- writeStartTag(DT_codeblock); - writeCharacters("\n"); - writeText(trimmedTrailing(atom->string()), relative); - writeEndTag(); // - break; - case Atom::CodeOld: - writeStartTag(DT_p); - xmlWriter().writeCharacters("For example, if you have code like"); - writeEndTag(); //

- // fallthrough - case Atom::CodeBad: - writeStartTag(DT_codeblock); - writeCharacters("\n"); - writeCharacters(trimmedTrailing(plainCode(atom->string()))); - writeEndTag(); // - break; - case Atom::DivLeft: - { - bool inStartElement = false; - attr = atom->string(); - DitaTag t = currentTag(); - if ((t == DT_section) || (t == DT_sectiondiv)) { - writeStartTag(DT_sectiondiv); - divNestingLevel++; - inStartElement = true; - } - else if ((t == DT_body) || (t == DT_bodydiv)) { - writeStartTag(DT_bodydiv); - divNestingLevel++; - inStartElement = true; - } - if (!attr.isEmpty()) { - if (attr.contains('=')) { - int index = 0; - int from = 0; - QString values; - while (index >= 0) { - index = attr.indexOf('"',from); - if (index >= 0) { - ++index; - from = index; - index = attr.indexOf('"',from); - if (index > from) { - if (!values.isEmpty()) - values.append(' '); - values += attr.mid(from,index-from); - from = index+1; - } - } - } - attr = values; - } - } - if (inStartElement) - xmlWriter().writeAttribute("outputclass", attr); - } - break; - case Atom::DivRight: - if ((currentTag() == DT_sectiondiv) || (currentTag() == DT_bodydiv)) { - writeEndTag(); // , , or

- if (divNestingLevel > 0) - --divNestingLevel; - } - break; - case Atom::FootnoteLeft: - // ### For now - if (in_para) { - writeEndTag(); //

- in_para = false; - } - xmlWriter().writeCharacters(""); - break; - case Atom::FormatElse: - case Atom::FormatEndif: - case Atom::FormatIf: - break; - case Atom::FormattingLeft: - { - DitaTag t = DT_LAST; - if (atom->string() == ATOM_FORMATTING_BOLD) - t = DT_b; - else if (atom->string() == ATOM_FORMATTING_PARAMETER) - t = DT_i; - else if (atom->string() == ATOM_FORMATTING_ITALIC) - t = DT_i; - else if (atom->string() == ATOM_FORMATTING_TELETYPE) - t = DT_tt; - else if (atom->string().startsWith("span ")) { - t = DT_keyword; - } - else if (atom->string() == ATOM_FORMATTING_UICONTROL) - t = DT_uicontrol; - else if (atom->string() == ATOM_FORMATTING_UNDERLINE) - t = DT_u; - else if (atom->string() == ATOM_FORMATTING_INDEX) - t = DT_comment; - else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT) - t = DT_sub; - else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT) - t = DT_sup; - else - qDebug() << "DT_LAST"; - writeStartTag(t); - 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)); - writeStartTag(DT_sub); - xmlWriter().writeCharacters(subscriptRegExp.cap(2)); - writeEndTag(); // - skipAhead = 1; - } - } - } - else if (t == DT_keyword) { - QString attr = atom->string().mid(5); - if (!attr.isEmpty()) { - if (attr.contains('=')) { - int index = 0; - int from = 0; - QString values; - while (index >= 0) { - index = attr.indexOf('"',from); - if (index >= 0) { - ++index; - from = index; - index = attr.indexOf('"',from); - if (index > from) { - if (!values.isEmpty()) - values.append(' '); - values += attr.mid(from,index-from); - from = index+1; - } - } - } - attr = values; - } - } - xmlWriter().writeAttribute("outputclass", attr); - } - } - break; - case Atom::FormattingRight: - if (atom->string() == ATOM_FORMATTING_LINK) { - endLink(); - } - else { - writeEndTag(); // ? - } - break; - case Atom::AnnotatedList: - { - GroupNode* gn = qdb_->getGroup(atom->string()); - if (gn) - generateAnnotatedList(relative, marker, gn->members()); - } - break; - case Atom::GeneratedList: - if (atom->string() == "annotatedclasses") { - generateAnnotatedList(relative, marker, qdb_->getCppClasses()); - } - else if (atom->string() == "classes") { - generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("Q")); - } - else if (atom->string() == "qmlclasses") { - generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral("")); - } - else if (atom->string().contains("classesbymodule")) { - QString arg = atom->string().trimmed(); - QString moduleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed(); - QDocDatabase* qdb = QDocDatabase::qdocDB(); - ModuleNode* mn = qdb->findModule(moduleName); - if (mn) { - NodeMap m; - mn->getMemberClasses(m); - if (!m.isEmpty()) { - generateAnnotatedList(relative, marker, m); - } - } - } - else if (atom->string() == "classhierarchy") { - generateClassHierarchy(relative, qdb_->getCppClasses()); - } - else if (atom->string() == "compatclasses") { - // "compatclasses" is no longer used. Delete this at some point. - // mws 03/10/2013 - generateCompactList(Generic, relative, qdb_->getCompatibilityClasses(), false, QStringLiteral("Q")); - } - else if (atom->string() == "obsoleteclasses") { - generateCompactList(Generic, relative, qdb_->getObsoleteClasses(), false, QStringLiteral("Q")); - } - else if (atom->string() == "obsoleteqmltypes") { - generateCompactList(Generic, relative, qdb_->getObsoleteQmlTypes(), false, QStringLiteral("")); - } - else if (atom->string() == "obsoletecppmembers") { - generateCompactList(Obsolete, relative, qdb_->getClassesWithObsoleteMembers(), false, QStringLiteral("Q")); - } - else if (atom->string() == "obsoleteqmlmembers") { - generateCompactList(Obsolete, relative, qdb_->getQmlTypesWithObsoleteMembers(), false, QStringLiteral("")); - } - else if (atom->string() == "functionindex") { - generateFunctionIndex(relative); - } - else if (atom->string() == "legalese") { - generateLegaleseList(relative, marker); - } - else if (atom->string() == "mainclasses") { - // "mainclasses" is no longer used. Delete this at some point. - // mws 03/10/2013 - generateCompactList(Generic, relative, qdb_->getMainClasses(), true, QStringLiteral("Q")); - } - else if (atom->string() == "services") { - // "services" is no longer used. Delete this at some point. - // mws 03/10/2013 - generateCompactList(Generic, relative, qdb_->getServiceClasses(), false, QStringLiteral("Q")); - } - else if (atom->string() == "overviews") { - generateOverviewList(relative); - } - else if (atom->string() == "namespaces") { - generateAnnotatedList(relative, marker, qdb_->getNamespaces()); - } - else if (atom->string() == "related") { - if (relative && relative->isCollectionNode()) { - const CollectionNode* cn = static_cast(relative); - if (cn) - generateAnnotatedList(cn, marker, cn->members()); - } - } - break; - case Atom::SinceList: - { - const NodeMultiMap& nsmap = qdb_->getSinceMap(atom->string()); - const NodeMap& ncmap = qdb_->getClassMap(atom->string()); - const NodeMap& nqcmap = qdb_->getQmlTypeMap(atom->string()); - if (!nsmap.isEmpty()) { - QList
sections; - QList
::ConstIterator s; - - for (int i=0; itype()) { - case Node::QmlType: - 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::QmlSignalHandler: - sections[QmlSignalHandler].appendMember((Node*)node); - break; - case Node::QmlMethod: - sections[QmlMethod].appendMember((Node*)node); - break; - default: - break; - } - ++n; - } - - writeStartTag(DT_ul); - s = sections.constBegin(); - while (s != sections.constEnd()) { - if (!(*s).members.isEmpty()) { - QString li = outFileName() + QLatin1Char('#') + Doc::canonicalTitle((*s).name); - writeXrefListItem(li, (*s).name); - } - ++s; - } - writeEndTag(); // - - int idx = 0; - s = sections.constBegin(); - while (s != sections.constEnd()) { - if (!(*s).members.isEmpty()) { - writeStartTag(DT_p); - writeGuidAttribute(Doc::canonicalTitle((*s).name)); - xmlWriter().writeAttribute("outputclass","h3"); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); //

- if (idx == Class) - generateCompactList(Generic, 0, ncmap, false, QString("Q")); - else if (idx == QmlClass) - generateCompactList(Generic, 0, nqcmap, 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(); - writeStartTag(DT_p); - xmlWriter().writeCharacters("Class "); - writeStartTag(DT_xref); - // formathtml - xmlWriter().writeAttribute("href",linkForNode(pmap.key(), 0)); - QStringList pieces = pmap.key()->fullName().split("::"); - writeCharacters(protectEnc(pieces.last())); - writeEndTag(); // - xmlWriter().writeCharacters(":"); - writeEndTag(); //

- - generateSection(nlist, 0, marker, CodeMarker::Summary); - ++pmap; - } - } - else { - generateSection(s->members, 0, marker, CodeMarker::Summary); - } - } - ++idx; - ++s; - } - } - } - break; - case Atom::BR: - // DITA XML can't do
- break; - case Atom::HR: //

- writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","horizontal-rule"); - writeEndTag(); //

- 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()) { - relative->location().warning(tr("Missing image: %1").arg(protectEnc(atom->string()))); - QString images = "images"; - if (!atom->string().isEmpty() && atom->string()[0] != '/') - images.append(QLatin1Char('/')); - fileName = images + atom->string(); - } - if (relative && relative->isExample()) { - const ExampleNode* cen = static_cast(relative); - if (cen->imageFileName().isEmpty()) { - ExampleNode* en = const_cast(cen); - en->setImageFileName(fileName); - } - } - - if (currentTag() != DT_xref && atom->type() != Atom::InlineImage) - writeStartTag(DT_fig); - writeStartTag(DT_image); - writeHrefAttribute(protectEnc(fileName)); - if (atom->type() == Atom::Image) { - xmlWriter().writeAttribute("placement","break"); - xmlWriter().writeAttribute("align","center"); - } - if (!text.isEmpty()) { - writeStartTag(DT_alt); - writeCharacters(protectEnc(text)); - writeEndTag(); // - } - writeEndTag(); // - if (currentTag() != DT_xref && atom->type() != Atom::InlineImage) - writeEndTag(); // - } - break; - case Atom::ImageText: - // nothing - break; - case Atom::ImportantLeft: - writeStartTag(DT_note); - xmlWriter().writeAttribute("type","important"); - break; - case Atom::ImportantRight: - writeEndTag(); // - break; - case Atom::NoteLeft: - writeStartTag(DT_note); - xmlWriter().writeAttribute("type","note"); - break; - case Atom::NoteRight: - writeEndTag(); // - 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 link = getLink(atom, relative, &node); - if (link.isEmpty() && !noLinkErrors()) - relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string())); - else if (!inSectionHeading_) - beginLink(link); - skipAhead = 1; - } - break; - case Atom::GuidLink: - { - 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) { - writeEndTag(); //

- in_para = false; - } - if (atom->string() == ATOM_LIST_BULLET) { - writeStartTag(DT_ul); - } - else if (atom->string() == ATOM_LIST_TAG) { - writeStartTag(DT_dl); - } - else if (atom->string() == ATOM_LIST_VALUE) { - threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom); - if (threeColumnEnumValueTable_) { - writeStartTag(DT_simpletable); - xmlWriter().writeAttribute("outputclass","valuelist"); - writeStartTag(DT_sthead); - writeStartTag(DT_stentry); - xmlWriter().writeCharacters("Constant"); - writeEndTag(); // - writeStartTag(DT_stentry); - xmlWriter().writeCharacters("Value"); - writeEndTag(); // - writeStartTag(DT_stentry); - xmlWriter().writeCharacters("Description"); - writeEndTag(); // - writeEndTag(); // - } - else { - writeStartTag(DT_simpletable); - xmlWriter().writeAttribute("outputclass","valuelist"); - writeStartTag(DT_sthead); - writeStartTag(DT_stentry); - xmlWriter().writeCharacters("Constant"); - writeEndTag(); // - writeStartTag(DT_stentry); - xmlWriter().writeCharacters("Value"); - writeEndTag(); // - writeEndTag(); // - } - } - else { - writeStartTag(DT_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) { - /* - This attribute is not supported in DITA, and at the - moment, including it is causing a validation error - wherever it is used. I think it is only used in the - qdoc manual. - */ - //xmlWriter().writeAttribute("start",atom->next()->string()); - } - } - break; - case Atom::ListItemNumber: - // nothing - break; - case Atom::ListTagLeft: - if (atom->string() == ATOM_LIST_TAG) { - writeStartTag(DT_dt); - } - else { // (atom->string() == ATOM_LIST_VALUE) - writeStartTag(DT_strow); - writeStartTag(DT_stentry); - writeStartTag(DT_tt); - writeCharacters(protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(), - relative)))); - writeEndTag(); // - writeEndTag(); // - writeStartTag(DT_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 { - writeStartTag(DT_tt); - writeCharacters(protectEnc(itemValue)); - writeEndTag(); // - } - skipAhead = 1; - } - break; - case Atom::ListTagRight: - if (atom->string() == ATOM_LIST_TAG) - writeEndTag(); // - break; - case Atom::ListItemLeft: - if (atom->string() == ATOM_LIST_TAG) { - writeStartTag(DT_dd); - } - else if (atom->string() == ATOM_LIST_VALUE) { - if (threeColumnEnumValueTable_) { - writeEndTag(); // - writeStartTag(DT_stentry); - } - } - else { - writeStartTag(DT_li); - } - if (matchAhead(atom, Atom::ParaLeft)) - skipAhead = 1; - break; - case Atom::ListItemRight: - if (atom->string() == ATOM_LIST_TAG) { - writeEndTag(); // - } - else if (atom->string() == ATOM_LIST_VALUE) { - writeEndTag(); // - writeEndTag(); // - } - else { - writeEndTag(); // - } - break; - case Atom::ListRight: - if (atom->string() == ATOM_LIST_BULLET) { - writeEndTag(); // - } - else if (atom->string() == ATOM_LIST_TAG) { - writeEndTag(); // - } - else if (atom->string() == ATOM_LIST_VALUE) { - writeEndTag(); // - } - else { - writeEndTag(); // - } - break; - case Atom::Nop: - // nothing - break; - case Atom::ParaLeft: - writeStartTag(DT_p); - if (inLegaleseText) - xmlWriter().writeAttribute("outputclass","legalese"); - in_para = true; - break; - case Atom::ParaRight: - endLink(); - if (in_para) { - writeEndTag(); //

- in_para = false; - } - break; - case Atom::QuotationLeft: - writeStartTag(DT_lq); - break; - case Atom::QuotationRight: - writeEndTag(); // - break; - case Atom::RawString: - if (atom->string() == " ") - break; - if (atom->string().startsWith(QLatin1Char('&'))) - writeCharacters(atom->string()); - else if (atom->string() == "*") { - writeStartTag(DT_sup); - writeCharacters("*"); - writeEndTag(); // - } - else if (atom->string() == "®") { - writeStartTag(DT_tm); - xmlWriter().writeAttribute("tmtype","reg"); - writeEndTag(); // - } - else { - writeStartTag(DT_pre); - xmlWriter().writeAttribute("outputclass","raw-html"); - writeCharacters(atom->string()); - writeEndTag(); // - } - break; - case Atom::SectionLeft: - enterSection("details",QString()); - break; - case Atom::SectionRight: - leaveSection(); - break; - case Atom::SectionHeadingLeft: - { - writeStartTag(DT_p); - QString id = Text::sectionHeading(atom).toString(); - id = stripMarkup(id); - id = Doc::canonicalTitle(id); - writeGuidAttribute(id); - hx = QLatin1Char('h') + QString::number(atom->string().toInt() + hOffset(relative)); - xmlWriter().writeAttribute("outputclass",hx); - inSectionHeading_ = true; - } - break; - case Atom::SectionHeadingRight: - writeEndTag(); // (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, marker); - } - else { - writeCharacters(atom->string()); - } - break; - case Atom::TableLeft: - { - QString attr; - if ((atom->count() > 0) && (atom->string(0) == "borderless")) - attr = "borderless"; - else if ((atom->count() > 1) && (atom->string(1) == "borderless")) - attr = "borderless"; - if (in_para) { - writeEndTag(); //

- in_para = false; - } - writeStartTag(DT_table); - if (!attr.isEmpty()) - xmlWriter().writeAttribute("outputclass",attr); - numTableRows_ = 0; - if (tableColumnCount != 0) { - qDebug() << "ERROR: Nested tables!"; - tableColumnCount = 0; - } - tableColumnCount = countTableColumns(atom->next()); - writeStartTag(DT_tgroup); - xmlWriter().writeAttribute("cols",QString::number(tableColumnCount)); - for (int i = 0; i < tableColumnCount; i++) { - writeStartTag(DT_colspec); - xmlWriter().writeAttribute("colname", QStringLiteral("col%1").arg(i)); - xmlWriter().writeAttribute("colnum", QString::number(i)); - xmlWriter().writeAttribute("colwidth", QStringLiteral("1*")); - writeEndTag(); // DT_colspec - } - inTableHeader_ = false; - inTableBody = false; - } - break; - case Atom::TableRight: - writeEndTag(); // - writeEndTag(); // - writeEndTag(); // - inTableHeader_ = false; - inTableBody = false; - tableColumnCount = 0; - currentColumn = 0; - break; - case Atom::TableHeaderLeft: - if (inTableBody) { - writeEndTag(); // - writeEndTag(); // - writeEndTag(); // - inTableHeader_ = false; - inTableBody = false; - tableColumnCount = 0; - writeStartTag(DT_table); - numTableRows_ = 0; - tableColumnCount = countTableColumns(atom); - writeStartTag(DT_tgroup); - xmlWriter().writeAttribute("cols",QString::number(tableColumnCount)); - } - currentColumn = 0; - writeStartTag(DT_thead); - xmlWriter().writeAttribute("valign","top"); - writeStartTag(DT_row); - xmlWriter().writeAttribute("valign","top"); - inTableHeader_ = true; - inTableBody = false; - break; - case Atom::TableHeaderRight: - writeEndTag(); // - if (matchAhead(atom, Atom::TableHeaderLeft)) { - skipAhead = 1; - writeStartTag(DT_row); - xmlWriter().writeAttribute("valign","top"); - } - else { - writeEndTag(); // - inTableHeader_ = false; - inTableBody = true; - writeStartTag(DT_tbody); - } - break; - case Atom::TableRowLeft: - if (!inTableHeader_ && !inTableBody) { - inTableBody = true; - writeStartTag(DT_tbody); - } - currentColumn = 0; - writeStartTag(DT_row); - attr = atom->string(); - if (!attr.isEmpty()) { - if (attr.contains('=')) { - int index = 0; - int from = 0; - QString values; - while (index >= 0) { - index = attr.indexOf('"',from); - if (index >= 0) { - ++index; - from = index; - index = attr.indexOf('"',from); - if (index > from) { - if (!values.isEmpty()) - values.append(' '); - values += attr.mid(from,index-from); - from = index+1; - } - } - } - attr = values; - } - xmlWriter().writeAttribute("outputclass", attr); - } - xmlWriter().writeAttribute("valign","top"); - break; - case Atom::TableRowRight: - writeEndTag(); // - break; - case Atom::TableItemLeft: - { - QString values; - writeStartTag(DT_entry); - for (int i=0; icount(); ++i) { - attr = atom->string(i); - if (attr.contains('=')) { - int index = 0; - int from = 0; - while (index >= 0) { - index = attr.indexOf('"',from); - if (index >= 0) { - ++index; - from = index; - index = attr.indexOf('"',from); - if (index > from) { - if (!values.isEmpty()) - values.append(' '); - values += attr.mid(from,index-from); - from = index+1; - } - } - } - } - else { - QStringList spans = attr.split(QLatin1Char(',')); - if (spans.size() == 2) { - if (spans[0].toInt()>1) { - xmlWriter().writeAttribute("namest",QStringLiteral("col%1").arg(currentColumn)); - xmlWriter().writeAttribute("nameend",QStringLiteral("col%1") - .arg(currentColumn + (spans[0].toInt() - 1))); - } - if (spans[1].toInt()>1) - xmlWriter().writeAttribute("morerows",spans[1].simplified()); - currentColumn += spans[0].toInt(); - } - } - } - if (!values.isEmpty()) - xmlWriter().writeAttribute("outputclass",values); - if (matchAhead(atom, Atom::ParaLeft)) - skipAhead = 1; - } - break; - case Atom::TableItemRight: - if (inTableHeader_) { - writeEndTag(); // - } - else { - writeEndTag(); // - } - if (matchAhead(atom, Atom::ParaLeft)) - skipAhead = 1; - break; - case Atom::TableOfContents: - { - int numColumns = 1; - const Node* node = relative; - - Doc::Sections sectionUnit = Doc::Section4; - QStringList params = atom->string().split(QLatin1Char(',')); - QString columnText = params.at(0); - QStringList pieces = columnText.split(QLatin1Char(' '), QString::SkipEmptyParts); - if (pieces.size() >= 2) { - columnText = pieces.at(0); - pieces.pop_front(); - QString path = pieces.join(' ').trimmed(); - node = qdb_->findNodeForTarget(path, relative); - if (!node) - relative->doc().location().warning(tr("Cannot link to '%1'").arg(path)); - } - - if (params.size() == 2) { - numColumns = qMax(columnText.toInt(), numColumns); - sectionUnit = (Doc::Sections)params.at(1).toInt(); - } - - if (node) - generateTableOfContents(node, - marker, - sectionUnit, - numColumns, - relative); - } - break; - case Atom::Target: - if (in_para) { - writeEndTag(); //

- in_para = false; - } - writeStartTag(DT_p); - writeGuidAttribute(Doc::canonicalTitle(atom->string())); - xmlWriter().writeAttribute("outputclass","target"); - //xmlWriter().writeCharacters(protectEnc(atom->string())); - writeEndTag(); //

- break; - case Atom::UnhandledFormat: - writeStartTag(DT_b); - xmlWriter().writeAttribute("outputclass","error"); - xmlWriter().writeCharacters(""); - writeEndTag(); // - break; - case Atom::UnknownCommand: - writeStartTag(DT_b); - xmlWriter().writeAttribute("outputclass","error unknown-command"); - writeCharacters(protectEnc(atom->string())); - writeEndTag(); // - 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(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 = inner->plainName(); - fullTitle = inner->plainFullName(); - 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); // - writeProlog(inner); - - writeStartTag(DT_cxxClassDetail); - writeStartTag(DT_cxxClassDefinition); - writeLocation(nsn); - writeEndTag(); // - - enterDesc(DT_apiDesc,QString(),title); - generateStatus(nsn, marker); - generateThreadSafeness(nsn, marker); - generateSince(nsn, marker); - - enterSection(QString(), QString()); - generateBody(nsn, marker); - generateAlsoList(nsn, marker); - leaveSection(); - leaveSection(); // - - bool needOtherSection = false; - QList
summarySections; - summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); - if (!summarySections.isEmpty()) { - enterSection("redundant",QString()); - s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { - if (!s->inherited.isEmpty()) - needOtherSection = true; - } - else { - QString attr; - if (!s->members.isEmpty()) { - writeStartTag(DT_p); - attr = cleanRef((*s).name).toLower() + " h2"; - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); // - generateSection(s->members, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - if (!s->reimpMembers.isEmpty()) { - QString name = QString("Reimplemented ") + (*s).name; - attr = cleanRef(name).toLower() + " h2"; - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc(name)); - writeEndTag(); // - generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - } - ++s; - } - if (needOtherSection) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","h3"); - xmlWriter().writeCharacters("Additional Inherited Members"); - writeEndTag(); // - s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty()) - generateSectionInheritedList(*s, inner); - ++s; - } - } - leaveSection(); - } - - writeEndTag(); // - - // not included: - // not included: - - QList
detailSections; - detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay); - s = detailSections.constBegin(); - while (s != detailSections.constEnd()) { - if ((*s).name == "Classes") { - writeNestedClasses((*s),nsn); - break; - } - ++s; - } - - s = detailSections.constBegin(); - while (s != detailSections.constEnd()) { - 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); - writeEndTag(); // - } - else if (inner->type() == Node::Class) { - const ClassNode* cn = const_cast(static_cast(inner)); - rawTitle = inner->plainName(); - fullTitle = inner->plainFullName(); - title = rawTitle + " Class"; - - generateHeader(inner, fullTitle); - generateBrief(inner, marker); // - writeProlog(inner); - - writeStartTag(DT_cxxClassDetail); - writeStartTag(DT_cxxClassDefinition); - writeStartTag(DT_cxxClassAccessSpecifier); - xmlWriter().writeAttribute("value",inner->accessString()); - writeEndTag(); // - if (cn->isAbstract()) { - writeStartTag(DT_cxxClassAbstract); - xmlWriter().writeAttribute("name","abstract"); - xmlWriter().writeAttribute("value","abstract"); - writeEndTag(); // - } - writeDerivations(cn); // - - // not included: - - writeLocation(cn); - writeEndTag(); // - - enterDesc(DT_apiDesc,QString(),title); - generateStatus(cn, marker); - generateInherits(cn, marker); - generateInheritedBy(cn, marker); - generateThreadSafeness(cn, marker); - generateSince(cn, marker); - enterSection(QString(), QString()); - generateBody(cn, marker); - generateAlsoList(cn, marker); - leaveSection(); - leaveSection(); // - - bool needOtherSection = false; - QList
summarySections; - summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); - if (!summarySections.isEmpty()) { - enterSection("redundant",QString()); - s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { - if (!s->inherited.isEmpty()) - needOtherSection = true; - } - else { - QString attr; - if (!s->members.isEmpty()) { - writeStartTag(DT_p); - attr = cleanRef((*s).name).toLower() + " h2"; - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); //

- generateSection(s->members, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - if (!s->reimpMembers.isEmpty()) { - QString name = QString("Reimplemented ") + (*s).name; - attr = cleanRef(name).toLower() + " h2"; - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc(name)); - writeEndTag(); //

- generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - } - ++s; - } - if (needOtherSection) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","h3"); - xmlWriter().writeCharacters("Additional Inherited Members"); - writeEndTag(); //

- s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty()) - generateSectionInheritedList(*s, inner); - ++s; - } - } - leaveSection(); - } - - // not included: or - - writeEndTag(); // - - // not included: - // not included: - - QList
detailSections; - detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay); - s = detailSections.constBegin(); - while (s != detailSections.constEnd()) { - 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); - } - else if ((*s).name == "Related Non-Members") { - QString attribute("related-non-member"); - writeFunctions((*s),cn,marker,attribute); - } - ++s; - } - - generateLowStatusMembers(inner,marker,CodeMarker::Obsolete); - generateLowStatusMembers(inner,marker,CodeMarker::Compat); - writeEndTag(); // - } - else if (inner->isHeaderFile()) { - const DocNode* dn = const_cast(static_cast(inner)); - rawTitle = inner->plainName(); - fullTitle = inner->plainFullName(); - 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); // - writeProlog(inner); - - writeStartTag(DT_cxxClassDetail); - enterDesc(DT_apiDesc,QString(),title); - generateStatus(dn, marker); - generateThreadSafeness(dn, marker); - generateSince(dn, marker); - generateSince(dn, marker); - enterSection(QString(), QString()); - generateBody(dn, marker); - generateAlsoList(dn, marker); - leaveSection(); - leaveSection(); // - - bool needOtherSection = false; - QList
summarySections; - summarySections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); - if (!summarySections.isEmpty()) { - enterSection("redundant",QString()); - s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { - if (!s->inherited.isEmpty()) - needOtherSection = true; - } - else { - QString attr; - if (!s->members.isEmpty()) { - writeStartTag(DT_p); - attr = cleanRef((*s).name).toLower() + " h2"; - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); //

- generateSection(s->members, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - if (!s->reimpMembers.isEmpty()) { - QString name = QString("Reimplemented ") + (*s).name; - attr = cleanRef(name).toLower() + " h2"; - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc(name)); - writeEndTag(); //

- generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); - generateSectionInheritedList(*s, inner); - } - } - ++s; - } - if (needOtherSection) { - enterSection("additional-inherited-members redundant",QString()); - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","h3"); - xmlWriter().writeCharacters("Additional Inherited Members"); - writeEndTag(); //

- s = summarySections.constBegin(); - while (s != summarySections.constEnd()) { - if (s->members.isEmpty()) - generateSectionInheritedList(*s, inner); - ++s; - } - } - leaveSection(); - } - - writeEndTag(); // - - // not included: - // not included: - - QList
detailSections; - detailSections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay); - s = detailSections.constBegin(); - while (s != detailSections.constEnd()) { - if ((*s).name == "Classes") { - writeNestedClasses((*s),dn); - break; - } - ++s; - } - - s = detailSections.constBegin(); - while (s != detailSections.constEnd()) { - if ((*s).name == "Function Documentation") { - writeFunctions((*s),dn,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); - writeEndTag(); // - } - else if (inner->isQmlType()) { - QmlClassNode* qcn = const_cast(static_cast(inner)); - ClassNode* cn = qcn->classNode(); - rawTitle = inner->plainName(); - fullTitle = inner->plainFullName(); - title = rawTitle + " Type"; - Node::clearPropertyGroupCount(); - - generateHeader(inner, fullTitle); - generateBrief(inner, marker); // - writeProlog(inner); - - writeStartTag(DT_qmlTypeDetail); - generateQmlModuleDef(qcn); - generateQmlInherits(qcn,marker); - generateQmlInheritedBy(qcn, marker); - generateQmlInstantiates(qcn,marker); - generateQmlSince(qcn); - - enterDesc(DT_apiDesc,QString(),title); - enterSection(QString(), QString()); - generateBody(qcn, marker); - if (cn) { - generateQmlText(cn->doc().body(), cn, marker, qcn->name()); - generateAlsoList(cn, marker); - } - leaveSection(); - leaveSection(); // - writeEndTag(); // - - QList
members = marker->qmlSections(qcn,CodeMarker::Detailed); - if (!members.isEmpty()) { - s = members.constBegin(); - while (s != members.constEnd()) { - if (!s->members.isEmpty()) { - NodeList::ConstIterator m = (*s).members.constBegin(); - while (m != (*s).members.constEnd()) { - generateDetailedQmlMember(*m, qcn, marker); - ++m; - } - } - ++s; - } - } - writeEndTag(); // - } -} - -/*! - Generate the DITA page for a qdoc file that doesn't map - to an underlying c++ file. - */ -void DitaXmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker) -{ - QList
sections; - QList
::const_iterator s; - QString fullTitle = "QML Basic Type: " + qbtn->fullTitle(); - - generateHeader(qbtn, fullTitle); - generateBrief(qbtn, marker); // - writeProlog(qbtn); - - writeStartTag(DT_body); - enterSection(QString(), QString()); - - if (!qbtn->doc().isEmpty()) { - generateBody(qbtn, marker); - generateAlsoList(qbtn, marker); - } - leaveSection(); //
- if (!writeEndTag()) { // - qbtn->doc().location().warning(tr("Pop of empty XML tag stack; generating DITA for '%1'").arg(qbtn->name())); - return; - } - writeRelatedLinks(qbtn); - writeEndTag(); // -} - -/*! - Write a list item for a \a link with the given \a text. - */ -void DitaXmlGenerator::writeXrefListItem(const QString& link, const QString& text) -{ - writeStartTag(DT_li); - writeStartTag(DT_xref); - // formathtml - writeHrefAttribute(link); - writeCharacters(text); - writeEndTag(); // - writeEndTag(); // -} - -/*! - Generate the DITA page for a qdoc file that doesn't map - to an underlying c++ file. - */ -void DitaXmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) -{ - /* - If the dn node is a page node, and if the page type - is DITA map page, write the node's contents as a dita - map and return without doing anything else. - */ - if (dn->subType() == Node::Page && dn->pageType() == Node::DitaMapPage) { - const DitaMapNode* dmn = static_cast(dn); - writeDitaMap(dmn); - return; - } - - QList
sections; - QList
::const_iterator s; - QString fullTitle = dn->fullTitle(); - - generateHeader(dn, fullTitle); - generateBrief(dn, marker); // - writeProlog(dn); - - writeStartTag(DT_body); - enterSection(QString(), QString()); - - if (dn->doc().isEmpty()) { - if (dn->subType() == Node::File) { - Text text; - Quoter quoter; - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass", "small-subtitle"); - text << dn->subTitle(); - generateText(text, dn, marker); - writeEndTag(); //

- Doc::quoteFromFile(dn->doc().location(), quoter, dn->name()); - QString code = quoter.quoteTo(dn->location(), QString(), QString()); - text.clear(); - text << Atom(Atom::Code, code); - generateText(text, dn, marker); - } - } - else { - generateBody(dn, marker); - generateAlsoList(dn, marker); - } - leaveSection(); //
- if (!writeEndTag()) { // - dn->doc().location().warning(tr("Pop of empty XML tag stack; generating DITA for '%1'").arg(dn->name())); - return; - } - writeRelatedLinks(dn); - writeEndTag(); // -} - -/*! - Generate the DITA XML file for a group, module, or QML module. - */ -void DitaXmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marker) -{ - QList
sections; - QList
::const_iterator s; - QString fullTitle = cn->fullTitle(); - - generateHeader(cn, fullTitle); - generateBrief(cn, marker); // - writeProlog(cn); - - writeStartTag(DT_body); - enterSection(QString(), QString()); - if (cn->isModule()) { - generateStatus(cn, marker); - NodeMap nm; - cn->getMemberNamespaces(nm); - if (!nm.isEmpty()) { - enterSection("h2","Namespaces"); - generateAnnotatedList(cn, marker, nm); - leaveSection(); - } - nm.clear(); - cn->getMemberClasses(nm); - if (!nm.isEmpty()) { - enterSection("h2","Classes"); - generateAnnotatedList(cn, marker, nm); - leaveSection(); - } - nm.clear(); - } - - if (!cn->doc().isEmpty()) { - if (cn->isModule()) { - enterSection(QString(), QString()); - generateBody(cn, marker); - leaveSection(); - } - else { - generateBody(cn, marker); - } - generateAlsoList(cn, marker); - generateAnnotatedList(cn, marker, cn->members()); - } - leaveSection(); //
- if (!writeEndTag()) { // - cn->doc().location().warning(tr("Pop of empty XML tag stack; generating DITA for '%1'").arg(cn->name())); - return; - } - writeRelatedLinks(cn); - writeEndTag(); // -} - -/*! - This function writes a \e{} element inside a - \e{} element. - - \sa writeRelatedLinks() - */ -void DitaXmlGenerator::writeLink(const Node* node, - const QString& text, - const QString& role) -{ - if (node) { - QString link = fileName(node) + QLatin1Char('#') + node->guid(); - if (link.endsWith(QLatin1Char('#'))) - qDebug() << "LINK ENDS WITH #:" << link << outFileName(); - writeStartTag(DT_link); - writeHrefAttribute(link); - xmlWriter().writeAttribute("role", role); - writeStartTag(DT_linktext); - writeCharacters(text); - writeEndTag(); // - writeEndTag(); // - } -} - -/*! - This function writes a \e{} element, which - contains the \c{next}, \c{previous}, and \c{start} - links for topic pages that have them. Note that the - value of the \e role attribute is \c{parent} for the - \c{start} link. - */ -void DitaXmlGenerator::writeRelatedLinks(const Node* node) -{ - const Node* linkNode = 0; - QPair linkPair; - if (node && !node->links().empty()) { - writeStartTag(DT_relatedLinks); - if (node->links().contains(Node::PreviousLink)) { - linkPair = node->links()[Node::PreviousLink]; - linkNode = qdb_->findNodeForTarget(linkPair.first, node); - if (!linkNode) - node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first)); - if (linkNode && linkNode->isDocNode()) { - const DocNode *docNode = static_cast(linkNode); - linkPair.second = docNode->title(); - } - writeLink(linkNode, linkPair.second, "previous"); - } - if (node->links().contains(Node::NextLink)) { - linkPair = node->links()[Node::NextLink]; - linkNode = qdb_->findNodeForTarget(linkPair.first, node); - if (!linkNode) - node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first)); - if (linkNode && linkNode->isDocNode()) { - const DocNode *docNode = static_cast(linkNode); - linkPair.second = docNode->title(); - } - writeLink(linkNode, linkPair.second, "next"); - } - if (node->links().contains(Node::StartLink)) { - linkPair = node->links()[Node::StartLink]; - linkNode = qdb_->findNodeForTarget(linkPair.first, node); - if (!linkNode) - node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first)); - if (linkNode && linkNode->isDocNode()) { - const DocNode *docNode = static_cast(linkNode); - linkPair.second = docNode->title(); - } - writeLink(linkNode, linkPair.second, "parent"); - } - writeEndTag(); // - } -} - -/*! - Returns "dita" for this subclass of class Generator. - */ -QString DitaXmlGenerator::fileExtension() const -{ - return "dita"; -} - -/*! - Writes an XML file header to the current XML stream. This - depends on which kind of DITA XML file is being generated, - which is determined by the \a node type and subtype and the - \a subpage flag. - */ -void DitaXmlGenerator::generateHeader(const Node* node, const QString& name) -{ - if (!node) - return; - - DitaTag mainTag = DT_cxxClass; - DitaTag nameTag = DT_apiName; - QString doctype; - QString dtd; - QString base; - QString version; - QString outputclass; - - if (node->isClass()) { - mainTag = DT_cxxClass; - nameTag = DT_apiName; - dtd = "dtd/cxxClass.dtd"; - version = "0.7.0"; - doctype = ""; - } - else if (node->isNamespace()) { - mainTag = DT_cxxClass; - nameTag = DT_apiName; - dtd = "dtd/cxxClass.dtd"; - version = "0.7.0"; - doctype = ""; - outputclass = "namespace"; - } - else if (node->isCollectionNode()) { - mainTag = DT_topic; - nameTag = DT_title; - dtd = "dtd/topic.dtd"; - doctype = ""; - switch (node->type()) { - case Node::Group: - outputclass = "group"; - break; - case Node::Module: - outputclass = "module"; - break; - case Node::QmlModule: - outputclass = "qmlmodule"; - break; - default: - outputclass = "page"; - } - } - else if (node->isDocNode()) { - if (node->isHeaderFile()) { - mainTag = DT_cxxClass; - nameTag = DT_apiName; - dtd = "dtd/cxxClass.dtd"; - version = "0.7.0"; - doctype = ""; - outputclass = "headerfile"; - } - else if (node->isQmlType()) { - mainTag = DT_qmlType; - nameTag = DT_apiName; - dtd = "dtd/qmlType.dtd"; - version = "0.1.0"; - doctype = ""; - outputclass = "QML-type"; - } - else { - mainTag = DT_topic; - nameTag = DT_title; - dtd = "dtd/topic.dtd"; - doctype = ""; - switch (node->subType()) { - case Node::Page: - outputclass = node->pageTypeString(); - break; - case Node::Example: - outputclass = "example"; - break; - case Node::File: - outputclass = "file"; - break; - case Node::Image: // not used - outputclass = "image"; - break; - case Node::ExternalPage: // not used - outputclass = "externalpage"; - break; - default: - outputclass = "page"; - } - } - } - - xmlWriter().writeDTD(doctype); - xmlWriter().writeComment(node->doc().location().fileName()); - writeStartTag(mainTag); - QString id = node->guid(); - xmlWriter().writeAttribute("id",id); - if (!outputclass.isEmpty()) - xmlWriter().writeAttribute("outputclass",outputclass); - writeStartTag(nameTag); // or <apiName> - if (!name.isEmpty()) - writeCharacters(name); - else - writeCharacters(node->name()); - writeEndTag(); // or -} - -/*! - Outputs the \e brief command as a element. - */ -void DitaXmlGenerator::generateBrief(const Node* node, CodeMarker* marker) -{ - Text brief = node->doc().briefText(true); // zzz - if (!brief.isEmpty()) { - generateText(brief, node, marker); - } -} - -/*! - zzz - Generates a table of contents beginning at \a node. - Currently just returns without writing anything. - */ -void DitaXmlGenerator::generateTableOfContents(const Node* node, - CodeMarker* marker, - Doc::Sections sectionUnit, - int numColumns, - const Node* relative) - -{ - return; - if (!node->doc().hasTableOfContents()) - return; - QList toc = node->doc().tableOfContents(); - if (toc.isEmpty()) - return; - - QString nodeName; - if (node != relative) - nodeName = node->name(); - - QStringList sectionNumber; - int columnSize = 0; - - QString tdTag; - if (numColumns > 1) { - tdTag = ""; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/ - out() << "\n" - << tdTag << '\n'; - } - - // disable nested links in table of contents - inContents_ = true; - inLink_ = true; - - for (int i = 0; i < toc.size(); ++i) { - Atom *atom = toc.at(i); - - int nextLevel = atom->string().toInt(); - if (nextLevel > (int)sectionUnit) - continue; - - if (sectionNumber.size() < nextLevel) { - do { - out() << "
    "; - sectionNumber.append("1"); - } while (sectionNumber.size() < nextLevel); - } - else { - while (sectionNumber.size() > nextLevel) { - out() << "
\n"; - sectionNumber.removeLast(); - } - sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); - } - int numAtoms; - Text headingText = Text::sectionHeading(atom); - - if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) { - out() << "" << tdTag << "
    \n"; - columnSize = 0; - } - out() << "
  • "; - out() << ""; - generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); - out() << "
  • \n"; - - ++columnSize; - } - while (!sectionNumber.isEmpty()) { - out() << "
\n"; - sectionNumber.removeLast(); - } - - if (numColumns > 1) - out() << "
\n"; - - inContents_ = false; - inLink_ = false; -} - -void DitaXmlGenerator::generateLowStatusMembers(InnerNode* inner, - CodeMarker* marker, - CodeMarker::Status status) -{ - QString attribute; - if (status == CodeMarker::Compat) - attribute = "Qt3-support"; - else if (status == CodeMarker::Obsolete) - attribute = "obsolete"; - else - return; - - QList
sections = marker->sections(inner, CodeMarker::Detailed, status); - QMutableListIterator
j(sections); - while (j.hasNext()) { - if (j.next().members.size() == 0) - j.remove(); - } - if (sections.isEmpty()) - return; - - if (status == CodeMarker::Obsolete) - inner->setObsoleteLink(fileBase(inner) + "-obsolete." + fileExtension()); - - QList
::ConstIterator s = sections.constBegin(); - while (s != sections.constEnd()) { - if ((*s).name == "Member Function Documentation") { - writeFunctions((*s),inner,marker,attribute); - } - else if ((*s).name == "Member Type Documentation") { - writeEnumerations((*s),marker,attribute); - writeTypedefs((*s),marker,attribute); - } - else if ((*s).name == "Member Variable Documentation") { - writeDataMembers((*s),marker,attribute); - } - else if ((*s).name == "Property Documentation") { - writeProperties((*s),marker,attribute); - } - else if ((*s).name == "Macro Documentation") { - //writeMacros((*s),marker,attribute); - } - ++s; - } -} - -/*! - Write the XML for the class hierarchy to the current XML stream. - */ -void DitaXmlGenerator::generateClassHierarchy(const Node* relative, NodeMap& classMap) -{ - if (classMap.isEmpty()) - return; - - NodeMap topLevel; - NodeMap::Iterator c = classMap.begin(); - while (c != classMap.end()) { - ClassNode* classe = static_cast(*c); - if (classe->baseClasses().isEmpty()) - topLevel.insert(classe->name(), classe); - ++c; - } - - QStack stack; - stack.push(topLevel); - - writeStartTag(DT_ul); - while (!stack.isEmpty()) { - if (stack.top().isEmpty()) { - stack.pop(); - writeEndTag(); // - if (!stack.isEmpty()) - writeEndTag(); // - } - else { - ClassNode* child = static_cast(*stack.top().begin()); - writeStartTag(DT_li); - generateFullName(child, relative); - writeEndTag(); // - stack.top().erase(stack.top().begin()); - - NodeMap newTop; - foreach (const RelatedClass &d, child->derivedClasses()) { - if (d.node_ && d.access_ != Node::Private && !d.node_->doc().isEmpty()) - newTop.insert(d.node_->name(), d.node_); - } - if (!newTop.isEmpty()) { - stack.push(newTop); - writeStartTag(DT_li); - writeStartTag(DT_ul); - } - } - } -} - -/*! - Output an annotated list of the nodes in \a nodeMap. - A two-column table is output. - */ -void DitaXmlGenerator::generateAnnotatedList(const Node* relative, - CodeMarker* marker, - const NodeMap& nodeMap) -{ - if (nodeMap.isEmpty()) - return; - NodeList nl; - NodeMap::const_iterator i = nodeMap.begin(); - while (i != nodeMap.end()) { - nl.append(i.value()); - ++i; - } - generateAnnotatedList(relative, marker, nl); -} - -/*! - Write XML for the contents of the \a nodes to the current - XML stream. - */ -void DitaXmlGenerator::generateAnnotatedList(const Node* relative, - CodeMarker* marker, - const NodeList& nodes) -{ - if (nodes.isEmpty()) - return; - bool allInternal = true; - foreach (const Node* node, nodes) { - if (!node->isInternal() && node->status() != Node::Obsolete) { - allInternal = false; - } - } - if (allInternal) - return; - - writeStartTag(DT_table); - xmlWriter().writeAttribute("outputclass","annotated"); - writeStartTag(DT_tgroup); - xmlWriter().writeAttribute("cols","2"); - writeStartTag(DT_tbody); - - foreach (const Node* node, nodes) { - if (node->isInternal() || node->status() == Node::Obsolete) - continue; - - writeStartTag(DT_row); - writeStartTag(DT_entry); - writeStartTag(DT_p); - generateFullName(node, relative); - writeEndTag(); //

- writeEndTag(); // - - if (!node->isDocNode()) { - Text brief = node->doc().trimmedBriefText(node->name()); - if (!brief.isEmpty()) { - writeStartTag(DT_entry); - writeStartTag(DT_p); - generateText(brief, node, marker); - writeEndTag(); //

- writeEndTag(); // - } - else if (!node->reconstitutedBrief().isEmpty()) { - writeStartTag(DT_entry); - writeStartTag(DT_p); - writeCharacters(node->reconstitutedBrief()); - writeEndTag(); //

- writeEndTag(); // - } - } - else { - writeStartTag(DT_entry); - writeStartTag(DT_p); - if (!node->reconstitutedBrief().isEmpty()) { - writeCharacters(node->reconstitutedBrief()); - } - else - writeCharacters(protectEnc(node->doc().briefText().toString())); - writeEndTag(); //

- writeEndTag(); // - } - writeEndTag(); // - } - writeEndTag(); // - writeEndTag(); // - writeEndTag(); // -} - -/*! - This function finds the common prefix of the names of all - the classes in \a classMap and then generates a compact - list of the class names alphabetized on the part of the - name not including the common prefix. You can tell the - function to use \a comonPrefix as the common prefix, but - normally you let it figure it out itself by looking at - the name of the first and last classes in \a classMap. - */ -void DitaXmlGenerator::generateCompactList(ListType , // currently not needed for DITA - const Node* relative, - const NodeMap& classMap, - bool includeAlphabet, - QString commonPrefix) -{ - const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' - - if (classMap.isEmpty()) - return; - - /* - If commonPrefix is not empty, then the caller knows what - the common prefix is and has passed it in, so just use that - one. But if the commonPrefix is empty (it normally is), then - compute a common prefix using this simple algorithm. Note we - assume the prefix length is 1, i.e. we will have a single - character as the common prefix. - */ - int commonPrefixLen = commonPrefix.length(); - if (commonPrefixLen == 0) { - QVector count(26); - for (int i=0; i<26; ++i) - count[i] = 0; - - NodeMap::const_iterator iter = classMap.constBegin(); - while (iter != classMap.constEnd()) { - if (!iter.key().contains("::")) { - QChar c = iter.key()[0]; - if ((c >= 'A') && (c <= 'Z')) { - int idx = c.unicode() - QChar('A').unicode(); - ++count[idx]; - } - } - ++iter; - } - int highest = 0; - int idx = -1; - for (int i=0; i<26; ++i) { - if (count[i] > highest) { - highest = count[i]; - idx = i; - } - } - idx += QChar('A').unicode(); - QChar common(idx); - commonPrefix = common; - commonPrefixLen = 1; - } - - /* - Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z, - underscore (_). QAccel will fall in paragraph 10 (A) and - QXtWidget in paragraph 33 (X). This is the only place where we - assume that NumParagraphs is 37. Each paragraph is a NodeMap. - */ - NodeMap paragraph[NumParagraphs+1]; - QString paragraphName[NumParagraphs+1]; - QSet usedParagraphNames; - - NodeMap::ConstIterator c = classMap.constBegin(); - while (c != classMap.constEnd()) { - QStringList pieces = c.key().split("::"); - QString key; - int idx = commonPrefixLen; - if (!pieces.last().startsWith(commonPrefix)) - idx = 0; - if (pieces.size() == 1) - key = pieces.last().mid(idx).toLower(); - else - key = pieces.last().toLower(); - - int paragraphNr = NumParagraphs - 1; - - if (key[0].digitValue() != -1) { - paragraphNr = key[0].digitValue(); - } - else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) { - paragraphNr = 10 + key[0].unicode() - 'a'; - } - - paragraphName[paragraphNr] = key[0].toUpper(); - usedParagraphNames.insert(key[0].toLower().cell()); - paragraph[paragraphNr].insert(key, c.value()); - ++c; - } - - /* - Each paragraph j has a size: paragraph[j].count(). In the - discussion, we will assume paragraphs 0 to 5 will have sizes - 3, 1, 4, 1, 5, 9. - - We now want to compute the paragraph offset. Paragraphs 0 to 6 - start at offsets 0, 3, 4, 8, 9, 14, 23. - */ - int paragraphOffset[NumParagraphs + 1]; // 37 + 1 - paragraphOffset[0] = 0; - for (int i=0; i cmap; - - /* - Output the alphabet as a row of links. - */ - if (includeAlphabet) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","alphabet"); - for (int i = 0; i < 26; i++) { - QChar ch('a' + i); - if (usedParagraphNames.contains(char('a' + i))) { - writeStartTag(DT_xref); - // formathtml - QString guid = lookupGuid(outFileName(),QString(ch)); - QString attr = outFileName() + QString("#%1").arg(guid); - xmlWriter().writeAttribute("href", attr); - xmlWriter().writeCharacters(QString(ch.toUpper())); - writeEndTag(); // - } - } - writeEndTag(); //

- } - - /* - Output a

element to contain all the

elements. - */ - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","compactlist"); - - for (int i=0; i. - */ - if (curParOffset == 0) { - if (i > 0) { - writeEndTag(); // - writeEndTag(); //
- } - writeStartTag(DT_dl); - writeStartTag(DT_dlentry); - writeStartTag(DT_dt); - if (includeAlphabet) { - QChar c = paragraphName[curParNr][0].toLower(); - writeGuidAttribute(QString(c)); - } - xmlWriter().writeAttribute("outputclass","sublist-header"); - xmlWriter().writeCharacters(paragraphName[curParNr]); - writeEndTag(); // - } - - /* - Output a
for the current offset in the current paragraph. - */ - writeStartTag(DT_dd); - if ((curParNr < NumParagraphs) && - !paragraphName[curParNr].isEmpty()) { - NodeMap::Iterator it; - it = paragraph[curParNr].begin(); - for (int i=0; iisQmlType()) - pieces << it.value()->name(); - else - pieces = it.value()->fullName(relative).split("::"); - xmlWriter().writeCharacters(protectEnc(pieces.last())); - writeEndTag(); // - if (pieces.size() > 1) { - xmlWriter().writeCharacters(" ("); - generateFullName(it.value()->parent(),relative); - xmlWriter().writeCharacters(")"); - } - } - writeEndTag(); //
- curParOffset++; - } - writeEndTag(); // - writeEndTag(); // - writeEndTag(); //

-} - -/*! - Write XML for a function index to the current XML stream. - */ -void DitaXmlGenerator::generateFunctionIndex(const Node* relative) -{ - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","alphabet"); - for (int i = 0; i < 26; i++) { - QChar ch('a' + i); - writeStartTag(DT_xref); - // formathtml - QString guid = lookupGuid(outFileName(),QString(ch)); - QString attr = outFileName() + QString("#%1").arg(guid); - xmlWriter().writeAttribute("href", attr); - xmlWriter().writeCharacters(QString(ch.toUpper())); - writeEndTag(); // - - } - writeEndTag(); //

- - char nextLetter = 'a'; - char currentLetter; - - writeStartTag(DT_ul); - NodeMapMap& funcIndex = qdb_->getFunctionIndex(); - NodeMapMap::ConstIterator f = funcIndex.constBegin(); - while (f != funcIndex.constEnd()) { - writeStartTag(DT_li); - currentLetter = f.key()[0].unicode(); - while (islower(currentLetter) && currentLetter >= nextLetter) { - writeStartTag(DT_p); - writeGuidAttribute(QString(nextLetter)); - xmlWriter().writeAttribute("outputclass","target"); - xmlWriter().writeCharacters(QString(nextLetter)); - writeEndTag(); //

- nextLetter++; - } - xmlWriter().writeCharacters(protectEnc(f.key())); - xmlWriter().writeCharacters(":"); - - NodeMap::ConstIterator s = (*f).constBegin(); - while (s != (*f).constEnd()) { - generateFullName((*s)->parent(), relative, *s); - ++s; - } - writeEndTag(); // - ++f; - } - writeEndTag(); // -} - -/*! - Write the legalese texts as XML to the current XML stream. - */ -void DitaXmlGenerator::generateLegaleseList(const Node* relative, CodeMarker* marker) -{ - TextToNodeMap& legaleseTexts = qdb_->getLegaleseTexts(); - TextToNodeMap::ConstIterator it = legaleseTexts.constBegin(); - while (it != legaleseTexts.constEnd()) { - Text text = it.key(); - generateText(text, relative, marker); - writeStartTag(DT_ul); - do { - writeStartTag(DT_li); - generateFullName(it.value(), relative); - writeEndTag(); // - ++it; - } while (it != legaleseTexts.constEnd() && it.key() == text); - writeEndTag(); // - } -} - -/*! - Generate the text for the QML item described by \a node - and write it to the current XML stream. - */ -void DitaXmlGenerator::generateQmlItem(const Node* node, - const Node* relative, - CodeMarker* marker, - bool summary) -{ - QString marked = marker->markedUpQmlItem(node,summary); - QRegExp tag("(<[^@>]*>)"); - if (marked.indexOf(tag) != -1) { - QString tmp = protectEnc(marked.mid(tag.pos(1), tag.cap(1).length())); - marked.replace(tag.pos(1), tag.cap(1).length(), tmp); - } - marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])"), - "\\1\\2"); - if (summary) { - marked.remove("<@type>"); - marked.remove(""); - } - writeText(marked, relative); -} - -/*! - Write the XML for the overview list to the current XML stream. - */ -void DitaXmlGenerator::generateOverviewList(const Node* relative) -{ - CNMap groups; - CNMap modules; - CNMap qmlModules; - QRegExp singleDigit("\\b([0-9])\\b"); - - qdb_->mergeCollections(Node::Group, groups, relative); - qdb_->mergeCollections(Node::Module, modules, relative); - qdb_->mergeCollections(Node::QmlModule, qmlModules, relative); - - QStringList keys = groups.uniqueKeys(); - foreach (QString key, keys) { - GroupNode* gn = static_cast(groups.value(key)); - if (gn) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","h3"); - writeStartTag(DT_xref); - // formathtml - xmlWriter().writeAttribute("href",linkForNode(gn, relative)); - writeCharacters(protectEnc(gn->fullTitle())); - writeEndTag(); // - writeEndTag(); //

- - if (gn->members().isEmpty()) - continue; - - NodeMap nm; - foreach (Node* member, gn->members()) { - if (member->isInternal() || member->isExample() || member->isExternalPage() || - member->isObsolete()) - continue; - // not interested either in individual (Qt Designer etc.) manual chapters - if (member->links().contains(Node::ContentsLink)) - continue; - QString sortKey = member->fullTitle().toLower(); - if (sortKey.startsWith("the ")) - sortKey.remove(0, 4); - sortKey.replace(singleDigit, "0\\1"); - nm.insert(sortKey, member); - } - - writeStartTag(DT_ul); - QStringList titles = nm.keys(); - foreach (QString t, titles) { - Node* member = nm.value(t); - QString title = member->fullTitle(); - if (title.startsWith("The ")) - title.remove(0, 4); - writeStartTag(DT_li); - writeStartTag(DT_xref); - // formathtml - xmlWriter().writeAttribute("href",linkForNode(member, relative)); - writeCharacters(protectEnc(title)); - writeEndTag(); // - writeEndTag(); // - } - writeEndTag(); // - } - } -} - -/*! - Write the XML for a standard section of a page, e.g. - "Public Functions" or "Protected Slots." The section - is written too the current XML stream as a table. - */ -void DitaXmlGenerator::generateSection(const NodeList& nl, - const Node* relative, - CodeMarker* marker, - CodeMarker::SynopsisStyle style) -{ - if (!nl.isEmpty()) { - writeStartTag(DT_ul); - NodeList::ConstIterator m = nl.constBegin(); - while (m != nl.constEnd()) { - if ((*m)->access() != Node::Private) { - writeStartTag(DT_li); - QString marked = getMarkedUpSynopsis(*m, relative, marker, style); - writeText(marked, relative); - writeEndTag(); // - } - ++m; - } - writeEndTag(); // - } -} - -/*! - Writes the "inherited from" list to the current XML stream. - */ -void DitaXmlGenerator::generateSectionInheritedList(const Section& section, const Node* relative) -{ - if (section.inherited.isEmpty()) - return; - writeStartTag(DT_ul); - QList >::ConstIterator p = section.inherited.constBegin(); - while (p != section.inherited.constEnd()) { - writeStartTag(DT_li); - QString text; - text.setNum((*p).second); - text += QLatin1Char(' '); - if ((*p).second == 1) - text += section.singularMember; - else - text += section.pluralMember; - text += " inherited from "; - writeCharacters(text); - writeStartTag(DT_xref); - // formathtml - // zzz - text = fileName((*p).first) + QLatin1Char('#'); - text += DitaXmlGenerator::cleanRef(section.name.toLower()); - xmlWriter().writeAttribute("href",text); - text = protectEnc((*p).first->plainFullName(relative)); - writeCharacters(text); - writeEndTag(); // - writeEndTag(); // - ++p; - } - writeEndTag(); // -} - -/*! - Get the synopsis from the \a node using the \a relative - node if needed, and mark up the synopsis using \a marker. - Use the style to decide which kind of sysnopsis to build, - normally \c Summary or \c Detailed. Return the marked up - string. - */ -QString DitaXmlGenerator::getMarkedUpSynopsis(const Node* node, - const Node* relative, - CodeMarker* marker, - CodeMarker::SynopsisStyle style) -{ - QString marked = marker->markedUpSynopsis(node, relative, style); - QRegExp tag("(<[^@>]*>)"); - if (marked.indexOf(tag) != -1) { - QString tmp = protectEnc(marked.mid(tag.pos(1), tag.cap(1).length())); - marked.replace(tag.pos(1), tag.cap(1).length(), tmp); - } - marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])"), - " \\1\\2"); - if (style == CodeMarker::Summary) { - marked.remove("<@name>"); // was "" - marked.remove(""); // was "" - } - - if (style == CodeMarker::Subpage) { - QRegExp extraRegExp("<@extra>.*"); - extraRegExp.setMinimal(true); - marked.remove(extraRegExp); - } - - if (style != CodeMarker::Detailed) { - marked.remove("<@type>"); - marked.remove(""); - } - return marked; -} - -/*! - Renamed from highlightedCode() in the html generator. Gets the text - from \a markedCode , and then the text is written to the current XML - stream. - */ -void DitaXmlGenerator::writeText(const QString& markedCode, const Node* relative) -{ - QString src = markedCode; - QString text; - QStringRef arg; - QStringRef par1; - - const QChar charLangle = '<'; - const QChar charAt = '@'; - - /* - First strip out all the extraneous markup. The table - below contains the markup we want to keep. Everything - else that begins with "<@" or "", "<@type>", - "<@headerfile>", "<@headerfile>", - "<@func>", "<@func>", - "<@func ", "<@func ", - "<@param>", "<@param>", - "<@extra>", "<@extra>", - "", "", - "", "", - "", "", - "", "", - "", "", - "", "" - }; - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle) { - bool handled = false; - for (int k = 0; k != 13; ++k) { - const QString & tag = spanTags[2 * k]; - if (tag == QStringRef(&src, i, tag.length())) { - text += spanTags[2 * k + 1]; - i += tag.length(); - handled = true; - break; - } - } - if (!handled) { - ++i; - if (src.at(i) == charAt || - (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { - // drop 'our' unknown tags (the ones still containing '@') - while (i < n && src.at(i) != QLatin1Char('>')) - ++i; - ++i; - } - else { - // retain all others - text += charLangle; - } - } - } - else { - text += src.at(i); - ++i; - } - } - - // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*()" - // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)()" tags - src = text; - text = QString(); - static const QString markTags[] = { - // 0 1 2 3 4 5 - "link", "type", "headerfile", "func", "param", "extra" - }; - - for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - for (int k = 0; k != 6; ++k) { - if (parseArg(src, markTags[k], &i, n, &arg, &par1)) { - const Node* n = 0; - switch (k) { - case 0: // <@link> - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } - n = CodeMarker::nodeForString(par1.toString()); - addLink(linkForNode(n, relative), arg); - break; - case 4: // <@param> - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } - writeStartTag(DT_i); - //writeCharacters(" " + arg.toString()); - writeCharacters(arg.toString()); - writeEndTag(); // - break; - case 5: // <@extra> - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } - writeStartTag(DT_tt); - writeCharacters(arg.toString()); - writeEndTag(); // - break; - case 3: - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } - par1 = QStringRef(); - n = qdb_->findFunctionNode(arg.toString(), relative, Node::DontCare); - addLink(linkForNode(n, relative), arg); - break; - case 1: - case 2: - default: - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } - par1 = QStringRef(); - n = qdb_->findTypeNode(arg.toString(), relative); - if (n && n->isQmlBasicType()) { - if (relative && relative->isQmlType()) - addLink(linkForNode(n, relative), arg); - else - writeCharacters(arg.toString()); - } - else - addLink(linkForNode(n, relative), arg); // (zzz) Is this correct for all cases? - break; - } // switch - break; - } - } - } - else - text += src.at(i++); - } - if (!text.isEmpty()) - writeCharacters(text); -} - -void DitaXmlGenerator::generateLink(const Atom* atom, CodeMarker* marker) -{ - static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_"); - - if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) { - // hack for C++: move () outside of link - int k = funcLeftParen.pos(1); - writeCharacters(protectEnc(atom->string().left(k))); - if (link_.isEmpty()) { - if (showBrokenLinks) - writeEndTag(); // - } - else - writeEndTag(); // - inLink_ = false; - writeCharacters(protectEnc(atom->string().mid(k))); - } - else if (marker->recognizeLanguage("Java")) { - // hack for Java: remove () and use when appropriate - bool func = atom->string().endsWith("()"); - bool tt = (func || atom->string().contains(camelCase)); - if (tt) - writeStartTag(DT_tt); - if (func) - writeCharacters(protectEnc(atom->string().left(atom->string().length() - 2))); - else - writeCharacters(protectEnc(atom->string())); - writeEndTag(); // - } - else - writeCharacters(protectEnc(atom->string())); -} - -QString DitaXmlGenerator::cleanRef(const QString& ref) -{ - QString clean; - - if (ref.isEmpty()) - return clean; - - clean.reserve(ref.size() + 20); - const QChar c = ref[0]; - const uint u = c.unicode(); - - if ((u >= 'a' && u <= 'z') || - (u >= 'A' && u <= 'Z') || - (u >= '0' && u <= '9')) { - clean += c; - } - else if (u == '~') { - clean += "dtor."; - } - else if (u == '_') { - clean += "underscore."; - } - else { - clean += QLatin1Char('A'); - } - - for (int i = 1; i < (int) ref.length(); i++) { - const QChar c = ref[i]; - const uint u = c.unicode(); - if ((u >= 'a' && u <= 'z') || - (u >= 'A' && u <= 'Z') || - (u >= '0' && u <= '9') || u == '-' || - u == '_' || u == ':' || u == '.') { - clean += c; - } - else if (c.isSpace()) { - clean += QLatin1Char('-'); - } - else if (u == '!') { - clean += "-not"; - } - else if (u == '&') { - clean += "-and"; - } - else if (u == '<') { - clean += "-lt"; - } - else if (u == '=') { - clean += "-eq"; - } - else if (u == '>') { - clean += "-gt"; - } - else if (u == '#') { - clean += QLatin1Char('#'); - } - else { - clean += QLatin1Char('-'); - clean += QString::number((int)u, 16); - } - } - return clean; -} - -QString DitaXmlGenerator::registerRef(const QString& ref) -{ - QString clean = DitaXmlGenerator::cleanRef(ref); - - for (;;) { - QString& prevRef = refMap[clean.toLower()]; - if (prevRef.isEmpty()) { - prevRef = ref; - break; - } - else if (prevRef == ref) - break; - clean += QLatin1Char('x'); - } - return clean; -} - -/*! - Calls protect() with the \a string. Returns the result. - */ -QString DitaXmlGenerator::protectEnc(const QString& string) -{ -#ifndef QT_NO_TEXTCODEC - return protect(string, outputEncoding); -#else - return protect(string); -#endif -} - -QString DitaXmlGenerator::protect(const QString& string, const QString& ) //outputEncoding) -{ -#define APPEND(x) \ - if (xml.isEmpty()) { \ - xml = string; \ - xml.truncate(i); \ -} \ - xml += (x); - - QString xml; - int n = string.length(); - - for (int i = 0; i < n; ++i) { - QChar ch = string.at(i); - - if (ch == QLatin1Char('&')) { - APPEND("&"); - } - else if (ch == QLatin1Char('<')) { - APPEND("<"); - } - else if (ch == QLatin1Char('>')) { - APPEND(">"); - } - else if (ch == QLatin1Char('"')) { - APPEND("""); - } - else { - if (!xml.isEmpty()) - xml += ch; - } - } - - if (!xml.isEmpty()) - return xml; - return string; - -#undef APPEND -} - -/*! - Constructs a file name appropriate for the \a node - and returns the file name. - */ -QString DitaXmlGenerator::fileBase(const Node* node) const -{ - QString result; - result = Generator::fileBase(node); - return result; -} - -QString DitaXmlGenerator::guidForNode(const Node* node) -{ - switch (node->type()) { - case Node::Namespace: - case Node::Class: - default: - break; - case Node::Enum: - return node->guid(); - case Node::Typedef: - { - const TypedefNode* tdn = static_cast(node); - if (tdn->associatedEnum()) - return guidForNode(tdn->associatedEnum()); - } - return node->guid(); - case Node::Function: - { - const FunctionNode* fn = static_cast(node); - if (fn->associatedProperty()) { - return guidForNode(fn->associatedProperty()); - } - else { - QString ref = fn->name(); - if (fn->overloadNumber() != 1) { - ref += QLatin1Char('-') + QString::number(fn->overloadNumber()); - } - } - return fn->guid(); - } - case Node::Document: - break; - case Node::QmlPropertyGroup: - case Node::QmlProperty: - case Node::Property: - return node->guid(); - case Node::QmlSignal: - return node->guid(); - case Node::QmlSignalHandler: - return node->guid(); - case Node::QmlMethod: - return node->guid(); - case Node::Variable: - return node->guid(); - } - return QString(); -} - -/*! - Constructs a file name appropriate for the \a node and returns - it. If the \a node is not a not an external page, an image, or - a ditamap, call fileName() in the base class, Generator. - */ -QString DitaXmlGenerator::fileName(const Node* node) -{ - if (node->isDocNode()) { - if (static_cast(node)->pageType() == Node::DitaMapPage) - return node->name(); - if (static_cast(node)->subType() == Node::ExternalPage) - return node->name(); - if (static_cast(node)->subType() == Node::Image) - return node->name(); - } - return Generator::fileName(node); -} - -/*! - This function is called for links, i.e. for words that - are marked with the qdoc link command. For autolinks - that are not marked with the qdoc link command, qdoc - calls getAutoLink(). - - Return the link represented by the \a atom, and set \a node - to point to the target node for that link. \a relative points - to the node holding the qdoc comment where the link command - was found. - */ -QString DitaXmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node) -{ - const QString& t = atom->string(); - if (t.at(0) == QChar('h')) { - if (t.startsWith("http:") || t.startsWith("https:")) - return t; - } - else if (t.at(0) == QChar('f')) { - if (t.startsWith("file:") || t.startsWith("ftp:")) - return t; - } - else if (t.at(0) == QChar('m')) { - if (t.startsWith("mailto:")) - return t; - } - - QString ref; - - *node = qdb_->findNodeForAtom(atom, relative, ref); - if (!(*node)) - return QString(); - - QString url = (*node)->url(); - if (!url.isEmpty()) { - if (ref.isEmpty()) - return url; - int hashtag = url.lastIndexOf(QChar('#')); - if (hashtag != -1) - url.truncate(hashtag); - return url + "#" + ref; - } - /* - Given that *node is not null, we now cconstruct a link - to the page that *node represents, and then if we found - a target on that page, we connect the target to the link - with '#'. - */ - QString link = linkForNode(*node, relative); - if (*node && (*node)->subType() == Node::Image) - link = "images/used-in-examples/" + link; - if (!ref.isEmpty()) { - int hashtag = link.lastIndexOf(QChar('#')); - if (hashtag != -1) - link.truncate(hashtag); - link += QLatin1Char('#') + ref; - } - return link; -} - -/*! - This function is called for autolinks, i.e. for words that - are not marked with the qdoc link command that qdoc has - reason to believe should be links. For links marked with - the qdoc link command, qdoc calls getLink(). - - Return the link represented by the \a atom, and set \a node - to point to the target node for that link. \a relative points - to the node holding the qdoc comment where the link command - was found. - */ -QString DitaXmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node) -{ - QString ref; - QString link; - - *node = qdb_->findNodeForAtom(atom, relative, ref); - if (!(*node)) - return QString(); - - QString url = (*node)->url(); - if (!url.isEmpty()) { - if (ref.isEmpty()) - return url; - int hashtag = url.lastIndexOf(QChar('#')); - if (hashtag != -1) - url.truncate(hashtag); - return url + "#" + ref; - } - - link = linkForNode(*node, relative); - if (!ref.isEmpty()) - link += QLatin1Char('#') + ref; - return link; -} - - -QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative) -{ - if (node == 0 || node == relative) - return QString(); - if (!node->url().isEmpty()) - return node->url(); - if (fileBase(node).isEmpty()) - return QString(); - if (node->access() == Node::Private) - return QString(); - - QString fn = fileName(node); - if (node && relative && node->parent() != relative) { - if (node->parent()->isQmlType() && relative->isQmlType()) { - if (node->parent()->isAbstract()) { - /* - This is a bit of a hack. What we discover with - the three 'if' statements immediately above, - is that node's parent is marked \qmlabstract - but the link appears in a qdoc comment for a - subclass of the node's parent. This means the - link should refer to the file for the relative - node, not the file for node. - */ - fn = fileName(relative); - } - } - } - QString link = fn; - - if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) { - QString guid = guidForNode(node); - if (relative && fn == fileName(relative) && guid == guidForNode(relative)) { - return QString(); - } - link += QLatin1Char('#'); - link += guid; - } - /* - If the output is going to subdirectories, then if the - two nodes will be output to different directories, then - the link must go up to the parent directory and then - back down into the other subdirectory. - */ - if (node && relative && (node != relative)) { - if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory()) - link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/'))); - } - return link; -} - -void DitaXmlGenerator::generateFullName(const Node* apparentNode, - const Node* relative, - const Node* actualNode) -{ - if (actualNode == 0) - actualNode = apparentNode; - writeStartTag(DT_xref); - // formathtml - QString href = linkForNode(actualNode, relative); - writeHrefAttribute(href); - writeCharacters(protectEnc(apparentNode->fullName(relative))); - writeEndTag(); // -} - -/*! - We're writing an attribute that indicates that the text - data is a heading, hence, h1, h2, h3... etc, and we must - decide which number to use. - */ -int DitaXmlGenerator::hOffset(const Node* node) -{ - switch (node->type()) { - case Node::Namespace: - case Node::Class: - return 2; - case Node::QmlType: - case Node::Document: - return 1; - case Node::Enum: - case Node::Typedef: - case Node::Function: - case Node::Property: - default: - return 3; - } -} - -bool DitaXmlGenerator::isThreeColumnEnumValueTable(const Atom* atom) -{ - while (atom != 0 && !(atom->type() == Atom::ListRight && atom->string() == ATOM_LIST_VALUE)) { - if (atom->type() == Atom::ListItemLeft && !matchAhead(atom, Atom::ListItemRight)) - return true; - atom = atom->next(); - } - return false; -} - -const QPair DitaXmlGenerator::anchorForNode(const Node* node) -{ - QPair anchorPair; - anchorPair.first = Generator::fileName(node); - if (node->type() == Node::Document) { - const DocNode *docNode = static_cast(node); - anchorPair.second = docNode->title(); - } - - return anchorPair; -} - -void DitaXmlGenerator::generateStatus(const Node* node, CodeMarker* marker) -{ - Text text; - - switch (node->status()) { - case Node::Obsolete: - if (node->isInnerNode()) - Generator::generateStatus(node, marker); - break; - case Node::Compat: - // Porting to Qt 4 no longer supported - break; - default: - Generator::generateStatus(node, marker); - } -} - -void DitaXmlGenerator::beginLink(const QString& link) -{ - link_ = link; - if (link_.isEmpty()) - return; - writeStartTag(DT_xref); - // formathtml - writeHrefAttribute(link_); - inLink_ = true; -} - -void DitaXmlGenerator::endLink() -{ - if (inLink_) { - if (link_.isEmpty()) { - if (showBrokenLinks) - writeEndTag(); // - } - else { - if (inObsoleteLink) { - writeStartTag(DT_sup); - xmlWriter().writeCharacters("(obsolete)"); - writeEndTag(); // - } - writeEndTag(); // - } - } - inLink_ = false; - inObsoleteLink = false; -} - -/*! - Generates the summary for the \a section. Only used for - sections of QML element documentation. - - Currently handles only the QML property group. - */ -void DitaXmlGenerator::generateQmlSummary(const Section& section, - const Node* relative, - CodeMarker* marker) -{ - if (!section.members.isEmpty()) { - writeStartTag(DT_ul); - NodeList::ConstIterator m; - m = section.members.constBegin(); - while (m != section.members.constEnd()) { - writeStartTag(DT_li); - generateQmlItem(*m,relative,marker,true); - writeEndTag(); // - ++m; - } - writeEndTag(); // - } -} - -/*! - Writes the QML property \a qpn to the current DITA XML file. - Assumes that the correct start tag has already been written, - but nothing has been written inside that tag. This function - begins by writing the GUID id attribute for the property. - */ -void DitaXmlGenerator::startQmlProperty(QmlPropertyNode* qpn, - const InnerNode* relative, - CodeMarker* marker) -{ - writeStartTag(DT_qmlProperty); - writeGuidAttribute((Node*)qpn); - writeStartTag(DT_apiName); - writeCharacters(qpn->name()); - writeEndTag(); // - generateBrief(qpn, marker); // - writeStartTag(DT_qmlPropertyDetail); - writeStartTag(DT_qmlPropertyDef); - if (!qpn->isReadOnlySet()) - qpn->setReadOnly(!qpn->isWritable()); - if (qpn->isReadOnly()) { - writeStartTag(DT_qmlQualifier); - xmlWriter().writeAttribute("name","read-only"); - xmlWriter().writeAttribute("value","read-only"); - writeEndTag(); // - } - if (qpn->isDefault()) { - writeStartTag(DT_qmlQualifier); - xmlWriter().writeAttribute("name","default"); - xmlWriter().writeAttribute("value","default"); - writeEndTag(); // - } - if (qpn->isAttached()) { - writeStartTag(DT_qmlAttached); - xmlWriter().writeAttribute("name","attached"); - xmlWriter().writeAttribute("value","yes"); - writeEndTag(); // - } - writeStartTag(DT_apiData); - generateQmlItem(qpn, relative, marker, false); - writeEndTag(); // - writeEndTag(); // -} - -/*! - Outputs the DITA detailed documentation for a section - on a QML element reference page. - */ -void DitaXmlGenerator::generateDetailedQmlMember(Node* node, - const InnerNode* relative, - CodeMarker* marker) -{ - QString marked; - QmlPropertyNode* qpn = 0; - - if (node->type() == Node::QmlPropertyGroup) { - const QmlPropertyGroupNode* qpgn = static_cast(node); - NodeList::ConstIterator p = qpgn->childNodes().constBegin(); - if (qpgn->childNodes().size() == 1) { - qpn = static_cast(*p); - startQmlProperty(qpn,relative,marker); - writeApiDesc(node, marker, node->title()); - writeEndTag(); // - writeEndTag(); // - } - else { - writeStartTag(DT_qmlPropertyGroup); - QString id = "id-qml-propertygroup-" + node->name(); - id.replace('.','-'); - xmlWriter().writeAttribute("id",id); - writeStartTag(DT_apiName); - //writeCharacters("..."); - writeEndTag(); // - writeStartTag(DT_qmlPropertyGroupDetail); - writeApiDesc(node, marker, node->title()); - writeEndTag(); // - while (p != qpgn->childNodes().constEnd()) { - if ((*p)->type() == Node::QmlProperty) { - qpn = static_cast(*p); - startQmlProperty(qpn,relative,marker); - writeEndTag(); // - writeEndTag(); // - } - ++p; - } - writeEndTag(); // type() == Node::QmlProperty) { - qpn = static_cast(node); - startQmlProperty(qpn,relative,marker); - writeApiDesc(node, marker, node->title()); - writeEndTag(); // - writeEndTag(); // - } - else if (node->type() == Node::QmlSignal) - writeQmlRef(DT_qmlSignal,node,relative,marker); - else if (node->type() == Node::QmlSignalHandler) - writeQmlRef(DT_qmlSignalHandler,node,relative,marker); - else if (node->type() == Node::QmlMethod) - writeQmlRef(DT_qmlMethod,node,relative,marker); -} - -/*! - Outputs the DITA detailed documentation for a section - on a QML element reference page. - */ -void DitaXmlGenerator::writeQmlRef(DitaTag tag, - Node* node, - const InnerNode* relative, - CodeMarker* marker) -{ - writeStartTag(tag); - Node* n = const_cast(node); - writeGuidAttribute(n); - writeStartTag(DT_apiName); - writeCharacters(n->name()); - writeEndTag(); // - writeStartTag((DitaTag)((int)tag+2)); - writeStartTag((DitaTag)((int)tag+1)); - writeStartTag(DT_apiData); - QString marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed); - writeText(marked, relative); - writeEndTag(); // - if (node->isAttached()) { - writeStartTag(DT_qmlAttached); - xmlWriter().writeAttribute("name","attached"); - xmlWriter().writeAttribute("value","yes"); - writeEndTag(); // - } - writeEndTag(); // - writeApiDesc(node, marker, node->title()); - writeEndTag(); // - writeEndTag(); // tag -} - -/*! - This generates a in which the - QML module name and version number are specified. - */ -void DitaXmlGenerator::generateQmlModuleDef(QmlClassNode* qcn) -{ - writeStartTag(DT_qmlImportModule); - writeStartTag(DT_apiItemName); - writeCharacters(qcn->qmlModuleName()); - writeEndTag(); // - writeStartTag(DT_apiData); - writeCharacters(qcn->qmlModuleVersion()); - writeEndTag(); // - writeEndTag(); // -} - -/*! - Output the "Inherits" line for the QML element, - if there should be one. - */ -void DitaXmlGenerator::generateQmlInherits(QmlClassNode* qcn, CodeMarker* marker) -{ - if (!qcn) - return; - QmlClassNode* base = qcn->qmlBaseNode(); - while (base && base->isInternal()) { - base = base->qmlBaseNode(); - } - if (base) { - writeStartTag(DT_qmlInherits); - //writeStartTag(DT_qmlTypeDef); - //xmlWriter().writeAttribute("outputclass","inherits"); - writeStartTag(DT_apiData); - Text text; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(base)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, base->name()); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - generateText(text, qcn, marker); - writeEndTag(); // - writeEndTag(); // - } -} - -/*! - Output the "Inherit by" list for the QML element, - if it is inherited by any other elements. - */ -void DitaXmlGenerator::generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker) -{ - if (qcn) { - NodeList subs; - QmlClassNode::subclasses(qcn->name(),subs); - if (!subs.isEmpty()) { - writeStartTag(DT_qmlInheritedBy); - //writeStartTag(DT_qmlTypeDef); - //xmlWriter().writeAttribute("outputclass","inherited-by"); - writeStartTag(DT_apiData); - Text text; - appendSortedQmlNames(text,qcn,subs); - text << Atom::ParaRight; - generateText(text, qcn, marker); - writeEndTag(); // - writeEndTag(); // - } - } -} - -/*! - Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" - line for the QML element, if there should be one. - - If there is no class node, or if the class node status - is set to Node::Internal, do nothing. - */ -void DitaXmlGenerator::generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker) -{ - ClassNode* cn = qcn->classNode(); - if (cn && (cn->status() != Node::Internal)) { - writeStartTag(DT_qmlInstantiates); - //writeStartTag(DT_qmlTypeDef); - //xmlWriter().writeAttribute("outputclass","instantiates"); - writeStartTag(DT_apiData); - Text text; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, cn->name()); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - generateText(text, qcn, marker); - writeEndTag(); // - writeEndTag(); // - } -} - -/*! - Generate a for the "since" version string, if there is one. - */ -void DitaXmlGenerator::generateQmlSince(const Node* node) -{ - if (!node->since().isEmpty()) { - writeStartTag(DT_qmlSince); - //writeStartTag(DT_qmlTypeDef); - //xmlWriter().writeAttribute("outputclass","since"); - writeStartTag(DT_apiItemName); - QStringList pieces = node->since().split(QLatin1Char(' ')); - writeCharacters(pieces[0]); - writeEndTag(); // - writeStartTag(DT_apiData); - if (pieces.size() > 1) - writeCharacters(pieces[1]); - writeEndTag(); // - writeEndTag(); // - } -} - -/*! - Output the "[QmlGraphicsXxx is instantiated by QML Type Xxx]" - line for the class, if there should be one. - - If there is no QML element, or if the class node status - is set to Node::Internal, do nothing. - */ -void DitaXmlGenerator::generateInstantiatedBy(ClassNode* cn, CodeMarker* marker) -{ - if (cn && cn->status() != Node::Internal && cn->qmlElement() != 0) { - const QmlClassNode* qcn = cn->qmlElement(); - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","instantiated-by"); - Text text; - text << "["; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, cn->name()); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << " is instantiated by QML Type "; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, qcn->name()); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << "]"; - generateText(text, cn, marker); - writeEndTag(); //

- } -} - -/*! - Return the full qualification of the node \a n, but without - the name of \a n itself. e.g. A::B::C - */ -QString DitaXmlGenerator::fullQualification(const Node* n) -{ - QString fq; - InnerNode* in = n->parent(); - while (in) { - if ((in->type() == Node::Class) || - (in->type() == Node::Namespace)) { - if (in->name().isEmpty()) - break; - if (fq.isEmpty()) - fq = in->name(); - else - fq = in->name() + "::" + fq; - } - else - break; - in = in->parent(); - } - return fq; -} - -/*! - Outputs the element. - \code - - - ... - - ... - - \endcode - - The element is: - - \code - - - Base - - \endcode - */ -void DitaXmlGenerator::writeDerivations(const ClassNode* cn) -{ - QList::ConstIterator r; - - if (!cn->baseClasses().isEmpty()) { - writeStartTag(DT_cxxClassDerivations); - r = cn->baseClasses().constBegin(); - while (r != cn->baseClasses().constEnd()) { - ClassNode* bcn = (*r).node_; - if (bcn) { - writeStartTag(DT_cxxClassDerivation); - writeStartTag(DT_cxxClassDerivationAccessSpecifier); - xmlWriter().writeAttribute("value",(*r).accessString()); - writeEndTag(); // - - // not included: - - writeStartTag(DT_cxxClassBaseClass); - QString attr = fileName(bcn) + QLatin1Char('#') + bcn->guid(); - xmlWriter().writeAttribute("href",attr); - writeCharacters(bcn->plainFullName()); - writeEndTag(); // - - // not included: or - - writeEndTag(); // - - // not included: - } - ++r; - } - writeEndTag(); // - } -} - -/*! - Writes a element, depending on the - type of the node \a n, which can be a class, function, enum, - typedef, or property. - */ -void DitaXmlGenerator::writeLocation(const Node* n) -{ - DitaTag s1, s2, s3a, s3b; - s1 = DT_cxxClassAPIItemLocation; - s2 = DT_cxxClassDeclarationFile; - s3a = DT_cxxClassDeclarationFileLineStart; - s3b = DT_cxxClassDeclarationFileLineEnd; - if (n->type() == Node::Class || n->type() == Node::Namespace) { - s1 = DT_cxxClassAPIItemLocation; - s2 = DT_cxxClassDeclarationFile; - s3a = DT_cxxClassDeclarationFileLineStart; - s3b = DT_cxxClassDeclarationFileLineEnd; - } - else if (n->type() == Node::Function) { - FunctionNode* fn = const_cast(static_cast(n)); - if (fn->isMacro()) { - s1 = DT_cxxDefineAPIItemLocation; - s2 = DT_cxxDefineDeclarationFile; - s3a = DT_cxxDefineDeclarationFileLine; - s3b = DT_NONE; - } - else { - s1 = DT_cxxFunctionAPIItemLocation; - s2 = DT_cxxFunctionDeclarationFile; - s3a = DT_cxxFunctionDeclarationFileLine; - s3b = DT_NONE; - } - } - else if (n->type() == Node::Enum) { - s1 = DT_cxxEnumerationAPIItemLocation; - s2 = DT_cxxEnumerationDeclarationFile; - s3a = DT_cxxEnumerationDeclarationFileLineStart; - s3b = DT_cxxEnumerationDeclarationFileLineEnd; - } - else if (n->type() == Node::Typedef) { - s1 = DT_cxxTypedefAPIItemLocation; - s2 = DT_cxxTypedefDeclarationFile; - s3a = DT_cxxTypedefDeclarationFileLine; - s3b = DT_NONE; - } - else if ((n->type() == Node::Property) || - (n->type() == Node::Variable)) { - s1 = DT_cxxVariableAPIItemLocation; - s2 = DT_cxxVariableDeclarationFile; - s3a = DT_cxxVariableDeclarationFileLine; - s3b = DT_NONE; - } - writeStartTag(s1); - writeStartTag(s2); - xmlWriter().writeAttribute("name","filePath"); - xmlWriter().writeAttribute("value",n->location().filePath()); - writeEndTag(); // - writeStartTag(s3a); - xmlWriter().writeAttribute("name","lineNumber"); - QString lineNr; - xmlWriter().writeAttribute("value",lineNr.setNum(n->location().lineNo())); - writeEndTag(); // - if (s3b != DT_NONE) { - writeStartTag(s3b); - xmlWriter().writeAttribute("name","lineNumber"); - QString lineNr; - xmlWriter().writeAttribute("value",lineNr.setNum(n->location().lineNo())); - writeEndTag(); // - } - writeEndTag(); // ApiItemLocation> -} - -/*! - Write the elements. - */ -void DitaXmlGenerator::writeFunctions(const Section& s, - const InnerNode* parent, - CodeMarker* marker, - const QString& attribute) -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Function) { - FunctionNode* fn = const_cast(static_cast(*m)); - writeStartTag(DT_cxxFunction); - xmlWriter().writeAttribute("id",fn->guid()); - if (fn->metaness() == FunctionNode::Signal) - xmlWriter().writeAttribute("otherprops","signal"); - else if (fn->metaness() == FunctionNode::Slot) - xmlWriter().writeAttribute("otherprops","slot"); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(fn->name()); - writeEndTag(); // - generateBrief(fn,marker); - - // not included: - - writeStartTag(DT_cxxFunctionDetail); - writeStartTag(DT_cxxFunctionDefinition); - writeStartTag(DT_cxxFunctionAccessSpecifier); - xmlWriter().writeAttribute("value",fn->accessString()); - writeEndTag(); // - - // not included: - - if (fn->isStatic()) { - writeStartTag(DT_cxxFunctionStorageClassSpecifierStatic); - xmlWriter().writeAttribute("name","static"); - xmlWriter().writeAttribute("value","static"); - writeEndTag(); // - } - - // not included: , - - if (fn->isConst()) { - writeStartTag(DT_cxxFunctionConst); - xmlWriter().writeAttribute("name","const"); - xmlWriter().writeAttribute("value","const"); - writeEndTag(); // - } - - // not included: - // virtualness() != FunctionNode::NonVirtual) { - writeStartTag(DT_cxxFunctionVirtual); - xmlWriter().writeAttribute("name","virtual"); - xmlWriter().writeAttribute("value","virtual"); - writeEndTag(); // - if (fn->virtualness() == FunctionNode::PureVirtual) { - writeStartTag(DT_cxxFunctionPureVirtual); - xmlWriter().writeAttribute("name","pure virtual"); - xmlWriter().writeAttribute("value","pure virtual"); - writeEndTag(); // - } - } - - if (fn->name() == parent->name()) { - writeStartTag(DT_cxxFunctionConstructor); - xmlWriter().writeAttribute("name","constructor"); - xmlWriter().writeAttribute("value","constructor"); - writeEndTag(); // - } - else if (fn->name()[0] == QChar('~')) { - writeStartTag(DT_cxxFunctionDestructor); - xmlWriter().writeAttribute("name","destructor"); - xmlWriter().writeAttribute("value","destructor"); - writeEndTag(); // - } - else { - writeStartTag(DT_cxxFunctionDeclaredType); - QString src = marker->typified(fn->returnType()); - replaceTypesWithLinks(fn,parent,src); - writeEndTag(); // - } - - // not included: - - QString fq = fullQualification(fn); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxFunctionScopedName); - writeCharacters(fq); - writeEndTag(); // - } - writeStartTag(DT_cxxFunctionPrototype); - writeCharacters(fn->signature(true)); - writeEndTag(); // - - QString fnl = fn->signature(false); - int idx = fnl.indexOf(' '); - if (idx < 0) - idx = 0; - else - ++idx; - fnl = fn->parent()->name() + "::" + fnl.mid(idx); - writeStartTag(DT_cxxFunctionNameLookup); - writeCharacters(fnl); - writeEndTag(); // - - if (!fn->isInternal() && fn->isReimp() && fn->reimplementedFrom() != 0) { - FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom(); - if (rfn && !rfn->isInternal()) { - writeStartTag(DT_cxxFunctionReimplemented); - xmlWriter().writeAttribute("href",ditaXmlHref(rfn)); - writeCharacters(rfn->plainFullName()); - writeEndTag(); // - } - } - writeParameters(fn,parent,marker); - writeLocation(fn); - writeEndTag(); // - - writeApiDesc(fn, marker, QString()); - // generateAlsoList(inner, marker); - - // not included: or - - writeEndTag(); // - writeEndTag(); // - - if (fn->metaness() == FunctionNode::Ctor || - fn->metaness() == FunctionNode::Dtor || - fn->overloadNumber() != 1) { - } - } - ++m; - } -} - -static const QString typeTag("type"); -static const QChar charLangle = '<'; -static const QChar charAt = '@'; - -/*! - This function replaces class and enum names with - elements, i.e. links. - */ -void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, const InnerNode* parent, QString& src) -{ - QStringRef arg; - QStringRef par1; - int srcSize = src.size(); - QString text; - for (int i=0; ifindTypeNode(arg.toString(), parent); - if (tn) { - //Do not generate a link from a C++ function to a QML Basic Type (such as int) - if (n->isFunction() && tn->isQmlBasicType()) - writeCharacters(arg.toString()); - else - addLink(linkForNode(tn,parent),arg,DT_apiRelation); - } - else { - // Write simple arguments, like void and bool, - // which do not have a Qt defined target. - writeCharacters(arg.toString()); - } - } - } - else { - text += src.at(i++); - } - } - if (!text.isEmpty()) { - writeCharacters(text); - text.clear(); - } -} - -/*! - This function writes the element. - */ -void DitaXmlGenerator::writeParameters(const FunctionNode* fn, - const InnerNode* parent, - CodeMarker* marker) -{ - const QList& parameters = fn->parameters(); - if (!parameters.isEmpty()) { - writeStartTag(DT_cxxFunctionParameters); - QList::ConstIterator p = parameters.constBegin(); - while (p != parameters.constEnd()) { - writeStartTag(DT_cxxFunctionParameter); - writeStartTag(DT_cxxFunctionParameterDeclaredType); - QString src = marker->typified((*p).leftType()); - replaceTypesWithLinks(fn,parent,src); - //writeCharacters((*p).leftType()); - if (!(*p).rightType().isEmpty()) - writeCharacters((*p).rightType()); - writeEndTag(); // - writeStartTag(DT_cxxFunctionParameterDeclarationName); - writeCharacters((*p).name()); - writeEndTag(); // - - // not included: - - if (!(*p).defaultValue().isEmpty()) { - writeStartTag(DT_cxxFunctionParameterDefaultValue); - writeCharacters((*p).defaultValue()); - writeEndTag(); // - } - - // not included: - - writeEndTag(); // - ++p; - } - writeEndTag(); // - } -} - -/*! - This function writes the enum types. - */ -void DitaXmlGenerator::writeEnumerations(const Section& s, - CodeMarker* marker, - const QString& attribute) -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Enum) { - const EnumNode* en = static_cast(*m); - writeStartTag(DT_cxxEnumeration); - xmlWriter().writeAttribute("id",en->guid()); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(en->name()); - writeEndTag(); // - generateBrief(en,marker); - - // not included - - writeStartTag(DT_cxxEnumerationDetail); - writeStartTag(DT_cxxEnumerationDefinition); - writeStartTag(DT_cxxEnumerationAccessSpecifier); - xmlWriter().writeAttribute("value",en->accessString()); - writeEndTag(); // - - QString fq = fullQualification(en); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxEnumerationScopedName); - writeCharacters(fq); - writeEndTag(); // - } - const QList& items = en->items(); - if (!items.isEmpty()) { - writeStartTag(DT_cxxEnumerationPrototype); - writeCharacters(en->name()); - xmlWriter().writeCharacters(" = { "); - QList::ConstIterator i = items.constBegin(); - while (i != items.constEnd()) { - writeCharacters((*i).name()); - if (!(*i).value().isEmpty()) { - xmlWriter().writeCharacters(" = "); - writeCharacters((*i).value()); - } - ++i; - if (i != items.constEnd()) - xmlWriter().writeCharacters(", "); - } - xmlWriter().writeCharacters(" }"); - writeEndTag(); // - } - - writeStartTag(DT_cxxEnumerationNameLookup); - writeCharacters(en->parent()->name() + "::" + en->name()); - writeEndTag(); // - - // not included: - - if (!items.isEmpty()) { - writeStartTag(DT_cxxEnumerators); - QList::ConstIterator i = items.constBegin(); - while (i != items.constEnd()) { - writeStartTag(DT_cxxEnumerator); - writeStartTag(DT_apiName); - writeCharacters((*i).name()); - writeEndTag(); // - - QString fq = fullQualification(en->parent()); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxEnumeratorScopedName); - writeCharacters(fq + "::" + (*i).name()); - writeEndTag(); // - } - writeStartTag(DT_cxxEnumeratorPrototype); - writeCharacters((*i).name()); - writeEndTag(); // - writeStartTag(DT_cxxEnumeratorNameLookup); - writeCharacters(en->parent()->name() + "::" + (*i).name()); - writeEndTag(); // - - if (!(*i).value().isEmpty()) { - writeStartTag(DT_cxxEnumeratorInitialiser); - if ((*i).value().toInt(0,16) == 0) - xmlWriter().writeAttribute("value", "0"); - else - xmlWriter().writeAttribute("value", (*i).value()); - writeEndTag(); // - } - - // not included: -#if 0 - if (!(*i).text().isEmpty()) { - writeStartTag(DT_apiDesc); - generateText((*i).text(), en, marker); - writeEndTag(); // - } -#endif - writeEndTag(); // - ++i; - } - writeEndTag(); // - } - - writeLocation(en); - writeEndTag(); // - - writeApiDesc(en, marker, QString()); - - // not included: or - - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - ++m; - } -} - -/*! - This function writes the output for the \typedef commands. - */ -void DitaXmlGenerator::writeTypedefs(const Section& s, - CodeMarker* marker, - const QString& attribute) - -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Typedef) { - const TypedefNode* tn = static_cast(*m); - writeStartTag(DT_cxxTypedef); - xmlWriter().writeAttribute("id",tn->guid()); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(tn->name()); - writeEndTag(); // - generateBrief(tn,marker); - - // not included: - - writeStartTag(DT_cxxTypedefDetail); - writeStartTag(DT_cxxTypedefDefinition); - writeStartTag(DT_cxxTypedefAccessSpecifier); - xmlWriter().writeAttribute("value",tn->accessString()); - writeEndTag(); // - - // not included: - - QString fq = fullQualification(tn); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxTypedefScopedName); - writeCharacters(fq); - writeEndTag(); // - } - - // not included: - - writeStartTag(DT_cxxTypedefNameLookup); - writeCharacters(tn->parent()->name() + "::" + tn->name()); - writeEndTag(); // - - // not included: - - writeLocation(tn); - writeEndTag(); // - - writeApiDesc(tn, marker, QString()); - - // not included: or - - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - ++m; - } -} - -/*! - This function writes the output for the \property commands. - This is the Q_PROPERTYs. - */ -void DitaXmlGenerator::writeProperties(const Section& s, - CodeMarker* marker, - const QString& attribute) -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Property) { - const PropertyNode* pn = static_cast(*m); - writeStartTag(DT_cxxVariable); - xmlWriter().writeAttribute("id",pn->guid()); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(pn->name()); - writeEndTag(); // - generateBrief(pn,marker); - - // not included: - - writeStartTag(DT_cxxVariableDetail); - writeStartTag(DT_cxxVariableDefinition); - writeStartTag(DT_cxxVariableAccessSpecifier); - xmlWriter().writeAttribute("value",pn->accessString()); - writeEndTag(); // - - // not included: , - // , - // , - // , - - if (!pn->qualifiedDataType().isEmpty()) { - writeStartTag(DT_cxxVariableDeclaredType); - writeCharacters(pn->qualifiedDataType()); - writeEndTag(); // - } - QString fq = fullQualification(pn); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxVariableScopedName); - writeCharacters(fq); - writeEndTag(); // - } - - writeStartTag(DT_cxxVariablePrototype); - xmlWriter().writeCharacters("Q_PROPERTY("); - writeCharacters(pn->qualifiedDataType()); - xmlWriter().writeCharacters(" "); - writeCharacters(pn->name()); - writePropertyParameter("READ",pn->getters()); - writePropertyParameter("WRITE",pn->setters()); - writePropertyParameter("RESET",pn->resetters()); - writePropertyParameter("NOTIFY",pn->notifiers()); - if (pn->isDesignable() != pn->designableDefault()) { - xmlWriter().writeCharacters(" DESIGNABLE "); - if (!pn->runtimeDesignabilityFunction().isEmpty()) - writeCharacters(pn->runtimeDesignabilityFunction()); - else - xmlWriter().writeCharacters(pn->isDesignable() ? "true" : "false"); - } - if (pn->isScriptable() != pn->scriptableDefault()) { - xmlWriter().writeCharacters(" SCRIPTABLE "); - if (!pn->runtimeScriptabilityFunction().isEmpty()) - writeCharacters(pn->runtimeScriptabilityFunction()); - else - xmlWriter().writeCharacters(pn->isScriptable() ? "true" : "false"); - } - if (pn->isWritable() != pn->writableDefault()) { - xmlWriter().writeCharacters(" STORED "); - xmlWriter().writeCharacters(pn->isStored() ? "true" : "false"); - } - if (pn->isUser() != pn->userDefault()) { - xmlWriter().writeCharacters(" USER "); - xmlWriter().writeCharacters(pn->isUser() ? "true" : "false"); - } - if (pn->isConstant()) - xmlWriter().writeCharacters(" CONSTANT"); - if (pn->isFinal()) - xmlWriter().writeCharacters(" FINAL"); - xmlWriter().writeCharacters(")"); - writeEndTag(); // - - writeStartTag(DT_cxxVariableNameLookup); - writeCharacters(pn->parent()->name() + "::" + pn->name()); - writeEndTag(); // - - if (pn->overriddenFrom() != 0) { - PropertyNode* opn = (PropertyNode*)pn->overriddenFrom(); - writeStartTag(DT_cxxVariableReimplemented); - xmlWriter().writeAttribute("href",ditaXmlHref(opn)); - writeCharacters(opn->plainFullName()); - writeEndTag(); // - } - - writeLocation(pn); - writeEndTag(); // - - writeApiDesc(pn, marker, QString()); - - // not included: or - - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - ++m; - } -} - -/*! - This function outputs the nodes resulting from \variable commands. - */ -void DitaXmlGenerator::writeDataMembers(const Section& s, - CodeMarker* marker, - const QString& attribute) -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Variable) { - const VariableNode* vn = static_cast(*m); - writeStartTag(DT_cxxVariable); - xmlWriter().writeAttribute("id",vn->guid()); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(vn->name()); - writeEndTag(); // - generateBrief(vn,marker); - - // not included: - - writeStartTag(DT_cxxVariableDetail); - writeStartTag(DT_cxxVariableDefinition); - writeStartTag(DT_cxxVariableAccessSpecifier); - xmlWriter().writeAttribute("value",vn->accessString()); - writeEndTag(); // - - // not included: - - if (vn->isStatic()) { - writeStartTag(DT_cxxVariableStorageClassSpecifierStatic); - xmlWriter().writeAttribute("name","static"); - xmlWriter().writeAttribute("value","static"); - writeEndTag(); // - } - - // not included: , - // , - - writeStartTag(DT_cxxVariableDeclaredType); - writeCharacters(vn->leftType()); - if (!vn->rightType().isEmpty()) - writeCharacters(vn->rightType()); - writeEndTag(); // - - QString fq = fullQualification(vn); - if (!fq.isEmpty()) { - writeStartTag(DT_cxxVariableScopedName); - writeCharacters(fq); - writeEndTag(); // - } - - writeStartTag(DT_cxxVariablePrototype); - writeCharacters(vn->leftType() + QLatin1Char(' ')); - //writeCharacters(vn->parent()->name() + "::" + vn->name()); - writeCharacters(vn->name()); - if (!vn->rightType().isEmpty()) - writeCharacters(vn->rightType()); - writeEndTag(); // - - writeStartTag(DT_cxxVariableNameLookup); - writeCharacters(vn->parent()->name() + "::" + vn->name()); - writeEndTag(); // - - // not included: - - writeLocation(vn); - writeEndTag(); // - - writeApiDesc(vn, marker, QString()); - - // not included: or - - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - ++m; - } -} - -/*! - This function writes a \macro as a . - */ -void DitaXmlGenerator::writeMacros(const Section& s, - CodeMarker* marker, - const QString& attribute) -{ - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Function) { - const FunctionNode* fn = static_cast(*m); - if (fn->isMacro()) { - writeStartTag(DT_cxxDefine); - xmlWriter().writeAttribute("id",fn->guid()); - if (!attribute.isEmpty()) - xmlWriter().writeAttribute("outputclass",attribute); - writeStartTag(DT_apiName); - writeCharacters(fn->name()); - writeEndTag(); // - generateBrief(fn,marker); - - // not included: - - writeStartTag(DT_cxxDefineDetail); - writeStartTag(DT_cxxDefineDefinition); - writeStartTag(DT_cxxDefineAccessSpecifier); - xmlWriter().writeAttribute("value",fn->accessString()); - writeEndTag(); // - - writeStartTag(DT_cxxDefinePrototype); - xmlWriter().writeCharacters("#define "); - writeCharacters(fn->name()); - if (fn->metaness() == FunctionNode::MacroWithParams) { - QStringList params = fn->parameterNames(); - if (!params.isEmpty()) { - xmlWriter().writeCharacters("("); - for (int i = 0; i < params.size(); ++i) { - if (params[i].isEmpty()) - xmlWriter().writeCharacters("..."); - else - writeCharacters(params[i]); - if ((i+1) < params.size()) - xmlWriter().writeCharacters(", "); - } - xmlWriter().writeCharacters(")"); - } - } - writeEndTag(); // - - writeStartTag(DT_cxxDefineNameLookup); - writeCharacters(fn->name()); - writeEndTag(); // - - if (fn->reimplementedFrom() != 0) { - FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom(); - writeStartTag(DT_cxxDefineReimplemented); - xmlWriter().writeAttribute("href",ditaXmlHref(rfn)); - writeCharacters(rfn->plainFullName()); - writeEndTag(); // - } - - if (fn->metaness() == FunctionNode::MacroWithParams) { - QStringList params = fn->parameterNames(); - if (!params.isEmpty()) { - writeStartTag(DT_cxxDefineParameters); - for (int i = 0; i < params.size(); ++i) { - writeStartTag(DT_cxxDefineParameter); - writeStartTag(DT_cxxDefineParameterDeclarationName); - writeCharacters(params[i]); - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - writeEndTag(); // - } - } - - writeLocation(fn); - writeEndTag(); // - - writeApiDesc(fn, marker, QString()); - - // not included: or - - writeEndTag(); // - - // not included: - - writeEndTag(); // - } - } - ++m; - } -} - -/*! - This function writes one parameter of a Q_PROPERTY macro. - The property is identified by \a tag ("READ" "WRIE" etc), - and it is found in the 'a nlist. - */ -void DitaXmlGenerator::writePropertyParameter(const QString& tag, const NodeList& nlist) -{ - NodeList::const_iterator n = nlist.constBegin(); - while (n != nlist.constEnd()) { - xmlWriter().writeCharacters(" "); - writeCharacters(tag); - xmlWriter().writeCharacters(" "); - writeCharacters((*n)->name()); - ++n; - } -} - -/*! - Calls beginSubPage() in the base class to open the file. - Then creates a new XML stream writer using the IO device - from opened file and pushes the XML writer onto a stackj. - Creates the file named \a fileName in the output directory. - Attaches a QTextStream to the created file, which is written - to all over the place using out(). Finally, it sets some - parameters in the XML writer and calls writeStartDocument(). - - It also ensures that a GUID map is created for the output file. - */ -void DitaXmlGenerator::beginSubPage(const InnerNode* node, - const QString& fileName) -{ - Generator::beginSubPage(node,fileName); - (void) lookupGuidMap(fileName); - QXmlStreamWriter* writer = new QXmlStreamWriter(out().device()); - xmlWriterStack.push(writer); - writer->setAutoFormatting(true); - writer->setAutoFormattingIndent(4); - writer->writeStartDocument(); - clearSectionNesting(); -} - -/*! - Calls writeEndDocument() and then pops the XML stream writer - off the stack and deletes it. Then it calls endSubPage() in - the base class to close the device. - */ -void DitaXmlGenerator::endSubPage() -{ - if (inSection()) - qDebug() << "Missing
in" << outFileName() << sectionNestingLevel; - xmlWriter().writeEndDocument(); - delete xmlWriterStack.pop(); - Generator::endSubPage(); -} - -/*! - Returns a reference to the XML stream writer currently in use. - There is one XML stream writer open for each XML file being - written, and they are kept on a stack. The one on top of the - stack is the one being written to at the moment. - */ -QXmlStreamWriter& DitaXmlGenerator::xmlWriter() -{ - return *xmlWriterStack.top(); -} - -/*! - Writes the \e {} element for \a node to the current XML - stream using the code \a marker and the \a title. - */ -void DitaXmlGenerator::writeApiDesc(const Node* node, - CodeMarker* marker, - const QString& title) -{ - if (!node->doc().isEmpty()) { - inDetailedDescription = true; - enterDesc(DT_apiDesc,QString(),title); - generateBody(node, marker); - generateAlsoList(node, marker); - leaveSection(); - } - inDetailedDescription = false; -} - -/*! - Write the nested class elements. - */ -void DitaXmlGenerator::writeNestedClasses(const Section& s, - const Node* n) -{ - if (s.members.isEmpty()) - return; - writeStartTag(DT_cxxClassNested); - writeStartTag(DT_cxxClassNestedDetail); - - NodeList::ConstIterator m = s.members.constBegin(); - while (m != s.members.constEnd()) { - if ((*m)->type() == Node::Class) { - writeStartTag(DT_cxxClassNestedClass); - QString link = linkForNode((*m), n); - xmlWriter().writeAttribute("href", link); - QString name = n->name() + "::" + (*m)->name(); - writeCharacters(name); - writeEndTag(); // - } - ++m; - } - writeEndTag(); // - writeEndTag(); // -} - -/*! - Recursive writing of DITA XML files from the root \a node. - */ -void -DitaXmlGenerator::generateInnerNode(InnerNode* node) -{ - if (!node->url().isNull()) - return; - - if (node->isDocNode()) { - DocNode* docNode = static_cast(node); - if (docNode->subType() == Node::ExternalPage) - return; - if (docNode->subType() == Node::Image) - return; - if (docNode->subType() == Node::Page) { - if (node->count() > 0) - qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title())); - } - } - else if (node->isQmlPropertyGroup()) - return; - - /* - Obtain a code marker for the source file. - */ - CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath()); - if (node->parent() != 0) { - if (!node->name().endsWith(".ditamap")) - beginSubPage(node, fileName(node)); - if (node->isNamespace() || node->isClass() || node->isQmlType() || node->isHeaderFile()) - generateClassLikeNode(node, marker); - else if (node->isDocNode()) - generateDocNode(static_cast(node), marker); - else if (node->isQmlBasicType()) - generateQmlBasicTypePage(static_cast(node), marker); - if (!node->name().endsWith(".ditamap")) - endSubPage(); - } - - NodeList::ConstIterator c = node->childNodes().constBegin(); - while (c != node->childNodes().constEnd()) { - if ((*c)->isInnerNode() && (*c)->access() != Node::Private) - generateInnerNode((InnerNode*)*c); - ++c; - } -} - -/*! - Returns \c true if \a format is "DITAXML" or "HTML" . - */ -bool DitaXmlGenerator::canHandleFormat(const QString& format) -{ - return (format == "HTML") || (format == this->format()); -} - -/*! - If the node multimap \a nmm contains nodes mapped to \a key, - if any of the nodes mapped to \a key has the same href as the - \a node, return true. Otherwise, return false. - */ -bool DitaXmlGenerator::isDuplicate(NodeMultiMap* nmm, const QString& key, Node* node) -{ - QList matches = nmm->values(key); - if (!matches.isEmpty()) { - for (int i=0; ichildNodes(); - if (children.size() == 0) - return rootPageNode; - - QString message; - for (int i=0; iisInternal() || child->doc().isEmpty() || child->isIndexNode()) - continue; - - if (child->name() == "index.html" || child->name() == "index") { - rootPageNode = child; - } - - switch (child->type()) { - case Node::Namespace: - if (!isDuplicate(nodeTypeMaps[Node::Namespace],child->name(),child)) - nodeTypeMaps[Node::Namespace]->insert(child->name(),child); - break; - case Node::Class: - if (!isDuplicate(nodeTypeMaps[Node::Class],child->name(),child)) - nodeTypeMaps[Node::Class]->insert(child->name(),child); - break; - case Node::QmlType: - if (!isDuplicate(nodeTypeMaps[Node::QmlType],child->name(),child)) - nodeTypeMaps[Node::QmlType]->insert(child->name(),child); - break; - case Node::QmlBasicType: - if (!isDuplicate(nodeTypeMaps[Node::QmlBasicType],child->title(),child)) - nodeTypeMaps[Node::QmlBasicType]->insert(child->title(),child); - break; - case Node::Group: - if (!isDuplicate(nodeTypeMaps[Node::Group],child->title(),child)) - nodeTypeMaps[Node::Group]->insert(child->title(),child); - break; - case Node::Module: - if (!isDuplicate(nodeTypeMaps[Node::Module],child->title(),child)) - nodeTypeMaps[Node::Module]->insert(child->title(),child); - break; - case Node::QmlModule: - if (!isDuplicate(nodeTypeMaps[Node::QmlModule],child->title(),child)) - nodeTypeMaps[Node::QmlModule]->insert(child->title(),child); - break; - case Node::Document: - switch (child->subType()) { - case Node::Example: - if (!isDuplicate(nodeSubtypeMaps[Node::Example],child->title(),child)) - nodeSubtypeMaps[Node::Example]->insert(child->title(),child); - break; - case Node::HeaderFile: - if (!isDuplicate(nodeSubtypeMaps[Node::HeaderFile],child->title(),child)) - nodeSubtypeMaps[Node::HeaderFile]->insert(child->title(),child); - break; - case Node::File: - break; - case Node::Image: - break; - case Node::Page: - if (!isDuplicate(pageTypeMaps[child->pageType()],child->title(),child)) - pageTypeMaps[child->pageType()]->insert(child->title(),child); - break; - case Node::ExternalPage: - if (!isDuplicate(nodeSubtypeMaps[Node::ExternalPage],child->title(),child)) - nodeSubtypeMaps[Node::ExternalPage]->insert(child->title(),child); - break; - default: - break; - } - break; - case Node::Enum: - break; - case Node::Typedef: - break; - case Node::Function: - break; - case Node::Property: - break; - case Node::Variable: - break; - case Node::QmlProperty: - break; - case Node::QmlPropertyGroup: - break; - case Node::QmlSignal: - break; - case Node::QmlSignalHandler: - break; - case Node::QmlMethod: - break; - default: - break; - } - } - return rootPageNode; -} - -/*! - Creates the DITA map for the qdoc run. The map is written - to the file \e{qt.ditamap" in the DITA XML output directory. - */ -void DitaXmlGenerator::writeDitaMap() -{ - QString doctype; - -/* - Remove #if 0 to get a flat ditamap. -*/ -#if 0 - beginSubPage(qdb_->primaryTreeRoot(),"qt.ditamap"); - doctype = ""; - xmlWriter().writeDTD(doctype); - writeStartTag(DT_map); - writeStartTag(DT_topicmeta); - writeStartTag(DT_shortdesc); - xmlWriter().writeCharacters("The top level map for the Qt documentation"); - writeEndTag(); // - writeEndTag(); // - GuidMaps::iterator i = guidMaps.constBegin(); - while (i != guidMaps.constEnd()) { - writeStartTag(DT_topicref); - if (i.key() != "qt.ditamap") - xmlWriter().writeAttribute("href",i.key()); - writeEndTag(); // - ++i; - } - endSubPage(); -#endif - - for (unsigned i=0; iprimaryTreeRoot()); - - beginSubPage(qdb_->primaryTreeRoot(),"qt.ditamap"); - - doctype = ""; - xmlWriter().writeDTD(doctype); - writeStartTag(DT_map); - writeStartTag(DT_topicmeta); - writeStartTag(DT_shortdesc); - xmlWriter().writeCharacters("The top level map for the Qt documentation"); - writeEndTag(); // - writeEndTag(); // - - writeStartTag(DT_topicref); - if (rootPageNode) { - if (!rootPageNode->title().isEmpty()) - xmlWriter().writeAttribute("navtitle",rootPageNode->title()); - else - xmlWriter().writeAttribute("navtitle",project); - xmlWriter().writeAttribute("href",fileName(rootPageNode)); - } - else - xmlWriter().writeAttribute("navtitle",project); - - writeTopicrefs(pageTypeMaps[Node::OverviewPage], "Overviews"); - writeTopicrefs(pageTypeMaps[Node::HowToPage], "Howtos"); - writeTopicrefs(pageTypeMaps[Node::TutorialPage], "Tutorials"); - writeTopicrefs(pageTypeMaps[Node::FAQPage], "FAQs"); - writeTopicrefs(pageTypeMaps[Node::ArticlePage], "Articles"); - writeTopicrefs(nodeSubtypeMaps[Node::Example], "Examples"); - - if (nodeTypeMaps[Node::QmlModule]->size() > 1) - writeTopicrefs(nodeTypeMaps[Node::QmlModule], "QML modules"); - - if (nodeTypeMaps[Node::QmlModule]->size() == 1) - writeTopicrefs(nodeTypeMaps[Node::QmlType], "QML types", nodeTypeMaps[Node::QmlModule]->values()[0]); - else - writeTopicrefs(nodeTypeMaps[Node::QmlType], "QML types"); - writeTopicrefs(nodeTypeMaps[Node::QmlBasicType], "QML basic types"); - - if (nodeTypeMaps[Node::Module]->size() > 1) - writeTopicrefs(nodeTypeMaps[Node::Module], "Modules"); - - if (nodeTypeMaps[Node::Module]->size() == 1) - writeTopicrefs(nodeTypeMaps[Node::Class], "C++ classes", nodeTypeMaps[Node::Module]->values()[0]); - else - writeTopicrefs(nodeTypeMaps[Node::Class], "C++ classes"); - writeTopicrefs(nodeTypeMaps[Node::Namespace], "C++ namespaces"); - writeTopicrefs(nodeSubtypeMaps[Node::HeaderFile], "Header files"); - writeTopicrefs(nodeTypeMaps[Node::Group], "Groups"); - - writeEndTag(); // - endSubPage(); - - for (unsigned i=0; iname()); - - QString doctype; - doctype = ""; - xmlWriter().writeDTD(doctype); - writeStartTag(DT_map); - writeStartTag(DT_topicmeta); - writeStartTag(DT_shortdesc); - xmlWriter().writeCharacters(node->title()); - writeEndTag(); // - writeEndTag(); // - const DitaRefList map = node->map(); - writeDitaRefs(map); - endSubPage(); -} - -/*! - Write the \a ditarefs to the current output file. - */ -void DitaXmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) -{ - foreach (DitaRef* t, ditarefs) { - if (t->isMapRef()) - writeStartTag(DT_mapref); - else - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",t->navtitle()); - if (t->href().isEmpty()) { - const DocNode* dn = qdb_->findDocNodeByTitle(t->navtitle()); - if (dn) - xmlWriter().writeAttribute("href",fileName(dn)); - } - else - xmlWriter().writeAttribute("href",t->href()); - if (t->subrefs() && !t->subrefs()->isEmpty()) - writeDitaRefs(*(t->subrefs())); - writeEndTag(); // or - } -} - -void DitaXmlGenerator::writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle, Node* headingnode) -{ - if (!nmm || nmm->isEmpty()) - return; - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",navtitle); - if (headingnode) - xmlWriter().writeAttribute("href",fileName(headingnode)); - NodeMultiMap::iterator i; - NodeMultiMap *ditaMaps = pageTypeMaps[Node::DitaMapPage]; - - /*! - Put all pages that are already in a hand-written ditamap not in - the qt.ditamap separately. It loops through all ditamaps recursively - before deciding to write an article to qt.ditamap. - */ - if ((navtitle == "Articles" && ditaMaps && ditaMaps->size() > 0)) { - NodeMultiMap::iterator mapIterator = ditaMaps->begin(); - while (mapIterator != ditaMaps->end()) { - writeStartTag(DT_mapref); - xmlWriter().writeAttribute("navtitle",mapIterator.key()); - xmlWriter().writeAttribute("href",fileName(mapIterator.value())); - writeEndTag(); - ++mapIterator; - } - i = nmm->begin(); - while (i != nmm->end()) { - // Hardcode not writing index.dita multiple times in the tree. - // index.dita should only appear at the top of the ditamap. - if (fileName(i.value()) == "index.dita") { - i++; - continue; - } - bool foundInDitaMap = false; - mapIterator = ditaMaps->begin(); - while (mapIterator != ditaMaps->end()) { - const DitaMapNode *dmNode = static_cast(mapIterator.value()); - for (int count = 0; count < dmNode->map().count(); count++) { - if (dmNode->map().at(count)->navtitle() == i.key()) { - foundInDitaMap = true; - break; - } - } - ++mapIterator; - } - if (!foundInDitaMap) { - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",i.key()); - xmlWriter().writeAttribute("href",fileName(i.value())); - writeEndTag(); // - } - ++i; - } - } - /*! - Shortcut when there are no hand-written ditamaps or when we are - not generating the articles list. - */ - else { - i = nmm->begin(); - while (i != nmm->end()) { - // Hardcode not writing index.dita multiple times in the tree. - // index.dita should only appear at the top of the ditamap. - if (fileName(i.value()) == "index.dita") { - i++; - continue; - } - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",i.key()); - xmlWriter().writeAttribute("href",fileName(i.value())); - switch (i.value()->type()) { - case Node::Class: - case Node::Namespace: { - const NamespaceNode* nn = static_cast(i.value()); - const NodeList& c = nn->childNodes(); - QMap tempMap; - for (int j=0; jisInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) - continue; - if (c[j]->type() == Node::Class) { - tempMap.insert(c[j]->name(), c[j]); - } - } - QMap::iterator classIterator = tempMap.begin(); - while (classIterator != tempMap.end()) { - const Node* currentNode = static_cast(classIterator.value()); - writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",currentNode->name()); - xmlWriter().writeAttribute("href",fileName(currentNode)); - writeEndTag(); // - ++classIterator; - } - - break; - } - default: - break; - } - writeEndTag(); // - ++i; - } - } - writeEndTag(); // -} - - -/*! - Looks up the tag name for \a t in the map of metadata - values for the current topic in \a inner. If a value - for the tag is found, the element is written with the - found value. Otherwise if \a force is set, an empty - element is written using the tag. - - Returns \c true or false depending on whether it writes - an element using the tag \a t. - - \note If \a t is found in the metadata map, it is erased. - i.e. Once you call this function for a particular \a t, - you consume \a t. - */ -bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner, - DitaXmlGenerator::DitaTag t, - bool force) -{ - QString s = getMetadataElement(inner,t); - if (s.isEmpty() && !force) - return false; - writeStartTag(t); - if (!s.isEmpty()) - xmlWriter().writeCharacters(s); - writeEndTag(); - return true; -} - - -/*! - Looks up the tag name for \a t in the map of metadata - values for the current topic in \a inner. If one or more - value sfor the tag are found, the elements are written. - Otherwise nothing is written. - - Returns \c true or false depending on whether it writes - at least one element using the tag \a t. - - \note If \a t is found in the metadata map, it is erased. - i.e. Once you call this function for a particular \a t, - you consume \a t. - */ -bool DitaXmlGenerator::writeMetadataElements(const InnerNode* inner, - DitaXmlGenerator::DitaTag t) -{ - QStringList s = getMetadataElements(inner,t); - if (s.isEmpty()) - return false; - for (int i=0; i element for the \a inner node - using the \a marker. The element contains - the element, plus some others. This - function writes one or more of these elements: - - \list - \o * - \o * - \o not used - \o * - \o * - \o * - \o * - \o not used - \o * - \o not used - \o not used - \o not used - \o * - \o * - \o * - \o not used - \o * - \o * - \o * - \o * - \o not used - \o not used - \o not used - \o not used - \o not used - \o * - \o * - \endlist - - \node * means the tag has been used. - - */ -void -DitaXmlGenerator::writeProlog(const InnerNode* inner) -{ - if (!inner) - return; - writeStartTag(DT_prolog); - writeMetadataElements(inner,DT_author); - writeMetadataElement(inner,DT_publisher); - QString s = getMetadataElement(inner,DT_copyryear); - QString t = getMetadataElement(inner,DT_copyrholder); - writeStartTag(DT_copyright); - writeStartTag(DT_copyryear); - if (!s.isEmpty()) - xmlWriter().writeAttribute("year",s); - writeEndTag(); // - writeStartTag(DT_copyrholder); - if (!s.isEmpty()) - xmlWriter().writeCharacters(t); - writeEndTag(); // - writeEndTag(); // - s = getMetadataElement(inner,DT_permissions); - writeStartTag(DT_permissions); - xmlWriter().writeAttribute("view",s); - writeEndTag(); // - writeStartTag(DT_metadata); - QStringList sl = getMetadataElements(inner,DT_audience); - if (!sl.isEmpty()) { - for (int i=0; i - } - } - if (!writeMetadataElement(inner,DT_category,false)) { - writeStartTag(DT_category); - QString category = "Page"; - if (inner->isClass()) - category = "Class reference"; - if (inner->isQmlType()) - category = "QML Reference"; - else if (inner->isQmlBasicType()) - category = "QML Basic Type"; - else if (inner->isNamespace()) - category = "Namespace"; - else if (inner->isModule()) - category = "Module"; - else if (inner->isQmlModule()) - category = "QML Module"; - else if (inner->isGroup()) - category = "Group"; - else if (inner->isDocNode()) { - if (inner->isHeaderFile()) - category = "Header File"; - else if (inner->subType() == Node::File) - category = "Example Source File"; - else if (inner->isExample()) - category = "Example"; - else if (inner->subType() == Node::Image) - category = "Image"; - else if (inner->subType() == Node::Page) - category = "Page"; - else if (inner->isExternalPage()) - category = "External Page"; // Is this necessary? - } - xmlWriter().writeCharacters(category); - writeEndTag(); // - } - if (vrm.size() > 0) { - writeStartTag(DT_prodinfo); - if (!writeMetadataElement(inner,DT_prodname,false)) { - writeStartTag(DT_prodname); - xmlWriter().writeCharacters(projectDescription); - writeEndTag(); // - } - writeStartTag(DT_vrmlist); - writeStartTag(DT_vrm); - if (vrm.size() > 0) - xmlWriter().writeAttribute("version",vrm[0]); - if (vrm.size() > 1) - xmlWriter().writeAttribute("release",vrm[1]); - if (vrm.size() > 2) - xmlWriter().writeAttribute("modification",vrm[2]); - writeEndTag(); // - writeEndTag(); // - if (!writeMetadataElement(inner,DT_component,false)) { - QString component = inner->moduleName(); - if (!component.isEmpty()) { - writeStartTag(DT_component); - xmlWriter().writeCharacters(component); - writeEndTag(); // - } - } - writeEndTag(); // - } - const QStringMultiMap& metaTagMap = inner->doc().metaTagMap(); - QMapIterator i(metaTagMap); - while (i.hasNext()) { - i.next(); - writeStartTag(DT_othermeta); - xmlWriter().writeAttribute("name",i.key()); - xmlWriter().writeAttribute("content",i.value()); - writeEndTag(); // - } - if ((tagStack.first() == DT_cxxClass && !inner->includes().isEmpty()) || inner->isHeaderFile()) { - writeStartTag(DT_othermeta); - xmlWriter().writeAttribute("name","includeFile"); - QString text; - QStringList::ConstIterator i = inner->includes().constBegin(); - while (i != inner->includes().constEnd()) { - if ((*i).startsWith(QLatin1Char('<')) && (*i).endsWith(QLatin1Char('>'))) - text += *i; - else - text += QLatin1Char('<') + *i + QLatin1Char('>'); - ++i; - if (i != inner->includes().constEnd()) - text += "\n"; - } - xmlWriter().writeAttribute("content",text); - writeEndTag(); // - } - writeEndTag(); // - writeEndTag(); // -} - -/*! - This function should be called to write the \a href attribute - if the href could be an \e http or \e ftp link. If \a href is - one or the other, a \e scope attribute is also writen, with - value \e external. - */ -void DitaXmlGenerator::writeHrefAttribute(const QString& href) -{ - xmlWriter().writeAttribute("href", href); - if (href.startsWith("http:") || href.startsWith("ftp:") || - href.startsWith("https:") || href.startsWith("mailto:")) - xmlWriter().writeAttribute("scope", "external"); -} - -/*! - Strips the markup tags from \a src, when we are trying to - create an \e{id} attribute. Returns the stripped text. - */ -QString DitaXmlGenerator::stripMarkup(const QString& src) const -{ - QString text; - const QChar charAt = '@'; - const QChar charSlash = '/'; - const QChar charLangle = '<'; - const QChar charRangle = '>'; - - int n = src.size(); - int i = 0; - while (i < n) { - if (src.at(i) == charLangle) { - ++i; - if (src.at(i) == charAt || (src.at(i) == charSlash && src.at(i+1) == charAt)) { - while (i < n && src.at(i) != charRangle) - ++i; - ++i; - } - else { - text += charLangle; - } - } - else - text += src.at(i++); - } - return text; -} - -QT_END_NAMESPACE diff --git a/src/tools/qdoc/ditaxmlgenerator.h b/src/tools/qdoc/ditaxmlgenerator.h deleted file mode 100644 index d2f445dd5b..0000000000 --- a/src/tools/qdoc/ditaxmlgenerator.h +++ /dev/null @@ -1,520 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DITAXMLGENERATOR_H -#define DITAXMLGENERATOR_H - -#include -#include -#include -#include "codemarker.h" -#include "generator.h" - -QT_BEGIN_NAMESPACE - -typedef QMap GuidMap; -typedef QMap GuidMaps; - -class DitaXmlGenerator : public Generator -{ - Q_DECLARE_TR_FUNCTIONS(QDoc::DitaXmlGenerator) - -public: - enum SinceType { - Namespace, - Class, - MemberFunction, - NamespaceFunction, - GlobalFunction, - Macro, - Enum, - Typedef, - Property, - Variable, - QmlClass, - QmlProperty, - QmlSignal, - QmlSignalHandler, - QmlMethod, - LastSinceType - }; - - enum DitaTag { - DT_NONE, - DT_alt, - DT_apiData, - DT_apiDef, - DT_apiDefItem, - DT_apiDesc, - DT_apiDetail, - DT_apiItemName, - DT_APIMap, - DT_apiName, - DT_apiRef, - DT_apiRelation, - DT_audience, - DT_author, - DT_b, - DT_body, - DT_bodydiv, - DT_brand, - DT_category, - DT_codeblock, - DT_colspec, - DT_comment, - DT_component, - DT_copyrholder, - DT_copyright, - DT_copyryear, - DT_created, - DT_critdates, - DT_cxxAPIMap, - DT_cxxClass, - DT_cxxClassAbstract, - DT_cxxClassAccessSpecifier, - DT_cxxClassAPIItemLocation, - DT_cxxClassBaseClass, - DT_cxxClassDeclarationFile, - DT_cxxClassDeclarationFileLine, - DT_cxxClassDeclarationFileLineStart, - DT_cxxClassDeclarationFileLineEnd, - DT_cxxClassDefinition, - DT_cxxClassDerivation, - DT_cxxClassDerivationAccessSpecifier, - DT_cxxClassDerivations, - DT_cxxClassDetail, - DT_cxxClassNested, - DT_cxxClassNestedClass, - DT_cxxClassNestedDetail, - DT_cxxDefine, - DT_cxxDefineAccessSpecifier, - DT_cxxDefineAPIItemLocation, - DT_cxxDefineDeclarationFile, - DT_cxxDefineDeclarationFileLine, - DT_cxxDefineDefinition, - DT_cxxDefineDetail, - DT_cxxDefineNameLookup, - DT_cxxDefineParameter, - DT_cxxDefineParameterDeclarationName, - DT_cxxDefineParameters, - DT_cxxDefinePrototype, - DT_cxxDefineReimplemented, - DT_cxxEnumeration, - DT_cxxEnumerationAccessSpecifier, - DT_cxxEnumerationAPIItemLocation, - DT_cxxEnumerationDeclarationFile, - DT_cxxEnumerationDeclarationFileLine, - DT_cxxEnumerationDeclarationFileLineStart, - DT_cxxEnumerationDeclarationFileLineEnd, - DT_cxxEnumerationDefinition, - DT_cxxEnumerationDetail, - DT_cxxEnumerationNameLookup, - DT_cxxEnumerationPrototype, - DT_cxxEnumerationScopedName, - DT_cxxEnumerator, - DT_cxxEnumeratorInitialiser, - DT_cxxEnumeratorNameLookup, - DT_cxxEnumeratorPrototype, - DT_cxxEnumerators, - DT_cxxEnumeratorScopedName, - DT_cxxFunction, - DT_cxxFunctionAccessSpecifier, - DT_cxxFunctionAPIItemLocation, - DT_cxxFunctionConst, - DT_cxxFunctionConstructor, - DT_cxxFunctionDeclarationFile, - DT_cxxFunctionDeclarationFileLine, - DT_cxxFunctionDeclaredType, - DT_cxxFunctionDefinition, - DT_cxxFunctionDestructor, - DT_cxxFunctionDetail, - DT_cxxFunctionNameLookup, - DT_cxxFunctionParameter, - DT_cxxFunctionParameterDeclarationName, - DT_cxxFunctionParameterDeclaredType, - DT_cxxFunctionParameterDefaultValue, - DT_cxxFunctionParameters, - DT_cxxFunctionPrototype, - DT_cxxFunctionPureVirtual, - DT_cxxFunctionReimplemented, - DT_cxxFunctionScopedName, - DT_cxxFunctionStorageClassSpecifierStatic, - DT_cxxFunctionVirtual, - DT_cxxTypedef, - DT_cxxTypedefAccessSpecifier, - DT_cxxTypedefAPIItemLocation, - DT_cxxTypedefDeclarationFile, - DT_cxxTypedefDeclarationFileLine, - DT_cxxTypedefDefinition, - DT_cxxTypedefDetail, - DT_cxxTypedefNameLookup, - DT_cxxTypedefScopedName, - DT_cxxVariable, - DT_cxxVariableAccessSpecifier, - DT_cxxVariableAPIItemLocation, - DT_cxxVariableDeclarationFile, - DT_cxxVariableDeclarationFileLine, - DT_cxxVariableDeclaredType, - DT_cxxVariableDefinition, - DT_cxxVariableDetail, - DT_cxxVariableNameLookup, - DT_cxxVariablePrototype, - DT_cxxVariableReimplemented, - DT_cxxVariableScopedName, - DT_cxxVariableStorageClassSpecifierStatic, - DT_data, - DT_dataabout, - DT_dd, - DT_dl, - DT_dlentry, - DT_dt, - DT_entry, - DT_fig, - DT_i, - DT_image, - DT_keyword, - DT_keywords, - DT_li, - DT_link, - DT_linktext, - DT_lq, - DT_map, - DT_mapref, - DT_metadata, - DT_note, - DT_ol, - DT_othermeta, - DT_p, - DT_parameter, - DT_permissions, - DT_ph, - DT_platform, - DT_pre, - DT_prodinfo, - DT_prodname, - DT_prolog, - DT_publisher, - DT_qmlAttached, - DT_qmlDetail, - DT_qmlImportModule, - DT_qmlInheritedBy, - DT_qmlInherits, - DT_qmlInstantiates, - DT_qmlMethod, - DT_qmlMethodDef, - DT_qmlMethodDetail, - DT_qmlName, - DT_qmlProperty, - DT_qmlPropertyDef, - DT_qmlPropertyDetail, - DT_qmlPropertyGroup, - DT_qmlPropertyGroupDef, - DT_qmlPropertyGroupDetail, - DT_qmlQualifier, - DT_qmlSignal, - DT_qmlSignalDef, - DT_qmlSignalDetail, - DT_qmlSignalHandler, - DT_qmlSignalHandlerDEf, - DT_qmlSignalHandlerDetail, - DT_qmlSignature, - DT_qmlSince, - DT_qmlType, - DT_qmlTypeDef, - DT_qmlTypeDetail, - DT_relatedLinks, - DT_resourceid, - DT_revised, - DT_row, - DT_section, - DT_sectiondiv, - DT_shortdesc, - DT_simpletable, - DT_source, - DT_stentry, - DT_sthead, - DT_strow, - DT_sub, - DT_sup, - DT_table, - DT_tbody, - DT_tgroup, - DT_thead, - DT_title, - DT_tm, - DT_topic, - DT_topicmeta, - DT_topicref, - DT_tt, - DT_u, - DT_uicontrol, - DT_ul, - DT_unknown, - DT_vrm, - DT_vrmlist, - DT_xref, - DT_LAST - }; - -public: - DitaXmlGenerator(); - ~DitaXmlGenerator(); - - virtual void initializeGenerator(const Config& config) Q_DECL_OVERRIDE; - virtual void terminateGenerator() Q_DECL_OVERRIDE; - virtual QString format() Q_DECL_OVERRIDE; - virtual bool canHandleFormat(const QString& format) Q_DECL_OVERRIDE; - virtual void generateDocs() Q_DECL_OVERRIDE; - - QString protectEnc(const QString& string); - static QString protect(const QString& string, const QString& encoding = "ISO-8859-1"); - static QString cleanRef(const QString& ref); - static QString sinceTitle(int i) { return sinceTitles[i]; } - -protected: - virtual int generateAtom(const Atom* atom, - const Node* relative, - CodeMarker* marker) Q_DECL_OVERRIDE; - virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker) Q_DECL_OVERRIDE; - virtual void generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker) Q_DECL_OVERRIDE; - virtual void generateDocNode(DocNode* dn, CodeMarker* marker) Q_DECL_OVERRIDE; - virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker) Q_DECL_OVERRIDE; - virtual QString fileExtension() const Q_DECL_OVERRIDE; - virtual QString guidForNode(const Node* node); - virtual QString linkForNode(const Node* node, const Node* relative); - - void writeXrefListItem(const QString& link, const QString& text); - QString fullQualification(const Node* n); - - void writeCharacters(const QString& text); - void writeDerivations(const ClassNode* cn); - void writeLocation(const Node* n); - void writeFunctions(const Section& s, - const InnerNode* parent, - CodeMarker* marker, - const QString& attribute = QString()); - void writeNestedClasses(const Section& s, const Node* n); - void replaceTypesWithLinks(const Node* n, const InnerNode* parent, QString& src); - void writeParameters(const FunctionNode* fn, const InnerNode* parent, CodeMarker* marker); - void writeEnumerations(const Section& s, - CodeMarker* marker, - const QString& attribute = QString()); - void writeTypedefs(const Section& s, - CodeMarker* marker, - const QString& attribute = QString()); - void writeDataMembers(const Section& s, - CodeMarker* marker, - const QString& attribute = QString()); - void writeProperties(const Section& s, - CodeMarker* marker, - const QString& attribute = QString()); - void writeMacros(const Section& s, - CodeMarker* marker, - const QString& attribute = QString()); - void writePropertyParameter(const QString& tag, const NodeList& nlist); - void writeRelatedLinks(const Node* dn); - void writeLink(const Node* node, const QString& tex, const QString& role); - void writeProlog(const InnerNode* inner); - bool writeMetadataElement(const InnerNode* inner, - DitaXmlGenerator::DitaTag t, - bool force=true); - bool writeMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t); - void writeHrefAttribute(const QString& href); - QString getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t); - QStringList getMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t); - -private: - enum SubTitleSize { SmallSubTitle, LargeSubTitle }; - - const QPair anchorForNode(const Node* node); - void generateHeader(const Node* node, const QString& name); - void generateBrief(const Node* node, CodeMarker* marker); - void generateTableOfContents(const Node* node, - CodeMarker* marker, - Doc::Sections sectioningUnit, - int numColumns, - const Node* relative = 0); - void generateLowStatusMembers(InnerNode* inner, CodeMarker* marker, CodeMarker::Status status); - void generateClassHierarchy(const Node* relative, NodeMap& classMap); - void generateAnnotatedList(const Node* relative, CodeMarker* marker, const NodeMap& nodeMap); - void generateAnnotatedList(const Node* relative, CodeMarker* marker, const NodeList& nodes); - void generateCompactList(ListType listType, - const Node* relative, - const NodeMap& classMap, - bool includeAlphabet, - QString commonPrefix); - void generateFunctionIndex(const Node* relative); - void generateLegaleseList(const Node* relative, CodeMarker* marker); - void generateOverviewList(const Node* relative); - - void generateQmlSummary(const Section& section, - const Node* relative, - CodeMarker* marker); - void generateQmlItem(const Node* node, - const Node* relative, - CodeMarker* marker, - bool summary); - void startQmlProperty(QmlPropertyNode* qpn, - const InnerNode* relative, - CodeMarker* marker); - void writeQmlRef(DitaTag tag, - Node* node, - const InnerNode* relative, - CodeMarker* marker); - void generateDetailedQmlMember(Node* node, - const InnerNode* relative, - CodeMarker* marker); - void generateQmlInherits(QmlClassNode* qcn, CodeMarker* marker) Q_DECL_OVERRIDE; - void generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker) Q_DECL_OVERRIDE; - void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker); - void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker); - void generateQmlModuleDef(QmlClassNode* qcn); - void generateQmlSince(const Node* node); - - void generateSection(const NodeList& nl, - const Node* relative, - CodeMarker* marker, - CodeMarker::SynopsisStyle style); - QString getMarkedUpSynopsis(const Node* node, - const Node* relative, - CodeMarker* marker, - CodeMarker::SynopsisStyle style); - void generateSectionInheritedList(const Section& section, const Node* relative); - void writeText(const QString& markedCode, const Node* relative); - - void generateFullName(const Node* apparentNode, const Node* relative, const Node* actualNode = 0); - void generateLink(const Atom* atom, CodeMarker* marker); - void generateStatus(const Node* node, CodeMarker* marker); - - QString getLink(const Atom *atom, const Node *relative, const Node** node); - QString getAutoLink(const Atom *atom, const Node *relative, const Node** node); - - QString registerRef(const QString& ref); - virtual QString fileBase(const Node *node) const Q_DECL_OVERRIDE; - QString fileName(const Node *node); - static int hOffset(const Node *node); - static bool isThreeColumnEnumValueTable(const Atom *atom); -#ifdef GENERATE_MAC_REFS - void generateMacRef(const Node* node, CodeMarker* marker); -#endif - void beginLink(const QString& link); - void endLink(); - QString writeGuidAttribute(QString text); - void writeGuidAttribute(Node* node); - QString lookupGuid(QString text); - QString lookupGuid(const QString& fileName, const QString& text); - GuidMap* lookupGuidMap(const QString& fileName); - virtual void beginSubPage(const InnerNode* node, const QString& fileName) Q_DECL_OVERRIDE; - virtual void endSubPage() Q_DECL_OVERRIDE; - virtual void generateInnerNode(InnerNode* node) Q_DECL_OVERRIDE; - QXmlStreamWriter& xmlWriter(); - void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title); - void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref); - void writeDitaMap(); - void writeDitaMap(const DitaMapNode* node); - void writeStartTag(DitaTag t); - bool writeEndTag(DitaTag t=DT_NONE); - DitaTag currentTag(); - void clearSectionNesting() { sectionNestingLevel = 0; } - int enterDesc(DitaTag tag, const QString& outputclass, const QString& title); - int enterSection(const QString& outputclass, const QString& title); - int leaveSection(); - bool inSection() const { return (sectionNestingLevel > 0); } - int currentSectionNestingLevel() const { return sectionNestingLevel; } - QStringList metadataDefault(DitaTag t) const; - QString stripMarkup(const QString& src) const; - Node* collectNodesByTypeAndSubtype(const InnerNode* parent); - void writeDitaRefs(const DitaRefList& ditarefs); - void writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle, Node* headingnode = 0); - bool isDuplicate(NodeMultiMap* nmm, const QString& key, Node* node); - void debugPara(const QString& t); - QString ditaXmlHref(Node* n); - -private: - /* - These flags indicate which elements the generator - is currently outputting. - */ - bool inDetailedDescription; - bool inLegaleseText; - bool inObsoleteLink; - bool inTableBody; - - bool noLinks; - bool obsoleteLinks; - - int divNestingLevel; - int sectionNestingLevel; - int tableColumnCount; - int currentColumn; - - QRegExp funcLeftParen; - QString style; - QString postHeader; - QString postPostHeader; - QString footer; - QString address; - bool pleaseGenerateMacRef; - QString project; - QString projectDescription; - QString projectUrl; - QString navigationLinks; - QString version; - QStringList vrm; - QStringList stylesheets; - QStringList customHeadElements; - QMap refMap; - QMap name2guidMap; - GuidMaps guidMaps; - static int id; - static QString ditaTags[]; - QStack xmlWriterStack; - QStack tagStack; - ConfigVarMultimap metadataDefaults; - QVector nodeTypeMaps; - QVector nodeSubtypeMaps; - QVector pageTypeMaps; -}; - -#define DITAXMLGENERATOR_ADDRESS "address" -#define DITAXMLGENERATOR_FOOTER "footer" -#define DITAXMLGENERATOR_GENERATEMACREFS "generatemacrefs" -#define DITAXMLGENERATOR_POSTHEADER "postheader" -#define DITAXMLGENERATOR_POSTPOSTHEADER "postpostheader" -#define DITAXMLGENERATOR_STYLE "style" -#define DITAXMLGENERATOR_STYLESHEETS "stylesheets" -#define DITAXMLGENERATOR_CUSTOMHEADELEMENTS "customheadelements" - -QT_END_NAMESPACE - -#endif diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 75bfa5033b..614ba37f49 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -38,7 +38,6 @@ #include #include "codemarker.h" #include "config.h" -#include "ditaxmlgenerator.h" #include "doc.h" #include "editdistance.h" #include "generator.h" diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 186fd3195b..443d3e7288 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -38,7 +38,6 @@ #include "config.h" #include "cppcodemarker.h" #include "cppcodeparser.h" -#include "ditaxmlgenerator.h" #include "doc.h" #include "htmlgenerator.h" #include "location.h" @@ -595,7 +594,7 @@ int main(int argc, char **argv) QmlCodeMarker qmlMarker; HtmlGenerator htmlGenerator; - DitaXmlGenerator ditaxmlGenerator; + //DitaXmlGenerator ditaxmlGenerator; QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::translate("qdoc", "Qt documentation generator")); diff --git a/src/tools/qdoc/qdoc.pro b/src/tools/qdoc/qdoc.pro index 7ec4b4f726..f0df113af8 100644 --- a/src/tools/qdoc/qdoc.pro +++ b/src/tools/qdoc/qdoc.pro @@ -26,7 +26,6 @@ HEADERS += atom.h \ config.h \ cppcodemarker.h \ cppcodeparser.h \ - ditaxmlgenerator.h \ doc.h \ editdistance.h \ generator.h \ @@ -52,7 +51,6 @@ SOURCES += atom.cpp \ config.cpp \ cppcodemarker.cpp \ cppcodeparser.cpp \ - ditaxmlgenerator.cpp \ doc.cpp \ editdistance.cpp \ generator.cpp \ -- cgit v1.2.3