diff -r b72c6db6890b -r 5dc02b23752f tools/qdoc3/htmlgenerator.cpp
--- a/tools/qdoc3/htmlgenerator.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/tools/qdoc3/htmlgenerator.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -44,6 +44,7 @@
*/
#include "codemarker.h"
+#include "codeparser.h"
#include "helpprojectwriter.h"
#include "htmlgenerator.h"
#include "node.h"
@@ -54,10 +55,12 @@
#include you can rewrite it as For example, if you have code like"
+ out() << "
"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "
\n";
break;
#ifdef QDOC_QML
case Atom::Qml:
- out() << ""
+ out() << "
"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "
\n";
@@ -506,7 +531,7 @@
#endif
case Atom::CodeNew:
out() << ""
+ << "
"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "
\n";
@@ -515,9 +540,9 @@
out() << ""
- << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
- << "
\n";
+ out() << ""
+ << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
+ << "
\n";
break;
case Atom::FootnoteLeft:
// ### For now
@@ -574,7 +599,7 @@
generateAnnotatedList(relative, marker, nonCompatClasses);
}
else if (atom->string() == "classes") {
- generateCompactList(relative, marker, nonCompatClasses);
+ generateCompactList(relative, marker, nonCompatClasses, true);
}
else if (atom->string().contains("classesbymodule")) {
QString arg = atom->string().trimmed();
@@ -622,10 +647,10 @@
generateClassHierarchy(relative, marker, nonCompatClasses);
}
else if (atom->string() == "compatclasses") {
- generateCompactList(relative, marker, compatClasses);
+ generateCompactList(relative, marker, compatClasses, false);
}
else if (atom->string() == "obsoleteclasses") {
- generateCompactList(relative, marker, obsoleteClasses);
+ generateCompactList(relative, marker, obsoleteClasses, false);
}
else if (atom->string() == "functionindex") {
generateFunctionIndex(relative, marker);
@@ -634,10 +659,10 @@
generateLegaleseList(relative, marker);
}
else if (atom->string() == "mainclasses") {
- generateCompactList(relative, marker, mainClasses);
+ generateCompactList(relative, marker, mainClasses, true);
}
else if (atom->string() == "services") {
- generateCompactList(relative, marker, serviceClasses);
+ generateCompactList(relative, marker, serviceClasses, false);
}
else if (atom->string() == "overviews") {
generateOverviewList(relative, marker);
@@ -676,16 +701,23 @@
nsmap = newSinceMaps.find(atom->string());
NewClassMaps::const_iterator ncmap;
ncmap = newClassMaps.find(atom->string());
+ NewClassMaps::const_iterator nqcmap;
+ nqcmap = newQmlClassMaps.find(atom->string());
if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
QList" << protect((*s).name) << "
\n";
+ out() << "" << protectEnc((*s).name) << "
\n";
if (idx == Class)
- generateCompactList(0, marker, ncmap.value(), QString("Q"));
+ generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
+ else if (idx == QmlClass)
+ generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
else if (idx == MemberFunction) {
ParentMaps parentmaps;
ParentMaps::iterator pmap;
@@ -792,11 +826,11 @@
<< linkForNode(pmap.key(), 0)
<< "\">";
QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
- out() << protect(pieces.last());
+ out() << protectEnc(pieces.last());
out() << "" << ":
"; + out() << "
";
if (fileName.isEmpty()) {
out() << "[Missing image "
- << protect(atom->string()) << "]";
+ << protectEnc(atom->string()) << "]";
}
else {
- out() << "";
helpProjectWriter->addExtraFile(fileName);
}
@@ -836,13 +870,13 @@
case Atom::ImageText:
break;
case Atom::LegaleseLeft:
- out() << "
Constant | " - << "Value | " - << "Description |
---|
Constant | " + << "Value | " + << "Description |
---|
Constant | Value |
---|
Constant | Value | ||||
---|---|---|---|---|---|
"
- << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
+ out() << ""
+ << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
relative)))
- << " | ";
+ << " | ";
QString itemValue;
if (relative->type() == Node::Enum) {
@@ -936,7 +973,7 @@
if (itemValue.isEmpty())
out() << "?";
else
- out() << "" << protect(itemValue) << "";
+ out() << "" << protectEnc(itemValue) << "";
skipAhead = 1;
}
@@ -951,7 +988,7 @@
}
else if (atom->string() == ATOM_LIST_VALUE) {
if (threeColumnEnumValueTable) {
- out() << " | ";
+ out() << " | ";
if (matchAhead(atom, Atom::ListItemRight))
out() << " ";
}
@@ -981,7 +1018,7 @@
out() << "\n";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- out() << " | |
"; } if (matchAhead(atom, Atom::ParaLeft)) skipAhead = 1; @@ -1126,7 +1162,7 @@ if (inTableHeader) out() << ""; else - out() << ""; + out() << "
"; if (matchAhead(atom, Atom::ParaLeft)) skipAhead = 1; break; @@ -1163,11 +1199,11 @@ out() << "string()) << "\">"; break; case Atom::UnhandledFormat: - out() << "<Missing HTML>"; + out() << "<Missing HTML>"; break; case Atom::UnknownCommand: - out() << "\\" << protect(atom->string())
- << "
";
+ out() << "\\" << protectEnc(atom->string())
+ << "
";
break;
#ifdef QDOC_QML
case Atom::QmlText:
@@ -1197,7 +1233,7 @@
namespasse = static_cast\n" << navigationLinks << "
\n"; +#endif } void HtmlGenerator::generateTitle(const QString& title, @@ -1771,17 +1847,17 @@ const Node *relative, CodeMarker *marker) { - out() << "\n" << navigationLinks << "
\n"; out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) - << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()) - << "\n" - "\n"; + << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()); + out() << " \n"; + out() << "\n"; + out() << "\n"; } void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker, @@ -1813,7 +1890,7 @@ void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker) { if (!inner->includes().isEmpty()) { - out() << "" + out() << "" << trimmedTrailing(highlightedCode(indent(codeIndent, marker->markedUpIncludes(inner->includes())), marker,inner)) @@ -1821,6 +1898,9 @@ } } +/*! + Generates a table of contents begining at \a node. + */ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker, Doc::SectioningUnit sectioningUnit, @@ -1828,6 +1908,7 @@ const Node *relative) { + return; if (!node->doc().hasTableOfContents()) return; QListtoc = node->doc().tableOfContents(); @@ -1843,8 +1924,8 @@ QString tdTag; if (numColumns > 1) { - tdTag = " "; - out() << " \n
\n"; + + inContents = false; + inLink = false; +} + +/*! + Revised for the new doc format. + Generates a table of contents begining at \a node. + */ +void HtmlGenerator::generateTableOfContents(const Node *node, + CodeMarker *marker, + QList" + tdTag = " "; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/ + out() << " \n
\n"; - + out() << "" << tdTag << "\n"; } @@ -1896,8 +1977,123 @@ } if (numColumns > 1) - out() << " * sections) +{ + QList toc; + if (node->doc().hasTableOfContents()) + toc = node->doc().tableOfContents(); + if (toc.isEmpty() && !sections && (node->subType() != Node::Module)) + return; + + QStringList sectionNumber; + int detailsBase = 0; + + // disable nested links in table of contents + inContents = true; + inLink = true; + + out() << " \n"; + out() << "\n"; inContents = false; inLink = false; } @@ -1909,7 +2105,7 @@ { if (bar.prev.begin() != 0 || bar.current.begin() != 0 || bar.next.begin() != 0) { - out() << "Contents
\n"; + sectionNumber.append("1"); + out() << "\n"; + + if (node->subType() == Node::Module) { + if (moduleNamespaceMap.contains(node->name())) { + out() << "
\n"; + out() << "- Namespaces
\n"; + } + if (moduleClassMap.contains(node->name())) { + out() << "- Classes
\n"; + } + out() << "- Detailed Description
\n"; + for (int i = 0; i < toc.size(); ++i) { + if (toc.at(i)->string().toInt() == 1) { + detailsBase = 1; + break; + } + } + } + else if (sections && (node->type() == Node::Class)) { + QList::ConstIterator s = sections->begin(); + while (s != sections->end()) { + if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) { + out() << " - " << (*s).name + << "
\n"; + } + ++s; + } + out() << "- Detailed Description
\n"; + for (int i = 0; i < toc.size(); ++i) { + if (toc.at(i)->string().toInt() == 1) { + detailsBase = 1; + break; + } + } + } + + for (int i = 0; i < toc.size(); ++i) { + Atom *atom = toc.at(i); + int nextLevel = atom->string().toInt() + detailsBase; + if (sectionNumber.size() < nextLevel) { + do { + sectionNumber.append("1"); + } while (sectionNumber.size() < nextLevel); + } + else { + while (sectionNumber.size() > nextLevel) { + sectionNumber.removeLast(); + } + sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); + } + int numAtoms; + Text headingText = Text::sectionHeading(atom); + QString s = headingText.toString(); + out() << "- "; + out() << ""; + generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); + out() << "
\n"; + } + while (!sectionNumber.isEmpty()) { + sectionNumber.removeLast(); + } + out() << ""; + out() << "
\n"; for (i = 0; i < sections.size(); ++i) { - out() << "" << protect(sections.at(i).name) << "
\n"; + out() << "" << protectEnc(sections.at(i).name) << "
\n"; generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary); } sections = marker->sections(inner, CodeMarker::Detailed, status); for (i = 0; i < sections.size(); ++i) { out() << "
\n"; - out() << "" << protect(sections.at(i).name) << "
\n"; + out() << "" << protectEnc(sections.at(i).name) << "
\n"; NodeList::ConstIterator m = sections.at(i).members.begin(); while (m != sections.at(i).members.end()) { @@ -2085,8 +2281,7 @@ CodeMarker *marker, const NodeMap &nodeMap) { - out() << "\n"; + out() << "
\n"; } /*! @@ -2133,10 +2328,11 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker, const NodeMap &classMap, + bool includeAlphabet, QString commonPrefix) { const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' - const int NumColumns = 4; // number of columns in the result + const int NumColumns = 3; // number of columns in the result if (classMap.isEmpty()) return; @@ -2205,6 +2401,7 @@ */ NodeMap paragraph[NumParagraphs+1]; QString paragraphName[NumParagraphs+1]; + QSet\n"; int row = 0; foreach (const QString &name, nodeMap.keys()) { @@ -2096,29 +2291,29 @@ continue; if (++row % 2 == 1) - out() << "
\n"; + out() << ""; + out() << " "; else - out() << " "; - out() << " "; + out() << " "; + out() << " \n"; } - out() << ""; if (!(node->type() == Node::Fake)) { Text brief = node->doc().trimmedBriefText(name); if (!brief.isEmpty()) { - out() << " "; generateFullName(node, relative, marker); - out() << ""; + out() << "
"; + out() << " "; + out() << ""; } } else { - out() << " "; generateText(brief, node, marker); - out() << "
"; - out() << protect(node->doc().briefText().toString()); - out() << " "; + out() << ""; } out() << " "; + out() << protectEnc(node->doc().briefText().toString()); + out() << "
usedParagraphNames; NodeMap::ConstIterator c = classMap.begin(); while (c != classMap.end()) { @@ -2228,6 +2425,7 @@ } paragraphName[paragraphNo] = key[0].toUpper(); + usedParagraphNames.insert(key[0].toLower().cell()); paragraph[paragraphNo].insert(key, c.value()); ++c; } @@ -2247,15 +2445,15 @@ for (j = 0; j < NumParagraphs; j++) // j = 0..36 paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count(); - int firstOffset[NumColumns + 1]; // 4 + 1 - int currentOffset[NumColumns]; // 4 - int currentParagraphNo[NumColumns]; // 4 - int currentOffsetInParagraph[NumColumns]; // 4 + int firstOffset[NumColumns + 1]; + int currentOffset[NumColumns]; + int currentParagraphNo[NumColumns]; + int currentOffsetInParagraph[NumColumns]; int numRows = (classMap.count() + NumColumns - 1) / NumColumns; int curParagNo = 0; - for (i = 0; i < NumColumns; i++) { // i = 0..3 + for (i = 0; i < NumColumns; i++) { firstOffset[i] = qMin(i * numRows, classMap.size()); currentOffset[i] = firstOffset[i]; @@ -2271,13 +2469,29 @@ } firstOffset[NumColumns] = classMap.count(); - out() << " \n"; + if (includeAlphabet) { + out() << "
\n"; } void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *marker) { - out() << ""; + for (int i = 0; i < 26; i++) { + QChar ch('a' + i); + if (usedParagraphNames.contains(char('a' + i))) + out() << QString("%2 ").arg(ch).arg(ch.toUpper()); + } + out() << "
\n"; + } + + out() << "\n"; for (k = 0; k < numRows; k++) { - out() << "
\n"; + out() << "\n"; + if (++numTableRows % 2 == 1) + out() << " "; + else + out() << " "; + //break; + +// out() << " \n"; for (i = 0; i < NumColumns; i++) { if (currentOffset[i] >= firstOffset[i + 1]) { // this column is finished - out() << " \n"; } - out() << "\n \n"; + out() << "\n \n"; // check why? } else { while ((currentParagraphNo[i] < NumParagraphs) && @@ -2292,16 +2506,20 @@ currentParagraphNo[i] = NumParagraphs - 1; } #endif - out() << ""; + out() << " "; if (currentOffsetInParagraph[i] == 0) { // start a new paragraph + if (includeAlphabet) { + QChar c = paragraphName[currentParagraphNo[i]][0].toLower(); + out() << QString("").arg(c); + } out() << "" << paragraphName[currentParagraphNo[i]] - << " "; + << ""; } - out() << "\n"; - - out() << "
"; + out() << "\n"; + + out() << " \n"; + out() << "\n"; currentOffset[i]++; currentOffsetInParagraph[i]++; @@ -2331,18 +2553,18 @@ } out() << " "; if ((currentParagraphNo[i] < NumParagraphs) && !paragraphName[currentParagraphNo[i]].isEmpty()) { NodeMap::Iterator it; @@ -2314,8 +2532,12 @@ out() << ""; - QStringList pieces = fullName(it.value(), relative, marker).split("::"); - out() << protect(pieces.last()); + QStringList pieces; + if (it.value()->subType() == Node::QmlClass) + pieces << it.value()->name(); + else + pieces = fullName(it.value(), relative, marker).split("::"); + out() << protectEnc(pieces.last()); out() << ""; if (pieces.size() > 1) { out() << " ("; @@ -2323,7 +2545,7 @@ out() << ")"; } } - out() << "
"; + out() << "
\n"; + out() << "\n"; char nextLetter = 'a'; char currentLetter; @@ -2357,7 +2579,7 @@ #else out() << ""; for (int i = 0; i < 26; i++) { QChar ch('a' + i); out() << QString("%2 ").arg(ch).arg(ch.toUpper()); } - out() << "
"; #endif - out() << protect(f.key()) << ":"; + out() << protectEnc(f.key()) << ":"; currentLetter = f.key()[0].unicode(); while (islower(currentLetter) && currentLetter >= nextLetter) { @@ -2411,7 +2633,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2450,7 +2672,7 @@ QString marked = marker->markedUpQmlItem(node,summary); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2463,7 +2685,7 @@ if (summary) marked.replace("@name>", "b>"); - marked.replace("<@extra>", " "); + marked.replace("<@extra>", ""); marked.replace("@extra>", ""); if (summary) { @@ -2556,7 +2778,7 @@ const FakeNode *groupNode = groupTitlesMap[groupTitle]; out() << QString("
%2
\n").arg( linkForNode(groupNode, relative)).arg( - protect(groupNode->fullTitle())); + protectEnc(groupNode->fullTitle())); if (fakeNodeMap[groupNode].count() == 0) continue; @@ -2568,7 +2790,7 @@ if (title.startsWith("The ")) title.remove(0, 4); out() << "" - << protect(title) << " \n"; + << protectEnc(title) << "\n"; } out() << "\n"; } @@ -2582,7 +2804,7 @@ if (title.startsWith("The ")) title.remove(0, 4); out() << "" - << protect(title) << " \n"; + << protectEnc(title) << "\n"; } out() << "\n"; } @@ -2606,15 +2828,12 @@ name_alignment = false; } if (name_alignment) { - out() << "\n"; + out() << "
\n"; } else { if (twoColumn) - out() << "
\n" - << "
\n"; } } } @@ -2671,15 +2889,12 @@ name_alignment = false; } if (name_alignment) { - out() << "\n "; + out() << " \n" + << "
\n"; + out() << "\n "; out() << " \n"; } @@ -2627,20 +2846,19 @@ } if (name_alignment) { - out() << "
\n"; if (twoColumn) - out() << ""; + out() << " \n"; else - out() << "\n"; + out() << "\n"; i++; ++m; } @@ -2649,7 +2867,7 @@ else { out() << " "; } else { if (twoColumn && i == (int) (nl.count() + 1) / 2) - out() << " \n"; - out() << "
"; + out() << "\n"; + out() << "
- "; } generateSynopsis(*m, relative, marker, style, name_alignment); if (name_alignment) out() << "
\n"; + out() << "
\n"; } else { if (twoColumn) - out() << "
\n" - << "
\n"; } } @@ -2733,9 +2947,9 @@ QList\n "; + out() << " \n" + << "
\n"; + out() << "\n "; out() << " \n"; } @@ -2692,20 +2907,19 @@ } if (name_alignment) { - out() << "
\n"; if (twoColumn) - out() << ""; + out() << " \n"; else - out() << "\n"; + out() << "\n"; i++; ++m; } @@ -2714,7 +2928,7 @@ else { out() << " "; } else { if (twoColumn && i == (int) (section.members.count() + 1) / 2) - out() << " \n"; - out() << "
"; + out() << "\n"; + out() << "
- "; } generateSynopsis(*m, relative, marker, style, name_alignment); if (name_alignment) out() << "
>::ConstIterator p = section.inherited.begin(); while (p != section.inherited.end()) { if (nameAlignment) - out() << " "; + out() << " "; else - out() << " "; + out() << " "; out() << (*p).second << " "; if ((*p).second == 1) { out() << section.singularMember; @@ -2745,7 +2959,7 @@ } out() << " inherited from " - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << " \n"; ++p; } @@ -2760,7 +2974,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2780,7 +2994,7 @@ extraRegExp.setMinimal(true); marked.replace(extraRegExp, ""); } else { - marked.replace("<@extra>", " "); + marked.replace("<@extra>", ""); marked.replace("@extra>", ""); } @@ -2811,7 +3025,7 @@ for (int i = 0, n = src.size(); i < n;) { if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') { if (nameAlignment && !done) {// && (i != 0)) Why was this here? - html += ""; + html += " "; done = true; } i += 2; @@ -2976,9 +3190,13 @@ twoColumn = (section.members.count() >= 5); } if (twoColumn) - out() << " \n" - << "
\n"; } if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { @@ -3020,7 +3238,7 @@ { QList\n "; + out() << " \n"; + if (++numTableRows % 2 == 1) + out() << "
\n"; + out() << ""; + else + out() << " "; + +// << " \n "; out() << " \n"; int i = 0; @@ -2990,9 +3208,9 @@ } if (twoColumn && i == (int) (section.members.count() + 1) / 2) - out() << "
\n"; - - out() << "
- "; + out() << "
\n"; + + out() << "
\n"; if (twoColumn) - out() << "- "; if (style == CodeMarker::Accessors) out() << ""; generateSynopsis(*m, relative, marker, style); @@ -3004,7 +3222,7 @@ } out() << "
>::ConstIterator p = section.inherited.begin(); while (p != section.inherited.end()) { - out() << " "; + out() << " "; out() << (*p).second << " "; if ((*p).second == 1) { out() << section.singularMember; @@ -3029,7 +3247,7 @@ } out() << " inherited from " - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << " \n"; ++p; } @@ -3043,7 +3261,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -3060,7 +3278,7 @@ extraRegExp.setMinimal(true); marked.replace(extraRegExp, ""); } else { - marked.replace("<@extra>", " "); + marked.replace("<@extra>", ""); marked.replace("@extra>", ""); } @@ -3241,7 +3459,7 @@ if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) { // hack for C++: move () outside of link int k = funcLeftParen.pos(1); - out() << protect(atom->string().left(k)); + out() << protectEnc(atom->string().left(k)); if (link.isEmpty()) { if (showBrokenLinks) out() << ""; @@ -3249,7 +3467,7 @@ out() << ""; } inLink = false; - out() << protect(atom->string().mid(k)); + out() << protectEnc(atom->string().mid(k)); } else if (marker->recognizeLanguage("Java")) { // hack for Java: remove () and use when appropriate bool func = atom->string().endsWith("()"); @@ -3257,13 +3475,13 @@ if (tt) out() << ""; if (func) { - out() << protect(atom->string().left(atom->string().length() - 2)); + out() << protectEnc(atom->string().left(atom->string().length() - 2)); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } out() << ""; } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } } @@ -3337,7 +3555,12 @@ return clean; } -QString HtmlGenerator::protect(const QString& string) +QString HtmlGenerator::protectEnc(const QString &string) +{ + return protect(string, outputEncoding); +} + +QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding) { #define APPEND(x) \ if (html.isEmpty()) { \ @@ -3360,7 +3583,7 @@ APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if (ch.unicode() > 0x007F + } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator @@ -3490,7 +3713,7 @@ ref = node->name() + "-var"; break; case Node::Target: - return protect(node->name()); + return protectEnc(node->name()); } return registerRef(ref); } @@ -3564,7 +3787,7 @@ } } out() << "\">"; - out() << protect(fullName(apparentNode, relative, marker)); + out() << protectEnc(fullName(apparentNode, relative, marker)); out() << ""; } @@ -3574,14 +3797,18 @@ { const EnumNode *enume; +#ifdef GENERATE_MAC_REFS generateMacRef(node, marker); +#endif if (node->type() == Node::Enum && (enume = static_cast(node))->flagsType()) { +#ifdef GENERATE_MAC_REFS generateMacRef(enume->flagsType(), marker); +#endif out() << " "; out() << ""; generateSynopsis(enume, relative, marker, CodeMarker::Detailed); - out() << "
"; + out() << "
"; generateSynopsis(enume->flagsType(), relative, marker, @@ -3625,12 +3852,12 @@ else if (node->type() == Node::Enum) { const EnumNode *enume = static_cast(node); if (enume->flagsType()) { - out() << " The " << protect(enume->flagsType()->name()) + out() << "
The " << protectEnc(enume->flagsType()->name()) << " type is a typedef for " << "QFlags<" - << protect(enume->name()) + << protectEnc(enume->name()) << ">. It stores an OR combination of " - << protect(enume->name()) + << protectEnc(enume->name()) << " values.
\n"; } } @@ -3700,6 +3927,9 @@ NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion); if (ncmap == newClassMaps.end()) ncmap = newClassMaps.insert(sinceVersion,NodeMap()); + NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); + if (nqcmap == newQmlClassMaps.end()) + nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); if ((*child)->type() == Node::Function) { FunctionNode *func = static_cast(*child); @@ -3719,6 +3949,15 @@ nsmap.value().insert(className,(*child)); ncmap.value().insert(className,(*child)); } + else if ((*child)->subType() == Node::QmlClass) { + QString className = (*child)->name(); + if ((*child)->parent() && + (*child)->parent()->type() == Node::Namespace && + !(*child)->parent()->name().isEmpty()) + className = (*child)->parent()->name()+"::"+className; + nsmap.value().insert(className,(*child)); + nqcmap.value().insert(className,(*child)); + } } else { QString name = (*child)->name(); @@ -3939,10 +4178,12 @@ } else { *node = marker->resolveTarget(first, myTree, relative); - if (!*node) + if (!*node) { *node = myTree->findFakeNodeByTitle(first); - if (!*node) + } + if (!*node) { *node = myTree->findUnambiguousTarget(first, targetAtom); + } } if (*node) { @@ -4077,6 +4318,10 @@ } } +#ifdef GENERATE_MAC_REFS +/* + No longer valid. + */ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) { if (!pleaseGenerateMacRef || marker == 0) @@ -4086,6 +4331,7 @@ foreach (const QString &macRef, macRefs) out() << "\n"; } +#endif void HtmlGenerator::beginLink(const QString &link, const Node *node, @@ -4137,12 +4383,10 @@ inObsoleteLink = false; } -QT_END_NAMESPACE - #ifdef QDOC_QML /*! - Generates the summary for for the \a section. Only used for + Generates the summary for the \a section. Only used for sections of QML element documentation. Currently handles only the QML property group. @@ -4159,17 +4403,20 @@ twoColumn = (count >= 5); } if (twoColumn) - out() << " \n" - << "
\n"; } } @@ -4190,32 +4437,34 @@ CodeMarker *marker) { const QmlPropertyNode* qpn = 0; +#ifdef GENERATE_MAC_REFS generateMacRef(node, marker); +#endif out() << "\n "; + out() << " \n"; + if (++numTableRows % 2 == 1) + out() << "
\n"; + out() << ""; + else + out() << " "; + // << " \n "; out() << " \n"; int row = 0; m = section.members.begin(); while (m != section.members.end()) { if (twoColumn && row == (int) (count + 1) / 2) - out() << "
\n"; - out() << "
- "; + out() << "
\n"; + out() << "
\n"; if (twoColumn) - out() << "- "; generateQmlItem(*m,relative,marker,true); out() << "
\n"; row++; @@ -4177,7 +4424,7 @@ } out() << ""; if (node->subType() == Node::QmlPropertyGroup) { const QmlPropGroupNode* qpgn = static_cast(node); NodeList::ConstIterator p = qpgn->childNodes().begin(); out() << " "; - out() << ""; + out() << "
" - << "" - << "" - << "
"; - } } ++p; } @@ -4226,11 +4475,16 @@ const FunctionNode* qsn = static_cast " - << "default (node); out() << " "; out() << ""; } @@ -4238,10 +4492,15 @@ const FunctionNode* qmn = static_cast(node); out() << " "; out() << ""; } @@ -4270,7 +4529,7 @@ const Node* n = myTree->findNode(strList,Node::Fake); if (n && n->subType() == Node::QmlClass) { const QmlClassNode* qcn = static_cast(n); - out() << " "; + out() << "
"; Text text; text << "[Inherits "; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); @@ -4286,6 +4545,26 @@ } /*! + Output the "Inherit by" list for the QML element, + if it is inherited by any other elements. + */ +void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, + CodeMarker* marker) +{ + if (cn) { + NodeList subs; + QmlClassNode::subclasses(cn->name(),subs); + if (!subs.isEmpty()) { + Text text; + text << Atom::ParaLeft << "Inherited by "; + appendSortedQmlNames(text,cn,subs,marker); + text << Atom::ParaRight; + generateText(text, cn, marker); + } + } +} + +/*! Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" line for the QML element, if there should be one. @@ -4297,7 +4576,7 @@ { const ClassNode* cn = qcn->classNode(); if (cn && (cn->status() != Node::Internal)) { - out() << "
"; + out() << "
"; Text text; text << "["; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); @@ -4328,7 +4607,7 @@ if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) { const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake); if (n && n->subType() == Node::QmlClass) { - out() << "
"; + out() << "
"; Text text; text << "["; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); @@ -4347,4 +4626,264 @@ } } +/*! + Generate the
element for the given \a node using the \a writer. + Return true if a element was written; otherwise return false. + */ +bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer, + const Node* node, + CodeMarker* marker) const +{ + if (node->pageType() == Node::NoPageType) + return false; + if (node->name().isEmpty()) + return true; + if (node->access() == Node::Private) + return false; + if (!node->isInnerNode()) + return false; + + QString title; + QString rawTitle; + QString fullTitle; + const InnerNode* inner = static_cast (node); + + writer.writeStartElement("page"); + QXmlStreamAttributes attributes; + QString t; + t.setNum(id++); + switch (node->type()) { + case Node::Fake: + { + const FakeNode* fake = static_cast (node); + title = fake->fullTitle(); + break; + } + case Node::Class: + { + title = node->name() + " Class Reference"; + break; + } + case Node::Namespace: + { + rawTitle = marker->plainName(inner); + fullTitle = marker->plainFullName(inner); + title = rawTitle + " Namespace Reference"; + break; + } + default: + title = node->name(); + break; + } + writer.writeAttribute("id",t); + writer.writeStartElement("pageWords"); + writer.writeCharacters(title); + if (!inner->pageKeywords().isEmpty()) { + const QStringList& w = inner->pageKeywords(); + for (int i = 0; i < w.size(); ++i) { + writer.writeCharacters(" "); + writer.writeCharacters(w.at(i).toLocal8Bit().constData()); + } + } + writer.writeEndElement(); + writer.writeStartElement("pageTitle"); + writer.writeCharacters(title); + writer.writeEndElement(); + writer.writeStartElement("pageUrl"); + writer.writeCharacters(PageGenerator::fileName(node)); + writer.writeEndElement(); + writer.writeStartElement("pageType"); + switch (node->pageType()) { + case Node::ApiPage: + writer.writeCharacters("APIPage"); + break; + case Node::ArticlePage: + writer.writeCharacters("Article"); + break; + case Node::ExamplePage: + writer.writeCharacters("Example"); + break; + default: + break; + } + writer.writeEndElement(); + writer.writeEndElement(); + return true; +} + +/*! + Traverse the tree recursively and generate the + elements. + */ +void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const +{ + if (generatePageElement(writer, node, marker)) { + + if (node->isInnerNode()) { + const InnerNode *inner = static_cast (node); + + // Recurse to write an element for this child node and all its children. + foreach (const Node *child, inner->childNodes()) + generatePageElements(writer, child, marker); + } + } +} + +/*! + Outputs the file containing the index used for searching the html docs. + */ +void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const +{ + QFile file(fileName); + if (!file.open(QFile::WriteOnly | QFile::Text)) + return ; + + QXmlStreamWriter writer(&file); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement("qtPageIndex"); + + generatePageElements(writer, myTree->root(), marker); + + writer.writeEndElement(); // qtPageIndex + writer.writeEndDocument(); + file.close(); +} + #endif + +#if 0 // fossil removed for new doc format MWS 19/04/2010 + out() << "\n"; + out() << QString("\n").arg(naturalLanguage); + + QString shortVersion; + if ((project != "Qtopia") && (project != "Qt Extended")) { + shortVersion = project + " " + shortVersion + ": "; + if (node && !node->doc().location().isEmpty()) + out() << "\n"; + + 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() << "\n" + " " << shortVersion << protectEnc(title) << " \n"; + out() << QString("").arg(outputEncoding); + + if (!style.isEmpty()) + out() << " \n"; + + const QMap&metaMap = node->doc().metaTagMap(); + if (!metaMap.isEmpty()) { + QMapIterator i(metaMap); + while (i.hasNext()) { + i.next(); + out() << " \n"; + } + } + + navigationLinks.clear(); + + if (node && !node->links().empty()) { + QPair linkPair; + QPair anchorPair; + const Node *linkNode; + + if (node->links().contains(Node::PreviousLink)) { + linkPair = node->links()[Node::PreviousLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Previous: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::ContentsLink)) { + linkPair = node->links()[Node::ContentsLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "["; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::NextLink)) { + linkPair = node->links()[Node::NextLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Next: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::IndexLink)) { + linkPair = node->links()[Node::IndexLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + if (node->links().contains(Node::StartLink)) { + linkPair = node->links()[Node::StartLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + } + + foreach (const QString &stylesheet, stylesheets) { + out() << " \n"; + } + + foreach (const QString &customHeadElement, customHeadElements) { + out() << " " << customHeadElement << "\n"; + } + + out() << "\n" + #endif + + QT_END_NAMESPACE