tools/qdoc3/htmlgenerator.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    59 
    59 
    60 QT_BEGIN_NAMESPACE
    60 QT_BEGIN_NAMESPACE
    61 
    61 
    62 #define COMMAND_VERSION                 Doc::alias("version")
    62 #define COMMAND_VERSION                 Doc::alias("version")
    63 int HtmlGenerator::id = 0;
    63 int HtmlGenerator::id = 0;
       
    64 bool HtmlGenerator::debugging_on = false;
       
    65 
       
    66 #if 0
       
    67 QString HtmlGenerator::divNavTop = "<div class=\"navTop\"><a href=\"#toc\"><img src=\"./images/bullet_up.png\"></a></div>";
       
    68 #endif
       
    69 
       
    70 QString HtmlGenerator::divNavTop = "";
    64 
    71 
    65 QString HtmlGenerator::sinceTitles[] =
    72 QString HtmlGenerator::sinceTitles[] =
    66     {
    73     {
    67         "    New Namespaces",
    74         "    New Namespaces",
    68         "    New Classes",
    75         "    New Classes",
   211       inSectionHeading(false),
   218       inSectionHeading(false),
   212       inTableHeader(false),
   219       inTableHeader(false),
   213       numTableRows(0),
   220       numTableRows(0),
   214       threeColumnEnumValueTable(true),
   221       threeColumnEnumValueTable(true),
   215       offlineDocs(true),
   222       offlineDocs(true),
       
   223       creatorDocs(true),
   216       funcLeftParen("\\S(\\()"),
   224       funcLeftParen("\\S(\\()"),
   217       myTree(0),
   225       myTree(0),
   218       slow(false),
   226       slow(false),
   219       obsoleteLinks(false)
   227       obsoleteLinks(false)
   220 {
   228 {
   273                                           Config::dot +
   281                                           Config::dot +
   274                                           HTMLGENERATOR_GENERATEMACREFS);
   282                                           HTMLGENERATOR_GENERATEMACREFS);
   275 
   283 
   276     project = config.getString(CONFIG_PROJECT);
   284     project = config.getString(CONFIG_PROJECT);
   277     offlineDocs = !config.getBool(CONFIG_ONLINE);
   285     offlineDocs = !config.getBool(CONFIG_ONLINE);
       
   286     creatorDocs = false; //!config.getBool(CONFIG_CREATOR);
   278     projectDescription = config.getString(CONFIG_DESCRIPTION);
   287     projectDescription = config.getString(CONFIG_DESCRIPTION);
   279     if (projectDescription.isEmpty() && !project.isEmpty())
   288     if (projectDescription.isEmpty() && !project.isEmpty())
   280         projectDescription = project + " Reference Documentation";
   289         projectDescription = project + " Reference Documentation";
   281 
   290 
   282     projectUrl = config.getString(CONFIG_URL);
   291     projectUrl = config.getString(CONFIG_URL);
   343   \note The html file generation is done in the base class,
   352   \note The html file generation is done in the base class,
   344   PageGenerator::generateTree().
   353   PageGenerator::generateTree().
   345  */
   354  */
   346 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
   355 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
   347 {
   356 {
   348 #if 0    
       
   349     // Copy the stylesheets from the directory containing the qdocconf file.
       
   350     // ### This should be changed to use a special directory in doc/src.
       
   351     QStringList::ConstIterator styleIter = stylesheets.begin();
       
   352     QDir configPath = QDir::current();
       
   353     while (styleIter != stylesheets.end()) {
       
   354         QString filePath = configPath.absoluteFilePath(*styleIter);
       
   355         Config::copyFile(Location(), filePath, filePath, outputDir());
       
   356         ++styleIter;
       
   357     }
       
   358 #endif
       
   359     myTree = tree;
   357     myTree = tree;
   360     nonCompatClasses.clear();
   358     nonCompatClasses.clear();
   361     mainClasses.clear();
   359     mainClasses.clear();
   362     compatClasses.clear();
   360     compatClasses.clear();
   363     obsoleteClasses.clear();
   361     obsoleteClasses.clear();
   368     serviceClasses.clear();
   366     serviceClasses.clear();
   369     findAllClasses(tree->root());
   367     findAllClasses(tree->root());
   370     findAllFunctions(tree->root());
   368     findAllFunctions(tree->root());
   371     findAllLegaleseTexts(tree->root());
   369     findAllLegaleseTexts(tree->root());
   372     findAllNamespaces(tree->root());
   370     findAllNamespaces(tree->root());
   373 #ifdef ZZZ_QDOC_QML
       
   374     findAllQmlClasses(tree->root());
       
   375 #endif
       
   376     findAllSince(tree->root());
   371     findAllSince(tree->root());
   377 
   372 
   378     PageGenerator::generateTree(tree, marker);
   373     PageGenerator::generateTree(tree, marker);
   379 
   374 
   380     dcfClassesRoot.ref = "classes.html";
   375     dcfClassesRoot.ref = "classes.html";
   432     threeColumnEnumValueTable = true;
   427     threeColumnEnumValueTable = true;
   433     link.clear();
   428     link.clear();
   434     sectionNumber.clear();
   429     sectionNumber.clear();
   435 }
   430 }
   436 
   431 
       
   432 /*!
       
   433   Generate html from an instance of Atom.
       
   434  */
   437 int HtmlGenerator::generateAtom(const Atom *atom,
   435 int HtmlGenerator::generateAtom(const Atom *atom,
   438                                 const Node *relative,
   436                                 const Node *relative,
   439                                 CodeMarker *marker)
   437                                 CodeMarker *marker)
   440 {
   438 {
   441     int skipAhead = 0;
   439     int skipAhead = 0;
   442     static bool in_para = false;
   440     static bool in_para = false;
   443 
   441 	
   444     switch (atom->type()) {
   442     switch (atom->type()) {
   445     case Atom::AbstractLeft:
   443     case Atom::AbstractLeft:
   446         break;
   444         break;
   447     case Atom::AbstractRight:
   445     case Atom::AbstractRight:
   448         break;
   446         break;
   514             out() << highlightedCode(atom->string(), marker, relative);
   512             out() << highlightedCode(atom->string(), marker, relative);
   515         }
   513         }
   516         out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
   514         out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
   517         break;
   515         break;
   518     case Atom::Code:
   516     case Atom::Code:
   519 	out() << "<pre class=\"highlightedCode\">"
   517 	out() << "<pre class=\"highlightedCode brush: cpp\">"
   520               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   518               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   521                                                  marker,relative))
   519                                                  marker,relative))
   522               << "</pre>\n";
   520               << "</pre>\n";
   523 	break;
   521 	break;
   524 #ifdef QDOC_QML
   522 #ifdef QDOC_QML
   525     case Atom::Qml:
   523     case Atom::Qml:
   526 	out() << "<pre class=\"highlightedCode\">"
   524 	out() << "<pre class=\"highlightedCode brush: cpp\">"
   527               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   525               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   528                                                  marker,relative))
   526                                                  marker,relative))
   529               << "</pre>\n";
   527               << "</pre>\n";
   530 	break;
   528 	break;
   531 #endif
   529 #endif
   532     case Atom::CodeNew:
   530     case Atom::CodeNew:
   533         out() << "<p>you can rewrite it as</p>\n"
   531         out() << "<p>you can rewrite it as</p>\n"
   534               << "<pre class=\"highlightedCode\">"
   532               << "<pre class=\"highlightedCode brush: cpp\">"
   535               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   533               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   536                                                  marker,relative))
   534                                                  marker,relative))
   537               << "</pre>\n";
   535               << "</pre>\n";
   538         break;
   536         break;
   539     case Atom::CodeOld:
   537     case Atom::CodeOld:
   540         out() << "<p>For example, if you have code like</p>\n";
   538         out() << "<p>For example, if you have code like</p>\n";
   541         // fallthrough
   539         // fallthrough
   542     case Atom::CodeBad:
   540     case Atom::CodeBad:
   543         out() << "<pre class=\"highlightedCode\">"
   541         out() << "<pre class=\"highlightedCode brush: cpp\">"
   544               << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
   542               << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
   545               << "</pre>\n";
   543               << "</pre>\n";
   546 	break;
   544 	break;
   547     case Atom::FootnoteLeft:
   545     case Atom::FootnoteLeft:
   548         // ### For now
   546         // ### For now
   917 				if (++numTableRows % 2 == 1)
   915 				if (++numTableRows % 2 == 1)
   918 					out() << "<tr class=\"odd\">";
   916 					out() << "<tr class=\"odd\">";
   919 				else
   917 				else
   920 					out() << "<tr class=\"even\">";
   918 					out() << "<tr class=\"even\">";
   921 
   919 
   922 					out() << "<tr><th>Constant</th>"
   920 					out() << "<tr><th class=\"tblConst\">Constant</th>"
   923                       << "<th>Value</th>"
   921                       << "<th class=\"tblval\">Value</th>"
   924                       << "<th>Description</th></tr>\n";
   922                       << "<th class=\"tbldscr\">Description</th></tr>\n";
   925             }
   923             }
   926             else {
   924             else {
   927                 out() << "<table class=\"valuelist\">"
   925                 out() << "<table class=\"valuelist\">"
   928                       << "<tr><th>Constant</th><th>Value</th></tr>\n";
   926                       << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n";
   929             }
   927             }
   930         }
   928         }
   931         else {
   929         else {
   932             out() << "<ol type=";
   930             out() << "<ol type=";
   933             if (atom->string() == ATOM_LIST_UPPERALPHA) {
   931             if (atom->string() == ATOM_LIST_UPPERALPHA) {
  1061                 while (sectionNumber.size() > nextLevel) {
  1059                 while (sectionNumber.size() > nextLevel) {
  1062                     sectionNumber.removeLast();
  1060                     sectionNumber.removeLast();
  1063                 }
  1061                 }
  1064                 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
  1062                 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
  1065             }
  1063             }
  1066             out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>\n";
  1064             out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>" << divNavTop << "\n";
  1067         }
  1065         }
  1068 #else
  1066 #else
  1069         out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
  1067         out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
  1070               << "\"></a>\n";
  1068               << "\"></a>" << divNavTop << "\n";
  1071 #endif
  1069 #endif
  1072         break;
  1070         break;
  1073     case Atom::SectionRight:
  1071     case Atom::SectionRight:
  1074         break;
  1072         break;
  1075     case Atom::SectionHeadingLeft:
  1073     case Atom::SectionHeadingLeft:
  1137         out() << "</tr>\n";
  1135         out() << "</tr>\n";
  1138         break;
  1136         break;
  1139     case Atom::TableItemLeft:
  1137     case Atom::TableItemLeft:
  1140         {
  1138         {
  1141             if (inTableHeader)
  1139             if (inTableHeader)
  1142                 out() << "<th";
  1140                 out() << "<th ";
  1143             else
  1141             else
  1144                 out() << "<td";
  1142                 out() << "<td ";
  1145 
  1143 
  1146             QStringList spans = atom->string().split(",");
  1144             QStringList spans = atom->string().split(",");
  1147             if (spans.size() == 2) {
  1145             if (spans.size() == 2) {
  1148                 if (spans.at(0) != "1")
  1146                 if (spans.at(0) != "1")
  1149                     out() << " colspan=\"" << spans.at(0) << "\"";
  1147                     out() << " colspan=\"" << spans.at(0) << "\"";
  1215         unknownAtom(atom);
  1213         unknownAtom(atom);
  1216     }
  1214     }
  1217     return skipAhead;
  1215     return skipAhead;
  1218 }
  1216 }
  1219 
  1217 
       
  1218 /*!
       
  1219   Generate a reference page for a C++ class.
       
  1220  */
  1220 void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
  1221 void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
  1221                                           CodeMarker *marker)
  1222                                           CodeMarker *marker)
  1222 {
  1223 {
  1223     QList<Section> sections;
  1224     QList<Section> sections;
  1224     QList<Section>::ConstIterator s;
  1225     QList<Section>::ConstIterator s;
  1250     Text subtitleText;
  1251     Text subtitleText;
  1251     if (rawTitle != fullTitle)
  1252     if (rawTitle != fullTitle)
  1252         subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
  1253         subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
  1253                      << Atom(Atom::LineBreak);
  1254                      << Atom(Atom::LineBreak);
  1254 
  1255 
  1255 #if 0
       
  1256     // No longer used because the modeule name is a breadcrumb.
       
  1257     QString fixedModule = inner->moduleName();
       
  1258     if (fixedModule == "Qt3SupportLight")
       
  1259         fixedModule = "Qt3Support";
       
  1260     if (!fixedModule.isEmpty())
       
  1261         subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
       
  1262 
       
  1263     if (fixedModule.isEmpty()) {
       
  1264         QMultiMap<QString, QString> publicGroups = myTree->publicGroups();
       
  1265         QList<QString> groupNames = publicGroups.values(inner->name());
       
  1266         if (!groupNames.isEmpty()) {
       
  1267             qSort(groupNames.begin(), groupNames.end());
       
  1268             subtitleText << "[";
       
  1269             for (int j=0; j<groupNames.count(); j++) {
       
  1270                 subtitleText <<  Atom(Atom::AutoLink, groupNames[j]);
       
  1271                 if (j<groupNames.count()-1)
       
  1272                     subtitleText <<", ";
       
  1273             }
       
  1274             subtitleText << "]";
       
  1275         }
       
  1276     }
       
  1277 #endif    
       
  1278 
       
  1279     generateHeader(title, inner, marker);
  1256     generateHeader(title, inner, marker);
  1280     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
  1257     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
  1281     generateTableOfContents(inner,marker,&sections);
  1258     generateTableOfContents(inner,marker,&sections);
  1282     generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
  1259     generateTitle(title, subtitleText, SmallSubTitle, inner, marker);    
  1283 
       
  1284 #ifdef QDOC_QML
       
  1285     if (classe && !classe->qmlElement().isEmpty()) {
       
  1286         generateInstantiatedBy(classe,marker);
       
  1287     }
       
  1288 #endif
       
  1289     
       
  1290     generateBrief(inner, marker);
  1260     generateBrief(inner, marker);
  1291     generateIncludes(inner, marker);
  1261     generateIncludes(inner, marker);
  1292     generateStatus(inner, marker);
  1262     generateStatus(inner, marker);
  1293     if (classe) {
  1263     if (classe) {
  1294         generateInherits(classe, marker);
  1264         generateInherits(classe, marker);
  1295         generateInheritedBy(classe, marker);
  1265         generateInheritedBy(classe, marker);
       
  1266 #ifdef QDOC_QML
       
  1267         if (!classe->qmlElement().isEmpty()) {
       
  1268             generateInstantiatedBy(classe,marker);
       
  1269         }
       
  1270 #endif
  1296     }
  1271     }
  1297     generateThreadSafeness(inner, marker);
  1272     generateThreadSafeness(inner, marker);
  1298     generateSince(inner, marker);
  1273     generateSince(inner, marker);
  1299 
  1274 
  1300     out() << "<ul>\n";
  1275     out() << "<ul>\n";
  1331             if (!s->inherited.isEmpty())
  1306             if (!s->inherited.isEmpty())
  1332                 needOtherSection = true;
  1307                 needOtherSection = true;
  1333         }
  1308         }
  1334         else {
  1309         else {
  1335             if (!s->members.isEmpty()) {
  1310             if (!s->members.isEmpty()) {
  1336                 out() << "<hr />\n";
  1311                // out() << "<hr />\n";
  1337                 out() << "<a name=\""
  1312                 out() << "<a name=\""
  1338                       << registerRef((*s).name.toLower())
  1313                       << registerRef((*s).name.toLower())
  1339                       << "\"></a>\n";
  1314                       << "\"></a>" << divNavTop << "\n";
  1340                 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1315                 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1341                 generateSection(s->members, inner, marker, CodeMarker::Summary);
  1316                 generateSection(s->members, inner, marker, CodeMarker::Summary);
  1342             }
  1317             }
  1343             if (!s->reimpMembers.isEmpty()) {
  1318             if (!s->reimpMembers.isEmpty()) {
  1344                 QString name = QString("Reimplemented ") + (*s).name;
  1319                 QString name = QString("Reimplemented ") + (*s).name;
  1345                 out() << "<hr />\n";
  1320               //  out() << "<hr />\n";
  1346                 out() << "<a name=\""
  1321                 out() << "<a name=\""
  1347                       << registerRef(name.toLower())
  1322                       << registerRef(name.toLower())
  1348                       << "\"></a>\n";
  1323                       << "\"></a>" << divNavTop << "\n";
  1349                 out() << "<h2>" << protectEnc(name) << "</h2>\n";
  1324                 out() << "<h2>" << protectEnc(name) << "</h2>\n";
  1350                 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
  1325                 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
  1351             }
  1326             }
  1352 
  1327 
  1353             if (!s->inherited.isEmpty()) {
  1328             if (!s->inherited.isEmpty()) {
  1354                 out() << "<ul>\n";
  1329                 out() << "<ul>\n";
  1355                 generateSectionInheritedList(*s, inner, marker, true);
  1330                 generateSectionInheritedList(*s, inner, marker);
  1356                 out() << "</ul>\n";
  1331                 out() << "</ul>\n";
  1357             }
  1332             }
  1358         }
  1333         }
  1359         ++s;
  1334         ++s;
  1360     }
  1335     }
  1370             ++s;
  1345             ++s;
  1371         }
  1346         }
  1372         out() << "</ul>\n";
  1347         out() << "</ul>\n";
  1373     }
  1348     }
  1374 
  1349 
  1375     out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1350     out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
  1376 
  1351 
  1377     if (!inner->doc().isEmpty()) {
  1352     if (!inner->doc().isEmpty()) {
  1378         out() << "<hr />\n"
  1353         generateExtractionMark(inner, DetailedDescriptionMark);
  1379               << "<div class=\"descr\"/>\n" // QTBUG-9504
  1354         //out() << "<hr />\n"
       
  1355         out() << "<div class=\"descr\">\n" // QTBUG-9504
  1380               << "<h2>" << "Detailed Description" << "</h2>\n";
  1356               << "<h2>" << "Detailed Description" << "</h2>\n";
  1381         generateBody(inner, marker);
  1357         generateBody(inner, marker);
  1382         out() << "</div>\n"; // QTBUG-9504
  1358         out() << "</div>\n"; // QTBUG-9504
  1383         generateAlsoList(inner, marker);
  1359         generateAlsoList(inner, marker);
       
  1360         generateExtractionMark(inner, EndMark);
  1384     }
  1361     }
  1385 
  1362 
  1386     sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
  1363     sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
  1387     s = sections.begin();
  1364     s = sections.begin();
  1388     while (s != sections.end()) {
  1365     while (s != sections.end()) {
  1389         out() << "<hr />\n";
  1366         //out() << "<hr />\n";
  1390         if (!(*s).divClass.isEmpty())
  1367         if (!(*s).divClass.isEmpty())
  1391             out() << "<div class=\"" << (*s).divClass << "\"/>\n"; // QTBUG-9504
  1368             out() << "<div class=\"" << (*s).divClass << "\">\n"; // QTBUG-9504
  1392         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1369         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1393 
  1370 
  1394         NodeList::ConstIterator m = (*s).members.begin();
  1371         NodeList::ConstIterator m = (*s).members.begin();
  1395         while (m != (*s).members.end()) {
  1372         while (m != (*s).members.end()) {
  1396             if ((*m)->access() != Node::Private) { // ### check necessary?
  1373             if ((*m)->access() != Node::Private) { // ### check necessary?
  1464     }
  1441     }
  1465 
  1442 
  1466     appendDcfSubSection(&dcfClassesRoot, classSection);
  1443     appendDcfSubSection(&dcfClassesRoot, classSection);
  1467 }
  1444 }
  1468 
  1445 
       
  1446 /*!
       
  1447   Generate the html page for a qdoc file that doesn't map
       
  1448   to an underlying c++ file.
       
  1449  */
  1469 void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
  1450 void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
  1470 {
  1451 {
  1471     SubTitleSize subTitleSize = LargeSubTitle;
  1452     SubTitleSize subTitleSize = LargeSubTitle;
  1472     DcfSection fakeSection;
  1453     DcfSection fakeSection;
  1473     fakeSection.title = fake->fullTitle();
  1454     fakeSection.title = fake->fullTitle();
  1491         
  1472         
  1492     /*
  1473     /*
  1493       Generate the TOC for the new doc format.
  1474       Generate the TOC for the new doc format.
  1494       Don't generate a TOC for the home page.
  1475       Don't generate a TOC for the home page.
  1495     */
  1476     */
  1496     if (fake->name() != QString("index.html"))
  1477     const QmlClassNode* qml_cn = 0;
       
  1478     if (fake->subType() == Node::QmlClass) {
       
  1479         qml_cn = static_cast<const QmlClassNode*>(fake);
       
  1480         sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
       
  1481         generateTableOfContents(fake,marker,&sections);
       
  1482     }
       
  1483     else if (fake->name() != QString("index.html"))
  1497         generateTableOfContents(fake,marker,0);
  1484         generateTableOfContents(fake,marker,0);
  1498 
  1485 
  1499     generateTitle(fullTitle,
  1486     generateTitle(fullTitle,
  1500                   Text() << fake->subTitle(),
  1487                   Text() << fake->subTitle(),
  1501                   subTitleSize,
  1488                   subTitleSize,
  1506         // Generate brief text and status for modules.
  1493         // Generate brief text and status for modules.
  1507         generateBrief(fake, marker);
  1494         generateBrief(fake, marker);
  1508         generateStatus(fake, marker);
  1495         generateStatus(fake, marker);
  1509 
  1496 
  1510         if (moduleNamespaceMap.contains(fake->name())) {
  1497         if (moduleNamespaceMap.contains(fake->name())) {
  1511             out() << "<a name=\"" << registerRef("namespaces") << "\"></a>\n";
  1498             out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << "\n";
  1512             out() << "<h2>Namespaces</h2>\n";
  1499             out() << "<h2>Namespaces</h2>\n";
  1513             generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
  1500             generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
  1514         }
  1501         }
  1515         if (moduleClassMap.contains(fake->name())) {
  1502         if (moduleClassMap.contains(fake->name())) {
  1516             out() << "<a name=\"" << registerRef("classes") << "\"></a>\n";
  1503             out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << "\n";
  1517             out() << "<h2>Classes</h2>\n";
  1504             out() << "<h2>Classes</h2>\n";
  1518             generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
  1505             generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
  1519         }
  1506         }
  1520     }
  1507     }
  1521     else if (fake->subType() == Node::HeaderFile) {
  1508     else if (fake->subType() == Node::HeaderFile) {
  1565             appendDcfSubSection(&fakeSection, compatSection);
  1552             appendDcfSubSection(&fakeSection, compatSection);
  1566         }
  1553         }
  1567     }
  1554     }
  1568 #ifdef QDOC_QML
  1555 #ifdef QDOC_QML
  1569     else if (fake->subType() == Node::QmlClass) {
  1556     else if (fake->subType() == Node::QmlClass) {
  1570         const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
       
  1571         const ClassNode* cn = qml_cn->classNode();
  1557         const ClassNode* cn = qml_cn->classNode();
       
  1558         generateBrief(qml_cn, marker);
  1572         generateQmlInherits(qml_cn, marker);
  1559         generateQmlInherits(qml_cn, marker);
       
  1560         generateQmlInheritedBy(qml_cn, marker);
  1573         generateQmlInstantiates(qml_cn, marker);
  1561         generateQmlInstantiates(qml_cn, marker);
  1574         generateBrief(qml_cn, marker);
       
  1575         generateQmlInheritedBy(qml_cn, marker);
       
  1576         sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
       
  1577         s = sections.begin();
  1562         s = sections.begin();
  1578         while (s != sections.end()) {
  1563         while (s != sections.end()) {
  1579             out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1564             out() << "<a name=\"" << registerRef((*s).name.toLower())
       
  1565                   << "\"></a>" << divNavTop << "\n";
  1580             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1566             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1581             generateQmlSummary(*s,fake,marker);
  1567             generateQmlSummary(*s,fake,marker);
  1582             ++s;
  1568             ++s;
  1583         }
  1569         }
  1584 
  1570 
  1585         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1571         generateExtractionMark(fake, DetailedDescriptionMark);
       
  1572         out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
  1586         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1573         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1587         generateBody(fake, marker);
  1574         generateBody(fake, marker);
  1588         if (cn)
  1575         if (cn)
  1589             generateQmlText(cn->doc().body(), cn, marker, fake->name());
  1576             generateQmlText(cn->doc().body(), cn, marker, fake->name());
  1590         generateAlsoList(fake, marker);
  1577         generateAlsoList(fake, marker);
  1591         out() << "<hr />\n";
  1578         generateExtractionMark(fake, EndMark);
       
  1579         //out() << "<hr />\n";
  1592 
  1580 
  1593         sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
  1581         sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
  1594         s = sections.begin();
  1582         s = sections.begin();
  1595         while (s != sections.end()) {
  1583         while (s != sections.end()) {
  1596             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1584             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1610 #endif
  1598 #endif
  1611     
  1599     
  1612     sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
  1600     sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
  1613     s = sections.begin();
  1601     s = sections.begin();
  1614     while (s != sections.end()) {
  1602     while (s != sections.end()) {
  1615         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1603         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>" << divNavTop << "\n";
  1616         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1604         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1617         generateSectionList(*s, fake, marker, CodeMarker::Summary);
  1605         generateSectionList(*s, fake, marker, CodeMarker::Summary);
  1618         ++s;
  1606         ++s;
  1619     }
  1607     }
  1620 
  1608 
  1621     Text brief = fake->doc().briefText();
  1609     Text brief = fake->doc().briefText();
  1622     if (fake->subType() == Node::Module && !brief.isEmpty()) {
  1610     if (fake->subType() == Node::Module && !brief.isEmpty()) {
  1623         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1611         generateExtractionMark(fake, DetailedDescriptionMark);
  1624         out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
  1612         out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
       
  1613         out() << "<div class=\"descr\">\n"; // QTBUG-9504
  1625         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1614         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1626     }
  1615     }
  1627     else
  1616     else {
  1628         out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
  1617         generateExtractionMark(fake, DetailedDescriptionMark);
       
  1618         out() << "<div class=\"descr\">\n"; // QTBUG-9504
       
  1619     }
  1629 
  1620 
  1630     generateBody(fake, marker);
  1621     generateBody(fake, marker);
  1631     out() << "</div>\n"; // QTBUG-9504
  1622     out() << "</div>\n"; // QTBUG-9504
  1632     generateAlsoList(fake, marker);
  1623     generateAlsoList(fake, marker);
       
  1624     generateExtractionMark(fake, EndMark);
  1633 
  1625 
  1634     if (!fake->groupMembers().isEmpty()) {
  1626     if (!fake->groupMembers().isEmpty()) {
  1635         NodeMap groupMembersMap;
  1627         NodeMap groupMembersMap;
  1636         foreach (const Node *node, fake->groupMembers()) {
  1628         foreach (const Node *node, fake->groupMembers()) {
  1637             if (node->type() == Node::Class || node->type() == Node::Namespace)
  1629             if (node->type() == Node::Class || node->type() == Node::Namespace)
  1643     fakeSection.keywords += qMakePair(fakeSection.title, fakeSection.ref);
  1635     fakeSection.keywords += qMakePair(fakeSection.title, fakeSection.ref);
  1644 
  1636 
  1645     sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
  1637     sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
  1646     s = sections.begin();
  1638     s = sections.begin();
  1647     while (s != sections.end()) {
  1639     while (s != sections.end()) {
  1648         out() << "<hr />\n";
  1640         //out() << "<hr />\n";
  1649         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1641         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1650 
  1642 
  1651         NodeList::ConstIterator m = (*s).members.begin();
  1643         NodeList::ConstIterator m = (*s).members.begin();
  1652         while (m != (*s).members.end()) {
  1644         while (m != (*s).members.end()) {
  1653             generateDetailedMember(*m, fake, marker);
  1645             generateDetailedMember(*m, fake, marker);
  1680             appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
  1672             appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
  1681         }
  1673         }
  1682     }
  1674     }
  1683 }
  1675 }
  1684 
  1676 
       
  1677 /*!
       
  1678   Returns "html" for this subclass of Generator.
       
  1679  */
  1685 QString HtmlGenerator::fileExtension(const Node * /* node */) const
  1680 QString HtmlGenerator::fileExtension(const Node * /* node */) const
  1686 {
  1681 {
  1687     return "html";
  1682     return "html";
  1688 }
  1683 }
  1689 
  1684 
  1696 {
  1691 {
  1697     Text breadcrumb;
  1692     Text breadcrumb;
  1698     if (node->type() == Node::Class) {
  1693     if (node->type() == Node::Class) {
  1699         const ClassNode* cn = static_cast<const ClassNode*>(node);
  1694         const ClassNode* cn = static_cast<const ClassNode*>(node);
  1700         QString name =  node->moduleName();
  1695         QString name =  node->moduleName();
  1701         out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
  1696         out() << "              <li><a href=\"modules.html\">Modules</a></li>";
  1702         if (!name.isEmpty()) {
  1697         if (!name.isEmpty()) {
  1703             out() << "              <li>";
  1698             out() << "              <li>";
  1704             breadcrumb << Atom(Atom::AutoLink,name);
  1699             breadcrumb << Atom(Atom::AutoLink,name);
  1705             generateText(breadcrumb, node, marker);
  1700             generateText(breadcrumb, node, marker);
  1706             out() << "</li>\n";
  1701             out() << "</li>\n";
  1707         }
  1702         }
  1708         breadcrumb.clear();
  1703         if (!cn->name().isEmpty())
  1709         if (!cn->name().isEmpty()) {
  1704             out() << "              <li>" << cn->name() << "</li>\n";
  1710             out() << "              <li>";
       
  1711             breadcrumb << Atom(Atom::AutoLink,cn->name());
       
  1712             generateText(breadcrumb, 0, marker);
       
  1713             out() << "</li>\n";
       
  1714         }
       
  1715     }
  1705     }
  1716     else if (node->type() == Node::Fake) {
  1706     else if (node->type() == Node::Fake) {
  1717         const FakeNode* fn = static_cast<const FakeNode*>(node);
  1707         const FakeNode* fn = static_cast<const FakeNode*>(node);
  1718         if (node->subType() == Node::Module) {
  1708         if (node->subType() == Node::Module) {
  1719             out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
  1709             out() << "              <li><a href=\"modules.html\">Modules</a></li>";
  1720             QString name =  node->name();
  1710             QString name =  node->name();
  1721             if (!name.isEmpty()) {
  1711             if (!name.isEmpty())
  1722                 out() << "              <li>";
  1712                 out() << "              <li>" << name << "</li>\n";
  1723                 breadcrumb << Atom(Atom::AutoLink,name);
       
  1724                 generateText(breadcrumb, 0, marker);
       
  1725                 out() << "</li>\n";
       
  1726             }
       
  1727         }
  1713         }
  1728         else if (node->subType() == Node::Group) {
  1714         else if (node->subType() == Node::Group) {
  1729             if (fn->name() == QString("modules"))
  1715             if (fn->name() == QString("modules"))
  1730                 out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
  1716                 out() << "              <li>Modules</li>";
  1731             else {
  1717             else {
  1732                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
  1718                 out() << "              <li>" << title << "</li>";
  1733                       << "</a></li>";
       
  1734             }
  1719             }
  1735         }
  1720         }
  1736         else if (node->subType() == Node::Page) {
  1721         else if (node->subType() == Node::Page) {
  1737             if (fn->name() == QString("examples.html")) {
  1722             if (fn->name() == QString("qdeclarativeexamples.html")) {
  1738                 out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
  1723                 out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
       
  1724                 out() << "              <li>QML Examples & Demos</li>";
  1739             }
  1725             }
  1740             else if (fn->name().startsWith("examples-")) {
  1726             else if (fn->name().startsWith("examples-")) {
  1741                 out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
  1727                 out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
  1742                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
  1728                 out() << "              <li>" << title << "</li>";
  1743                       << "</a></li>";
       
  1744             }
  1729             }
  1745             else if (fn->name() == QString("namespaces.html")) {
  1730             else if (fn->name() == QString("namespaces.html")) {
  1746                 out() << "              <li><a href=\"namespaces.html\">All Namespaces</a></li>";
  1731                 out() << "              <li>Namespaces</li>";
  1747             }
  1732             }
  1748             else {
  1733             else {
  1749                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
  1734                 out() << "              <li>" << title << "</li>";
  1750                       << "</a></li>";
       
  1751             }
  1735             }
  1752         }
  1736         }
  1753         else if (node->subType() == Node::QmlClass) {
  1737         else if (node->subType() == Node::QmlClass) {
  1754             out() << "              <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>";
  1738             out() << "              <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>";
  1755             out() << "              <li><a href=\"" << fn->name() << "\">" << title
  1739             out() << "              <li>" << title << "</li>";
  1756                   << "</a></li>";
       
  1757         }
  1740         }
  1758         else if (node->subType() == Node::Example) {
  1741         else if (node->subType() == Node::Example) {
  1759             out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
  1742             out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
  1760             QStringList sl = fn->name().split('/');
  1743             QStringList sl = fn->name().split('/');
  1761             QString name = "examples-" + sl.at(0) + ".html";
  1744             if (sl.contains("declarative"))
  1762             QString t = CodeParser::titleFromName(name);
  1745                 out() << "              <li><a href=\"qdeclarativeexamples.html\">QML Examples & Demos</a></li>";
  1763             out() << "              <li><a href=\"" << name << "\">"
  1746             else {
  1764                   << t << "</a></li>";
  1747                 QString name = "examples-" + sl.at(0) + ".html";
  1765             out() << "              <li><a href=\"" << sl.at(0)
  1748                 QString t = CodeParser::titleFromName(name);
  1766                   << "-" << sl.at(sl.size()-1) << ".html\">"
  1749                 out() << "              <li><a href=\"" << name << "\">"
  1767                   << title << "</a></li>";
  1750                       << t << "</a></li>";
       
  1751             }
       
  1752             out() << "              <li>" << title << "</li>";
  1768         }
  1753         }
  1769     }
  1754     }
  1770     else if (node->type() == Node::Namespace) {
  1755     else if (node->type() == Node::Namespace) {
  1771         const NamespaceNode* nsn = static_cast<const NamespaceNode*>(node);
  1756         out() << "              <li><a href=\"namespaces.html\">Namespaces</a></li>";
  1772         out() << "              <li><a href=\"namespaces.html\">All Namespaces</a></li>";
  1757         out() << "              <li>" << title << "</li>";
  1773         out() << "              <li><a href=\"" << fileName(nsn) << "\">" << title
       
  1774               << "</a></li>";
       
  1775     }
  1758     }
  1776 }
  1759 }
  1777 
  1760 
  1778 void HtmlGenerator::generateHeader(const QString& title,
  1761 void HtmlGenerator::generateHeader(const QString& title,
  1779                                    const Node *node,
  1762                                    const Node *node,
  1780                                    CodeMarker *marker)
  1763                                    CodeMarker *marker)
  1781 {
  1764 {
  1782     out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding);
  1765     out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding);
  1783     out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
  1766     out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
  1784     out() << "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
  1767     out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
  1785     out() << "<head>\n";
  1768     out() << "<head>\n";
  1786     out() << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
  1769     out() << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
  1787     QString shortVersion;
  1770     QString shortVersion;
  1788     shortVersion = project + " " + shortVersion + ": ";
  1771     shortVersion = project + " " + shortVersion + ": ";
  1789     if (node && !node->doc().location().isEmpty())
  1772     if (node && !node->doc().location().isEmpty())
  1796         if (project == "QSA")
  1779         if (project == "QSA")
  1797             shortVersion = "QSA " + shortVersion + ": ";
  1780             shortVersion = "QSA " + shortVersion + ": ";
  1798         else
  1781         else
  1799             shortVersion = "Qt " + shortVersion + ": ";
  1782             shortVersion = "Qt " + shortVersion + ": ";
  1800     }
  1783     }
  1801 
  1784 	// Generating page title
  1802     out() << "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
  1785     out() << "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
  1803 
  1786 	// Adding style sheet
  1804 	out() << "  <!--[if IE]>";
  1787 	out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />";
  1805 	out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">";
  1788 	// Adding jquery and functions - providing online tools and search features
  1806 	out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">";
  1789 	out() << "  <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n";
  1807 	out() << "<![endif]-->";
  1790 	out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
  1808     out() << "<!--[if lt IE 7]>";
  1791 	// Adding style and js for small windows
  1809 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">";
  1792 	out() << "  <script src=\"./scripts/superfish.js\" type=\"text/javascript\"></script>\n";
  1810 	out() << "<![endif]-->";
  1793 	out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/superfish.css\" />";
  1811     out() << "<!--[if IE 7]>";
  1794 	out() << "  <script src=\"./scripts/narrow.js\" type=\"text/javascript\"></script>\n";
  1812 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">";
  1795 	out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/narrow.css\" />";
  1813 	out() << "<![endif]-->";
  1796 	
  1814     out() << "<!--[if IE 8]>";
  1797 	// Adding syntax highlighter 	// future release
  1815 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">";
  1798 	
  1816 	out() << "<![endif]-->";
  1799 	// Setting assistant configuration
  1817 
       
  1818 
       
  1819     //out() << "  <title>Qt Reference Documentation</title>";
       
  1820     out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n";
       
  1821     out() << "  <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n";
       
  1822     out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
       
  1823     out() << "</head>\n";
       
  1824 
       
  1825     if (offlineDocs)
  1800     if (offlineDocs)
  1826         out() << "<body class=\"offline\"  onload=\"CheckEmptyAndLoadList();\">\n";
  1801 	{
       
  1802 		out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />"; // Only for Qt Creator
       
  1803 		out() << "</head>\n";
       
  1804 		out() << "<body class=\"offline \">\n"; // offline for  Assistant
       
  1805 	}	
       
  1806     if (creatorDocs)
       
  1807 	{
       
  1808 		out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />"; // Only for Qt Creator
       
  1809 		out() << "</head>\n";
       
  1810 		out() << "<body class=\"offline narrow creator\">\n"; // offline for Creator
       
  1811 	}	
       
  1812 	// Setting online doc configuration
  1827     else
  1813     else
  1828         out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n";
  1814 		{
       
  1815 		// Browser spec styles
       
  1816 		out() << "  <!--[if IE]>\n";
       
  1817 		out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">\n";
       
  1818 		out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">\n";
       
  1819 		out() << "<![endif]-->\n";
       
  1820 		out() << "<!--[if lt IE 7]>\n";
       
  1821 		out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">\n";
       
  1822 		out() << "<![endif]-->\n";
       
  1823 		out() << "<!--[if IE 7]>\n";
       
  1824 		out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">\n";
       
  1825 		out() << "<![endif]-->\n";
       
  1826 		out() << "<!--[if IE 8]>\n";
       
  1827 		out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">\n";
       
  1828 		out() << "<![endif]-->\n";
       
  1829 		
       
  1830 		out() << "</head>\n";
       
  1831 		// CheckEmptyAndLoadList activating search
       
  1832 		out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n";
       
  1833 		}
  1829 
  1834 
  1830 #ifdef GENERATE_MAC_REFS    
  1835 #ifdef GENERATE_MAC_REFS    
  1831     if (mainPage)
  1836     if (mainPage)
  1832         generateMacRef(node, marker);
  1837         generateMacRef(node, marker);
  1833 #endif    
  1838 #endif    
  1834     out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1839     out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1835     generateBreadCrumbs(title,node,marker);
  1840     generateBreadCrumbs(title,node,marker);
  1836     out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1841     out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1837 
  1842 
  1838 #if 0 // Removed for new docf format. MWS
  1843 #if 0 // Removed for new doc format. MWS
  1839     if (node && !node->links().empty())
  1844     if (node && !node->links().empty())
  1840         out() << "<p>\n" << navigationLinks << "</p>\n";
  1845         out() << "<p>\n" << navigationLinks << "</p>\n";
  1841 #endif    
  1846 #endif    
  1842 }
  1847 }
  1843 
  1848 
  1865     if (node && !node->links().empty())
  1870     if (node && !node->links().empty())
  1866         out() << "<p>\n" << navigationLinks << "</p>\n";
  1871         out() << "<p>\n" << navigationLinks << "</p>\n";
  1867 
  1872 
  1868     out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
  1873     out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
  1869           << QString(address).replace("\\" + COMMAND_VERSION, myTree->version());
  1874           << QString(address).replace("\\" + COMMAND_VERSION, myTree->version());
  1870 	      out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
  1875 	
       
  1876 	    if (offlineDocs)
       
  1877 		{
  1871           out() << "</body>\n";
  1878           out() << "</body>\n";
       
  1879 		}
       
  1880 	    if (creatorDocs)
       
  1881 		{
       
  1882           out() << "</body>\n";
       
  1883 		}
       
  1884 		else
       
  1885 		{
       
  1886 			out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
       
  1887 			out() << "  <!-- <script type=\"text/javascript\">\n";
       
  1888 			out() << "  var _gaq = _gaq || [];\n";
       
  1889 			out() << "  _gaq.push(['_setAccount', 'UA-4457116-5']);\n";
       
  1890 			out() << "  _gaq.push(['_trackPageview']);\n";
       
  1891 			out() << "  (function() {\n";
       
  1892 			out() << "  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n";
       
  1893 			out() << "  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n";
       
  1894 			out() << "  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n";
       
  1895 			out() << "  })();\n";
       
  1896 			out() << "  </script> -->\n";
       
  1897 			out() << "</body>\n";
       
  1898 		}
  1872           out() <<   "</html>\n";
  1899           out() <<   "</html>\n";
  1873 }
  1900 }
  1874 
  1901 
  1875 void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
  1902 void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
  1876                                   const Node *relative)
  1903                                   const Node *relative)
  1877 {
  1904 {
  1878     Text brief = node->doc().briefText();
  1905     Text brief = node->doc().briefText();
  1879     if (!brief.isEmpty()) {
  1906     if (!brief.isEmpty()) {
       
  1907         generateExtractionMark(node, BriefMark);
  1880         out() << "<p>";
  1908         out() << "<p>";
  1881         generateText(brief, node, marker);
  1909         generateText(brief, node, marker);
  1882         if (!relative || node == relative)
  1910         if (!relative || node == relative)
  1883             out() << " <a href=\"#";
  1911             out() << " <a href=\"#";
  1884         else
  1912         else
  1885             out() << " <a href=\"" << linkForNode(node, relative) << "#";
  1913             out() << " <a href=\"" << linkForNode(node, relative) << "#";
  1886         out() << registerRef("details") << "\">More...</a></p>\n";
  1914         out() << registerRef("details") << "\">More...</a></p>\n";
       
  1915         generateExtractionMark(node, EndMark);
  1887     }
  1916     }
  1888 }
  1917 }
  1889 
  1918 
  1890 void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
  1919 void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
  1891 {
  1920 {
  1892     if (!inner->includes().isEmpty()) {
  1921     if (!inner->includes().isEmpty()) {
  1893         out() << "<pre class=\"highlightedCode\">"
  1922         out() << "<pre class=\"highlightedCode brush: cpp\">"
  1894               << trimmedTrailing(highlightedCode(indent(codeIndent,
  1923               << trimmedTrailing(highlightedCode(indent(codeIndent,
  1895                                                         marker->markedUpIncludes(inner->includes())),
  1924                                                         marker->markedUpIncludes(inner->includes())),
  1896                                                  marker,inner))
  1925                                                  marker,inner))
  1897               << "</pre>";
  1926               << "</pre>";
  1898     }
  1927     }
  2003     // disable nested links in table of contents
  2032     // disable nested links in table of contents
  2004     inContents = true;
  2033     inContents = true;
  2005     inLink = true;
  2034     inLink = true;
  2006 
  2035 
  2007     out() << "<div class=\"toc\">\n";
  2036     out() << "<div class=\"toc\">\n";
  2008     out() << "<h3>Contents</h3>\n";
  2037     out() << "<h3><a name=\"toc\">Contents</a></h3>\n";
  2009     sectionNumber.append("1");
  2038     sectionNumber.append("1");
  2010     out() << "<ul>\n";
  2039     out() << "<ul>\n";
  2011 
  2040 
  2012     if (node->subType() == Node::Module) {
  2041     if (node->subType() == Node::Module) {
  2013         if (moduleNamespaceMap.contains(node->name())) {
  2042         if (moduleNamespaceMap.contains(node->name())) {
  2034                 detailsBase = 1;
  2063                 detailsBase = 1;
  2035                 break;
  2064                 break;
  2036             }
  2065             }
  2037         }
  2066         }
  2038     }
  2067     }
  2039     else if (sections && (node->type() == Node::Class)) {
  2068     else if (sections && ((node->type() == Node::Class) ||
       
  2069                           (node->type() == Node::Namespace) ||
       
  2070                           (node->subType() == Node::QmlClass))) {
  2040         QList<Section>::ConstIterator s = sections->begin();
  2071         QList<Section>::ConstIterator s = sections->begin();
  2041         while (s != sections->end()) {
  2072         while (s != sections->end()) {
  2042             if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
  2073             if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
  2043                 out() << "<li class=\"level"
  2074                 out() << "<li class=\"level"
  2044                       << sectionNumber.size()
  2075                       << sectionNumber.size()
  2112                   << ".html\">Prev: ";
  2143                   << ".html\">Prev: ";
  2113             generateText(section.previousHeading(), node, marker);
  2144             generateText(section.previousHeading(), node, marker);
  2114             out() << "</a>]\n";
  2145             out() << "</a>]\n";
  2115 #endif
  2146 #endif
  2116         }
  2147         }
       
  2148 		if (fake->name() != QString("index.html"))
       
  2149 			{
  2117         if (bar.current.begin() != 0) {
  2150         if (bar.current.begin() != 0) {
  2118             out() << "[<a href=\"" << "home"
  2151             out() << "[<a href=\"" << "home"
  2119                   << ".html\">Home</a>]\n";
  2152                   << ".html\">Home</a>]\n";
  2120         }
  2153         }
  2121         if (bar.next.begin() != 0) {
  2154         if (bar.next.begin() != 0) {
  2123                   << ".html\">Next: ";
  2156                   << ".html\">Next: ";
  2124             generateText(Text::sectionHeading(bar.next.begin()), node, marker);
  2157             generateText(Text::sectionHeading(bar.next.begin()), node, marker);
  2125             out() << "</a>]\n";
  2158             out() << "</a>]\n";
  2126         }
  2159         }
  2127         out() << "</p>\n";
  2160         out() << "</p>\n";
       
  2161 		}
  2128     }
  2162     }
  2129 }
  2163 }
  2130 #endif
  2164 #endif
  2131 
  2165 
  2132 QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
  2166 QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
  2213         generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
  2247         generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
  2214     }
  2248     }
  2215 
  2249 
  2216     sections = marker->sections(inner, CodeMarker::Detailed, status);
  2250     sections = marker->sections(inner, CodeMarker::Detailed, status);
  2217     for (i = 0; i < sections.size(); ++i) {
  2251     for (i = 0; i < sections.size(); ++i) {
  2218         out() << "<hr />\n";
  2252         //out() << "<hr />\n";
  2219         out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
  2253         out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
  2220 
  2254 
  2221         NodeList::ConstIterator m = sections.at(i).members.begin();
  2255         NodeList::ConstIterator m = sections.at(i).members.begin();
  2222         while (m != sections.at(i).members.end()) {
  2256         while (m != sections.at(i).members.end()) {
  2223             if ((*m)->access() != Node::Private)
  2257             if ((*m)->access() != Node::Private)
  2292 
  2326 
  2293         if (++row % 2 == 1)
  2327         if (++row % 2 == 1)
  2294             out() << "<tr class=\"odd topAlign\">";
  2328             out() << "<tr class=\"odd topAlign\">";
  2295         else
  2329         else
  2296             out() << "<tr class=\"even topAlign\">";
  2330             out() << "<tr class=\"even topAlign\">";
  2297         out() << "<td><p>";
  2331         out() << "<td class=\"tblName\"><p>";
  2298         generateFullName(node, relative, marker);
  2332         generateFullName(node, relative, marker);
  2299         out() << "</p></td>";
  2333         out() << "</p></td>";
  2300 
  2334 
  2301         if (!(node->type() == Node::Fake)) {
  2335         if (!(node->type() == Node::Fake)) {
  2302             Text brief = node->doc().trimmedBriefText(name);
  2336             Text brief = node->doc().trimmedBriefText(name);
  2303             if (!brief.isEmpty()) {
  2337             if (!brief.isEmpty()) {
  2304                 out() << "<td><p>";
  2338                 out() << "<td class=\"tblDescr\"><p>";
  2305                 generateText(brief, node, marker);
  2339                 generateText(brief, node, marker);
  2306                 out() << "</p></td>";
  2340                 out() << "</p></td>";
  2307             }
  2341             }
  2308         }
  2342         }
  2309         else {
  2343         else {
  2310             out() << "<td><p>";
  2344             out() << "<td class=\"tblDescr\"><p>";
  2311             out() << protectEnc(node->doc().briefText().toString());
  2345             out() << protectEnc(node->doc().briefText().toString());
  2312             out() << "</p></td>";
  2346             out() << "</p></td>";
  2313         }
  2347         }
  2314         out() << "</tr>\n";
  2348         out() << "</tr>\n";
  2315     }
  2349     }
  2330                                         const NodeMap &classMap,
  2364                                         const NodeMap &classMap,
  2331                                         bool includeAlphabet,
  2365                                         bool includeAlphabet,
  2332                                         QString commonPrefix)
  2366                                         QString commonPrefix)
  2333 {
  2367 {
  2334     const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
  2368     const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
  2335     const int NumColumns = 3; // number of columns in the result
       
  2336 
  2369 
  2337     if (classMap.isEmpty())
  2370     if (classMap.isEmpty())
  2338         return;
  2371         return;
  2339 
  2372 
  2340     /*
  2373     /*
  2413         if (pieces.size() == 1)
  2446         if (pieces.size() == 1)
  2414             key = pieces.last().mid(idx).toLower();
  2447             key = pieces.last().mid(idx).toLower();
  2415         else
  2448         else
  2416             key = pieces.last().toLower();
  2449             key = pieces.last().toLower();
  2417 
  2450 
  2418         int paragraphNo = NumParagraphs - 1;
  2451         int paragraphNr = NumParagraphs - 1;
  2419 
  2452 
  2420         if (key[0].digitValue() != -1) {
  2453         if (key[0].digitValue() != -1) {
  2421             paragraphNo = key[0].digitValue();
  2454             paragraphNr = key[0].digitValue();
  2422         }
  2455         }
  2423         else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
  2456         else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
  2424             paragraphNo = 10 + key[0].unicode() - 'a';
  2457             paragraphNr = 10 + key[0].unicode() - 'a';
  2425         }
  2458         }
  2426 
  2459 
  2427         paragraphName[paragraphNo] = key[0].toUpper();
  2460         paragraphName[paragraphNr] = key[0].toUpper();
  2428         usedParagraphNames.insert(key[0].toLower().cell());
  2461         usedParagraphNames.insert(key[0].toLower().cell());
  2429         paragraph[paragraphNo].insert(key, c.value());
  2462         paragraph[paragraphNr].insert(key, c.value());
  2430         ++c;
  2463         ++c;
  2431     }
  2464     }
  2432 
  2465 
  2433     /*
  2466     /*
  2434       Each paragraph j has a size: paragraph[j].count(). In the
  2467       Each paragraph j has a size: paragraph[j].count(). In the
  2437 
  2470 
  2438       We now want to compute the paragraph offset. Paragraphs 0 to 6
  2471       We now want to compute the paragraph offset. Paragraphs 0 to 6
  2439       start at offsets 0, 3, 4, 8, 9, 14, 23.
  2472       start at offsets 0, 3, 4, 8, 9, 14, 23.
  2440     */
  2473     */
  2441     int paragraphOffset[NumParagraphs + 1];     // 37 + 1
  2474     int paragraphOffset[NumParagraphs + 1];     // 37 + 1
  2442     int i, j, k;
       
  2443 
       
  2444     paragraphOffset[0] = 0;
  2475     paragraphOffset[0] = 0;
  2445     for (j = 0; j < NumParagraphs; j++)         // j = 0..36
  2476     for (int i=0; i<NumParagraphs; i++)         // i = 0..36
  2446         paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
  2477         paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count();
  2447 
  2478 
  2448     int firstOffset[NumColumns + 1];
  2479     int curParNr = 0;
  2449     int currentOffset[NumColumns];
  2480     int curParOffset = 0;
  2450     int currentParagraphNo[NumColumns];
  2481 
  2451     int currentOffsetInParagraph[NumColumns];
  2482     /*
  2452 
  2483       Output the alphabet as a row of links.
  2453     int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
  2484      */
  2454     int curParagNo = 0;
       
  2455 
       
  2456     for (i = 0; i < NumColumns; i++) {
       
  2457         firstOffset[i] = qMin(i * numRows, classMap.size());
       
  2458         currentOffset[i] = firstOffset[i];
       
  2459 
       
  2460         for (j = curParagNo; j < NumParagraphs; j++) {
       
  2461             if (paragraphOffset[j] > firstOffset[i])
       
  2462                 break;
       
  2463             if (paragraphOffset[j] <= firstOffset[i])
       
  2464                 curParagNo = j;
       
  2465         }
       
  2466         currentParagraphNo[i] = curParagNo;
       
  2467         currentOffsetInParagraph[i] = firstOffset[i] -
       
  2468                                       paragraphOffset[curParagNo];
       
  2469     }
       
  2470     firstOffset[NumColumns] = classMap.count();
       
  2471 
       
  2472     if (includeAlphabet) {
  2485     if (includeAlphabet) {
  2473         out() << "<p  class=\"centerAlign functionIndex\"><b>";
  2486         out() << "<p  class=\"centerAlign functionIndex\"><b>";
  2474         for (int i = 0; i < 26; i++) {
  2487         for (int i = 0; i < 26; i++) {
  2475             QChar ch('a' + i);
  2488             QChar ch('a' + i);
  2476             if (usedParagraphNames.contains(char('a' + i)))
  2489             if (usedParagraphNames.contains(char('a' + i)))
  2477                 out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
  2490                 out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
  2478         }
  2491         }
  2479         out() << "</b></p>\n";
  2492         out() << "</b></p>\n";
  2480     }
  2493     }
  2481 
  2494 
  2482     out() << "<table class=\"generic\">\n";
  2495     /*
  2483     for (k = 0; k < numRows; k++) {
  2496       Output a <div> element to contain all the <dl> elements.
  2484         if (++numTableRows % 2 == 1)
  2497      */
  2485             out() << "<tr class=\"odd topAlign\">";
  2498     out() << "<div class=\"flowListDiv\">\n";
  2486         else
  2499 
  2487             out() << "<tr class=\"even topAlign\">";
  2500     for (int i=0; i<classMap.count()-1; i++) {
  2488         //break;
  2501         while ((curParNr < NumParagraphs) &&
  2489 
  2502                (curParOffset == paragraph[curParNr].count())) {
  2490 //	out() << "<tr>\n";
  2503             ++curParNr;
  2491         for (i = 0; i < NumColumns; i++) {
  2504             curParOffset = 0;
  2492             if (currentOffset[i] >= firstOffset[i + 1]) {
  2505         }
  2493                 // this column is finished
  2506 
  2494                 out() << "<td>\n</td>\n"; // check why?
  2507         /*
  2495             }
  2508           Starting a new paragraph means starting a new <dl>.
  2496             else {
  2509         */
  2497                 while ((currentParagraphNo[i] < NumParagraphs) &&
  2510         if (curParOffset == 0) {
  2498                        (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) {
  2511             if (i > 0)
  2499                     ++currentParagraphNo[i];
  2512                 out() << "</dl>\n";
  2500                     currentOffsetInParagraph[i] = 0;
  2513             if (++numTableRows % 2 == 1)
  2501                 }
  2514                 out() << "<dl class=\"flowList odd\">";
  2502 #if 0
  2515             else
  2503                 if (currentParagraphNo[i] >= NumParagraphs) {
  2516                 out() << "<dl class=\"flowList even\">";
  2504                     qDebug() << "### Internal error ###" << __FILE__ << __LINE__
  2517             out() << "<dt class=\"alphaChar\">";
  2505                              << currentParagraphNo[i] << NumParagraphs;
  2518             if (includeAlphabet) {
  2506                     currentParagraphNo[i] = NumParagraphs - 1;
  2519                 QChar c = paragraphName[curParNr][0].toLower();
  2507                 }
  2520                 out() << QString("<a name=\"%1\"></a>").arg(c);
  2508 #endif
  2521             }
  2509                 out() << "<th  class=\"rightAlign alphaChar\"><p>";
  2522             out() << "<b>"
  2510                 if (currentOffsetInParagraph[i] == 0) {
  2523                   << paragraphName[curParNr]
  2511                     // start a new paragraph
  2524                   << "</b>";
  2512                     if (includeAlphabet) {
  2525             out() << "</dt>\n";
  2513                         QChar c = paragraphName[currentParagraphNo[i]][0].toLower();
  2526         }
  2514                         out() << QString("<a name=\"%1\"></a>").arg(c);
  2527 
  2515                     }
  2528         /*
  2516                     out() << "<b>"
  2529           Output a <dd> for the current offset in the current paragraph.
  2517                           << paragraphName[currentParagraphNo[i]]
  2530          */
  2518                           << "</b>";
  2531         out() << "<dd>";
  2519                 }
  2532         if ((curParNr < NumParagraphs) &&
  2520                 out() << "</p></th>\n";
  2533             !paragraphName[curParNr].isEmpty()) {
  2521 
  2534             NodeMap::Iterator it;
  2522                 out() << "<td><p>";
  2535             it = paragraph[curParNr].begin();
  2523                 if ((currentParagraphNo[i] < NumParagraphs) &&
  2536             for (int i=0; i<curParOffset; i++)
  2524                     !paragraphName[currentParagraphNo[i]].isEmpty()) {
  2537                 ++it;
  2525                     NodeMap::Iterator it;
  2538 
  2526                     it = paragraph[currentParagraphNo[i]].begin();
  2539             /*
  2527                     for (j = 0; j < currentOffsetInParagraph[i]; j++)
  2540               Previously, we used generateFullName() for this, but we
  2528                         ++it;
  2541               require some special formatting.
  2529 
  2542             */
  2530                     // Previously, we used generateFullName() for this, but we
  2543             out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">";
  2531                     // require some special formatting.
  2544             
  2532                     out() << "<a href=\""
  2545             QStringList pieces;
  2533                         << linkForNode(it.value(), relative)
  2546             if (it.value()->subType() == Node::QmlClass)
  2534                         << "\">";
  2547                 pieces << it.value()->name();
  2535                     QStringList pieces;
  2548             else
  2536                     if (it.value()->subType() == Node::QmlClass)
  2549                 pieces = fullName(it.value(), relative, marker).split("::");
  2537                         pieces << it.value()->name();
  2550             out() << protectEnc(pieces.last());
  2538                     else
  2551             out() << "</a>";
  2539                         pieces = fullName(it.value(), relative, marker).split("::");
  2552             if (pieces.size() > 1) {
  2540                     out() << protectEnc(pieces.last());
  2553                 out() << " (";
  2541                     out() << "</a>";
  2554                 generateFullName(it.value()->parent(), relative, marker);
  2542                     if (pieces.size() > 1) {
  2555                 out() << ")";
  2543                         out() << " (";
  2556             }
  2544                         generateFullName(it.value()->parent(), relative, marker);
  2557         }
  2545                         out() << ")";
  2558         out() << "</dd>\n";
  2546                     }
  2559         curParOffset++;
  2547                 }
  2560     }
  2548                 out() << "</p></td>\n";
  2561     out() << "</dl>\n";
  2549 
  2562     out() << "</div>\n";
  2550                 currentOffset[i]++;
       
  2551                 currentOffsetInParagraph[i]++;
       
  2552             }
       
  2553         }
       
  2554         out() << "</tr>\n";
       
  2555     }
       
  2556     out() << "</table>\n";
       
  2557 }
  2563 }
  2558 
  2564 
  2559 void HtmlGenerator::generateFunctionIndex(const Node *relative,
  2565 void HtmlGenerator::generateFunctionIndex(const Node *relative,
  2560                                           CodeMarker *marker)
  2566                                           CodeMarker *marker)
  2561 {
  2567 {
  2610                                          CodeMarker *marker)
  2616                                          CodeMarker *marker)
  2611 {
  2617 {
  2612     QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
  2618     QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
  2613     while (it != legaleseTexts.end()) {
  2619     while (it != legaleseTexts.end()) {
  2614         Text text = it.key();
  2620         Text text = it.key();
  2615         out() << "<hr />\n";
  2621         //out() << "<hr />\n";
  2616         generateText(text, relative, marker);
  2622         generateText(text, relative, marker);
  2617         out() << "<ul>\n";
  2623         out() << "<ul>\n";
  2618         do {
  2624         do {
  2619             out() << "<li>";
  2625             out() << "<li>";
  2620             generateFullName(it.value(), relative, marker);
  2626             generateFullName(it.value(), relative, marker);
  2622             ++it;
  2628             ++it;
  2623         } while (it != legaleseTexts.end() && it.key() == text);
  2629         } while (it != legaleseTexts.end() && it.key() == text);
  2624         out() << "</ul>\n";
  2630         out() << "</ul>\n";
  2625     }
  2631     }
  2626 }
  2632 }
  2627 
       
  2628 /*void HtmlGenerator::generateSynopsis(const Node *node,
       
  2629                                      const Node *relative,
       
  2630                                      CodeMarker *marker,
       
  2631                                      CodeMarker::SynopsisStyle style)
       
  2632 {
       
  2633     QString marked = marker->markedUpSynopsis(node, relative, style);
       
  2634     QRegExp templateTag("(<[^@>]*>)");
       
  2635     if (marked.indexOf(templateTag) != -1) {
       
  2636         QString contents = protectEnc(marked.mid(templateTag.pos(1),
       
  2637                                               templateTag.cap(1).length()));
       
  2638         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
       
  2639                         contents);
       
  2640     }
       
  2641     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
       
  2642                    "<i>\\1<sub>\\2</sub></i>");
       
  2643     marked.replace("<@param>", "<i>");
       
  2644     marked.replace("</@param>", "</i>");
       
  2645 
       
  2646     if (style == CodeMarker::Summary)
       
  2647         marked.replace("@name>", "b>");
       
  2648 
       
  2649     if (style == CodeMarker::SeparateList) {
       
  2650         QRegExp extraRegExp("<@extra>.*</@extra>");
       
  2651         extraRegExp.setMinimal(true);
       
  2652         marked.replace(extraRegExp, "");
       
  2653     }
       
  2654     else {
       
  2655         marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
       
  2656         marked.replace("</@extra>", "</tt>");
       
  2657     }
       
  2658 
       
  2659     if (style != CodeMarker::Detailed) {
       
  2660         marked.replace("<@type>", "");
       
  2661         marked.replace("</@type>", "");
       
  2662     }
       
  2663     out() << highlightedCode(marked, marker, relative);
       
  2664 }*/
       
  2665 
  2633 
  2666 #ifdef QDOC_QML
  2634 #ifdef QDOC_QML
  2667 void HtmlGenerator::generateQmlItem(const Node *node,
  2635 void HtmlGenerator::generateQmlItem(const Node *node,
  2668                                     const Node *relative,
  2636                                     const Node *relative,
  2669                                     CodeMarker *marker,
  2637                                     CodeMarker *marker,
  2690 
  2658 
  2691     if (summary) {
  2659     if (summary) {
  2692         marked.replace("<@type>", "");
  2660         marked.replace("<@type>", "");
  2693         marked.replace("</@type>", "");
  2661         marked.replace("</@type>", "");
  2694     }
  2662     }
  2695     out() << highlightedCode(marked, marker, relative);
  2663     out() << highlightedCode(marked, marker, relative, false, node);
  2696 }
  2664 }
  2697 #endif
  2665 #endif
  2698 
  2666 
  2699 void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
  2667 void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
  2700 {
  2668 {
  2808         }
  2776         }
  2809         out() << "</ul>\n";
  2777         out() << "</ul>\n";
  2810     }
  2778     }
  2811 }
  2779 }
  2812 
  2780 
  2813 #ifdef QDOC_NAME_ALIGNMENT
       
  2814 void HtmlGenerator::generateSection(const NodeList& nl,
  2781 void HtmlGenerator::generateSection(const NodeList& nl,
  2815                                     const Node *relative,
  2782                                     const Node *relative,
  2816                                     CodeMarker *marker,
  2783                                     CodeMarker *marker,
  2817                                     CodeMarker::SynopsisStyle style)
  2784                                     CodeMarker::SynopsisStyle style)
  2818 {
  2785 {
  2819     bool name_alignment = true;
  2786     bool alignNames = true;
  2820     if (!nl.isEmpty()) {
  2787     if (!nl.isEmpty()) {
  2821         bool twoColumn = false;
  2788         bool twoColumn = false;
  2822         if (style == CodeMarker::SeparateList) {
  2789         if (style == CodeMarker::SeparateList) {
  2823             name_alignment = false;
  2790             alignNames = false;
  2824             twoColumn = (nl.count() >= 16);
  2791             twoColumn = (nl.count() >= 16);
  2825         }
  2792         }
  2826         else if (nl.first()->type() == Node::Property) {
  2793         else if (nl.first()->type() == Node::Property) {
  2827             twoColumn = (nl.count() >= 5);
  2794             twoColumn = (nl.count() >= 5);
  2828             name_alignment = false;
  2795             alignNames = false;
  2829         }
  2796         }
  2830         if (name_alignment) {
  2797         if (alignNames) {
  2831             out() << "<table class=\"alignedsummary\">\n";
  2798             out() << "<table class=\"alignedsummary\">\n";
  2832         }
  2799         }
  2833         else {
  2800         else {
  2834             if (twoColumn)
  2801             if (twoColumn)
  2835                 out() << "<table class=\"propsummary\">\n"
  2802                 out() << "<table class=\"propsummary\">\n"
  2843             if ((*m)->access() == Node::Private) {
  2810             if ((*m)->access() == Node::Private) {
  2844                 ++m;
  2811                 ++m;
  2845                 continue;
  2812                 continue;
  2846             }
  2813             }
  2847 
  2814 
  2848             if (name_alignment) {
  2815             if (alignNames) {
  2849                 out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
  2816                 out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
  2850             }
  2817             }
  2851             else {
  2818             else {
  2852                 if (twoColumn && i == (int) (nl.count() + 1) / 2)
  2819                 if (twoColumn && i == (int) (nl.count() + 1) / 2)
  2853                     out() << "</ul></td><td  class=\"topAlign\"><ul>\n";
  2820                     out() << "</ul></td><td  class=\"topAlign\"><ul>\n";
  2854                 out() << "<li class=\"fn\">";
  2821                 out() << "<li class=\"fn\">";
  2855             }
  2822             }
  2856 
  2823 
  2857             generateSynopsis(*m, relative, marker, style, name_alignment);
  2824             generateSynopsis(*m, relative, marker, style, alignNames);
  2858             if (name_alignment)
  2825             if (alignNames)
  2859                 out() << "</td></tr>\n";
  2826                 out() << "</td></tr>\n";
  2860             else
  2827             else
  2861                 out() << "</li>\n";
  2828                 out() << "</li>\n";
  2862             i++;
  2829             i++;
  2863             ++m;
  2830             ++m;
  2864         }
  2831         }
  2865         if (name_alignment)
  2832         if (alignNames)
  2866             out() << "</table>\n";
  2833             out() << "</table>\n";
  2867         else {
  2834         else {
  2868             out() << "</ul>\n";
  2835             out() << "</ul>\n";
  2869             if (twoColumn)
  2836             if (twoColumn)
  2870                 out() << "</td></tr>\n</table>\n";
  2837                 out() << "</td></tr>\n</table>\n";
  2875 void HtmlGenerator::generateSectionList(const Section& section,
  2842 void HtmlGenerator::generateSectionList(const Section& section,
  2876                                         const Node *relative,
  2843                                         const Node *relative,
  2877                                         CodeMarker *marker,
  2844                                         CodeMarker *marker,
  2878                                         CodeMarker::SynopsisStyle style)
  2845                                         CodeMarker::SynopsisStyle style)
  2879 {
  2846 {
  2880     bool name_alignment = true;
  2847     bool alignNames = true;
  2881     if (!section.members.isEmpty()) {
  2848     if (!section.members.isEmpty()) {
  2882         bool twoColumn = false;
  2849         bool twoColumn = false;
  2883         if (style == CodeMarker::SeparateList) {
  2850         if (style == CodeMarker::SeparateList) {
  2884             name_alignment = false;
  2851             alignNames = false;
  2885             twoColumn = (section.members.count() >= 16);
  2852             twoColumn = (section.members.count() >= 16);
  2886         }
  2853         }
  2887         else if (section.members.first()->type() == Node::Property) {
  2854         else if (section.members.first()->type() == Node::Property) {
  2888             twoColumn = (section.members.count() >= 5);
  2855             twoColumn = (section.members.count() >= 5);
  2889             name_alignment = false;
  2856             alignNames = false;
  2890         }
  2857         }
  2891         if (name_alignment) {
  2858         if (alignNames) {
  2892             out() << "<table class=\"alignedsummary\">\n";
  2859             out() << "<table class=\"alignedsummary\">\n";
  2893         }
  2860         }
  2894         else {
  2861         else {
  2895             if (twoColumn)
  2862             if (twoColumn)
  2896                 out() << "<table class=\"propsummary\">\n"
  2863                 out() << "<table class=\"propsummary\">\n"
  2904             if ((*m)->access() == Node::Private) {
  2871             if ((*m)->access() == Node::Private) {
  2905                 ++m;
  2872                 ++m;
  2906                 continue;
  2873                 continue;
  2907             }
  2874             }
  2908 
  2875 
  2909             if (name_alignment) {
  2876             if (alignNames) {
  2910                 out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
  2877                 out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
  2911             }
  2878             }
  2912             else {
  2879             else {
  2913                 if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  2880                 if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  2914                     out() << "</ul></td><td class=\"topAlign\"><ul>\n";
  2881                     out() << "</ul></td><td class=\"topAlign\"><ul>\n";
  2915                 out() << "<li class=\"fn\">";
  2882                 out() << "<li class=\"fn\">";
  2916             }
  2883             }
  2917 
  2884 
  2918             generateSynopsis(*m, relative, marker, style, name_alignment);
  2885             generateSynopsis(*m, relative, marker, style, alignNames);
  2919             if (name_alignment)
  2886             if (alignNames)
  2920                 out() << "</td></tr>\n";
  2887                 out() << "</td></tr>\n";
  2921             else
  2888             else
  2922                 out() << "</li>\n";
  2889                 out() << "</li>\n";
  2923             i++;
  2890             i++;
  2924             ++m;
  2891             ++m;
  2925         }
  2892         }
  2926         if (name_alignment)
  2893         if (alignNames)
  2927             out() << "</table>\n";
  2894             out() << "</table>\n";
  2928         else {
  2895         else {
  2929             out() << "</ul>\n";
  2896             out() << "</ul>\n";
  2930             if (twoColumn)
  2897             if (twoColumn)
  2931                 out() << "</td></tr>\n</table>\n";
  2898                 out() << "</td></tr>\n</table>\n";
  2932         }
  2899         }
  2933     }
  2900     }
  2934 
  2901 
  2935     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  2902     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  2936         out() << "<ul>\n";
  2903         out() << "<ul>\n";
  2937         generateSectionInheritedList(section, relative, marker, name_alignment);
  2904         generateSectionInheritedList(section, relative, marker);
  2938         out() << "</ul>\n";
  2905         out() << "</ul>\n";
  2939     }
  2906     }
  2940 }
  2907 }
  2941 
  2908 
  2942 void HtmlGenerator::generateSectionInheritedList(const Section& section,
  2909 void HtmlGenerator::generateSectionInheritedList(const Section& section,
  2943                                                  const Node *relative,
  2910                                                  const Node *relative,
  2944                                                  CodeMarker *marker,
  2911                                                  CodeMarker *marker)
  2945                                                  bool nameAlignment)
       
  2946 {
  2912 {
  2947     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  2913     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  2948     while (p != section.inherited.end()) {
  2914     while (p != section.inherited.end()) {
  2949         if (nameAlignment)
  2915         out() << "<li class=\"fn\">";
  2950             out() << "<li class=\"fn\">";
       
  2951         else
       
  2952             out() << "<li class=\"fn\">";
       
  2953         out() << (*p).second << " ";
  2916         out() << (*p).second << " ";
  2954         if ((*p).second == 1) {
  2917         if ((*p).second == 1) {
  2955             out() << section.singularMember;
  2918             out() << section.singularMember;
  2956         }
  2919         }
  2957         else {
  2920         else {
  2967 
  2930 
  2968 void HtmlGenerator::generateSynopsis(const Node *node,
  2931 void HtmlGenerator::generateSynopsis(const Node *node,
  2969                                      const Node *relative,
  2932                                      const Node *relative,
  2970                                      CodeMarker *marker,
  2933                                      CodeMarker *marker,
  2971                                      CodeMarker::SynopsisStyle style,
  2934                                      CodeMarker::SynopsisStyle style,
  2972                                      bool nameAlignment)
  2935                                      bool alignNames)
  2973 {
  2936 {
  2974     QString marked = marker->markedUpSynopsis(node, relative, style);
  2937     QString marked = marker->markedUpSynopsis(node, relative, style);
  2975     QRegExp templateTag("(<[^@>]*>)");
  2938     QRegExp templateTag("(<[^@>]*>)");
  2976     if (marked.indexOf(templateTag) != -1) {
  2939     if (marked.indexOf(templateTag) != -1) {
  2977         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  2940         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  3000 
  2963 
  3001     if (style != CodeMarker::Detailed) {
  2964     if (style != CodeMarker::Detailed) {
  3002         marked.replace("<@type>", "");
  2965         marked.replace("<@type>", "");
  3003         marked.replace("</@type>", "");
  2966         marked.replace("</@type>", "");
  3004     }
  2967     }
  3005     out() << highlightedCode(marked, marker, relative, style, nameAlignment);
  2968     out() << highlightedCode(marked, marker, relative, alignNames);
  3006 }
  2969 }
  3007 
  2970 
  3008 QString HtmlGenerator::highlightedCode(const QString& markedCode,
  2971 QString HtmlGenerator::highlightedCode(const QString& markedCode,
  3009                                        CodeMarker *marker,
  2972                                        CodeMarker* marker,
  3010                                        const Node *relative,
  2973                                        const Node* relative,
  3011                                        CodeMarker::SynopsisStyle ,
  2974                                        bool alignNames,
  3012                                        bool nameAlignment)
  2975                                        const Node* self)
  3013 {
  2976 {
  3014     QString src = markedCode;
  2977     QString src = markedCode;
  3015     QString html;
  2978     QString html;
  3016     QStringRef arg;
  2979     QStringRef arg;
  3017     QStringRef par1;
  2980     QStringRef par1;
  3018 
  2981 
  3019     const QChar charLangle = '<';
  2982     const QChar charLangle = '<';
  3020     const QChar charAt = '@';
  2983     const QChar charAt = '@';
  3021 
  2984 
       
  2985     static const QString typeTag("type");
       
  2986     static const QString headerTag("headerfile");
       
  2987     static const QString funcTag("func");
       
  2988     static const QString linkTag("link");
       
  2989     
  3022     // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
  2990     // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
  3023     static const QString linkTag("link");
       
  3024     bool done = false;
  2991     bool done = false;
  3025     for (int i = 0, n = src.size(); i < n;) {
  2992     for (int i = 0, srcSize = src.size(); i < srcSize;) {
  3026         if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
  2993         if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
  3027             if (nameAlignment && !done) {// && (i != 0)) Why was this here?
  2994             if (alignNames && !done) {// && (i != 0)) Why was this here?
  3028                 html += "</td><td class=\"memItemRight bottomAlign\">";
  2995                 html += "</td><td class=\"memItemRight bottomAlign\">";
  3029                 done = true;
  2996                 done = true;
  3030             }
  2997             }
  3031             i += 2;
  2998             i += 2;
  3032             if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
  2999             if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) {
  3033                 html += "<b>";
  3000                 html += "<b>";
  3034                 QString link = linkForNode(
  3001                 const Node* n = CodeMarker::nodeForString(par1.toString());
  3035                     CodeMarker::nodeForString(par1.toString()), relative);
  3002                 QString link = linkForNode(n, relative);
  3036                 addLink(link, arg, &html);
  3003                 addLink(link, arg, &html);
  3037                 html += "</b>";
  3004                 html += "</b>";
  3038             }
  3005             }
  3039             else {
  3006             else {
  3040                 html += charLangle;
  3007                 html += charLangle;
  3050     if (slow) {
  3017     if (slow) {
  3051         // is this block ever used at all?
  3018         // is this block ever used at all?
  3052         // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
  3019         // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
  3053         src = html;
  3020         src = html;
  3054         html = QString();
  3021         html = QString();
  3055         static const QString funcTag("func");
  3022         for (int i = 0, srcSize = src.size(); i < srcSize;) {
  3056         for (int i = 0, n = src.size(); i < n;) {
       
  3057             if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
  3023             if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
  3058                 i += 2;
  3024                 i += 2;
  3059                 if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
  3025                 if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
  3060                     QString link = linkForNode(
  3026                     const Node* n = marker->resolveTarget(par1.toString(),
  3061                             marker->resolveTarget(par1.toString(),
  3027                                                           myTree,
  3062                                                   myTree,
  3028                                                           relative);
  3063                                                   relative),
  3029                     QString link = linkForNode(n, relative);
  3064                             relative);
       
  3065                     addLink(link, arg, &html);
  3030                     addLink(link, arg, &html);
  3066                     par1 = QStringRef();
  3031                     par1 = QStringRef();
  3067                 }
  3032                 }
  3068                 else {
  3033                 else {
  3069                     html += charLangle;
  3034                     html += charLangle;
  3077     }
  3042     }
  3078 
  3043 
  3079     // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
  3044     // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
  3080     src = html;
  3045     src = html;
  3081     html = QString();
  3046     html = QString();
  3082     static const QString typeTags[] = { "type", "headerfile", "func" };
  3047 
  3083     for (int i = 0, n = src.size(); i < n;) {
  3048     for (int i=0, srcSize=src.size(); i<srcSize;) {
  3084         if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
  3049         if (src.at(i) == charLangle && src.at(i+1) == charAt) {
  3085             i += 2;
  3050             i += 2;
  3086             bool handled = false;
  3051             bool handled = false;
  3087             for (int k = 0; k != 3; ++k) {
  3052             if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
  3088                 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
  3053                 par1 = QStringRef();
  3089                     par1 = QStringRef();
  3054                 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative, self);
  3090                     QString link = linkForNode(
  3055                 addLink(linkForNode(n,relative), arg, &html);
  3091                             marker->resolveTarget(arg.toString(), myTree, relative),
  3056                 handled = true;
  3092                             relative);
  3057             }
  3093                     addLink(link, arg, &html);
  3058             else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
  3094                     handled = true;
  3059                 par1 = QStringRef();
  3095                     break;
  3060                 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
  3096                 }
  3061                 addLink(linkForNode(n,relative), arg, &html);
  3097             }
  3062                 handled = true;
       
  3063             }
       
  3064             else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
       
  3065                 par1 = QStringRef();
       
  3066                 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
       
  3067                 addLink(linkForNode(n,relative), arg, &html);
       
  3068                 handled = true;
       
  3069             }
       
  3070 
  3098             if (!handled) {
  3071             if (!handled) {
  3099                 html += charLangle;
  3072                 html += charLangle;
  3100                 html += charAt;
  3073                 html += charAt;
  3101             }
  3074             }
  3102         }
  3075         }
  3120         "<@char>",         "<span class=\"char\">",
  3093         "<@char>",         "<span class=\"char\">",
  3121         "</@comment>",     "</span>",
  3094         "</@comment>",     "</span>",
  3122         "</@preprocessor>","</span>",
  3095         "</@preprocessor>","</span>",
  3123         "</@string>",      "</span>",
  3096         "</@string>",      "</span>",
  3124         "</@char>",        "</span>"
  3097         "</@char>",        "</span>"
  3125         // "<@char>",      "<font color=blue>",
       
  3126         // "</@char>",     "</font>",
       
  3127         // "<@func>",      "<font color=green>",
       
  3128         // "</@func>",     "</font>",
       
  3129         // "<@id>",        "<i>",
       
  3130         // "</@id>",       "</i>",
       
  3131         // "<@keyword>",   "<b>",
       
  3132         // "</@keyword>",  "</b>",
       
  3133         // "<@number>",    "<font color=yellow>",
       
  3134         // "</@number>",   "</font>",
       
  3135         // "<@op>",        "<b>",
       
  3136         // "</@op>",       "</b>",
       
  3137         // "<@param>",     "<i>",
       
  3138         // "</@param>",    "</i>",
       
  3139         // "<@string>",    "<font color=green>",
       
  3140         // "</@string>",  "</font>",
       
  3141     };
  3098     };
  3142     for (int i = 0, n = src.size(); i < n;) {
  3099     for (int i = 0, n = src.size(); i < n;) {
  3143         if (src.at(i) == charLangle) {
  3100         if (src.at(i) == charLangle) {
  3144             bool handled = false;
  3101             bool handled = false;
  3145             for (int k = 0; k != 8; ++k) {
  3102             for (int k = 0; k != 8; ++k) {
  3172         }
  3129         }
  3173     }
  3130     }
  3174 
  3131 
  3175     return html;
  3132     return html;
  3176 }
  3133 }
  3177 
       
  3178 #else
       
  3179 void HtmlGenerator::generateSectionList(const Section& section,
       
  3180                                         const Node *relative,
       
  3181                                         CodeMarker *marker,
       
  3182                                         CodeMarker::SynopsisStyle style)
       
  3183 {
       
  3184     if (!section.members.isEmpty()) {
       
  3185         bool twoColumn = false;
       
  3186         if (style == CodeMarker::SeparateList) {
       
  3187             twoColumn = (section.members.count() >= 16);
       
  3188         }
       
  3189         else if (section.members.first()->type() == Node::Property) {
       
  3190             twoColumn = (section.members.count() >= 5);
       
  3191         }
       
  3192         if (twoColumn)
       
  3193             out() << "<table class=\"generic\">\n";
       
  3194         if (++numTableRows % 2 == 1)
       
  3195             out() << "<tr class=\"odd topAlign\">";
       
  3196         else
       
  3197             out() << "<tr class=\"even topAlign\">";
       
  3198 			
       
  3199 //                  << "<tr><td  class=\"topAlign\">";
       
  3200         out() << "<ul>\n";
       
  3201 
       
  3202         int i = 0;
       
  3203         NodeList::ConstIterator m = section.members.begin();
       
  3204         while (m != section.members.end()) {
       
  3205             if ((*m)->access() == Node::Private) {
       
  3206                 ++m;
       
  3207                 continue;
       
  3208             }
       
  3209 
       
  3210             if (twoColumn && i == (int) (section.members.count() + 1) / 2)
       
  3211                 out() << "</ul></td><td class=\"topAlign\"><ul>\n";
       
  3212 
       
  3213             out() << "<li class=\"fn\">";
       
  3214             if (style == CodeMarker::Accessors)
       
  3215                 out() << "<b>";
       
  3216             generateSynopsis(*m, relative, marker, style);
       
  3217             if (style == CodeMarker::Accessors)
       
  3218                 out() << "</b>";
       
  3219             out() << "</li>\n";
       
  3220             i++;
       
  3221             ++m;
       
  3222         }
       
  3223         out() << "</ul>\n";
       
  3224         if (twoColumn)
       
  3225             out() << "</td></tr>\n</table>\n";
       
  3226     }
       
  3227 
       
  3228     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
       
  3229         out() << "<ul>\n";
       
  3230         generateSectionInheritedList(section, relative, marker);
       
  3231         out() << "</ul>\n";
       
  3232     }
       
  3233 }
       
  3234 
       
  3235 void HtmlGenerator::generateSectionInheritedList(const Section& section,
       
  3236                                                  const Node *relative,
       
  3237                                                  CodeMarker *marker)
       
  3238 {
       
  3239     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
       
  3240     while (p != section.inherited.end()) {
       
  3241         out() << "<li class=\"fn\">";
       
  3242         out() << (*p).second << " ";
       
  3243         if ((*p).second == 1) {
       
  3244             out() << section.singularMember;
       
  3245         } else {
       
  3246             out() << section.pluralMember;
       
  3247         }
       
  3248         out() << " inherited from <a href=\"" << fileName((*p).first)
       
  3249               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
       
  3250               << protectEnc(marker->plainFullName((*p).first, relative))
       
  3251               << "</a></li>\n";
       
  3252         ++p;
       
  3253     }
       
  3254 }
       
  3255 
       
  3256 void HtmlGenerator::generateSynopsis(const Node *node,
       
  3257                                      const Node *relative,
       
  3258                                      CodeMarker *marker,
       
  3259                                      CodeMarker::SynopsisStyle style)
       
  3260 {
       
  3261     QString marked = marker->markedUpSynopsis(node, relative, style);
       
  3262     QRegExp templateTag("(<[^@>]*>)");
       
  3263     if (marked.indexOf(templateTag) != -1) {
       
  3264         QString contents = protectEnc(marked.mid(templateTag.pos(1),
       
  3265                                               templateTag.cap(1).length()));
       
  3266         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
       
  3267                         contents);
       
  3268     }
       
  3269     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
       
  3270     marked.replace("<@param>", "<i>");
       
  3271     marked.replace("</@param>", "</i>");
       
  3272 
       
  3273     if (style == CodeMarker::Summary)
       
  3274         marked.replace("@name>", "b>");
       
  3275 
       
  3276     if (style == CodeMarker::SeparateList) {
       
  3277         QRegExp extraRegExp("<@extra>.*</@extra>");
       
  3278         extraRegExp.setMinimal(true);
       
  3279         marked.replace(extraRegExp, "");
       
  3280     } else {
       
  3281         marked.replace("<@extra>", "<tt>");
       
  3282         marked.replace("</@extra>", "</tt>");
       
  3283     }
       
  3284 
       
  3285     if (style != CodeMarker::Detailed) {
       
  3286         marked.replace("<@type>", "");
       
  3287         marked.replace("</@type>", "");
       
  3288     }
       
  3289     out() << highlightedCode(marked, marker, relative);
       
  3290 }
       
  3291 
       
  3292 QString HtmlGenerator::highlightedCode(const QString& markedCode,
       
  3293                                        CodeMarker *marker,
       
  3294                                        const Node *relative)
       
  3295 {
       
  3296     QString src = markedCode;
       
  3297     QString html;
       
  3298     QStringRef arg;
       
  3299     QStringRef par1;
       
  3300 
       
  3301     const QChar charLangle = '<';
       
  3302     const QChar charAt = '@';
       
  3303 
       
  3304     // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
       
  3305     static const QString linkTag("link");
       
  3306     for (int i = 0, n = src.size(); i < n;) {
       
  3307         if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
       
  3308             i += 2;
       
  3309             if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
       
  3310                 const Node* node = CodeMarker::nodeForString(par1.toString());
       
  3311                 QString link = linkForNode(node, relative);
       
  3312                 addLink(link, arg, &html);
       
  3313             }
       
  3314             else {
       
  3315                 html += charLangle;
       
  3316                 html += charAt;
       
  3317             }
       
  3318         }
       
  3319         else {
       
  3320             html += src.at(i++);
       
  3321         }
       
  3322     }
       
  3323 
       
  3324     if (slow) {
       
  3325         // is this block ever used at all?
       
  3326         // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
       
  3327         src = html;
       
  3328         html = QString();
       
  3329         static const QString funcTag("func");
       
  3330         for (int i = 0, n = src.size(); i < n;) {
       
  3331             if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
       
  3332                 i += 2;
       
  3333                 if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
       
  3334                     QString link = linkForNode(
       
  3335                             marker->resolveTarget(par1.toString(),
       
  3336                                                   myTree,
       
  3337                                                   relative),
       
  3338                             relative);
       
  3339                     addLink(link, arg, &html);
       
  3340                     par1 = QStringRef();
       
  3341                 }
       
  3342                 else {
       
  3343                     html += charLangle;
       
  3344                     html += charAt;
       
  3345                 }
       
  3346             }
       
  3347             else {
       
  3348                 html += src.at(i++);
       
  3349             }
       
  3350         }
       
  3351     }
       
  3352 
       
  3353     // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
       
  3354     src = html;
       
  3355     html = QString();
       
  3356     static const QString typeTags[] = { "type", "headerfile", "func" };
       
  3357     for (int i = 0, n = src.size(); i < n;) {
       
  3358         if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
       
  3359             i += 2;
       
  3360             bool handled = false;
       
  3361             for (int k = 0; k != 3; ++k) {
       
  3362                 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
       
  3363                     par1 = QStringRef();
       
  3364                     QString link = linkForNode(
       
  3365                             marker->resolveTarget(arg.toString(), myTree, relative),
       
  3366                             relative);
       
  3367                     addLink(link, arg, &html);
       
  3368                     handled = true;
       
  3369                     break;
       
  3370                 }
       
  3371             }
       
  3372             if (!handled) {
       
  3373                 html += charLangle;
       
  3374                 html += charAt;
       
  3375             }
       
  3376         }
       
  3377         else {
       
  3378             html += src.at(i++);
       
  3379         }
       
  3380     }
       
  3381 
       
  3382     // replace all
       
  3383     // "<@comment>" -> "<span class=\"comment\">";
       
  3384     // "<@preprocessor>" -> "<span class=\"preprocessor\">";
       
  3385     // "<@string>" -> "<span class=\"string\">";
       
  3386     // "<@char>" -> "<span class=\"char\">";
       
  3387     // "</@(?:comment|preprocessor|string|char)>" -> "</span>"
       
  3388     src = html;
       
  3389     html = QString();
       
  3390     static const QString spanTags[] = {
       
  3391         "<@comment>",      "<span class=\"comment\">",
       
  3392         "<@preprocessor>", "<span class=\"preprocessor\">",
       
  3393         "<@string>",       "<span class=\"string\">",
       
  3394         "<@char>",         "<span class=\"char\">",
       
  3395         "</@comment>",     "</span>",
       
  3396         "</@preprocessor>","</span>",
       
  3397         "</@string>",      "</span>",
       
  3398         "</@char>",        "</span>"
       
  3399         // "<@char>",      "<font color=blue>",
       
  3400         // "</@char>",     "</font>",
       
  3401         // "<@func>",      "<font color=green>",
       
  3402         // "</@func>",     "</font>",
       
  3403         // "<@id>",        "<i>",
       
  3404         // "</@id>",       "</i>",
       
  3405         // "<@keyword>",   "<b>",
       
  3406         // "</@keyword>",  "</b>",
       
  3407         // "<@number>",    "<font color=yellow>",
       
  3408         // "</@number>",   "</font>",
       
  3409         // "<@op>",        "<b>",
       
  3410         // "</@op>",       "</b>",
       
  3411         // "<@param>",     "<i>",
       
  3412         // "</@param>",    "</i>",
       
  3413         // "<@string>",    "<font color=green>",
       
  3414         // "</@string>",  "</font>",
       
  3415     };
       
  3416     for (int i = 0, n = src.size(); i < n;) {
       
  3417         if (src.at(i) == charLangle) {
       
  3418             bool handled = false;
       
  3419             for (int k = 0; k != 8; ++k) {
       
  3420                 const QString & tag = spanTags[2 * k];
       
  3421                 if (tag == QStringRef(&src, i, tag.length())) {
       
  3422                     html += spanTags[2 * k + 1];
       
  3423                     i += tag.length();
       
  3424                     handled = true;
       
  3425                     break;
       
  3426                 }
       
  3427             }
       
  3428             if (!handled) {
       
  3429                 ++i;
       
  3430                 if (src.at(i) == charAt ||
       
  3431                     (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {
       
  3432                     // drop 'our' unknown tags (the ones still containing '@')
       
  3433                     while (i < n && src.at(i) != QLatin1Char('>'))
       
  3434                         ++i;
       
  3435                     ++i;
       
  3436                 }
       
  3437                 else {
       
  3438                     // retain all others
       
  3439                     html += charLangle;
       
  3440                 }
       
  3441             }
       
  3442         }
       
  3443         else {
       
  3444             html += src.at(i);
       
  3445             ++i;
       
  3446         }
       
  3447     }
       
  3448 
       
  3449     return html;
       
  3450 }
       
  3451 #endif
       
  3452 
  3134 
  3453 void HtmlGenerator::generateLink(const Atom* atom,
  3135 void HtmlGenerator::generateLink(const Atom* atom,
  3454                                  const Node* /* relative */,
  3136                                  const Node* /* relative */,
  3455                                  CodeMarker* marker)
  3137                                  CodeMarker* marker)
  3456 {
  3138 {
  3798     const EnumNode *enume;
  3480     const EnumNode *enume;
  3799 
  3481 
  3800 #ifdef GENERATE_MAC_REFS    
  3482 #ifdef GENERATE_MAC_REFS    
  3801     generateMacRef(node, marker);
  3483     generateMacRef(node, marker);
  3802 #endif    
  3484 #endif    
       
  3485     generateExtractionMark(node, MemberMark);
  3803     if (node->type() == Node::Enum
  3486     if (node->type() == Node::Enum
  3804             && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
  3487             && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
  3805 #ifdef GENERATE_MAC_REFS    
  3488 #ifdef GENERATE_MAC_REFS    
  3806         generateMacRef(enume->flagsType(), marker);
  3489         generateMacRef(enume->flagsType(), marker);
  3807 #endif        
  3490 #endif        
  3817     }
  3500     }
  3818     else {
  3501     else {
  3819         out() << "<h3 class=\"fn\">";
  3502         out() << "<h3 class=\"fn\">";
  3820         out() << "<a name=\"" + refForNode(node) + "\"></a>";
  3503         out() << "<a name=\"" + refForNode(node) + "\"></a>";
  3821         generateSynopsis(node, relative, marker, CodeMarker::Detailed);
  3504         generateSynopsis(node, relative, marker, CodeMarker::Detailed);
  3822         out() << "</h3>\n";
  3505         out() << "</h3>" << divNavTop << "\n";
  3823     }
  3506     }
  3824 
  3507 
  3825     generateStatus(node, marker);
  3508     generateStatus(node, marker);
  3826     generateBody(node, marker);
  3509     generateBody(node, marker);
  3827     generateThreadSafeness(node, marker);
  3510     generateThreadSafeness(node, marker);
  3860                   << protectEnc(enume->name())
  3543                   << protectEnc(enume->name())
  3861                   << " values.</p>\n";
  3544                   << " values.</p>\n";
  3862         }
  3545         }
  3863     }
  3546     }
  3864     generateAlsoList(node, marker);
  3547     generateAlsoList(node, marker);
       
  3548     generateExtractionMark(node, EndMark);
  3865 }
  3549 }
  3866 
  3550 
  3867 void HtmlGenerator::findAllClasses(const InnerNode *node)
  3551 void HtmlGenerator::findAllClasses(const InnerNode *node)
  3868 {
  3552 {
  3869     NodeList::const_iterator c = node->childNodes().constBegin();
  3553     NodeList::const_iterator c = node->childNodes().constBegin();
  3973         }
  3657         }
  3974         ++child;
  3658         ++child;
  3975     }
  3659     }
  3976 }
  3660 }
  3977 
  3661 
  3978 #if 0
       
  3979     const QRegExp versionSeparator("[\\-\\.]");
       
  3980     const int minorIndex = version.indexOf(versionSeparator);
       
  3981     const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);
       
  3982     version = version.left(patchIndex);
       
  3983 #endif
       
  3984 
       
  3985 void HtmlGenerator::findAllFunctions(const InnerNode *node)
  3662 void HtmlGenerator::findAllFunctions(const InnerNode *node)
  3986 {
  3663 {
  3987     NodeList::ConstIterator c = node->childNodes().begin();
  3664     NodeList::ConstIterator c = node->childNodes().begin();
  3988     while (c != node->childNodes().end()) {
  3665     while (c != node->childNodes().end()) {
  3989         if ((*c)->access() != Node::Private) {
  3666         if ((*c)->access() != Node::Private) {
  4043         }
  3720         }
  4044         ++c;
  3721         ++c;
  4045     }
  3722     }
  4046 }
  3723 }
  4047 
  3724 
  4048 #ifdef ZZZ_QDOC_QML
       
  4049 /*!
       
  4050   This function finds all the qml element nodes and
       
  4051   stores them in a map for later use.
       
  4052  */
       
  4053 void HtmlGenerator::findAllQmlClasses(const InnerNode *node)
       
  4054 {
       
  4055     NodeList::const_iterator c = node->childNodes().constBegin();
       
  4056     while (c != node->childNodes().constEnd()) {
       
  4057         if ((*c)->type() == Node::Fake) {
       
  4058             const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);
       
  4059             if (fakeNode->subType() == Node::QmlClass) {
       
  4060                 const QmlClassNode* qmlNode =
       
  4061                     static_cast<const QmlClassNode*>(fakeNode);
       
  4062                 const Node* n = qmlNode->classNode();
       
  4063             }
       
  4064             qmlClasses.insert(fakeNode->name(),*c);
       
  4065         }
       
  4066         ++c;
       
  4067     }
       
  4068 }
       
  4069 #endif
       
  4070 
       
  4071 int HtmlGenerator::hOffset(const Node *node)
  3725 int HtmlGenerator::hOffset(const Node *node)
  4072 {
  3726 {
  4073     switch (node->type()) {
  3727     switch (node->type()) {
  4074     case Node::Namespace:
  3728     case Node::Namespace:
  4075     case Node::Class:
  3729     case Node::Class:
  4076         return 2;
  3730         return 2;
  4077     case Node::Fake:
  3731     case Node::Fake:
  4078         if (node->doc().briefText().isEmpty())
  3732         return 1;
  4079             return 1;
       
  4080         else
       
  4081             return 2;
       
  4082     case Node::Enum:
  3733     case Node::Enum:
  4083     case Node::Typedef:
  3734     case Node::Typedef:
  4084     case Node::Function:
  3735     case Node::Function:
  4085     case Node::Property:
  3736     case Node::Property:
  4086     default:
  3737     default:
  4399         NodeList::ConstIterator m;
  4050         NodeList::ConstIterator m;
  4400         int count = section.members.size();
  4051         int count = section.members.size();
  4401         bool twoColumn = false;
  4052         bool twoColumn = false;
  4402         if (section.members.first()->type() == Node::QmlProperty) {
  4053         if (section.members.first()->type() == Node::QmlProperty) {
  4403             twoColumn = (count >= 5);
  4054             twoColumn = (count >= 5);
       
  4055             twoColumn = false;
  4404         }
  4056         }
  4405         if (twoColumn)
  4057         if (twoColumn)
  4406             out() << "<table class=\"qmlsummary\">\n";
  4058             out() << "<table class=\"qmlsummary\">\n";
  4407 			        if (++numTableRows % 2 == 1)
  4059 			        if (++numTableRows % 2 == 1)
  4408 				out() << "<tr class=\"odd topAlign\">";
  4060 				out() << "<tr class=\"odd topAlign\">";
  4438 {
  4090 {
  4439     const QmlPropertyNode* qpn = 0;
  4091     const QmlPropertyNode* qpn = 0;
  4440 #ifdef GENERATE_MAC_REFS    
  4092 #ifdef GENERATE_MAC_REFS    
  4441     generateMacRef(node, marker);
  4093     generateMacRef(node, marker);
  4442 #endif    
  4094 #endif    
       
  4095     generateExtractionMark(node, MemberMark);
  4443     out() << "<div class=\"qmlitem\">";
  4096     out() << "<div class=\"qmlitem\">";
  4444     if (node->subType() == Node::QmlPropertyGroup) {
  4097     if (node->subType() == Node::QmlPropertyGroup) {
  4445         const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
  4098         const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
  4446         NodeList::ConstIterator p = qpgn->childNodes().begin();
  4099         NodeList::ConstIterator p = qpgn->childNodes().begin();
  4447         out() << "<div class=\"qmlproto\">";
  4100         out() << "<div class=\"qmlproto\">";
  4448         out() << "<table class=\"qmlname\">";
  4101         out() << "<table class=\"qmlname\">";
  4449 
  4102 
  4450         while (p != qpgn->childNodes().end()) {
  4103         while (p != qpgn->childNodes().end()) {
  4451             if ((*p)->type() == Node::QmlProperty) {
  4104             if ((*p)->type() == Node::QmlProperty) {
  4452                 qpn = static_cast<const QmlPropertyNode*>(*p);
  4105                 qpn = static_cast<const QmlPropertyNode*>(*p);
  4453                 
  4106                 if (++numTableRows % 2 == 1)
  4454 				if (++numTableRows % 2 == 1)
  4107                     out() << "<tr class=\"odd\">";
  4455 					out() << "<tr class=\"odd\">";
  4108                 else
  4456 				else
  4109                     out() << "<tr class=\"even\">";
  4457 					out() << "<tr class=\"even\">";
       
  4458 				
  4110 				
  4459 				out() << "<td><p>";
  4111                 out() << "<td class=\"tblQmlPropNode\"><p>";
  4460                 //out() << "<tr><td>"; // old
  4112 
  4461                 out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
  4113                 out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
  4462                 if (!qpn->isWritable())
  4114 
       
  4115                 if (!qpn->isWritable(myTree)) {
  4463                     out() << "<span class=\"qmlreadonly\">read-only</span>";
  4116                     out() << "<span class=\"qmlreadonly\">read-only</span>";
       
  4117                 }
  4464                 if (qpgn->isDefault())
  4118                 if (qpgn->isDefault())
  4465                     out() << "<span class=\"qmldefault\">default</span>";
  4119                     out() << "<span class=\"qmldefault\">default</span>";
  4466                 generateQmlItem(qpn, relative, marker, false);
  4120                 generateQmlItem(qpn, relative, marker, false);
  4467                 out() << "</td></tr>";
  4121                 out() << "</td></tr>";
  4468             }
  4122             }
  4474     else if (node->type() == Node::QmlSignal) {
  4128     else if (node->type() == Node::QmlSignal) {
  4475         const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
  4129         const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
  4476         out() << "<div class=\"qmlproto\">";
  4130         out() << "<div class=\"qmlproto\">";
  4477         out() << "<table class=\"qmlname\">";
  4131         out() << "<table class=\"qmlname\">";
  4478         //out() << "<tr>";
  4132         //out() << "<tr>";
  4479 		if (++numTableRows % 2 == 1)
  4133         if (++numTableRows % 2 == 1)
  4480 			out() << "<tr class=\"odd\">";
  4134             out() << "<tr class=\"odd\">";
  4481 		else
  4135         else
  4482 			out() << "<tr class=\"even\">";
  4136             out() << "<tr class=\"even\">";
  4483         out() << "<td><p>";
  4137         out() << "<td class=\"tblQmlFuncNode\"><p>";
  4484         out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
  4138         out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
  4485         generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
  4139         generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
  4486         //generateQmlItem(qsn,relative,marker,false);
  4140         //generateQmlItem(qsn,relative,marker,false);
  4487         out() << "</p></td></tr>";
  4141         out() << "</p></td></tr>";
  4488         out() << "</table>";
  4142         out() << "</table>";
  4495         //out() << "<tr>";
  4149         //out() << "<tr>";
  4496 		if (++numTableRows % 2 == 1)
  4150 		if (++numTableRows % 2 == 1)
  4497 			out() << "<tr class=\"odd\">";
  4151 			out() << "<tr class=\"odd\">";
  4498 		else
  4152 		else
  4499 			out() << "<tr class=\"even\">";
  4153 			out() << "<tr class=\"even\">";
  4500         out() << "<td><p>";
  4154         out() << "<td class=\"tblQmlFuncNode\"><p>";
  4501         out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
  4155         out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
  4502         generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
  4156         generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
  4503         out() << "</p></td></tr>";
  4157         out() << "</p></td></tr>";
  4504         out() << "</table>";
  4158         out() << "</table>";
  4505         out() << "</div>";
  4159         out() << "</div>";
  4510     generateThreadSafeness(node, marker);
  4164     generateThreadSafeness(node, marker);
  4511     generateSince(node, marker);
  4165     generateSince(node, marker);
  4512     generateAlsoList(node, marker);
  4166     generateAlsoList(node, marker);
  4513     out() << "</div>";
  4167     out() << "</div>";
  4514     out() << "</div>";
  4168     out() << "</div>";
       
  4169     generateExtractionMark(node, EndMark);
  4515 }
  4170 }
  4516 
  4171 
  4517 /*!
  4172 /*!
  4518   Output the "Inherits" line for the QML element,
  4173   Output the "Inherits" line for the QML element,
  4519   if there should be one.
  4174   if there should be one.
  4527             linkPair = cn->links()[Node::InheritsLink];
  4182             linkPair = cn->links()[Node::InheritsLink];
  4528             QStringList strList(linkPair.first);
  4183             QStringList strList(linkPair.first);
  4529             const Node* n = myTree->findNode(strList,Node::Fake);
  4184             const Node* n = myTree->findNode(strList,Node::Fake);
  4530             if (n && n->subType() == Node::QmlClass) {
  4185             if (n && n->subType() == Node::QmlClass) {
  4531                 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
  4186                 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
  4532                 out() << "<p class=\"centerAlign\">";
       
  4533                 Text text;
  4187                 Text text;
  4534                 text << "[Inherits ";
  4188                 text << Atom::ParaLeft << "Inherits ";
  4535                 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4189                 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4536                 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4190                 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4537                 text << Atom(Atom::String, linkPair.second);
  4191                 text << Atom(Atom::String, linkPair.second);
  4538                 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4192                 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4539                 text << "]";
  4193                 text << Atom::ParaRight;
  4540                 generateText(text, cn, marker);
  4194                 generateText(text, cn, marker);
  4541                 out() << "</p>";
       
  4542             }
  4195             }
  4543         }
  4196         }
  4544     }
  4197     }
  4545 }
  4198 }
  4546 
  4199 
  4574 void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
  4227 void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
  4575                                             CodeMarker* marker)
  4228                                             CodeMarker* marker)
  4576 {
  4229 {
  4577     const ClassNode* cn = qcn->classNode();
  4230     const ClassNode* cn = qcn->classNode();
  4578     if (cn && (cn->status() != Node::Internal)) {
  4231     if (cn && (cn->status() != Node::Internal)) {
  4579         out() << "<p class=\"centerAlign\">";
       
  4580         Text text;
  4232         Text text;
  4581         text << "[";
  4233         text << Atom::ParaLeft;
  4582         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4234         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4583         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4235         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4584         text << Atom(Atom::String, qcn->name());
  4236         QString name = qcn->name();
       
  4237         if (name.startsWith(QLatin1String("QML:")))
       
  4238             name = name.mid(4); // remove the "QML:" prefix
       
  4239         text << Atom(Atom::String, name);
  4585         text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4240         text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4586         text << " instantiates the C++ class ";
  4241         text << " instantiates the C++ class ";
  4587         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4242         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4588         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4243         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4589         text << Atom(Atom::String, cn->name());
  4244         text << Atom(Atom::String, cn->name());
  4590         text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4245         text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4591         text << "]";
  4246         text << Atom::ParaRight;
  4592         generateText(text, qcn, marker);
  4247         generateText(text, qcn, marker);
  4593         out() << "</p>";
       
  4594     }
  4248     }
  4595 }
  4249 }
  4596 
  4250 
  4597 /*!
  4251 /*!
  4598   Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]"
  4252   Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]"
  4605                                            CodeMarker* marker)
  4259                                            CodeMarker* marker)
  4606 {
  4260 {
  4607     if (cn &&  cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
  4261     if (cn &&  cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
  4608         const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
  4262         const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
  4609         if (n && n->subType() == Node::QmlClass) {
  4263         if (n && n->subType() == Node::QmlClass) {
  4610             out() << "<p class=\"centerAlign\">";
       
  4611             Text text;
  4264             Text text;
  4612             text << "[";
  4265             text << Atom::ParaLeft;
  4613             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4266             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4614             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4267             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4615             text << Atom(Atom::String, cn->name());
  4268             text << Atom(Atom::String, cn->name());
  4616             text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4269             text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4617             text << " is instantiated by QML element ";
  4270             text << " is instantiated by QML element ";
  4618             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n));
  4271             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n));
  4619             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4272             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4620             text << Atom(Atom::String, n->name());
  4273             text << Atom(Atom::String, n->name());
  4621             text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4274             text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
  4622             text << "]";
  4275             text << Atom::ParaRight;
  4623             generateText(text, cn, marker);
  4276             generateText(text, cn, marker);
  4624             out() << "</p>";
       
  4625         }
  4277         }
  4626     }
  4278     }
  4627 }
  4279 }
  4628 
  4280 
  4629 /*!
  4281 /*!
  4748     writer.writeEndElement(); // qtPageIndex
  4400     writer.writeEndElement(); // qtPageIndex
  4749     writer.writeEndDocument();
  4401     writer.writeEndDocument();
  4750     file.close();
  4402     file.close();
  4751 }
  4403 }
  4752 
  4404 
       
  4405 void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType markType)
       
  4406 {
       
  4407     if (markType != EndMark) {
       
  4408         out() << "<!-- $$$" + node->name();
       
  4409         if (markType == MemberMark) {
       
  4410             if (node->type() == Node::Function) {
       
  4411                 const FunctionNode *func = static_cast<const FunctionNode *>(node);
       
  4412                 if (!func->associatedProperty()) {
       
  4413                     if (func->overloadNumber() == 1)
       
  4414                         out() << "[overload1]";
       
  4415                     out() << "$$$" + func->name() + func->rawParameters().remove(' ');
       
  4416                 }
       
  4417             } else if (node->type() == Node::Property) {
       
  4418                 out() << "-prop";
       
  4419                 const PropertyNode *prop = static_cast<const PropertyNode *>(node);
       
  4420                 const NodeList &list = prop->functions();
       
  4421                 foreach (const Node *propFuncNode, list) {
       
  4422                     if (propFuncNode->type() == Node::Function) {
       
  4423                         const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode);
       
  4424                         out() << "$$$" + func->name() + func->rawParameters().remove(' ');
       
  4425                     }
       
  4426                 }
       
  4427             } else if (node->type() == Node::Enum) {
       
  4428                 const EnumNode *enumNode = static_cast<const EnumNode *>(node);
       
  4429                 foreach (const EnumItem &item, enumNode->items())
       
  4430                     out() << "$$$" + item.name();
       
  4431             }
       
  4432         } else if (markType == BriefMark) {
       
  4433             out() << "-brief";
       
  4434         } else if (markType == DetailedDescriptionMark) {
       
  4435             out() << "-description";
       
  4436         }
       
  4437         out() << " -->\n";
       
  4438     } else {
       
  4439         out() << "<!-- @@@" + node->name() + " -->\n";
       
  4440     }
       
  4441 }
       
  4442 
  4753 #endif
  4443 #endif
  4754 
  4444 
  4755 #if 0 // fossil removed for new doc format MWS 19/04/2010
       
  4756     out() << "<!DOCTYPE html\n"
       
  4757              "    PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n";
       
  4758     out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
       
  4759 
       
  4760     QString shortVersion;
       
  4761     if ((project != "Qtopia") && (project != "Qt Extended")) {
       
  4762         shortVersion = project + " " + shortVersion + ": ";
       
  4763         if (node && !node->doc().location().isEmpty())
       
  4764             out() << "<!-- " << node->doc().location().fileName() << " -->\n";
       
  4765 
       
  4766         shortVersion = myTree->version();
       
  4767         if (shortVersion.count(QChar('.')) == 2)
       
  4768             shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
       
  4769         if (!shortVersion.isEmpty()) {
       
  4770             if (project == "QSA")
       
  4771                 shortVersion = "QSA " + shortVersion + ": ";
       
  4772             else
       
  4773                 shortVersion = "Qt " + shortVersion + ": ";
       
  4774         }
       
  4775     }
       
  4776 
       
  4777     out() << "<head>\n"
       
  4778              "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
       
  4779     out() << QString("<meta http-equiv=\"Content-type\" content=\"text/html; charset=%1\" />").arg(outputEncoding);
       
  4780 
       
  4781     if (!style.isEmpty())
       
  4782         out() << "    <style type=\"text/css\">" << style << "</style>\n";
       
  4783 
       
  4784     const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
       
  4785     if (!metaMap.isEmpty()) {
       
  4786         QMapIterator<QString, QString> i(metaMap);
       
  4787         while (i.hasNext()) {
       
  4788             i.next();
       
  4789             out() << "    <meta name=\"" << protectEnc(i.key()) << "\" contents=\""
       
  4790                   << protectEnc(i.value()) << "\" />\n";
       
  4791         }
       
  4792     }
       
  4793 
       
  4794     navigationLinks.clear();
       
  4795 
       
  4796     if (node && !node->links().empty()) {
       
  4797         QPair<QString,QString> linkPair;
       
  4798         QPair<QString,QString> anchorPair;
       
  4799         const Node *linkNode;
       
  4800 
       
  4801         if (node->links().contains(Node::PreviousLink)) {
       
  4802             linkPair = node->links()[Node::PreviousLink];
       
  4803             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4804             if (!linkNode || linkNode == node)
       
  4805                 anchorPair = linkPair;
       
  4806             else
       
  4807                 anchorPair = anchorForNode(linkNode);
       
  4808 
       
  4809             out() << "  <link rel=\"prev\" href=\""
       
  4810                   << anchorPair.first << "\" />\n";
       
  4811 
       
  4812             navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">";
       
  4813             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4814                 navigationLinks += protectEnc(anchorPair.second);
       
  4815             else
       
  4816                 navigationLinks += protectEnc(linkPair.second);
       
  4817             navigationLinks += "</a>]\n";
       
  4818         }
       
  4819         if (node->links().contains(Node::ContentsLink)) {
       
  4820             linkPair = node->links()[Node::ContentsLink];
       
  4821             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4822             if (!linkNode || linkNode == node)
       
  4823                 anchorPair = linkPair;
       
  4824             else
       
  4825                 anchorPair = anchorForNode(linkNode);
       
  4826 
       
  4827             out() << "  <link rel=\"contents\" href=\""
       
  4828                   << anchorPair.first << "\" />\n";
       
  4829 
       
  4830             navigationLinks += "[<a href=\"" + anchorPair.first + "\">";
       
  4831             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4832                 navigationLinks += protectEnc(anchorPair.second);
       
  4833             else
       
  4834                 navigationLinks += protectEnc(linkPair.second);
       
  4835             navigationLinks += "</a>]\n";
       
  4836         }
       
  4837         if (node->links().contains(Node::NextLink)) {
       
  4838             linkPair = node->links()[Node::NextLink];
       
  4839             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4840             if (!linkNode || linkNode == node)
       
  4841                 anchorPair = linkPair;
       
  4842             else
       
  4843                 anchorPair = anchorForNode(linkNode);
       
  4844 
       
  4845             out() << "  <link rel=\"next\" href=\""
       
  4846                   << anchorPair.first << "\" />\n";
       
  4847 
       
  4848             navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">";
       
  4849             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4850                 navigationLinks += protectEnc(anchorPair.second);
       
  4851             else
       
  4852                 navigationLinks += protectEnc(linkPair.second);
       
  4853             navigationLinks += "</a>]\n";
       
  4854         }
       
  4855         if (node->links().contains(Node::IndexLink)) {
       
  4856             linkPair = node->links()[Node::IndexLink];
       
  4857             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4858             if (!linkNode || linkNode == node)
       
  4859                 anchorPair = linkPair;
       
  4860             else
       
  4861                 anchorPair = anchorForNode(linkNode);
       
  4862             out() << "  <link rel=\"index\" href=\""
       
  4863                   << anchorPair.first << "\" />\n";
       
  4864         }
       
  4865         if (node->links().contains(Node::StartLink)) {
       
  4866             linkPair = node->links()[Node::StartLink];
       
  4867             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4868             if (!linkNode || linkNode == node)
       
  4869                 anchorPair = linkPair;
       
  4870             else
       
  4871                 anchorPair = anchorForNode(linkNode);
       
  4872             out() << "  <link rel=\"start\" href=\""
       
  4873                   << anchorPair.first << "\" />\n";
       
  4874         }
       
  4875     }
       
  4876 
       
  4877     foreach (const QString &stylesheet, stylesheets) {
       
  4878         out() << "  <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "
       
  4879               << "type=\"text/css\" />\n";
       
  4880     }
       
  4881 
       
  4882     foreach (const QString &customHeadElement, customHeadElements) {
       
  4883         out() << "  " << customHeadElement << "\n";
       
  4884     }
       
  4885 
       
  4886     out() << "</head>\n"
       
  4887  #endif       
       
  4888 
       
  4889  QT_END_NAMESPACE
  4445  QT_END_NAMESPACE