From e9e93fe79d7451f05a714241f759c557a455de67 Mon Sep 17 00:00:00 2001
From: Martin Smith
Date: Tue, 15 Jun 2010 14:54:37 +0200
Subject: doc: Added more DITA output to the XML generator
Task-number: QTBUG-11391
---
tools/qdoc3/ditaxmlgenerator.cpp | 542 ++++++++++-----------------------------
tools/qdoc3/ditaxmlgenerator.h | 45 +---
tools/qdoc3/node.cpp | 35 +++
tools/qdoc3/node.h | 2 +
4 files changed, 178 insertions(+), 446 deletions(-)
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index 2c578f0..197bc13 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -501,6 +501,34 @@ QString DitaXmlGenerator::format()
}
/*!
+ Create a new GUID, write it to the XML stream
+ as an "id" attribute, and return it.
+ */
+QString DitaXmlGenerator::writeGuidAttribute(QString text)
+{
+ QString guid = QUuid::createUuid().toString();
+ name2guidMap.insert(text,guid);
+ writer.writeAttribute("id",guid);
+ return guid;
+}
+
+/*!
+ Looks up \a text in the GUID map. It 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.find(text);
+ if (i != name2guidMap.end())
+ return i.value();
+ QString guid = QUuid::createUuid().toString();
+ name2guidMap.insert(text,guid);
+ return guid;
+}
+
+/*!
This is where the DITA XML files are written.
\note The file generation is done in the base class,
PageGenerator::generateTree().
@@ -521,9 +549,6 @@ void DitaXmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
findAllFunctions(tree->root());
findAllLegaleseTexts(tree->root());
findAllNamespaces(tree->root());
-#ifdef ZZZ_QDOC_QML
- findAllQmlClasses(tree->root());
-#endif
findAllSince(tree->root());
PageGenerator::generateTree(tree, marker);
@@ -552,7 +577,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
int skipAhead = 0;
QString hx;
static bool in_para = false;
-
+ QString guid;
+
switch (atom->type()) {
case Atom::AbstractLeft:
break;
@@ -922,10 +948,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
s = sections.constBegin();
while (s != sections.constEnd()) {
if (!(*s).members.isEmpty()) {
- QString guid = QUuid::createUuid().toString();
- guidMap.insert(Doc::canonicalTitle((*s).name),guid);
writer.writeStartElement("p");
- writer.writeAttribute("id",guid);
+ writeGuidAttribute(Doc::canonicalTitle((*s).name));
writer.writeAttribute("outputclass","h3");
writer.writeCharacters(protectEnc((*s).name));
writer.writeEndElement(); //
@@ -1203,10 +1227,11 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeCharacters(atom->string());
break;
case Atom::SectionLeft:
-#if zzz
- out() << "\n";
-#endif
+ writer.writeStartElement("p");
+ writeGuidAttribute(Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
+ writer.writeAttribute("outputclass","target");
+ writer.writeCharacters(protectEnc(Text::sectionHeading(atom).toString()));
+ writer.writeEndElement(); //
break;
case Atom::SectionRight:
// nothing
@@ -1338,20 +1363,23 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
}
break;
case Atom::Target:
-#if zzz
- out() << "string()) << "\">";
-#endif
+ writer.writeStartElement("p");
+ writeGuidAttribute(Doc::canonicalTitle(atom->string()));
+ writer.writeAttribute("outputclass","target");
+ writer.writeCharacters(protectEnc(atom->string()));
+ writer.writeEndElement(); //
break;
case Atom::UnhandledFormat:
-#if zzz
- out() << "<Missing DITAXML>";
-#endif
+ writer.writeStartElement("b");
+ writer.writeAttribute("outputclass","redFont");
+ writer.writeCharacters("<Missing DITAXML>");
+ writer.writeEndElement(); //
break;
case Atom::UnknownCommand:
-#if zzz
- out() << "\\" << protectEnc(atom->string())
- << "
";
-#endif
+ writer.writeStartElement("b");
+ writer.writeAttribute("outputclass","redFont code");
+ writer.writeCharacters(protectEnc(atom->string()));
+ writer.writeEndElement(); //
break;
#ifdef QDOC_QML
case Atom::QmlText:
@@ -1375,7 +1403,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
QList sections;
QList::ConstIterator s;
- const ClassNode *classe = 0;
+ const ClassNode* cn = 0;
const NamespaceNode *namespasse = 0;
QString title;
@@ -1388,43 +1416,51 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
- classe = static_cast(inner);
+ cn = static_cast(inner);
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
title = rawTitle + " Class Reference";
- }
-
- Text subtitleText;
- if (rawTitle != fullTitle)
- subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
- << Atom(Atom::LineBreak);
- generateHeader(inner);
+ generateHeader(inner);
- writer.writeStartElement(CXXCLASS);
- writer.writeStartElement(APINAME);
- writer.writeCharacters(fullTitle);
- writer.writeEndElement(); // apiName
+ writer.writeStartElement(CXXCLASS);
+ writeGuidAttribute(fullTitle);
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(fullTitle);
+ writer.writeEndElement(); //
- generateBrief(inner, marker);
+ generateBrief(inner, marker);
- writer.writeStartElement(CXXCLASSDETAIL);
- writer.writeStartElement(APIDESC);
-
- if (!inner->doc().isEmpty()) {
- writer.writeStartElement("p");
- writer.writeAttribute("outputclass","h2");
- writer.writeCharacters("Detailed Description");
- writer.writeEndElement(); // p
- generateBody(inner, marker);
- // generateAlsoList(inner, marker);
- }
+ writer.writeStartElement(CXXCLASSDETAIL);
+ writer.writeStartElement(CXXCLASSDEFINITION);
+ writer.writeStartElement(CXXCLASSACCESSSPECIFIER);
+ writer.writeAttribute("value",inner->accessString());
+ writer.writeEndElement(); //
+ writeDerivations(cn, marker);
+ writeLocation(cn, marker);
+ writer.writeEndElement(); //
+ writer.writeStartElement(APIDESC);
+
+ if (!inner->doc().isEmpty()) {
+ writer.writeStartElement("p");
+ writer.writeAttribute("outputclass","h2");
+ writer.writeCharacters("Detailed Description");
+ writer.writeEndElement(); //
+ generateBody(inner, marker);
+ // generateAlsoList(inner, marker);
+ }
- writer.writeEndElement(); // apiDesc
- writer.writeEndElement(); // cxxClassDetail
- writer.writeEndElement(); // cxxClass
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
+ }
#ifdef WRITE_HTML
+ Text subtitleText;
+ if (rawTitle != fullTitle)
+ subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
+ << Atom(Atom::LineBreak);
+
QString shortVersion;
shortVersion = project + " " + shortVersion + ": ";
shortVersion = myTree->version();
@@ -1450,17 +1486,17 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
#ifdef QDOC_QML
- if (classe && !classe->qmlElement().isEmpty()) {
- generateInstantiatedBy(classe,marker);
+ if (cn && !cn->qmlElement().isEmpty()) {
+ generateInstantiatedBy(cn,marker);
}
#endif
generateBrief(inner, marker);
generateIncludes(inner, marker);
generateStatus(inner, marker);
- if (classe) {
- generateInherits(classe, marker);
- generateInheritedBy(classe, marker);
+ if (cn) {
+ generateInherits(cn, marker);
+ generateInheritedBy(cn, marker);
}
generateThreadSafeness(inner, marker);
generateSince(inner, marker);
@@ -1895,37 +1931,11 @@ void DitaXmlGenerator::generateHeader(const Node* node)
version = "0.6.0";
}
-#if 0
- writer.writeCharacters("\n\n");
-
- if (node && !node->doc().location().isEmpty()) {
- writer.writeCharacters("\n");
- }
-#endif
-
QString doctype = "";
writer.writeDTD(doctype);
writer.writeComment(node->doc().location().fileName());
-
-#if 0
- out() << "\n\n";
-
- if (node && !node->doc().location().isEmpty())
- out() << "\n";
- out().flush();
-#endif
}
void DitaXmlGenerator::generateTitle(const QString& title,
@@ -2173,37 +2183,6 @@ void DitaXmlGenerator::generateTableOfContents(const Node *node,
inLink = false;
}
-#if 0
-void DitaXmlGenerator::generateNavigationBar(const NavigationBar& bar,
- const Node *node,
- CodeMarker *marker)
-{
- if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
- bar.next.begin() != 0) {
- out() << "";
- if (bar.prev.begin() != 0) {
-#if 0
- out() << "[Prev: ";
- generateText(section.previousHeading(), node, marker);
- out() << "]\n";
-#endif
- }
- if (bar.current.begin() != 0) {
- out() << "[Home]\n";
- }
- if (bar.next.begin() != 0) {
- out() << "[Next: ";
- generateText(Text::sectionHeading(bar.next.begin()), node, marker);
- out() << "]\n";
- }
- out() << "
\n";
- }
-}
-#endif
-
QString DitaXmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
CodeMarker *marker)
{
@@ -2855,7 +2834,6 @@ void DitaXmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /
}
}
-#ifdef QDOC_NAME_ALIGNMENT
void DitaXmlGenerator::generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
@@ -3220,281 +3198,6 @@ QString DitaXmlGenerator::highlightedCode(const QString& markedCode,
return html;
}
-#else
-void DitaXmlGenerator::generateSectionList(const Section& section,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style)
-{
- if (!section.members.isEmpty()) {
- bool twoColumn = false;
- if (style == CodeMarker::SeparateList) {
- twoColumn = (section.members.count() >= 16);
- }
- else if (section.members.first()->type() == Node::Property) {
- twoColumn = (section.members.count() >= 5);
- }
- if (twoColumn)
- out() << "\n";
- if (++numTableRows % 2 == 1)
- out() << "";
- else
- out() << "
";
-
-// << "
";
- out() << "\n";
-
- int i = 0;
- NodeList::ConstIterator m = section.members.begin();
- while (m != section.members.end()) {
- if ((*m)->access() == Node::Private) {
- ++m;
- continue;
- }
-
- if (twoColumn && i == (int) (section.members.count() + 1) / 2)
- out() << " | \n";
-
- out() << "- ";
- if (style == CodeMarker::Accessors)
- out() << "";
- generateSynopsis(*m, relative, marker, style);
- if (style == CodeMarker::Accessors)
- out() << "";
- out() << "
\n";
- i++;
- ++m;
- }
- out() << " \n";
- if (twoColumn)
- out() << " |
\n
\n";
- }
-
- if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
- out() << "\n";
- generateSectionInheritedList(section, relative, marker);
- out() << "
\n";
- }
-}
-
-void DitaXmlGenerator::generateSectionInheritedList(const Section& section,
- const Node *relative,
- CodeMarker *marker)
-{
- QList >::ConstIterator p = section.inherited.begin();
- while (p != section.inherited.end()) {
- out() << "";
- out() << (*p).second << " ";
- if ((*p).second == 1) {
- out() << section.singularMember;
- } else {
- out() << section.pluralMember;
- }
- out() << " inherited from "
- << protectEnc(marker->plainFullName((*p).first, relative))
- << "\n";
- ++p;
- }
-}
-
-void DitaXmlGenerator::generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style)
-{
- QString marked = marker->markedUpSynopsis(node, relative, style);
- QRegExp templateTag("(<[^@>]*>)");
- if (marked.indexOf(templateTag) != -1) {
- QString contents = protectEnc(marked.mid(templateTag.pos(1),
- templateTag.cap(1).length()));
- marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
- contents);
- }
- marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])@param>"), "\\1\\2");
- marked.replace("<@param>", "");
- marked.replace("@param>", "");
-
- if (style == CodeMarker::Summary)
- marked.replace("@name>", "b>");
-
- if (style == CodeMarker::SeparateList) {
- QRegExp extraRegExp("<@extra>.*@extra>");
- extraRegExp.setMinimal(true);
- marked.replace(extraRegExp, "");
- } else {
- marked.replace("<@extra>", "");
- marked.replace("@extra>", "");
- }
-
- if (style != CodeMarker::Detailed) {
- marked.replace("<@type>", "");
- marked.replace("@type>", "");
- }
- out() << highlightedCode(marked, marker, relative);
-}
-
-QString DitaXmlGenerator::highlightedCode(const QString& markedCode,
- CodeMarker *marker,
- const Node *relative)
-{
- QString src = markedCode;
- QString html;
- QStringRef arg;
- QStringRef par1;
-
- const QChar charLangle = '<';
- const QChar charAt = '@';
-
- // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(@link>)"
- static const QString linkTag("link");
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
- const Node* node = CodeMarker::nodeForString(par1.toString());
- QString link = linkForNode(node, relative);
- addLink(link, arg, &html);
- }
- else {
- html += charLangle;
- html += charAt;
- }
- }
- else {
- html += src.at(i++);
- }
- }
-
- if (slow) {
- // is this block ever used at all?
- // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(@func>)"
- src = html;
- html = QString();
- static const QString funcTag("func");
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
- QString link = linkForNode(
- marker->resolveTarget(par1.toString(),
- myTree,
- relative),
- relative);
- addLink(link, arg, &html);
- par1 = QStringRef();
- }
- else {
- html += charLangle;
- html += charAt;
- }
- }
- else {
- html += src.at(i++);
- }
- }
- }
-
- // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(@\\2>)" tags
- src = html;
- html = QString();
- static const QString typeTags[] = { "type", "headerfile", "func" };
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- bool handled = false;
- for (int k = 0; k != 3; ++k) {
- if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
- par1 = QStringRef();
- QString link = linkForNode(
- marker->resolveTarget(arg.toString(), myTree, relative),
- relative);
- addLink(link, arg, &html);
- handled = true;
- break;
- }
- }
- if (!handled) {
- html += charLangle;
- html += charAt;
- }
- }
- else {
- html += src.at(i++);
- }
- }
-
- // replace all
- // "<@comment>" -> "