From 4051e1cfc7f5d8a7017ca4ff7b30de483950a59b Mon Sep 17 00:00:00 2001
From: Martin Smith
Date: Tue, 7 Sep 2010 09:13:59 +0200
Subject: qdoc: Updated with current dita xml generation code from
oslo-staging-1.
---
tools/qdoc3/ditaxmlgenerator.cpp | 1250 +++++++++++++++++++++-----------------
tools/qdoc3/ditaxmlgenerator.h | 22 +-
tools/qdoc3/node.cpp | 4 +-
tools/qdoc3/pagegenerator.cpp | 10 +
4 files changed, 717 insertions(+), 569 deletions(-)
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index a83a321..3d1c53e 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
@@ -378,6 +377,7 @@ DitaXmlGenerator::DitaXmlGenerator()
inContents(false),
inSectionHeading(false),
inTableHeader(false),
+ inTableBody(false),
numTableRows(0),
threeColumnEnumValueTable(true),
offlineDocs(true),
@@ -385,7 +385,8 @@ DitaXmlGenerator::DitaXmlGenerator()
myTree(0),
slow(false),
obsoleteLinks(false),
- noLinks(0)
+ noLinks(0),
+ tableColumnCount(0)
{
}
@@ -577,7 +578,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
int skipAhead = 0;
QString hx;
static bool in_para = false;
- QString guid;
+ QString guid, hc;
switch (atom->type()) {
case Atom::AbstractLeft:
@@ -649,37 +650,29 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeCharacters(protectEnc(plainCode(atom->string())));
}
else {
- writer.writeCharacters(highlightedCode(atom->string(), marker, relative));
+ writeText(atom->string(), marker, relative);
}
writer.writeEndElement(); // sse writeStartElement() above
break;
case Atom::Code:
writer.writeStartElement("pre");
- writer.writeAttribute("outputclass","highlightedCode");
- writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,
- relative)));
+ writer.writeAttribute("outputclass","highlightedcode");
+ writeText(atom->string(), marker, relative);
writer.writeEndElement(); //
break;
-#ifdef QDOC_QML
case Atom::Qml:
writer.writeStartElement("pre");
- writer.writeAttribute("outputclass","highlightedCode");
- writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,
- relative)));
+ writer.writeAttribute("outputclass","highlightedcode");
+ writeText(atom->string(), marker, relative);
writer.writeEndElement(); // pre
break;
-#endif
case Atom::CodeNew:
writer.writeStartElement("p");
writer.writeCharacters("you can rewrite it as");
writer.writeEndElement(); //
writer.writeStartElement("pre");
- writer.writeAttribute("outputclass","highlightedCode");
- writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,
- relative)));
+ writer.writeAttribute("outputclass","highlightedcode");
+ writeText(atom->string(), marker, relative);
writer.writeEndElement(); //
break;
case Atom::CodeOld:
@@ -689,7 +682,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
// fallthrough
case Atom::CodeBad:
writer.writeStartElement("pre");
- writer.writeAttribute("outputclass","highlightedCode");
+ writer.writeAttribute("outputclass","highlightedcode");
writer.writeCharacters(trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string())))));
writer.writeEndElement(); //
break;
@@ -1075,51 +1068,53 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
- writer.writeStartElement("table");
+ writer.writeStartElement("simpletable");
writer.writeAttribute("outputclass","valuelist");
- writer.writeStartElement("tr");
+ writer.writeStartElement("sthead");
if (++numTableRows % 2 == 1)
writer.writeAttribute("outputclass","odd");
else
writer.writeAttribute("outputclass","even");
- writer.writeStartElement("th");
+ writer.writeStartElement("stentry");
writer.writeCharacters("Constant");
- writer.writeEndElement(); //
- writer.writeStartElement("th");
+ writer.writeEndElement(); //
+ writer.writeStartElement("stentry");
writer.writeCharacters("Value");
- writer.writeEndElement(); //
- writer.writeStartElement("th");
+ writer.writeEndElement(); //
+ writer.writeStartElement("stentry");
writer.writeCharacters("Description");
- writer.writeEndElement(); //
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
}
else {
- writer.writeStartElement("table");
+ writer.writeStartElement("simpletable");
writer.writeAttribute("outputclass","valuelist");
- writer.writeStartElement("tr");
- writer.writeStartElement("th");
+ writer.writeStartElement("sthead");
+ writer.writeStartElement("stentry");
writer.writeCharacters("Constant");
- writer.writeEndElement(); //
- writer.writeStartElement("th");
+ writer.writeEndElement(); //
+ writer.writeStartElement("stentry");
writer.writeCharacters("Value");
- writer.writeEndElement(); //
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
}
}
else {
writer.writeStartElement("ol");
if (atom->string() == ATOM_LIST_UPPERALPHA)
- writer.writeAttribute("type","A");
+ writer.writeAttribute("outputclass","upperalpha");
else if (atom->string() == ATOM_LIST_LOWERALPHA)
- writer.writeAttribute("type","a");
+ writer.writeAttribute("outputclass","loweralpha");
else if (atom->string() == ATOM_LIST_UPPERROMAN)
- writer.writeAttribute("type","I");
+ writer.writeAttribute("outputclass","upperroman");
else if (atom->string() == ATOM_LIST_LOWERROMAN)
- writer.writeAttribute("type","i");
+ writer.writeAttribute("outputclass","lowerroman");
else // (atom->string() == ATOM_LIST_NUMERIC)
- writer.writeAttribute("type","1");
- if (atom->next() != 0 && atom->next()->string().toInt() != 1)
+ writer.writeAttribute("outputclass","numeric");
+ if (atom->next() != 0 && atom->next()->string().toInt() != 1) {
+ // I don't think this attribute is supported.
writer.writeAttribute("start",atom->next()->string());
+ }
}
break;
case Atom::ListItemNumber:
@@ -1130,15 +1125,15 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeStartElement("dt");
}
else { // (atom->string() == ATOM_LIST_VALUE)
- writer.writeStartElement("tr");
- writer.writeStartElement("td");
+ writer.writeStartElement("strow");
+ writer.writeStartElement("stentry");
writer.writeAttribute("outputclass","topAlign");
writer.writeStartElement("tt");
writer.writeCharacters(protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
relative))));
writer.writeEndElement(); //
- writer.writeEndElement(); //
- writer.writeStartElement("td");
+ writer.writeEndElement(); //
+ writer.writeStartElement("stentry");
writer.writeAttribute("outputclass","topAlign");
QString itemValue;
@@ -1167,8 +1162,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
}
else if (atom->string() == ATOM_LIST_VALUE) {
if (threeColumnEnumValueTable) {
- writer.writeEndElement(); //
- writer.writeStartElement("td");
+ writer.writeEndElement(); //
+ writer.writeStartElement("stentry");
writer.writeAttribute("outputclass","topAlign");
if (matchAhead(atom, Atom::ListItemRight))
writer.writeCharacters(" ");
@@ -1185,8 +1180,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeEndElement(); //
}
else if (atom->string() == ATOM_LIST_VALUE) {
- writer.writeEndElement(); //
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
}
else {
writer.writeEndElement(); //
@@ -1200,7 +1195,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeEndElement(); //
}
else if (atom->string() == ATOM_LIST_VALUE) {
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
}
else {
writer.writeEndElement(); //
@@ -1264,61 +1259,80 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
}
break;
case Atom::TableLeft:
- if (in_para) {
- writer.writeEndElement(); //
- in_para = false;
+ {
+ if (in_para) {
+ writer.writeEndElement(); //
+ in_para = false;
+ }
+ writer.writeStartElement("table");
+ writer.writeAttribute("outputclass","generic");
+ numTableRows = 0;
+ if (tableColumnCount != 0) {
+ qDebug() << "ERROR: Nested tables!";
+ tableColumnCount = 0;
+ }
+ const Atom* t = atom->next();
+ while ((t->type() != Atom::TableHeaderRight) &&
+ (t->type() != Atom::TableRowRight) &&
+ (t->type() != Atom::TableRight)) {
+ if (t->type() == Atom::TableItemLeft)
+ ++tableColumnCount;
+ t = t->next();
+ }
+ writer.writeStartElement("tgroup");
+ writer.writeAttribute("cols",QString::number(tableColumnCount));
}
- writer.writeStartElement("table");
- writer.writeAttribute("outputclass","generic");
- numTableRows = 0;
break;
case Atom::TableRight:
+ writer.writeEndElement(); //
+ writer.writeEndElement(); //
writer.writeEndElement(); //
+ tableColumnCount = 0;
break;
case Atom::TableHeaderLeft:
writer.writeStartElement("thead");
- writer.writeStartElement("tr");
+ writer.writeStartElement("row");
writer.writeAttribute("outputclass","qt-style topAlign");
inTableHeader = true;
+ inTableBody = false;
break;
case Atom::TableHeaderRight:
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
if (matchAhead(atom, Atom::TableHeaderLeft)) {
skipAhead = 1;
- writer.writeStartElement("tr");
+ writer.writeStartElement("row");
writer.writeAttribute("outputclass","qt-style topAlign");
}
else {
writer.writeEndElement(); //
inTableHeader = false;
+ inTableBody = true;
+ writer.writeStartElement("tbody");
}
break;
case Atom::TableRowLeft:
- writer.writeStartElement("tr");
+ if (!inTableHeader && !inTableBody) {
+ inTableBody = true;
+ writer.writeStartElement("tbody");
+ }
+ writer.writeStartElement("row");
if (++numTableRows % 2 == 1)
writer.writeAttribute("outputclass","odd topAlign");
else
writer.writeAttribute("outputclass","even topAlign");
break;
case Atom::TableRowRight:
- writer.writeEndElement(); // \n";
+ writer.writeEndElement(); // \n";
break;
case Atom::TableItemLeft:
{
if (inTableHeader)
- writer.writeStartElement("th");
+ writer.writeStartElement("entry");
else
- writer.writeStartElement("td");
+ writer.writeStartElement("entry");
QStringList spans = atom->string().split(",");
if (spans.size() == 2) {
-#if zzz
-
- if (spans.at(0) != "1")
- out() << " colspan=\"" << spans.at(0) << "\"";
- if (spans.at(1) != "1")
- out() << " rowspan=\"" << spans.at(1) << "\"";
-#endif
if (!inTableHeader)
writer.writeStartElement("p");
}
@@ -1328,10 +1342,10 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
break;
case Atom::TableItemRight:
if (inTableHeader)
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
else {
writer.writeEndElement(); //
- writer.writeEndElement(); //
+ writer.writeEndElement(); //
}
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
@@ -1384,12 +1398,10 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
writer.writeCharacters(protectEnc(atom->string()));
writer.writeEndElement(); //
break;
-#ifdef QDOC_QML
case Atom::QmlText:
case Atom::EndQmlText:
// don't do anything with these. They are just tags.
break;
-#endif
default:
// unknownAtom(atom);
break;
@@ -1398,7 +1410,9 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
}
/*!
- Generate a reference page for a C++ class.
+ Generate a element (and all the stuff inside it)
+ for the C++ class represented by \a innerNode. \a marker is
+ for marking up the code. I don't know what that means exactly.
*/
void
DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* marker)
@@ -1432,7 +1446,9 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
writer.writeCharacters(fullTitle);
writer.writeEndElement(); //
- generateBrief(inner, marker);
+ generateBrief(inner, marker); //
+
+ // not included:
writer.writeStartElement(CXXCLASSDETAIL);
writer.writeStartElement(CXXCLASSDEFINITION);
@@ -1445,7 +1461,10 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
writer.writeAttribute("value","abstract");
writer.writeEndElement(); //
}
- writeDerivations(cn, marker);
+ writeDerivations(cn, marker); //
+
+ // not included:
+
writeLocation(cn);
writer.writeEndElement(); //
writer.writeStartElement(APIDESC);
@@ -1456,12 +1475,18 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
writer.writeCharacters("Detailed Description");
writer.writeEndElement(); //
generateBody(inner, marker);
- // generateAlsoList(inner, marker);
+ // generateAlsoList(inner, marker);
}
writer.writeEndElement(); //
+
+ // not included: , , or
+
writer.writeEndElement(); //
+ // not included:
+ // not included:
+
sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
@@ -1483,199 +1508,11 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
}
++s;
}
- 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();
- if (shortVersion.count(QChar('.')) == 2)
- shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
- if (!shortVersion.isEmpty()) {
- if (project == "QSA")
- shortVersion = "QSA " + shortVersion + ": ";
- else
- shortVersion = "Qt " + shortVersion + ": ";
- }
-
- out() << " " << shortVersion << protectEnc(title) << "\n";
-
-#if 0
- out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
- generateBreadCrumbs(title,node,marker);
- out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
-#endif
-
- sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
- generateTableOfContents(inner,marker,§ions);
- generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
-
-#ifdef QDOC_QML
- if (cn && !cn->qmlElement().isEmpty()) {
- generateInstantiatedBy(cn,marker);
- }
-#endif
-
- generateBrief(inner, marker);
- generateIncludes(inner, marker);
- generateStatus(inner, marker);
- if (cn) {
- generateInherits(cn, marker);
- generateInheritedBy(cn, marker);
- }
- generateThreadSafeness(inner, marker);
- generateSince(inner, marker);
-
- out() << "\n";
-
- QString membersLink = generateListOfAllMemberFile(inner, marker);
- if (!membersLink.isEmpty())
- out() << "- "
- << "List of all members, including inherited members
\n";
-
- QString obsoleteLink = generateLowStatusMemberFile(inner,
- marker,
- CodeMarker::Obsolete);
- if (!obsoleteLink.isEmpty())
- out() << "- "
- << "Obsolete members
\n";
-
- QString compatLink = generateLowStatusMemberFile(inner,
- marker,
- CodeMarker::Compat);
- if (!compatLink.isEmpty())
- out() << "- "
- << "Qt 3 support members
\n";
-
- out() << "
\n";
-
- bool needOtherSection = false;
-
- /*
- sections is built above for the call to generateTableOfContents().
- */
- s = sections.begin();
- while (s != sections.end()) {
- if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
- if (!s->inherited.isEmpty())
- needOtherSection = true;
- }
- else {
- if (!s->members.isEmpty()) {
- out() << "
\n";
- out() << "\n";
- out() << "" << protectEnc((*s).name) << "
\n";
- generateSection(s->members, inner, marker, CodeMarker::Summary);
- }
- if (!s->reimpMembers.isEmpty()) {
- QString name = QString("Reimplemented ") + (*s).name;
- out() << "
\n";
- out() << "\n";
- out() << "" << protectEnc(name) << "
\n";
- generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
- }
-
- if (!s->inherited.isEmpty()) {
- out() << "\n";
- generateSectionInheritedList(*s, inner, marker, true);
- out() << "
\n";
- }
- }
- ++s;
- }
-
- if (needOtherSection) {
- out() << "Additional Inherited Members
\n"
- "\n";
-
- s = sections.begin();
- while (s != sections.end()) {
- if (s->members.isEmpty() && !s->inherited.isEmpty())
- generateSectionInheritedList(*s, inner, marker);
- ++s;
- }
- out() << "
\n";
- }
-
- out() << "\n";
-
- if (!inner->doc().isEmpty()) {
- out() << "
\n"
- << "\n" // QTBUG-9504
- << "
" << "Detailed Description" << "
\n";
- generateBody(inner, marker);
- out() << "\n"; // QTBUG-9504
- generateAlsoList(inner, marker);
- }
-
- sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
- s = sections.begin();
- while (s != sections.end()) {
- out() << "
\n";
- if (!(*s).divClass.isEmpty())
- out() << "\n"; // QTBUG-9504
- out() << "" << protectEnc((*s).name) << "
\n";
-
- NodeList::ConstIterator m = (*s).members.begin();
- while (m != (*s).members.end()) {
- if ((*m)->access() != Node::Private) { // ### check necessary?
- if ((*m)->type() != Node::Class)
- generateDetailedMember(*m, inner, marker);
- else {
- out() << " class ";
- generateFullName(*m, inner, marker);
- out() << "
";
- generateBrief(*m, marker, inner);
- }
- QStringList names;
- names << (*m)->name();
- if ((*m)->type() == Node::Function) {
- const FunctionNode *func = reinterpret_cast(*m);
- if (func->metaness() == FunctionNode::Ctor ||
- func->metaness() == FunctionNode::Dtor ||
- func->overloadNumber() != 1)
- names.clear();
- }
- else if ((*m)->type() == Node::Property) {
- const PropertyNode *prop = reinterpret_cast(*m);
- if (!prop->getters().isEmpty() &&
- !names.contains(prop->getters().first()->name()))
- names << prop->getters().first()->name();
- if (!prop->setters().isEmpty())
- names << prop->setters().first()->name();
- if (!prop->resetters().isEmpty())
- names << prop->resetters().first()->name();
- }
- else if ((*m)->type() == Node::Enum) {
- const EnumNode *enume = reinterpret_cast(*m);
- if (enume->flagsType())
- names << enume->flagsType()->name();
+ // not included:
- foreach (const QString &enumName,
- enume->doc().enumItemNames().toSet() -
- enume->doc().omitEnumItemNames().toSet())
- names << plainCode(marker->markedUpEnumValue(enumName,
- enume));
- }
- }
- ++m;
- }
- if (!(*s).divClass.isEmpty())
- out() << "\n"; // QTBUG-9504
- ++s;
+ writer.writeEndElement(); //
}
-#endif
}
/*!
@@ -1684,14 +1521,18 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
*/
void DitaXmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
{
- return; // zzz
-
SubTitleSize subTitleSize = LargeSubTitle;
QList sections;
QList::const_iterator s;
QString fullTitle = fake->fullTitle();
QString htmlTitle = fullTitle;
+ /*
+ NOTE: For now we only handle \page elements.
+ */
+ if (fake->subType() != Node::Page)
+ return;
+
if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
subTitleSize = SmallSubTitle;
htmlTitle += " (" + fake->subTitle() + ")";
@@ -1702,7 +1543,30 @@ void DitaXmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker
}
generateHeader(fake);
-
+
+ if (fake->subType() == Node::Page) {
+ writer.writeStartElement("topic");
+ writer.writeAttribute("id",fake->guid());
+ writer.writeStartElement("title");
+ writer.writeCharacters(fullTitle);
+ writer.writeEndElement(); //
+
+ generateBrief(fake, marker); //
+
+ if (!fake->doc().isEmpty()) {
+ writer.writeStartElement("body");
+ writer.writeStartElement("p");
+ writer.writeAttribute("outputclass","h2");
+ writer.writeCharacters("Detailed Description");
+ writer.writeEndElement(); //
+ generateBody(fake, marker);
+ writer.writeEndElement(); //