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(); //