Changeset 846 for trunk/tools/qdoc3/htmlgenerator.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/qdoc3/htmlgenerator.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 45 45 46 46 #include "codemarker.h" 47 #include "codeparser.h" 47 48 #include "helpprojectwriter.h" 48 49 #include "htmlgenerator.h" … … 55 56 #include <qlist.h> 56 57 #include <qiterator.h> 58 #include <qtextcodec.h> 57 59 58 60 QT_BEGIN_NAMESPACE 59 61 60 62 #define COMMAND_VERSION Doc::alias("version") 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 = ""; 61 71 62 72 QString HtmlGenerator::sinceTitles[] = … … 72 82 " New Properties", 73 83 " New Variables", 84 " New QML Elements", 74 85 " New Qml Properties", 75 86 " New Qml Signals", … … 202 213 203 214 HtmlGenerator::HtmlGenerator() 204 : helpProjectWriter(0), inLink(false), inContents(false), 205 inSectionHeading(false), inTableHeader(false), numTableRows(0), 206 threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), 207 myTree(0), slow(false), obsoleteLinks(false) 215 : helpProjectWriter(0), 216 inLink(false), 217 inContents(false), 218 inSectionHeading(false), 219 inTableHeader(false), 220 numTableRows(0), 221 threeColumnEnumValueTable(true), 222 application(Online), 223 funcLeftParen("\\S(\\()"), 224 myTree(0), 225 slow(false), 226 obsoleteLinks(false) 208 227 { 209 228 } … … 249 268 Config::dot + 250 269 HTMLGENERATOR_POSTHEADER); 270 postPostHeader = config.getString(HtmlGenerator::format() + 271 Config::dot + 272 HTMLGENERATOR_POSTPOSTHEADER); 273 creatorPostHeader = config.getString(HtmlGenerator::format() + 274 Config::dot + 275 HTMLGENERATOR_CREATORPOSTHEADER); 276 creatorPostPostHeader = config.getString(HtmlGenerator::format() + 277 Config::dot + 278 HTMLGENERATOR_CREATORPOSTPOSTHEADER); 251 279 footer = config.getString(HtmlGenerator::format() + 252 280 Config::dot + … … 261 289 project = config.getString(CONFIG_PROJECT); 262 290 291 QString app = config.getString(CONFIG_APPLICATION); 292 if (app == "online") 293 application = Online; 294 else if (app == "creator") 295 application = Creator; 296 else 297 application = Creator; 298 263 299 projectDescription = config.getString(CONFIG_DESCRIPTION); 264 300 if (projectDescription.isEmpty() && !project.isEmpty()) … … 266 302 267 303 projectUrl = config.getString(CONFIG_URL); 304 305 outputEncoding = config.getString(CONFIG_OUTPUTENCODING); 306 if (outputEncoding.isEmpty()) 307 outputEncoding = QLatin1String("ISO-8859-1"); 308 outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit()); 309 310 naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE); 311 if (naturalLanguage.isEmpty()) 312 naturalLanguage = QLatin1String("en"); 268 313 269 314 QSet<QString> editionNames = config.subVars(CONFIG_EDITION); … … 322 367 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) 323 368 { 324 // Copy the stylesheets from the directory containing the qdocconf file.325 // ### This should be changed to use a special directory in doc/src.326 QStringList::ConstIterator styleIter = stylesheets.begin();327 QDir configPath = QDir::current();328 while (styleIter != stylesheets.end()) {329 QString filePath = configPath.absoluteFilePath(*styleIter);330 Config::copyFile(Location(), filePath, filePath, outputDir());331 ++styleIter;332 }333 334 369 myTree = tree; 335 370 nonCompatClasses.clear(); … … 342 377 legaleseTexts.clear(); 343 378 serviceClasses.clear(); 379 qmlClasses.clear(); 344 380 findAllClasses(tree->root()); 345 381 findAllFunctions(tree->root()); 346 382 findAllLegaleseTexts(tree->root()); 347 383 findAllNamespaces(tree->root()); 348 #ifdef ZZZ_QDOC_QML349 findAllQmlClasses(tree->root());350 #endif351 384 findAllSince(tree->root()); 352 385 … … 390 423 dcfQmakeRoot); 391 424 392 generateIndex(project.toLower().simplified().replace(" ", "-"),393 projectUrl,394 projectDescription);425 QString fileBase = project.toLower().simplified().replace(" ", "-"); 426 generateIndex(fileBase, projectUrl, projectDescription); 427 generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker); 395 428 396 429 helpProjectWriter->generate(myTree); … … 410 443 } 411 444 445 /*! 446 Generate html from an instance of Atom. 447 */ 412 448 int HtmlGenerator::generateAtom(const Atom *atom, 413 449 const Node *relative, … … 432 468 } 433 469 else { 434 out() << protect (atom->string());470 out() << protectEnc(atom->string()); 435 471 } 436 472 } 437 473 else { 438 out() << protect (atom->string());474 out() << protectEnc(atom->string()); 439 475 } 440 476 break; … … 484 520 out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]; 485 521 if (inLink) { 486 out() << protect (plainCode(atom->string()));522 out() << protectEnc(plainCode(atom->string())); 487 523 } 488 524 else { … … 492 528 break; 493 529 case Atom::Code: 494 out() << "<pre>"530 out() << "<pre class=\"highlightedCode brush: cpp\">" 495 531 << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), 496 532 marker,relative)) 497 533 << "</pre>\n"; 498 534 break; 499 535 #ifdef QDOC_QML 500 536 case Atom::Qml: 501 out() << "<pre>"537 out() << "<pre class=\"highlightedCode brush: cpp\">" 502 538 << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), 503 539 marker,relative)) 504 540 << "</pre>\n"; 505 541 break; 506 542 #endif 507 543 case Atom::CodeNew: 508 544 out() << "<p>you can rewrite it as</p>\n" 509 << "<pre >"545 << "<pre class=\"highlightedCode brush: cpp\">" 510 546 << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), 511 547 marker,relative)) … … 516 552 // fallthrough 517 553 case Atom::CodeBad: 518 out() << "<pre ><font color=\"#404040\">"519 << trimmedTrailing(protect (plainCode(indent(codeIndent,atom->string()))))520 << "</ font></pre>\n";521 554 out() << "<pre class=\"highlightedCode brush: cpp\">" 555 << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string())))) 556 << "</pre>\n"; 557 break; 522 558 case Atom::FootnoteLeft: 523 559 // ### For now … … 575 611 } 576 612 else if (atom->string() == "classes") { 577 generateCompactList(relative, marker, nonCompatClasses); 613 generateCompactList(relative, marker, nonCompatClasses, true); 614 } 615 else if (atom->string() == "qmlclasses") { 616 generateCompactList(relative, marker, qmlClasses, true); 578 617 } 579 618 else if (atom->string().contains("classesbymodule")) { … … 623 662 } 624 663 else if (atom->string() == "compatclasses") { 625 generateCompactList(relative, marker, compatClasses );664 generateCompactList(relative, marker, compatClasses, false); 626 665 } 627 666 else if (atom->string() == "obsoleteclasses") { 628 generateCompactList(relative, marker, obsoleteClasses );667 generateCompactList(relative, marker, obsoleteClasses, false); 629 668 } 630 669 else if (atom->string() == "functionindex") { … … 635 674 } 636 675 else if (atom->string() == "mainclasses") { 637 generateCompactList(relative, marker, mainClasses );676 generateCompactList(relative, marker, mainClasses, true); 638 677 } 639 678 else if (atom->string() == "services") { 640 generateCompactList(relative, marker, serviceClasses );679 generateCompactList(relative, marker, serviceClasses, false); 641 680 } 642 681 else if (atom->string() == "overviews") { … … 677 716 NewClassMaps::const_iterator ncmap; 678 717 ncmap = newClassMaps.find(atom->string()); 718 NewClassMaps::const_iterator nqcmap; 719 nqcmap = newQmlClassMaps.find(atom->string()); 679 720 if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) { 680 721 QList<Section> sections; 681 722 QList<Section>::ConstIterator s; 682 723 for (int i=0; i<LastSinceType; ++i) 683 sections.append(Section(sinceTitle(i),QString(),QString() ));724 sections.append(Section(sinceTitle(i),QString(),QString(),QString())); 684 725 685 726 NodeMultiMap::const_iterator n = nsmap.value().constBegin(); … … 687 728 const Node* node = n.value(); 688 729 switch (node->type()) { 730 case Node::Fake: 731 if (node->subType() == Node::QmlClass) { 732 sections[QmlClass].appendMember((Node*)node); 733 } 734 break; 689 735 case Node::Namespace: 690 736 sections[Namespace].appendMember((Node*)node); … … 769 815 << Doc::canonicalTitle((*s).name) 770 816 << "\"></a>\n"; 771 out() << "<h3>" << protect ((*s).name) << "</h3>\n";817 out() << "<h3>" << protectEnc((*s).name) << "</h3>\n"; 772 818 if (idx == Class) 773 generateCompactList(0, marker, ncmap.value(), QString("Q")); 819 generateCompactList(0, marker, ncmap.value(), false, QString("Q")); 820 else if (idx == QmlClass) 821 generateCompactList(0, marker, nqcmap.value(), false, QString("Q")); 774 822 else if (idx == MemberFunction) { 775 823 ParentMaps parentmaps; … … 793 841 << "\">"; 794 842 QStringList pieces = fullName(pmap.key(), 0, marker).split("::"); 795 out() << protect (pieces.last());843 out() << protectEnc(pieces.last()); 796 844 out() << "</a>" << ":</p>\n"; 797 845 798 846 generateSection(nlist, 0, marker, CodeMarker::Summary); 799 out() << "<br 847 out() << "<br/>"; 800 848 ++pmap; 801 849 } … … 818 866 text = atom->next()->string(); 819 867 if (atom->type() == Atom::Image) 820 out() << "<p align=\"center\">";868 out() << "<p class=\"centerAlign\">"; 821 869 if (fileName.isEmpty()) { 822 870 out() << "<font color=\"red\">[Missing image " 823 << protect (atom->string()) << "]</font>";871 << protectEnc(atom->string()) << "]</font>"; 824 872 } 825 873 else { 826 out() << "<img src=\"" << protect (fileName) << "\"";874 out() << "<img src=\"" << protectEnc(fileName) << "\""; 827 875 if (!text.isEmpty()) 828 out() << " alt=\"" << protect (text) << "\"";876 out() << " alt=\"" << protectEnc(text) << "\""; 829 877 out() << " />"; 830 878 helpProjectWriter->addExtraFile(fileName); … … 837 885 break; 838 886 case Atom::LegaleseLeft: 839 out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";887 out() << "<div class=\"LegaleseLeft\">"; 840 888 break; 841 889 case Atom::LegaleseRight: … … 843 891 break; 844 892 case Atom::LineBreak: 845 out() << "<br 893 out() << "<br/>"; 846 894 break; 847 895 case Atom::Link: … … 879 927 threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom); 880 928 if (threeColumnEnumValueTable) { 881 out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" " 882 << "cellspacing=\"1\" width=\"100%\">\n" 883 << "<tr><th width=\"25%\">Constant</th>" 884 << "<th width=\"15%\">Value</th>" 885 << "<th width=\"60%\">Description</th></tr>\n"; 929 out() << "<table class=\"valuelist\">"; 930 if (++numTableRows % 2 == 1) 931 out() << "<tr class=\"odd\">"; 932 else 933 out() << "<tr class=\"even\">"; 934 935 out() << "<th class=\"tblConst\">Constant</th>" 936 << "<th class=\"tblval\">Value</th>" 937 << "<th class=\"tbldscr\">Description</th></tr>\n"; 886 938 } 887 939 else { 888 out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" " 889 << "cellspacing=\"1\" width=\"40%\">\n" 890 << "<tr><th width=\"60%\">Constant</th><th " 891 << "width=\"40%\">Value</th></tr>\n"; 940 out() << "<table class=\"valuelist\">" 941 << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n"; 892 942 } 893 943 } 894 944 else { 895 out() << "<ol type=";945 out() << "<ol class="; 896 946 if (atom->string() == ATOM_LIST_UPPERALPHA) { 897 947 out() << "\"A\""; 898 } 948 } /* why type? changed to */ 899 949 else if (atom->string() == ATOM_LIST_LOWERALPHA) { 900 950 out() << "\"a\""; … … 923 973 // ### Trenton 924 974 925 out() << "<tr><td valign=\"top\"><tt>"926 << protect (plainCode(marker->markedUpEnumValue(atom->next()->string(),975 out() << "<tr><td class=\"topAlign\"><tt>" 976 << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(), 927 977 relative))) 928 << "</tt></td><td align=\"center\" valign=\"top\">";978 << "</tt></td><td class=\" topAlign\">"; 929 979 930 980 QString itemValue; … … 937 987 out() << "?"; 938 988 else 939 out() << "<tt>" << protect (itemValue) << "</tt>";989 out() << "<tt>" << protectEnc(itemValue) << "</tt>"; 940 990 941 991 skipAhead = 1; … … 952 1002 else if (atom->string() == ATOM_LIST_VALUE) { 953 1003 if (threeColumnEnumValueTable) { 954 out() << "</td><td valign=\"top\">";1004 out() << "</td><td class=\"topAlign\">"; 955 1005 if (matchAhead(atom, Atom::ListItemRight)) 956 1006 out() << " "; … … 982 1032 } 983 1033 else if (atom->string() == ATOM_LIST_VALUE) { 984 out() << "</table> </p>\n";1034 out() << "</table>\n"; 985 1035 } 986 1036 else { … … 1027 1077 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); 1028 1078 } 1029 out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a> \n";1079 out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>" << divNavTop << "\n"; 1030 1080 } 1031 1081 #else 1032 1082 out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString()) 1033 << "\"></a> \n";1083 << "\"></a>" << divNavTop << "\n"; 1034 1084 #endif 1035 1085 break; … … 1053 1103 } 1054 1104 else { 1055 out() << protect (atom->string());1105 out() << protectEnc(atom->string()); 1056 1106 } 1057 1107 break; … … 1063 1113 if (!atom->string().isEmpty()) { 1064 1114 if (atom->string().contains("%")) 1065 out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" " 1066 << "align=\"center\" cellpadding=\"2\" " 1067 << "cellspacing=\"1\" border=\"0\">\n"; 1115 out() << "<table class=\"generic\">\n "; // width=\"" << atom->string() << "\">\n "; 1068 1116 else { 1069 out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" " 1070 << "cellspacing=\"1\" border=\"0\">\n"; 1117 out() << "<table class=\"generic\">\n"; 1071 1118 } 1072 1119 } 1073 1120 else { 1074 out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" " 1075 << "cellspacing=\"1\" border=\"0\">\n"; 1121 out() << "<table class=\"generic\">\n"; 1076 1122 } 1077 1123 numTableRows = 0; 1078 1124 break; 1079 1125 case Atom::TableRight: 1080 out() << "</table> </p>\n";1126 out() << "</table>\n"; 1081 1127 break; 1082 1128 case Atom::TableHeaderLeft: 1083 out() << "<thead><tr valign=\"top\" class=\"qt-style\">";1129 out() << "<thead><tr class=\"qt-style topAlign\">"; 1084 1130 inTableHeader = true; 1085 1131 break; … … 1088 1134 if (matchAhead(atom, Atom::TableHeaderLeft)) { 1089 1135 skipAhead = 1; 1090 out() << "\n<tr valign=\"top\" class=\"qt-style\">";1136 out() << "\n<tr class=\"qt-style topAlign\">"; 1091 1137 } 1092 1138 else { … … 1097 1143 case Atom::TableRowLeft: 1098 1144 if (++numTableRows % 2 == 1) 1099 out() << "<tr valign=\"top\" class=\"odd\">";1145 out() << "<tr class=\"odd topAlign\">"; 1100 1146 else 1101 out() << "<tr valign=\"top\" class=\"even\">";1147 out() << "<tr class=\"even topAlign\">"; 1102 1148 break; 1103 1149 case Atom::TableRowRight: … … 1107 1153 { 1108 1154 if (inTableHeader) 1109 out() << "<th ";1155 out() << "<th "; 1110 1156 else 1111 out() << "<td ";1157 out() << "<td "; 1112 1158 1113 1159 QStringList spans = atom->string().split(","); … … 1117 1163 if (spans.at(1) != "1") 1118 1164 out() << " rowspan=\"" << spans.at(1) << "\""; 1165 if (inTableHeader) 1119 1166 out() << ">"; 1167 else 1168 out() << "><p>"; 1120 1169 } 1121 1170 if (matchAhead(atom, Atom::ParaLeft)) … … 1127 1176 out() << "</th>"; 1128 1177 else 1129 out() << "</ td>";1178 out() << "</p></td>"; 1130 1179 if (matchAhead(atom, Atom::ParaLeft)) 1131 1180 skipAhead = 1; … … 1164 1213 break; 1165 1214 case Atom::UnhandledFormat: 1166 out() << "< font color=\"red\"><b><Missing HTML></b></font>";1215 out() << "<b class=\"redFont\"><Missing HTML></b>"; 1167 1216 break; 1168 1217 case Atom::UnknownCommand: 1169 out() << "< font color=\"red\"><b><code>\\" << protect(atom->string())1170 << "</code></b> </font>";1218 out() << "<b class=\"redFont\"><code>\\" << protectEnc(atom->string()) 1219 << "</code></b>"; 1171 1220 break; 1172 1221 #ifdef QDOC_QML … … 1182 1231 } 1183 1232 1233 /*! 1234 Generate a reference page for a C++ class. 1235 */ 1184 1236 void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, 1185 1237 CodeMarker *marker) … … 1198 1250 rawTitle = marker->plainName(inner); 1199 1251 fullTitle = marker->plainFullName(inner); 1200 title = rawTitle + " Namespace Reference";1252 title = rawTitle + " Namespace"; 1201 1253 } 1202 1254 else if (inner->type() == Node::Class) { … … 1217 1269 << Atom(Atom::LineBreak); 1218 1270 1219 QString fixedModule = inner->moduleName(); 1220 if (fixedModule == "Qt3SupportLight") 1221 fixedModule = "Qt3Support"; 1222 if (!fixedModule.isEmpty()) 1223 subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]"; 1224 1225 if (fixedModule.isEmpty()) { 1226 QMultiMap<QString, QString> publicGroups = myTree->publicGroups(); 1227 QList<QString> groupNames = publicGroups.values(inner->name()); 1228 if (!groupNames.isEmpty()) { 1229 qSort(groupNames.begin(), groupNames.end()); 1230 subtitleText << "["; 1231 for (int j=0; j<groupNames.count(); j++) { 1232 subtitleText << Atom(Atom::AutoLink, groupNames[j]); 1233 if (j<groupNames.count()-1) 1234 subtitleText <<", "; 1235 } 1236 subtitleText << "]"; 1237 } 1238 } 1239 1240 generateHeader(title, inner, marker, true); 1241 generateTitle(title, subtitleText, SmallSubTitle, inner, marker); 1242 1243 #ifdef QDOC_QML 1244 if (classe && !classe->qmlElement().isEmpty()) { 1245 generateInstantiatedBy(classe,marker); 1246 } 1247 #endif 1248 1271 generateHeader(title, inner, marker); 1272 sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); 1273 generateTableOfContents(inner,marker,§ions); 1274 generateTitle(title, subtitleText, SmallSubTitle, inner, marker); 1249 1275 generateBrief(inner, marker); 1250 1276 generateIncludes(inner, marker); 1251 1277 generateStatus(inner, marker); 1252 1278 if (classe) { 1253 generateModuleWarning(classe, marker);1254 1279 generateInherits(classe, marker); 1255 1280 generateInheritedBy(classe, marker); 1281 #ifdef QDOC_QML 1282 if (!classe->qmlElement().isEmpty()) { 1283 generateInstantiatedBy(classe,marker); 1284 } 1285 #endif 1256 1286 } 1257 1287 generateThreadSafeness(inner, marker); … … 1283 1313 bool needOtherSection = false; 1284 1314 1285 sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); 1315 /* 1316 sections is built above for the call to generateTableOfContents(). 1317 */ 1286 1318 s = sections.begin(); 1287 1319 while (s != sections.end()) { … … 1292 1324 else { 1293 1325 if (!s->members.isEmpty()) { 1294 out() << "<hr />\n";1326 // out() << "<hr />\n"; 1295 1327 out() << "<a name=\"" 1296 1328 << registerRef((*s).name.toLower()) 1297 << "\"></a> \n";1298 out() << "<h2>" << protect ((*s).name) << "</h2>\n";1329 << "\"></a>" << divNavTop << "\n"; 1330 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1299 1331 generateSection(s->members, inner, marker, CodeMarker::Summary); 1300 1332 } 1301 1333 if (!s->reimpMembers.isEmpty()) { 1302 1334 QString name = QString("Reimplemented ") + (*s).name; 1303 out() << "<hr />\n";1335 // out() << "<hr />\n"; 1304 1336 out() << "<a name=\"" 1305 1337 << registerRef(name.toLower()) 1306 << "\"></a> \n";1307 out() << "<h2>" << protect (name) << "</h2>\n";1338 << "\"></a>" << divNavTop << "\n"; 1339 out() << "<h2>" << protectEnc(name) << "</h2>\n"; 1308 1340 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); 1309 1341 } … … 1311 1343 if (!s->inherited.isEmpty()) { 1312 1344 out() << "<ul>\n"; 1313 generateSectionInheritedList(*s, inner, marker , true);1345 generateSectionInheritedList(*s, inner, marker); 1314 1346 out() << "</ul>\n"; 1315 1347 } … … 1331 1363 } 1332 1364 1333 out() << "<a name=\"" << registerRef("details") << "\"></a> \n";1365 out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n"; 1334 1366 1335 1367 if (!inner->doc().isEmpty()) { 1336 out() << "<hr />\n" 1368 generateExtractionMark(inner, DetailedDescriptionMark); 1369 //out() << "<hr />\n" 1370 out() << "<div class=\"descr\">\n" // QTBUG-9504 1337 1371 << "<h2>" << "Detailed Description" << "</h2>\n"; 1338 1372 generateBody(inner, marker); 1373 out() << "</div>\n"; // QTBUG-9504 1339 1374 generateAlsoList(inner, marker); 1375 generateExtractionMark(inner, EndMark); 1340 1376 } 1341 1377 … … 1343 1379 s = sections.begin(); 1344 1380 while (s != sections.end()) { 1345 out() << "<hr />\n"; 1346 out() << "<h2>" << protect((*s).name) << "</h2>\n"; 1381 //out() << "<hr />\n"; 1382 if (!(*s).divClass.isEmpty()) 1383 out() << "<div class=\"" << (*s).divClass << "\">\n"; // QTBUG-9504 1384 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1347 1385 1348 1386 NodeList::ConstIterator m = (*s).members.begin(); … … 1393 1431 ++m; 1394 1432 } 1433 if (!(*s).divClass.isEmpty()) 1434 out() << "</div>\n"; // QTBUG-9504 1395 1435 ++s; 1396 1436 } … … 1419 1459 } 1420 1460 1461 /*! 1462 Generate the html page for a qdoc file that doesn't map 1463 to an underlying c++ file. 1464 */ 1421 1465 void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) 1422 1466 { … … 1429 1473 QList<Section>::const_iterator s; 1430 1474 1431 QString htmlTitle = fake->fullTitle(); 1475 QString fullTitle = fake->fullTitle(); 1476 QString htmlTitle = fullTitle; 1432 1477 if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) { 1433 1478 subTitleSize = SmallSubTitle; 1434 1479 htmlTitle += " (" + fake->subTitle() + ")"; 1435 1480 } 1436 1437 generateHeader(htmlTitle, fake, marker, true); 1438 generateTitle(fake->fullTitle(), 1481 else if (fake->subType() == Node::QmlBasicType) { 1482 fullTitle = "QML Basic Type: " + fullTitle; 1483 htmlTitle = fullTitle; 1484 } 1485 1486 generateHeader(htmlTitle, fake, marker); 1487 1488 /* 1489 Generate the TOC for the new doc format. 1490 Don't generate a TOC for the home page. 1491 */ 1492 const QmlClassNode* qml_cn = 0; 1493 if (fake->subType() == Node::QmlClass) { 1494 qml_cn = static_cast<const QmlClassNode*>(fake); 1495 sections = marker->qmlSections(qml_cn,CodeMarker::Summary,0); 1496 generateTableOfContents(fake,marker,§ions); 1497 } 1498 else if (fake->name() != QString("index.html")) 1499 generateTableOfContents(fake,marker,0); 1500 1501 generateTitle(fullTitle, 1439 1502 Text() << fake->subTitle(), 1440 1503 subTitleSize, … … 1448 1511 1449 1512 if (moduleNamespaceMap.contains(fake->name())) { 1513 out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << "\n"; 1450 1514 out() << "<h2>Namespaces</h2>\n"; 1451 1515 generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]); 1452 1516 } 1453 1517 if (moduleClassMap.contains(fake->name())) { 1518 out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << "\n"; 1454 1519 out() << "<h2>Classes</h2>\n"; 1455 1520 generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]); … … 1505 1570 #ifdef QDOC_QML 1506 1571 else if (fake->subType() == Node::QmlClass) { 1507 const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);1508 1572 const ClassNode* cn = qml_cn->classNode(); 1573 generateBrief(qml_cn, marker); 1509 1574 generateQmlInherits(qml_cn, marker); 1575 generateQmlInheritedBy(qml_cn, marker); 1510 1576 generateQmlInstantiates(qml_cn, marker); 1511 generateBrief(qml_cn, marker); 1512 sections = marker->qmlSections(qml_cn,CodeMarker::Summary); 1577 1578 QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); 1579 if (!allQmlMembersLink.isEmpty()) { 1580 out() << "<li><a href=\"" << allQmlMembersLink << "\">" 1581 << "List of all members, including inherited members</a></li>\n"; 1582 } 1583 1513 1584 s = sections.begin(); 1514 1585 while (s != sections.end()) { 1515 out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; 1516 out() << "<h2>" << protect((*s).name) << "</h2>\n"; 1586 out() << "<a name=\"" << registerRef((*s).name.toLower()) 1587 << "\"></a>" << divNavTop << "\n"; 1588 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1517 1589 generateQmlSummary(*s,fake,marker); 1518 1590 ++s; 1519 1591 } 1520 1592 1521 out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; 1593 generateExtractionMark(fake, DetailedDescriptionMark); 1594 out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n"; 1522 1595 out() << "<h2>" << "Detailed Description" << "</h2>\n"; 1523 1596 generateBody(fake, marker); … … 1525 1598 generateQmlText(cn->doc().body(), cn, marker, fake->name()); 1526 1599 generateAlsoList(fake, marker); 1527 out() << "<hr />\n"; 1528 1529 sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); 1600 generateExtractionMark(fake, EndMark); 1601 //out() << "<hr />\n"; 1602 1603 sections = marker->qmlSections(qml_cn,CodeMarker::Detailed,0); 1530 1604 s = sections.begin(); 1531 1605 while (s != sections.end()) { 1532 out() << "<h2>" << protect ((*s).name) << "</h2>\n";1606 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1533 1607 NodeList::ConstIterator m = (*s).members.begin(); 1534 1608 while (m != (*s).members.end()) { 1535 1609 generateDetailedQmlMember(*m, fake, marker); 1536 out() << "<br 1610 out() << "<br/>\n"; 1537 1611 fakeSection.keywords += qMakePair((*m)->name(), 1538 1612 linkForNode(*m,0)); … … 1549 1623 s = sections.begin(); 1550 1624 while (s != sections.end()) { 1551 out() << "<a name=\"" << registerRef((*s).name) << "\"></a> \n";1552 out() << "<h2>" << protect ((*s).name) << "</h2>\n";1625 out() << "<a name=\"" << registerRef((*s).name) << "\"></a>" << divNavTop << "\n"; 1626 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1553 1627 generateSectionList(*s, fake, marker, CodeMarker::Summary); 1554 1628 ++s; … … 1557 1631 Text brief = fake->doc().briefText(); 1558 1632 if (fake->subType() == Node::Module && !brief.isEmpty()) { 1559 out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; 1633 generateExtractionMark(fake, DetailedDescriptionMark); 1634 out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n"; 1635 out() << "<div class=\"descr\">\n"; // QTBUG-9504 1560 1636 out() << "<h2>" << "Detailed Description" << "</h2>\n"; 1561 1637 } 1638 else { 1639 generateExtractionMark(fake, DetailedDescriptionMark); 1640 out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504 1641 } 1562 1642 1563 1643 generateBody(fake, marker); 1644 out() << "</div>\n"; // QTBUG-9504 1564 1645 generateAlsoList(fake, marker); 1646 generateExtractionMark(fake, EndMark); 1565 1647 1566 1648 if (!fake->groupMembers().isEmpty()) { … … 1578 1660 s = sections.begin(); 1579 1661 while (s != sections.end()) { 1580 out() << "<hr />\n";1581 out() << "<h2>" << protect ((*s).name) << "</h2>\n";1662 //out() << "<hr />\n"; 1663 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; 1582 1664 1583 1665 NodeList::ConstIterator m = (*s).members.begin(); … … 1615 1697 } 1616 1698 1617 QString HtmlGenerator::fileExtension(const Node * /* node */) 1699 /*! 1700 Returns "html" for this subclass of Generator. 1701 */ 1702 QString HtmlGenerator::fileExtension(const Node * /* node */) const 1618 1703 { 1619 1704 return "html"; 1705 } 1706 1707 /*! 1708 Output breadcrumb list in the html file. 1709 */ 1710 void HtmlGenerator::generateBreadCrumbs(const QString& title, 1711 const Node *node, 1712 CodeMarker *marker) 1713 { 1714 Text breadcrumb; 1715 if (node->type() == Node::Class) { 1716 const ClassNode* cn = static_cast<const ClassNode*>(node); 1717 QString name = node->moduleName(); 1718 out() << " <li><a href=\"modules.html\">Modules</a></li>"; 1719 if (!name.isEmpty()) { 1720 out() << " <li>"; 1721 breadcrumb << Atom(Atom::AutoLink,name); 1722 generateText(breadcrumb, node, marker); 1723 out() << "</li>\n"; 1724 } 1725 if (!cn->name().isEmpty()) 1726 out() << " <li>" << protectEnc(cn->name()) << "</li>\n"; 1727 } 1728 else if (node->type() == Node::Fake) { 1729 const FakeNode* fn = static_cast<const FakeNode*>(node); 1730 if (node->subType() == Node::Module) { 1731 out() << " <li><a href=\"modules.html\">Modules</a></li>"; 1732 QString name = node->name(); 1733 if (!name.isEmpty()) 1734 out() << " <li>" << protectEnc(name) << "</li>\n"; 1735 } 1736 else if (node->subType() == Node::Group) { 1737 if (fn->name() == QString("modules")) 1738 out() << " <li>Modules</li>"; 1739 else { 1740 out() << " <li>" << protectEnc(title) << "</li>"; 1741 } 1742 } 1743 else if (node->subType() == Node::Page) { 1744 if (fn->name() == QString("qdeclarativeexamples.html")) { 1745 out() << " <li><a href=\"all-examples.html\">Examples</a></li>"; 1746 out() << " <li>QML Examples & Demos</li>"; 1747 } 1748 else if (fn->name().startsWith("examples-")) { 1749 out() << " <li><a href=\"all-examples.html\">Examples</a></li>"; 1750 out() << " <li>" << protectEnc(title) << "</li>"; 1751 } 1752 else if (fn->name() == QString("namespaces.html")) { 1753 out() << " <li>Namespaces</li>"; 1754 } 1755 else { 1756 out() << " <li>" << protectEnc(title) << "</li>"; 1757 } 1758 } 1759 else if (node->subType() == Node::QmlClass) { 1760 out() << " <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>"; 1761 out() << " <li>" << protectEnc(title) << "</li>"; 1762 } 1763 else if (node->subType() == Node::Example) { 1764 out() << " <li><a href=\"all-examples.html\">Examples</a></li>"; 1765 QStringList sl = fn->name().split('/'); 1766 if (sl.contains("declarative")) 1767 out() << " <li><a href=\"qdeclarativeexamples.html\">QML Examples & Demos</a></li>"; 1768 else { 1769 QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link 1770 QString t = CodeParser::titleFromName(name); 1771 } 1772 out() << " <li>" << protectEnc(title) << "</li>"; 1773 } 1774 } 1775 else if (node->type() == Node::Namespace) { 1776 out() << " <li><a href=\"namespaces.html\">Namespaces</a></li>"; 1777 out() << " <li>" << protectEnc(title) << "</li>"; 1778 } 1620 1779 } 1621 1780 1622 1781 void HtmlGenerator::generateHeader(const QString& title, 1623 1782 const Node *node, 1624 CodeMarker *marker, 1625 bool mainPage) 1626 { 1627 out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"; 1628 1629 out() << "<!DOCTYPE html\n" 1630 " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" 1631 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"; 1632 1783 CodeMarker *marker) 1784 { 1785 out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding); 1786 out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; 1787 out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage); 1788 out() << "<head>\n"; 1789 out() << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"; 1633 1790 QString shortVersion; 1634 if ((project != "Qtopia") && (project != "Qt Extended")) { 1635 shortVersion = project + " " + shortVersion + ": "; 1636 if (node && !node->doc().location().isEmpty()) 1637 out() << "<!-- " << node->doc().location().fileName() << " -->\n"; 1638 1639 shortVersion = myTree->version(); 1640 if (shortVersion.count(QChar('.')) == 2) 1641 shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); 1642 if (!shortVersion.isEmpty()) { 1643 if (project == "QSA") 1644 shortVersion = "QSA " + shortVersion + ": "; 1645 else 1646 shortVersion = "Qt " + shortVersion + ": "; 1647 } 1648 } 1649 1650 out() << "<head>\n" 1651 " <title>" << shortVersion << protect(title) << "</title>\n"; 1652 if (!style.isEmpty()) 1653 out() << " <style type=\"text/css\">" << style << "</style>\n"; 1654 1655 const QMap<QString, QString> &metaMap = node->doc().metaTagMap(); 1656 if (!metaMap.isEmpty()) { 1657 QMapIterator<QString, QString> i(metaMap); 1658 while (i.hasNext()) { 1659 i.next(); 1660 out() << " <meta name=\"" << protect(i.key()) << "\" contents=\"" 1661 << protect(i.value()) << "\" />\n"; 1662 } 1663 } 1664 1665 navigationLinks.clear(); 1791 shortVersion = project + " " + shortVersion + ": "; 1792 if (node && !node->doc().location().isEmpty()) 1793 out() << "<!-- " << node->doc().location().fileName() << " -->\n"; 1794 1795 shortVersion = myTree->version(); 1796 if (shortVersion.count(QChar('.')) == 2) 1797 shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); 1798 if (!shortVersion.isEmpty()) { 1799 if (project == "QSA") 1800 shortVersion = "QSA " + shortVersion + ": "; 1801 else 1802 shortVersion = "Qt " + shortVersion + ": "; 1803 } 1804 1805 // Generating page title 1806 out() << " <title>" << shortVersion << protectEnc(title) << "</title>\n"; 1807 // Adding style sheet 1808 out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n"; 1809 // Adding jquery and functions - providing online tools and search features 1810 out() << " <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n"; 1811 out() << " <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n"; 1812 1813 1814 // Adding syntax highlighter // future release 1815 1816 // Setting some additional style sheet related details depending on configuration (e.g. Online/Creator) 1817 1818 switch (application) { 1819 case Online: 1820 // Adding style and js for small windows 1821 out() << " <script src=\"./scripts/superfish.js\" type=\"text/javascript\"></script>\n"; 1822 out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/superfish.css\" />"; 1823 out() << " <script src=\"./scripts/narrow.js\" type=\"text/javascript\"></script>\n"; 1824 out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/narrow.css\" />\n"; 1825 // Browser spec styles 1826 out() << " <!--[if IE]>\n"; 1827 out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">\n"; 1828 out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">\n"; 1829 out() << "<![endif]-->\n"; 1830 out() << "<!--[if lt IE 7]>\n"; 1831 out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">\n"; 1832 out() << "<![endif]-->\n"; 1833 out() << "<!--[if IE 7]>\n"; 1834 out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">\n"; 1835 out() << "<![endif]-->\n"; 1836 out() << "<!--[if IE 8]>\n"; 1837 out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">\n"; 1838 out() << "<![endif]-->\n"; 1839 1840 out() << "</head>\n"; 1841 // CheckEmptyAndLoadList activating search 1842 out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n"; 1843 break; 1844 case Creator: 1845 out() << "</head>\n"; 1846 out() << "<body class=\"offline narrow creator\">\n"; // offline narrow 1847 break; 1848 default: 1849 out() << "</head>\n"; 1850 out() << "<body>\n"; 1851 break; 1852 } 1853 1854 #ifdef GENERATE_MAC_REFS 1855 if (mainPage) 1856 generateMacRef(node, marker); 1857 #endif 1858 1859 switch (application) { 1860 case Online: 1861 out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1862 generateBreadCrumbs(title,node,marker); 1863 out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1864 break; 1865 case Creator: 1866 out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1867 generateBreadCrumbs(title,node,marker); 1868 out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1869 break; 1870 default: // default -- not used except if one forgets to set any of the above settings to true 1871 out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1872 generateBreadCrumbs(title,node,marker); 1873 out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); 1874 break; 1875 } 1876 1877 navigationLinks.clear(); 1666 1878 1667 1879 if (node && !node->links().empty()) { … … 1688 1900 navigationLinks += "</a>]\n"; 1689 1901 } 1690 if (node->links().contains(Node::ContentsLink)) {1691 linkPair = node->links()[Node::ContentsLink];1692 linkNode = findNodeForTarget(linkPair.first, node, marker);1693 if (!linkNode || linkNode == node)1694 anchorPair = linkPair;1695 else1696 anchorPair = anchorForNode(linkNode);1697 1698 out() << " <link rel=\"contents\" href=\""1699 << anchorPair.first << "\" />\n";1700 1701 navigationLinks += "[<a href=\"" + anchorPair.first + "\">";1702 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())1703 navigationLinks += protect(anchorPair.second);1704 else1705 navigationLinks += protect(linkPair.second);1706 navigationLinks += "</a>]\n";1707 }1708 1902 if (node->links().contains(Node::NextLink)) { 1709 1903 linkPair = node->links()[Node::NextLink]; … … 1723 1917 navigationLinks += protect(linkPair.second); 1724 1918 navigationLinks += "</a>]\n"; 1725 }1726 if (node->links().contains(Node::IndexLink)) {1727 linkPair = node->links()[Node::IndexLink];1728 linkNode = findNodeForTarget(linkPair.first, node, marker);1729 if (!linkNode || linkNode == node)1730 anchorPair = linkPair;1731 else1732 anchorPair = anchorForNode(linkNode);1733 out() << " <link rel=\"index\" href=\""1734 << anchorPair.first << "\" />\n";1735 1919 } 1736 1920 if (node->links().contains(Node::StartLink)) { … … 1746 1930 } 1747 1931 1748 foreach (const QString &stylesheet, stylesheets) {1749 out() << " <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "1750 << "type=\"text/css\" />\n";1751 }1752 1753 foreach (const QString &customHeadElement, customHeadElements) {1754 out() << " " << customHeadElement << "\n";1755 }1756 1757 out() << "</head>\n"1758 "<body>\n";1759 if (mainPage)1760 generateMacRef(node, marker);1761 out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());1762 1763 1764 1932 if (node && !node->links().empty()) 1765 out() << "<p >\n" << navigationLinks << "</p>\n";1933 out() << "<p class=\"naviNextPrevious headerNavi\">\n" << navigationLinks << "</p><p/>\n"; 1766 1934 } 1767 1935 … … 1772 1940 CodeMarker *marker) 1773 1941 { 1774 out() << "<h1 class=\"title\">" << protect(title); 1942 if (!title.isEmpty()) 1943 out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n"; 1775 1944 if (!subTitle.isEmpty()) { 1776 out() << "< br />";1945 out() << "<span"; 1777 1946 if (subTitleSize == SmallSubTitle) 1778 out() << " <spanclass=\"small-subtitle\">";1947 out() << " class=\"small-subtitle\">"; 1779 1948 else 1780 out() << " <spanclass=\"subtitle\">";1949 out() << " class=\"subtitle\">"; 1781 1950 generateText(subTitle, relative, marker); 1782 1951 out() << "</span>\n"; 1783 1952 } 1784 out() << "</h1>\n";1785 1953 } 1786 1954 … … 1788 1956 { 1789 1957 if (node && !node->links().empty()) 1790 out() << "<p >\n" << navigationLinks << "</p>\n";1958 out() << "<p class=\"naviNextPrevious footerNavi\">\n" << navigationLinks << "</p>\n"; 1791 1959 1792 1960 out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) 1793 << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()) 1794 << "</body>\n" 1795 "</html>\n"; 1961 << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()); 1962 1963 switch (application) { 1964 case Online: 1965 out() << " <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n"; 1966 out() << " <script type=\"text/javascript\">\n"; 1967 out() << " var _gaq = _gaq || [];\n"; 1968 out() << " _gaq.push(['_setAccount', 'UA-4457116-5']);\n"; 1969 out() << " _gaq.push(['_trackPageview']);\n"; 1970 out() << " (function() {\n"; 1971 out() << " var ga = document.createElement('script'); "; 1972 out() << "ga.type = 'text/javascript'; ga.async = true;\n"; 1973 out() << " ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + "; 1974 out() << "'.google-analytics.com/ga.js';\n"; 1975 out() << " var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n"; 1976 out() << " })();\n"; 1977 out() << " </script>\n"; 1978 out() << "</body>\n"; 1979 break; 1980 case Creator: 1981 out() << "</body>\n"; 1982 break; 1983 default: 1984 out() << "</body>\n"; 1985 } 1986 out() << "</html>\n"; 1796 1987 } 1797 1988 … … 1801 1992 Text brief = node->doc().briefText(); 1802 1993 if (!brief.isEmpty()) { 1994 generateExtractionMark(node, BriefMark); 1803 1995 out() << "<p>"; 1804 1996 generateText(brief, node, marker); 1997 1805 1998 if (!relative || node == relative) 1806 1999 out() << " <a href=\"#"; … … 1808 2001 out() << " <a href=\"" << linkForNode(node, relative) << "#"; 1809 2002 out() << registerRef("details") << "\">More...</a></p>\n"; 2003 2004 2005 generateExtractionMark(node, EndMark); 1810 2006 } 1811 2007 } … … 1814 2010 { 1815 2011 if (!inner->includes().isEmpty()) { 1816 out() << "<pre >"2012 out() << "<pre class=\"highlightedCode brush: cpp\">" 1817 2013 << trimmedTrailing(highlightedCode(indent(codeIndent, 1818 2014 marker->markedUpIncludes(inner->includes())), … … 1822 2018 } 1823 2019 2020 /*! 2021 Generates a table of contents beginning at \a node. 2022 */ 1824 2023 void HtmlGenerator::generateTableOfContents(const Node *node, 1825 2024 CodeMarker *marker, … … 1829 2028 1830 2029 { 2030 return; 1831 2031 if (!node->doc().hasTableOfContents()) 1832 2032 return; … … 1844 2044 QString tdTag; 1845 2045 if (numColumns > 1) { 1846 tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";1847 out() << "< p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"2046 tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/ 2047 out() << "<table class=\"toc\">\n<tr class=\"topAlign\">" 1848 2048 << tdTag << "\n"; 1849 2049 } … … 1897 2097 1898 2098 if (numColumns > 1) 1899 out() << "</td></tr></table></p>\n"; 1900 2099 out() << "</td></tr></table>\n"; 2100 2101 inContents = false; 2102 inLink = false; 2103 } 2104 2105 /*! 2106 Revised for the new doc format. 2107 Generates a table of contents beginning at \a node. 2108 */ 2109 void HtmlGenerator::generateTableOfContents(const Node *node, 2110 CodeMarker *marker, 2111 QList<Section>* sections) 2112 { 2113 QList<Atom*> toc; 2114 if (node->doc().hasTableOfContents()) 2115 toc = node->doc().tableOfContents(); 2116 if (toc.isEmpty() && !sections && (node->subType() != Node::Module)) 2117 return; 2118 2119 QStringList sectionNumber; 2120 int detailsBase = 0; 2121 2122 // disable nested links in table of contents 2123 inContents = true; 2124 inLink = true; 2125 2126 out() << "<div class=\"toc\">\n"; 2127 out() << "<h3><a name=\"toc\">Contents</a></h3>\n"; 2128 sectionNumber.append("1"); 2129 out() << "<ul>\n"; 2130 2131 if (node->subType() == Node::Module) { 2132 if (moduleNamespaceMap.contains(node->name())) { 2133 out() << "<li class=\"level" 2134 << sectionNumber.size() 2135 << "\"><a href=\"#" 2136 << registerRef("namespaces") 2137 << "\">Namespaces</a></li>\n"; 2138 } 2139 if (moduleClassMap.contains(node->name())) { 2140 out() << "<li class=\"level" 2141 << sectionNumber.size() 2142 << "\"><a href=\"#" 2143 << registerRef("classes") 2144 << "\">Classes</a></li>\n"; 2145 } 2146 out() << "<li class=\"level" 2147 << sectionNumber.size() 2148 << "\"><a href=\"#" 2149 << registerRef("details") 2150 << "\">Detailed Description</a></li>\n"; 2151 for (int i = 0; i < toc.size(); ++i) { 2152 if (toc.at(i)->string().toInt() == 1) { 2153 detailsBase = 1; 2154 break; 2155 } 2156 } 2157 } 2158 else if (sections && ((node->type() == Node::Class) || 2159 (node->type() == Node::Namespace) || 2160 (node->subType() == Node::QmlClass))) { 2161 QList<Section>::ConstIterator s = sections->begin(); 2162 while (s != sections->end()) { 2163 if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) { 2164 out() << "<li class=\"level" 2165 << sectionNumber.size() 2166 << "\"><a href=\"#" 2167 << registerRef((*s).pluralMember) 2168 << "\">" << (*s).name 2169 << "</a></li>\n"; 2170 } 2171 ++s; 2172 } 2173 out() << "<li class=\"level" 2174 << sectionNumber.size() 2175 << "\"><a href=\"#" 2176 << registerRef("details") 2177 << "\">Detailed Description</a></li>\n"; 2178 for (int i = 0; i < toc.size(); ++i) { 2179 if (toc.at(i)->string().toInt() == 1) { 2180 detailsBase = 1; 2181 break; 2182 } 2183 } 2184 } 2185 2186 for (int i = 0; i < toc.size(); ++i) { 2187 Atom *atom = toc.at(i); 2188 int nextLevel = atom->string().toInt() + detailsBase; 2189 if (sectionNumber.size() < nextLevel) { 2190 do { 2191 sectionNumber.append("1"); 2192 } while (sectionNumber.size() < nextLevel); 2193 } 2194 else { 2195 while (sectionNumber.size() > nextLevel) { 2196 sectionNumber.removeLast(); 2197 } 2198 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); 2199 } 2200 int numAtoms; 2201 Text headingText = Text::sectionHeading(atom); 2202 QString s = headingText.toString(); 2203 out() << "<li class=\"level" 2204 << sectionNumber.size() 2205 << "\">"; 2206 out() << "<a href=\"" 2207 << "#" 2208 << Doc::canonicalTitle(s) 2209 << "\">"; 2210 generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); 2211 out() << "</a></li>\n"; 2212 } 2213 while (!sectionNumber.isEmpty()) { 2214 sectionNumber.removeLast(); 2215 } 2216 out() << "</ul>\n"; 2217 out() << "</div>\n"; 1901 2218 inContents = false; 1902 2219 inLink = false; … … 1910 2227 if (bar.prev.begin() != 0 || bar.current.begin() != 0 || 1911 2228 bar.next.begin() != 0) { 1912 out() << "<p align=\"right\">";2229 out() << "<p class=\"rightAlign\">"; 1913 2230 if (bar.prev.begin() != 0) { 1914 2231 #if 0 … … 1919 2236 #endif 1920 2237 } 1921 if (bar.current.begin() != 0) { 1922 out() << "[<a href=\"" << "home" 1923 << ".html\">Home</a>]\n"; 1924 } 1925 if (bar.next.begin() != 0) { 1926 out() << "[<a href=\"" << fileBase(node, bar.next) 1927 << ".html\">Next: "; 1928 generateText(Text::sectionHeading(bar.next.begin()), node, marker); 1929 out() << "</a>]\n"; 1930 } 1931 out() << "</p>\n"; 2238 if (fake->name() != QString("index.html")) { 2239 if (bar.current.begin() != 0) { 2240 out() << "[<a href=\"" << "home" 2241 << ".html\">Home</a>]\n"; 2242 } 2243 if (bar.next.begin() != 0) { 2244 out() << "[<a href=\"" << fileBase(node, bar.next) 2245 << ".html\">Next: "; 2246 generateText(Text::sectionHeading(bar.next.begin()), node, marker); 2247 out() << "</a>]\n"; 2248 } 2249 out() << "</p>\n"; 2250 } 1932 2251 } 1933 2252 } … … 1949 2268 beginSubPage(inner->location(), fileName); 1950 2269 QString title = "List of All Members for " + inner->name(); 1951 generateHeader(title, inner, marker , false);2270 generateHeader(title, inner, marker); 1952 2271 generateTitle(title, Text(), SmallSubTitle, inner, marker); 1953 2272 out() << "<p>This is the complete list of members for "; 1954 2273 generateFullName(inner, 0, marker); 2274 out() << ", including inherited members.</p>\n"; 2275 2276 Section section = sections.first(); 2277 generateSectionList(section, 0, marker, CodeMarker::SeparateList); 2278 2279 generateFooter(); 2280 endSubPage(); 2281 return fileName; 2282 } 2283 2284 /*! 2285 This function creates an html page on which are listed all 2286 the members of QML class \a qml_cn, including the inherited 2287 members. The \a marker is used for formatting stuff. 2288 */ 2289 QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn, 2290 CodeMarker* marker) 2291 { 2292 QList<Section> sections; 2293 QList<Section>::ConstIterator s; 2294 2295 sections = marker->qmlSections(qml_cn,CodeMarker::SeparateList,myTree); 2296 if (sections.isEmpty()) 2297 return QString(); 2298 2299 QString fileName = fileBase(qml_cn) + "-members." + fileExtension(qml_cn); 2300 beginSubPage(qml_cn->location(), fileName); 2301 QString title = "List of All Members for " + qml_cn->name(); 2302 generateHeader(title, qml_cn, marker); 2303 generateTitle(title, Text(), SmallSubTitle, qml_cn, marker); 2304 out() << "<p>This is the complete list of members for "; 2305 generateFullName(qml_cn, 0, marker); 1955 2306 out() << ", including inherited members.</p>\n"; 1956 2307 … … 1993 2344 1994 2345 beginSubPage(inner->location(), fileName); 1995 generateHeader(title, inner, marker , false);2346 generateHeader(title, inner, marker); 1996 2347 generateTitle(title, Text(), SmallSubTitle, inner, marker); 1997 2348 … … 2010 2361 out() << "<p><ul><li><a href=\"" 2011 2362 << linkForNode(inner, 0) << "\">" 2012 << protect (inner->name())2363 << protectEnc(inner->name()) 2013 2364 << " class reference</a></li></ul></p>\n"; 2014 2365 2015 2366 for (i = 0; i < sections.size(); ++i) { 2016 out() << "<h2>" << protect (sections.at(i).name) << "</h2>\n";2367 out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; 2017 2368 generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary); 2018 2369 } … … 2020 2371 sections = marker->sections(inner, CodeMarker::Detailed, status); 2021 2372 for (i = 0; i < sections.size(); ++i) { 2022 out() << "<hr />\n";2023 out() << "<h2>" << protect (sections.at(i).name) << "</h2>\n";2373 //out() << "<hr />\n"; 2374 out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; 2024 2375 2025 2376 NodeList::ConstIterator m = sections.at(i).members.begin(); … … 2086 2437 const NodeMap &nodeMap) 2087 2438 { 2088 out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" " 2089 << "cellspacing=\"1\" border=\"0\">\n"; 2439 out() << "<table class=\"annotated\">\n"; 2090 2440 2091 2441 int row = 0; … … 2097 2447 2098 2448 if (++row % 2 == 1) 2099 out() << "<tr valign=\"top\" class=\"odd\">";2449 out() << "<tr class=\"odd topAlign\">"; 2100 2450 else 2101 out() << "<tr valign=\"top\" class=\"even\">";2102 out() << "<t h>";2451 out() << "<tr class=\"even topAlign\">"; 2452 out() << "<td class=\"tblName\"><p>"; 2103 2453 generateFullName(node, relative, marker); 2104 out() << "</ th>";2454 out() << "</p></td>"; 2105 2455 2106 2456 if (!(node->type() == Node::Fake)) { 2107 2457 Text brief = node->doc().trimmedBriefText(name); 2108 2458 if (!brief.isEmpty()) { 2109 out() << "<td >";2459 out() << "<td class=\"tblDescr\"><p>"; 2110 2460 generateText(brief, node, marker); 2111 out() << "</ td>";2461 out() << "</p></td>"; 2112 2462 } 2113 2463 } 2114 2464 else { 2115 out() << "<td >";2116 out() << protect (node->doc().briefText().toString());2117 out() << "</ td>";2465 out() << "<td class=\"tblDescr\"><p>"; 2466 out() << protectEnc(node->doc().briefText().toString()); 2467 out() << "</p></td>"; 2118 2468 } 2119 2469 out() << "</tr>\n"; 2120 2470 } 2121 out() << "</table> </p>\n";2471 out() << "</table>\n"; 2122 2472 } 2123 2473 … … 2134 2484 CodeMarker *marker, 2135 2485 const NodeMap &classMap, 2486 bool includeAlphabet, 2136 2487 QString commonPrefix) 2137 2488 { 2138 2489 const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' 2139 const int NumColumns = 4; // number of columns in the result2140 2490 2141 2491 if (classMap.isEmpty()) … … 2206 2556 NodeMap paragraph[NumParagraphs+1]; 2207 2557 QString paragraphName[NumParagraphs+1]; 2558 QSet<char> usedParagraphNames; 2208 2559 2209 2560 NodeMap::ConstIterator c = classMap.begin(); … … 2219 2570 key = pieces.last().toLower(); 2220 2571 2221 int paragraphN o= NumParagraphs - 1;2572 int paragraphNr = NumParagraphs - 1; 2222 2573 2223 2574 if (key[0].digitValue() != -1) { 2224 paragraphN o= key[0].digitValue();2575 paragraphNr = key[0].digitValue(); 2225 2576 } 2226 2577 else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) { 2227 paragraphNo = 10 + key[0].unicode() - 'a'; 2228 } 2229 2230 paragraphName[paragraphNo] = key[0].toUpper(); 2231 paragraph[paragraphNo].insert(key, c.value()); 2578 paragraphNr = 10 + key[0].unicode() - 'a'; 2579 } 2580 2581 paragraphName[paragraphNr] = key[0].toUpper(); 2582 usedParagraphNames.insert(key[0].toLower().cell()); 2583 paragraph[paragraphNr].insert(key, c.value()); 2232 2584 ++c; 2233 2585 } … … 2242 2594 */ 2243 2595 int paragraphOffset[NumParagraphs + 1]; // 37 + 1 2244 int i, j, k;2245 2246 2596 paragraphOffset[0] = 0; 2247 for (j = 0; j < NumParagraphs; j++) // j = 0..36 2248 paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count(); 2249 2250 int firstOffset[NumColumns + 1]; // 4 + 1 2251 int currentOffset[NumColumns]; // 4 2252 int currentParagraphNo[NumColumns]; // 4 2253 int currentOffsetInParagraph[NumColumns]; // 4 2254 2255 int numRows = (classMap.count() + NumColumns - 1) / NumColumns; 2256 int curParagNo = 0; 2257 2258 for (i = 0; i < NumColumns; i++) { // i = 0..3 2259 firstOffset[i] = qMin(i * numRows, classMap.size()); 2260 currentOffset[i] = firstOffset[i]; 2261 2262 for (j = curParagNo; j < NumParagraphs; j++) { 2263 if (paragraphOffset[j] > firstOffset[i]) 2264 break; 2265 if (paragraphOffset[j] <= firstOffset[i]) 2266 curParagNo = j; 2267 } 2268 currentParagraphNo[i] = curParagNo; 2269 currentOffsetInParagraph[i] = firstOffset[i] - 2270 paragraphOffset[curParagNo]; 2271 } 2272 firstOffset[NumColumns] = classMap.count(); 2273 2274 out() << "<p><table class=\"generic\" width=\"100%\">\n"; 2275 for (k = 0; k < numRows; k++) { 2276 out() << "<tr>\n"; 2277 for (i = 0; i < NumColumns; i++) { 2278 if (currentOffset[i] >= firstOffset[i + 1]) { 2279 // this column is finished 2280 out() << "<td>\n</td>\n"; 2281 } 2282 else { 2283 while ((currentParagraphNo[i] < NumParagraphs) && 2284 (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) { 2285 ++currentParagraphNo[i]; 2286 currentOffsetInParagraph[i] = 0; 2287 } 2288 #if 0 2289 if (currentParagraphNo[i] >= NumParagraphs) { 2290 qDebug() << "### Internal error ###" << __FILE__ << __LINE__ 2291 << currentParagraphNo[i] << NumParagraphs; 2292 currentParagraphNo[i] = NumParagraphs - 1; 2293 } 2294 #endif 2295 out() << "<td align=\"right\">"; 2296 if (currentOffsetInParagraph[i] == 0) { 2297 // start a new paragraph 2298 out() << "<b>" 2299 << paragraphName[currentParagraphNo[i]] 2300 << " </b>"; 2301 } 2302 out() << "</td>\n"; 2303 2304 out() << "<td>"; 2305 if ((currentParagraphNo[i] < NumParagraphs) && 2306 !paragraphName[currentParagraphNo[i]].isEmpty()) { 2307 NodeMap::Iterator it; 2308 it = paragraph[currentParagraphNo[i]].begin(); 2309 for (j = 0; j < currentOffsetInParagraph[i]; j++) 2310 ++it; 2311 2312 // Previously, we used generateFullName() for this, but we 2313 // require some special formatting. 2314 out() << "<a href=\"" 2315 << linkForNode(it.value(), relative) 2316 << "\">"; 2317 QStringList pieces = fullName(it.value(), relative, marker).split("::"); 2318 out() << protect(pieces.last()); 2319 out() << "</a>"; 2320 if (pieces.size() > 1) { 2321 out() << " ("; 2322 generateFullName(it.value()->parent(), relative, marker); 2323 out() << ")"; 2324 } 2325 } 2326 out() << "</td>\n"; 2327 2328 currentOffset[i]++; 2329 currentOffsetInParagraph[i]++; 2330 } 2331 } 2332 out() << "</tr>\n"; 2333 } 2334 out() << "</table></p>\n"; 2597 for (int i=0; i<NumParagraphs; i++) // i = 0..36 2598 paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count(); 2599 2600 int curParNr = 0; 2601 int curParOffset = 0; 2602 2603 /* 2604 Output the alphabet as a row of links. 2605 */ 2606 if (includeAlphabet) { 2607 out() << "<p class=\"centerAlign functionIndex\"><b>"; 2608 for (int i = 0; i < 26; i++) { 2609 QChar ch('a' + i); 2610 if (usedParagraphNames.contains(char('a' + i))) 2611 out() << QString("<a href=\"#%1\">%2</a> ").arg(ch).arg(ch.toUpper()); 2612 } 2613 out() << "</b></p>\n"; 2614 } 2615 2616 /* 2617 Output a <div> element to contain all the <dl> elements. 2618 */ 2619 out() << "<div class=\"flowListDiv\">\n"; 2620 2621 for (int i=0; i<classMap.count()-1; i++) { 2622 while ((curParNr < NumParagraphs) && 2623 (curParOffset == paragraph[curParNr].count())) { 2624 ++curParNr; 2625 curParOffset = 0; 2626 } 2627 2628 /* 2629 Starting a new paragraph means starting a new <dl>. 2630 */ 2631 if (curParOffset == 0) { 2632 if (i > 0) 2633 out() << "</dl>\n"; 2634 if (++numTableRows % 2 == 1) 2635 out() << "<dl class=\"flowList odd\">"; 2636 else 2637 out() << "<dl class=\"flowList even\">"; 2638 out() << "<dt class=\"alphaChar\">"; 2639 if (includeAlphabet) { 2640 QChar c = paragraphName[curParNr][0].toLower(); 2641 out() << QString("<a name=\"%1\"></a>").arg(c); 2642 } 2643 out() << "<b>" 2644 << paragraphName[curParNr] 2645 << "</b>"; 2646 out() << "</dt>\n"; 2647 } 2648 2649 /* 2650 Output a <dd> for the current offset in the current paragraph. 2651 */ 2652 out() << "<dd>"; 2653 if ((curParNr < NumParagraphs) && 2654 !paragraphName[curParNr].isEmpty()) { 2655 NodeMap::Iterator it; 2656 it = paragraph[curParNr].begin(); 2657 for (int i=0; i<curParOffset; i++) 2658 ++it; 2659 2660 /* 2661 Previously, we used generateFullName() for this, but we 2662 require some special formatting. 2663 */ 2664 out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">"; 2665 2666 QStringList pieces; 2667 if (it.value()->subType() == Node::QmlClass) 2668 pieces << it.value()->name(); 2669 else 2670 pieces = fullName(it.value(), relative, marker).split("::"); 2671 out() << protectEnc(pieces.last()); 2672 out() << "</a>"; 2673 if (pieces.size() > 1) { 2674 out() << " ("; 2675 generateFullName(it.value()->parent(), relative, marker); 2676 out() << ")"; 2677 } 2678 } 2679 out() << "</dd>\n"; 2680 curParOffset++; 2681 } 2682 out() << "</dl>\n"; 2683 out() << "</div>\n"; 2335 2684 } 2336 2685 … … 2338 2687 CodeMarker *marker) 2339 2688 { 2340 out() << "<p align=\"center\"><font size=\"+1\"><b>";2689 out() << "<p class=\"centerAlign functionIndex\"><b>"; 2341 2690 for (int i = 0; i < 26; i++) { 2342 2691 QChar ch('a' + i); 2343 2692 out() << QString("<a href=\"#%1\">%2</a> ").arg(ch).arg(ch.toUpper()); 2344 2693 } 2345 out() << "</b></ font></p>\n";2694 out() << "</b></p>\n"; 2346 2695 2347 2696 char nextLetter = 'a'; … … 2358 2707 out() << "<p>"; 2359 2708 #endif 2360 out() << protect (f.key()) << ":";2709 out() << protectEnc(f.key()) << ":"; 2361 2710 2362 2711 currentLetter = f.key()[0].unicode(); … … 2391 2740 while (it != legaleseTexts.end()) { 2392 2741 Text text = it.key(); 2393 out() << "<hr />\n";2742 //out() << "<hr />\n"; 2394 2743 generateText(text, relative, marker); 2395 2744 out() << "<ul>\n"; … … 2404 2753 } 2405 2754 2406 /*void HtmlGenerator::generateSynopsis(const Node *node,2407 const Node *relative,2408 CodeMarker *marker,2409 CodeMarker::SynopsisStyle style)2410 {2411 QString marked = marker->markedUpSynopsis(node, relative, style);2412 QRegExp templateTag("(<[^@>]*>)");2413 if (marked.indexOf(templateTag) != -1) {2414 QString contents = protect(marked.mid(templateTag.pos(1),2415 templateTag.cap(1).length()));2416 marked.replace(templateTag.pos(1), templateTag.cap(1).length(),2417 contents);2418 }2419 marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),2420 "<i>\\1<sub>\\2</sub></i>");2421 marked.replace("<@param>", "<i>");2422 marked.replace("</@param>", "</i>");2423 2424 if (style == CodeMarker::Summary)2425 marked.replace("@name>", "b>");2426 2427 if (style == CodeMarker::SeparateList) {2428 QRegExp extraRegExp("<@extra>.*</@extra>");2429 extraRegExp.setMinimal(true);2430 marked.replace(extraRegExp, "");2431 }2432 else {2433 marked.replace("<@extra>", " <tt>");2434 marked.replace("</@extra>", "</tt>");2435 }2436 2437 if (style != CodeMarker::Detailed) {2438 marked.replace("<@type>", "");2439 marked.replace("</@type>", "");2440 }2441 out() << highlightedCode(marked, marker, relative);2442 }*/2443 2444 2755 #ifdef QDOC_QML 2445 2756 void HtmlGenerator::generateQmlItem(const Node *node, … … 2451 2762 QRegExp templateTag("(<[^@>]*>)"); 2452 2763 if (marked.indexOf(templateTag) != -1) { 2453 QString contents = protect (marked.mid(templateTag.pos(1),2764 QString contents = protectEnc(marked.mid(templateTag.pos(1), 2454 2765 templateTag.cap(1).length())); 2455 2766 marked.replace(templateTag.pos(1), templateTag.cap(1).length(), … … 2464 2775 marked.replace("@name>", "b>"); 2465 2776 2466 marked.replace("<@extra>", " <tt>");2777 marked.replace("<@extra>", "<tt>"); 2467 2778 marked.replace("</@extra>", "</tt>"); 2468 2779 … … 2471 2782 marked.replace("</@type>", ""); 2472 2783 } 2473 out() << highlightedCode(marked, marker, relative );2784 out() << highlightedCode(marked, marker, relative, false, node); 2474 2785 } 2475 2786 #endif … … 2557 2868 out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg( 2558 2869 linkForNode(groupNode, relative)).arg( 2559 protect (groupNode->fullTitle()));2870 protectEnc(groupNode->fullTitle())); 2560 2871 2561 2872 if (fakeNodeMap[groupNode].count() == 0) … … 2569 2880 title.remove(0, 4); 2570 2881 out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">" 2571 << protect (title) << "</a></li>\n";2882 << protectEnc(title) << "</a></li>\n"; 2572 2883 } 2573 2884 out() << "</ul>\n"; … … 2583 2894 title.remove(0, 4); 2584 2895 out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">" 2585 << protect (title) << "</a></li>\n";2896 << protectEnc(title) << "</a></li>\n"; 2586 2897 } 2587 2898 out() << "</ul>\n"; … … 2589 2900 } 2590 2901 2591 #ifdef QDOC_NAME_ALIGNMENT2592 2902 void HtmlGenerator::generateSection(const NodeList& nl, 2593 2903 const Node *relative, … … 2595 2905 CodeMarker::SynopsisStyle style) 2596 2906 { 2597 bool name_alignment= true;2907 bool alignNames = true; 2598 2908 if (!nl.isEmpty()) { 2599 2909 bool twoColumn = false; 2600 2910 if (style == CodeMarker::SeparateList) { 2601 name_alignment= false;2911 alignNames = false; 2602 2912 twoColumn = (nl.count() >= 16); 2603 2913 } 2604 2914 else if (nl.first()->type() == Node::Property) { 2605 2915 twoColumn = (nl.count() >= 5); 2606 name_alignment = false; 2607 } 2608 if (name_alignment) { 2609 out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" " 2610 << "cellspacing=\"0\" width=\"100%\">\n"; 2916 alignNames = false; 2917 } 2918 if (alignNames) { 2919 out() << "<table class=\"alignedsummary\">\n"; 2611 2920 } 2612 2921 else { 2613 2922 if (twoColumn) 2614 out() << "<p><table class=\"propsummary\" width=\"100%\" " 2615 << "border=\"0\" cellpadding=\"0\"" 2616 << " cellspacing=\"0\">\n" 2617 << "<tr><td width=\"45%\" valign=\"top\">"; 2923 out() << "<table class=\"propsummary\">\n" 2924 << "<tr><td class=\"topAlign\">"; 2618 2925 out() << "<ul>\n"; 2619 2926 } … … 2627 2934 } 2628 2935 2629 if (name_alignment) { 2630 out() << "<tr><td class=\"memItemLeft\" " 2631 << "align=\"right\" valign=\"top\">"; 2936 if (alignNames) { 2937 out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> "; 2632 2938 } 2633 2939 else { 2634 2940 if (twoColumn && i == (int) (nl.count() + 1) / 2) 2635 out() << "</ul></td><td valign=\"top\"><ul>\n";2636 out() << "<li ><divclass=\"fn\">";2637 } 2638 2639 generateSynopsis(*m, relative, marker, style, name_alignment);2640 if ( name_alignment)2941 out() << "</ul></td><td class=\"topAlign\"><ul>\n"; 2942 out() << "<li class=\"fn\">"; 2943 } 2944 2945 generateSynopsis(*m, relative, marker, style, alignNames); 2946 if (alignNames) 2641 2947 out() << "</td></tr>\n"; 2642 2948 else 2643 out() << "</ div></li>\n";2949 out() << "</li>\n"; 2644 2950 i++; 2645 2951 ++m; 2646 2952 } 2647 if ( name_alignment)2953 if (alignNames) 2648 2954 out() << "</table>\n"; 2649 2955 else { 2650 2956 out() << "</ul>\n"; 2651 2957 if (twoColumn) 2652 out() << "</td></tr>\n</table> </p>\n";2958 out() << "</td></tr>\n</table>\n"; 2653 2959 } 2654 2960 } … … 2660 2966 CodeMarker::SynopsisStyle style) 2661 2967 { 2662 bool name_alignment= true;2968 bool alignNames = true; 2663 2969 if (!section.members.isEmpty()) { 2664 2970 bool twoColumn = false; 2665 2971 if (style == CodeMarker::SeparateList) { 2666 name_alignment= false;2972 alignNames = false; 2667 2973 twoColumn = (section.members.count() >= 16); 2668 2974 } 2669 2975 else if (section.members.first()->type() == Node::Property) { 2670 2976 twoColumn = (section.members.count() >= 5); 2671 name_alignment = false; 2672 } 2673 if (name_alignment) { 2674 out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" " 2675 << "cellspacing=\"0\" width=\"100%\">\n"; 2977 alignNames = false; 2978 } 2979 if (alignNames) { 2980 out() << "<table class=\"alignedsummary\">\n"; 2676 2981 } 2677 2982 else { 2678 2983 if (twoColumn) 2679 out() << "<p><table class=\"propsummary\" width=\"100%\" " 2680 << "border=\"0\" cellpadding=\"0\"" 2681 << " cellspacing=\"0\">\n" 2682 << "<tr><td width=\"45%\" valign=\"top\">"; 2984 out() << "<table class=\"propsummary\">\n" 2985 << "<tr><td class=\"topAlign\">"; 2683 2986 out() << "<ul>\n"; 2684 2987 } … … 2692 2995 } 2693 2996 2694 if (name_alignment) { 2695 out() << "<tr><td class=\"memItemLeft\" " 2696 << "align=\"right\" valign=\"top\">"; 2997 if (alignNames) { 2998 out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> "; 2697 2999 } 2698 3000 else { 2699 3001 if (twoColumn && i == (int) (section.members.count() + 1) / 2) 2700 out() << "</ul></td><td valign=\"top\"><ul>\n";2701 out() << "<li ><divclass=\"fn\">";2702 } 2703 2704 generateSynopsis(*m, relative, marker, style, name_alignment);2705 if ( name_alignment)3002 out() << "</ul></td><td class=\"topAlign\"><ul>\n"; 3003 out() << "<li class=\"fn\">"; 3004 } 3005 3006 generateSynopsis(*m, relative, marker, style, alignNames); 3007 if (alignNames) 2706 3008 out() << "</td></tr>\n"; 2707 3009 else 2708 out() << "</ div></li>\n";3010 out() << "</li>\n"; 2709 3011 i++; 2710 3012 ++m; 2711 3013 } 2712 if ( name_alignment)3014 if (alignNames) 2713 3015 out() << "</table>\n"; 2714 3016 else { 2715 3017 out() << "</ul>\n"; 2716 3018 if (twoColumn) 2717 out() << "</td></tr>\n</table> </p>\n";3019 out() << "</td></tr>\n</table>\n"; 2718 3020 } 2719 3021 } … … 2721 3023 if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { 2722 3024 out() << "<ul>\n"; 2723 generateSectionInheritedList(section, relative, marker , name_alignment);3025 generateSectionInheritedList(section, relative, marker); 2724 3026 out() << "</ul>\n"; 2725 3027 } … … 2728 3030 void HtmlGenerator::generateSectionInheritedList(const Section& section, 2729 3031 const Node *relative, 2730 CodeMarker *marker, 2731 bool nameAlignment) 3032 CodeMarker *marker) 2732 3033 { 2733 3034 QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin(); 2734 3035 while (p != section.inherited.end()) { 2735 if (nameAlignment) 2736 out() << "<li><div bar=\"2\" class=\"fn\"></div>"; 2737 else 2738 out() << "<li><div class=\"fn\"></div>"; 3036 out() << "<li class=\"fn\">"; 2739 3037 out() << (*p).second << " "; 2740 3038 if ((*p).second == 1) { … … 2746 3044 out() << " inherited from <a href=\"" << fileName((*p).first) 2747 3045 << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">" 2748 << protect (marker->plainFullName((*p).first, relative))3046 << protectEnc(marker->plainFullName((*p).first, relative)) 2749 3047 << "</a></li>\n"; 2750 3048 ++p; … … 2756 3054 CodeMarker *marker, 2757 3055 CodeMarker::SynopsisStyle style, 2758 bool nameAlignment)3056 bool alignNames) 2759 3057 { 2760 3058 QString marked = marker->markedUpSynopsis(node, relative, style); 2761 3059 QRegExp templateTag("(<[^@>]*>)"); 2762 3060 if (marked.indexOf(templateTag) != -1) { 2763 QString contents = protect (marked.mid(templateTag.pos(1),3061 QString contents = protectEnc(marked.mid(templateTag.pos(1), 2764 3062 templateTag.cap(1).length())); 2765 3063 marked.replace(templateTag.pos(1), templateTag.cap(1).length(), … … 2781 3079 marked.replace(extraRegExp, ""); 2782 3080 } else { 2783 marked.replace("<@extra>", " <tt>");3081 marked.replace("<@extra>", "<tt>"); 2784 3082 marked.replace("</@extra>", "</tt>"); 2785 3083 } … … 2789 3087 marked.replace("</@type>", ""); 2790 3088 } 2791 out() << highlightedCode(marked, marker, relative, style, nameAlignment);3089 out() << highlightedCode(marked, marker, relative, alignNames); 2792 3090 } 2793 3091 2794 3092 QString HtmlGenerator::highlightedCode(const QString& markedCode, 2795 CodeMarker *marker,2796 const Node *relative,2797 CodeMarker::SynopsisStyle,2798 bool nameAlignment)3093 CodeMarker* marker, 3094 const Node* relative, 3095 bool alignNames, 3096 const Node* self) 2799 3097 { 2800 3098 QString src = markedCode; … … 2806 3104 const QChar charAt = '@'; 2807 3105 3106 static const QString typeTag("type"); 3107 static const QString headerTag("headerfile"); 3108 static const QString funcTag("func"); 3109 static const QString linkTag("link"); 3110 2808 3111 // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" 2809 static const QString linkTag("link");2810 3112 bool done = false; 2811 for (int i = 0, n = src.size(); i < n;) {3113 for (int i = 0, srcSize = src.size(); i < srcSize;) { 2812 3114 if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') { 2813 if ( nameAlignment&& !done) {// && (i != 0)) Why was this here?2814 html += "</td><td class=\"memItemRight \" valign=\"bottom\">";3115 if (alignNames && !done) {// && (i != 0)) Why was this here? 3116 html += "</td><td class=\"memItemRight bottomAlign\">"; 2815 3117 done = true; 2816 3118 } 2817 3119 i += 2; 2818 if (parseArg(src, linkTag, &i, n, &arg, &par1)) {3120 if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) { 2819 3121 html += "<b>"; 2820 QString link = linkForNode(2821 CodeMarker::nodeForString(par1.toString()), relative);3122 const Node* n = CodeMarker::nodeForString(par1.toString()); 3123 QString link = linkForNode(n, relative); 2822 3124 addLink(link, arg, &html); 2823 3125 html += "</b>"; … … 2839 3141 src = html; 2840 3142 html = QString(); 2841 static const QString funcTag("func"); 2842 for (int i = 0, n = src.size(); i < n;) { 3143 for (int i = 0, srcSize = src.size(); i < srcSize;) { 2843 3144 if (src.at(i) == charLangle && src.at(i + 1) == charAt) { 2844 3145 i += 2; 2845 if (parseArg(src, funcTag, &i, n, &arg, &par1)) { 2846 QString link = linkForNode( 2847 marker->resolveTarget(par1.toString(), 2848 myTree, 2849 relative), 2850 relative); 3146 if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { 3147 const Node* n = marker->resolveTarget(par1.toString(), 3148 myTree, 3149 relative); 3150 QString link = linkForNode(n, relative); 2851 3151 addLink(link, arg, &html); 2852 3152 par1 = QStringRef(); … … 2866 3166 src = html; 2867 3167 html = QString(); 2868 static const QString typeTags[] = { "type", "headerfile", "func" }; 2869 for (int i = 0, n = src.size(); i < n;) {2870 if (src.at(i) == charLangle && src.at(i +1) == charAt) {3168 3169 for (int i=0, srcSize=src.size(); i<srcSize;) { 3170 if (src.at(i) == charLangle && src.at(i+1) == charAt) { 2871 3171 i += 2; 2872 3172 bool handled = false; 2873 for (int k = 0; k != 3; ++k) { 2874 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) { 2875 par1 = QStringRef(); 2876 QString link = linkForNode( 2877 marker->resolveTarget(arg.toString(), myTree, relative), 2878 relative); 2879 addLink(link, arg, &html); 2880 handled = true; 2881 break; 3173 if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { 3174 par1 = QStringRef(); 3175 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative, self); 3176 if (n && n->subType() == Node::QmlBasicType) { 3177 if (relative && relative->subType() == Node::QmlClass) 3178 addLink(linkForNode(n,relative), arg, &html); 3179 else 3180 html += arg.toString(); 2882 3181 } 2883 } 3182 else 3183 addLink(linkForNode(n,relative), arg, &html); 3184 handled = true; 3185 } 3186 else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { 3187 par1 = QStringRef(); 3188 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); 3189 addLink(linkForNode(n,relative), arg, &html); 3190 handled = true; 3191 } 3192 else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { 3193 par1 = QStringRef(); 3194 const Node* n = marker->resolveTarget(arg.toString(), myTree, relative); 3195 addLink(linkForNode(n,relative), arg, &html); 3196 handled = true; 3197 } 3198 2884 3199 if (!handled) { 2885 3200 html += charLangle; … … 2909 3224 "</@string>", "</span>", 2910 3225 "</@char>", "</span>" 2911 // "<@char>", "<font color=blue>",2912 // "</@char>", "</font>",2913 // "<@func>", "<font color=green>",2914 // "</@func>", "</font>",2915 // "<@id>", "<i>",2916 // "</@id>", "</i>",2917 // "<@keyword>", "<b>",2918 // "</@keyword>", "</b>",2919 // "<@number>", "<font color=yellow>",2920 // "</@number>", "</font>",2921 // "<@op>", "<b>",2922 // "</@op>", "</b>",2923 // "<@param>", "<i>",2924 // "</@param>", "</i>",2925 // "<@string>", "<font color=green>",2926 // "</@string>", "</font>",2927 3226 }; 2928 3227 for (int i = 0, n = src.size(); i < n;) { … … 2962 3261 } 2963 3262 2964 #else2965 void HtmlGenerator::generateSectionList(const Section& section,2966 const Node *relative,2967 CodeMarker *marker,2968 CodeMarker::SynopsisStyle style)2969 {2970 if (!section.members.isEmpty()) {2971 bool twoColumn = false;2972 if (style == CodeMarker::SeparateList) {2973 twoColumn = (section.members.count() >= 16);2974 }2975 else if (section.members.first()->type() == Node::Property) {2976 twoColumn = (section.members.count() >= 5);2977 }2978 if (twoColumn)2979 out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "2980 << "cellpadding=\"0\" cellspacing=\"0\">\n"2981 << "<tr><td width=\"45%\" valign=\"top\">";2982 out() << "<ul>\n";2983 2984 int i = 0;2985 NodeList::ConstIterator m = section.members.begin();2986 while (m != section.members.end()) {2987 if ((*m)->access() == Node::Private) {2988 ++m;2989 continue;2990 }2991 2992 if (twoColumn && i == (int) (section.members.count() + 1) / 2)2993 out() << "</ul></td><td valign=\"top\"><ul>\n";2994 2995 out() << "<li><div class=\"fn\"></div>";2996 if (style == CodeMarker::Accessors)2997 out() << "<b>";2998 generateSynopsis(*m, relative, marker, style);2999 if (style == CodeMarker::Accessors)3000 out() << "</b>";3001 out() << "</li>\n";3002 i++;3003 ++m;3004 }3005 out() << "</ul>\n";3006 if (twoColumn)3007 out() << "</td></tr>\n</table></p>\n";3008 }3009 3010 if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {3011 out() << "<ul>\n";3012 generateSectionInheritedList(section, relative, marker);3013 out() << "</ul>\n";3014 }3015 }3016 3017 void HtmlGenerator::generateSectionInheritedList(const Section& section,3018 const Node *relative,3019 CodeMarker *marker)3020 {3021 QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();3022 while (p != section.inherited.end()) {3023 out() << "<li><div bar=\"2\" class=\"fn\"></div>";3024 out() << (*p).second << " ";3025 if ((*p).second == 1) {3026 out() << section.singularMember;3027 } else {3028 out() << section.pluralMember;3029 }3030 out() << " inherited from <a href=\"" << fileName((*p).first)3031 << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"3032 << protect(marker->plainFullName((*p).first, relative))3033 << "</a></li>\n";3034 ++p;3035 }3036 }3037 3038 void HtmlGenerator::generateSynopsis(const Node *node,3039 const Node *relative,3040 CodeMarker *marker,3041 CodeMarker::SynopsisStyle style)3042 {3043 QString marked = marker->markedUpSynopsis(node, relative, style);3044 QRegExp templateTag("(<[^@>]*>)");3045 if (marked.indexOf(templateTag) != -1) {3046 QString contents = protect(marked.mid(templateTag.pos(1),3047 templateTag.cap(1).length()));3048 marked.replace(templateTag.pos(1), templateTag.cap(1).length(),3049 contents);3050 }3051 marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");3052 marked.replace("<@param>", "<i>");3053 marked.replace("</@param>", "</i>");3054 3055 if (style == CodeMarker::Summary)3056 marked.replace("@name>", "b>");3057 3058 if (style == CodeMarker::SeparateList) {3059 QRegExp extraRegExp("<@extra>.*</@extra>");3060 extraRegExp.setMinimal(true);3061 marked.replace(extraRegExp, "");3062 } else {3063 marked.replace("<@extra>", " <tt>");3064 marked.replace("</@extra>", "</tt>");3065 }3066 3067 if (style != CodeMarker::Detailed) {3068 marked.replace("<@type>", "");3069 marked.replace("</@type>", "");3070 }3071 out() << highlightedCode(marked, marker, relative);3072 }3073 3074 QString HtmlGenerator::highlightedCode(const QString& markedCode,3075 CodeMarker *marker,3076 const Node *relative)3077 {3078 QString src = markedCode;3079 QString html;3080 QStringRef arg;3081 QStringRef par1;3082 3083 const QChar charLangle = '<';3084 const QChar charAt = '@';3085 3086 // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"3087 static const QString linkTag("link");3088 for (int i = 0, n = src.size(); i < n;) {3089 if (src.at(i) == charLangle && src.at(i + 1) == charAt) {3090 i += 2;3091 if (parseArg(src, linkTag, &i, n, &arg, &par1)) {3092 const Node* node = CodeMarker::nodeForString(par1.toString());3093 QString link = linkForNode(node, relative);3094 addLink(link, arg, &html);3095 }3096 else {3097 html += charLangle;3098 html += charAt;3099 }3100 }3101 else {3102 html += src.at(i++);3103 }3104 }3105 3106 if (slow) {3107 // is this block ever used at all?3108 // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"3109 src = html;3110 html = QString();3111 static const QString funcTag("func");3112 for (int i = 0, n = src.size(); i < n;) {3113 if (src.at(i) == charLangle && src.at(i + 1) == charAt) {3114 i += 2;3115 if (parseArg(src, funcTag, &i, n, &arg, &par1)) {3116 QString link = linkForNode(3117 marker->resolveTarget(par1.toString(),3118 myTree,3119 relative),3120 relative);3121 addLink(link, arg, &html);3122 par1 = QStringRef();3123 }3124 else {3125 html += charLangle;3126 html += charAt;3127 }3128 }3129 else {3130 html += src.at(i++);3131 }3132 }3133 }3134 3135 // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags3136 src = html;3137 html = QString();3138 static const QString typeTags[] = { "type", "headerfile", "func" };3139 for (int i = 0, n = src.size(); i < n;) {3140 if (src.at(i) == charLangle && src.at(i + 1) == charAt) {3141 i += 2;3142 bool handled = false;3143 for (int k = 0; k != 3; ++k) {3144 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {3145 par1 = QStringRef();3146 QString link = linkForNode(3147 marker->resolveTarget(arg.toString(), myTree, relative),3148 relative);3149 addLink(link, arg, &html);3150 handled = true;3151 break;3152 }3153 }3154 if (!handled) {3155 html += charLangle;3156 html += charAt;3157 }3158 }3159 else {3160 html += src.at(i++);3161 }3162 }3163 3164 // replace all3165 // "<@comment>" -> "<span class=\"comment\">";3166 // "<@preprocessor>" -> "<span class=\"preprocessor\">";3167 // "<@string>" -> "<span class=\"string\">";3168 // "<@char>" -> "<span class=\"char\">";3169 // "</@(?:comment|preprocessor|string|char)>" -> "</span>"3170 src = html;3171 html = QString();3172 static const QString spanTags[] = {3173 "<@comment>", "<span class=\"comment\">",3174 "<@preprocessor>", "<span class=\"preprocessor\">",3175 "<@string>", "<span class=\"string\">",3176 "<@char>", "<span class=\"char\">",3177 "</@comment>", "</span>",3178 "</@preprocessor>","</span>",3179 "</@string>", "</span>",3180 "</@char>", "</span>"3181 // "<@char>", "<font color=blue>",3182 // "</@char>", "</font>",3183 // "<@func>", "<font color=green>",3184 // "</@func>", "</font>",3185 // "<@id>", "<i>",3186 // "</@id>", "</i>",3187 // "<@keyword>", "<b>",3188 // "</@keyword>", "</b>",3189 // "<@number>", "<font color=yellow>",3190 // "</@number>", "</font>",3191 // "<@op>", "<b>",3192 // "</@op>", "</b>",3193 // "<@param>", "<i>",3194 // "</@param>", "</i>",3195 // "<@string>", "<font color=green>",3196 // "</@string>", "</font>",3197 };3198 for (int i = 0, n = src.size(); i < n;) {3199 if (src.at(i) == charLangle) {3200 bool handled = false;3201 for (int k = 0; k != 8; ++k) {3202 const QString & tag = spanTags[2 * k];3203 if (tag == QStringRef(&src, i, tag.length())) {3204 html += spanTags[2 * k + 1];3205 i += tag.length();3206 handled = true;3207 break;3208 }3209 }3210 if (!handled) {3211 ++i;3212 if (src.at(i) == charAt ||3213 (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {3214 // drop 'our' unknown tags (the ones still containing '@')3215 while (i < n && src.at(i) != QLatin1Char('>'))3216 ++i;3217 ++i;3218 }3219 else {3220 // retain all others3221 html += charLangle;3222 }3223 }3224 }3225 else {3226 html += src.at(i);3227 ++i;3228 }3229 }3230 3231 return html;3232 }3233 #endif3234 3235 3263 void HtmlGenerator::generateLink(const Atom* atom, 3236 3264 const Node* /* relative */, … … 3242 3270 // hack for C++: move () outside of link 3243 3271 int k = funcLeftParen.pos(1); 3244 out() << protect (atom->string().left(k));3272 out() << protectEnc(atom->string().left(k)); 3245 3273 if (link.isEmpty()) { 3246 3274 if (showBrokenLinks) … … 3250 3278 } 3251 3279 inLink = false; 3252 out() << protect (atom->string().mid(k));3280 out() << protectEnc(atom->string().mid(k)); 3253 3281 } else if (marker->recognizeLanguage("Java")) { 3254 3282 // hack for Java: remove () and use <tt> when appropriate 3255 3283 bool func = atom->string().endsWith("()"); 3256 3284 bool tt = (func || atom->string().contains(camelCase)); … … 3258 3286 out() << "<tt>"; 3259 3287 if (func) { 3260 out() << protect (atom->string().left(atom->string().length() - 2));3288 out() << protectEnc(atom->string().left(atom->string().length() - 2)); 3261 3289 } else { 3262 out() << protect (atom->string());3290 out() << protectEnc(atom->string()); 3263 3291 } 3264 3292 out() << "</tt>"; 3265 3293 } else { 3266 out() << protect (atom->string());3294 out() << protectEnc(atom->string()); 3267 3295 } 3268 3296 } … … 3338 3366 } 3339 3367 3340 QString HtmlGenerator::protect(const QString& string) 3368 QString HtmlGenerator::protectEnc(const QString &string) 3369 { 3370 return protect(string, outputEncoding); 3371 } 3372 3373 QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding) 3341 3374 { 3342 3375 #define APPEND(x) \ … … 3361 3394 } else if (ch == QLatin1Char('"')) { 3362 3395 APPEND("""); 3363 } else if ( ch.unicode() > 0x007F3396 } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) 3364 3397 || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) 3365 3398 || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { … … 3381 3414 } 3382 3415 3383 QString HtmlGenerator::fileBase(const Node *node) 3416 QString HtmlGenerator::fileBase(const Node *node) const 3384 3417 { 3385 3418 QString result; … … 3491 3524 break; 3492 3525 case Node::Target: 3493 return protect (node->name());3526 return protectEnc(node->name()); 3494 3527 } 3495 3528 return registerRef(ref); … … 3510 3543 if (node->access() == Node::Private) 3511 3544 return QString(); 3512 3545 3513 3546 fn = fileName(node); 3514 /* if (!node->url().isEmpty()) 3515 return fn;*/ 3547 #if 0 3548 if (!node->url().isEmpty()) 3549 return fn; 3550 #endif 3551 3516 3552 #if 0 3517 3553 // ### reintroduce this test, without breaking .dcf files … … 3565 3601 } 3566 3602 out() << "\">"; 3567 out() << protect (fullName(apparentNode, relative, marker));3603 out() << protectEnc(fullName(apparentNode, relative, marker)); 3568 3604 out() << "</a>"; 3569 3605 } … … 3575 3611 const EnumNode *enume; 3576 3612 3613 #ifdef GENERATE_MAC_REFS 3577 3614 generateMacRef(node, marker); 3615 #endif 3616 generateExtractionMark(node, MemberMark); 3578 3617 if (node->type() == Node::Enum 3579 3618 && (enume = static_cast<const EnumNode *>(node))->flagsType()) { 3619 #ifdef GENERATE_MAC_REFS 3580 3620 generateMacRef(enume->flagsType(), marker); 3621 #endif 3581 3622 out() << "<h3 class=\"flags\">"; 3582 3623 out() << "<a name=\"" + refForNode(node) + "\"></a>"; 3583 3624 generateSynopsis(enume, relative, marker, CodeMarker::Detailed); 3584 out() << "<br 3625 out() << "<br/>"; 3585 3626 generateSynopsis(enume->flagsType(), 3586 3627 relative, … … 3593 3634 out() << "<a name=\"" + refForNode(node) + "\"></a>"; 3594 3635 generateSynopsis(node, relative, marker, CodeMarker::Detailed); 3595 out() << "</h3> \n";3636 out() << "</h3>" << divNavTop << "\n"; 3596 3637 } 3597 3638 … … 3626 3667 const EnumNode *enume = static_cast<const EnumNode *>(node); 3627 3668 if (enume->flagsType()) { 3628 out() << "<p>The " << protect (enume->flagsType()->name())3669 out() << "<p>The " << protectEnc(enume->flagsType()->name()) 3629 3670 << " type is a typedef for " 3630 3671 << "<a href=\"qflags.html\">QFlags</a><" 3631 << protect (enume->name())3672 << protectEnc(enume->name()) 3632 3673 << ">. It stores an OR combination of " 3633 << protect (enume->name())3674 << protectEnc(enume->name()) 3634 3675 << " values.</p>\n"; 3635 3676 } 3636 3677 } 3637 3678 generateAlsoList(node, marker); 3679 generateExtractionMark(node, EndMark); 3638 3680 } 3639 3681 … … 3677 3719 serviceClasses.insert(serviceName, *c); 3678 3720 } 3721 else if ((*c)->type() == Node::Fake && 3722 (*c)->subType() == Node::QmlClass && 3723 !(*c)->doc().isEmpty()) { 3724 QString qmlClassName = (*c)->name(); 3725 // Remove the "QML:" prefix if present. 3726 if (qmlClassName.startsWith(QLatin1String("QML:"))) 3727 qmlClasses.insert(qmlClassName.mid(4),*c); 3728 else 3729 qmlClasses.insert(qmlClassName,*c); 3730 } 3679 3731 else if ((*c)->isInnerNode()) { 3680 3732 findAllClasses(static_cast<InnerNode *>(*c)); … … 3701 3753 if (ncmap == newClassMaps.end()) 3702 3754 ncmap = newClassMaps.insert(sinceVersion,NodeMap()); 3755 NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); 3756 if (nqcmap == newQmlClassMaps.end()) 3757 nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); 3703 3758 3704 3759 if ((*child)->type() == Node::Function) { … … 3720 3775 ncmap.value().insert(className,(*child)); 3721 3776 } 3777 else if ((*child)->subType() == Node::QmlClass) { 3778 QString className = (*child)->name(); 3779 if ((*child)->parent() && 3780 (*child)->parent()->type() == Node::Namespace && 3781 !(*child)->parent()->name().isEmpty()) 3782 className = (*child)->parent()->name()+"::"+className; 3783 nsmap.value().insert(className,(*child)); 3784 nqcmap.value().insert(className,(*child)); 3785 } 3722 3786 } 3723 3787 else { … … 3736 3800 } 3737 3801 } 3738 3739 #if 03740 const QRegExp versionSeparator("[\\-\\.]");3741 const int minorIndex = version.indexOf(versionSeparator);3742 const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);3743 version = version.left(patchIndex);3744 #endif3745 3802 3746 3803 void HtmlGenerator::findAllFunctions(const InnerNode *node) … … 3807 3864 } 3808 3865 3809 #ifdef ZZZ_QDOC_QML3810 /*!3811 This function finds all the qml element nodes and3812 stores them in a map for later use.3813 */3814 void HtmlGenerator::findAllQmlClasses(const InnerNode *node)3815 {3816 NodeList::const_iterator c = node->childNodes().constBegin();3817 while (c != node->childNodes().constEnd()) {3818 if ((*c)->type() == Node::Fake) {3819 const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);3820 if (fakeNode->subType() == Node::QmlClass) {3821 const QmlClassNode* qmlNode =3822 static_cast<const QmlClassNode*>(fakeNode);3823 const Node* n = qmlNode->classNode();3824 }3825 qmlClasses.insert(fakeNode->name(),*c);3826 }3827 ++c;3828 }3829 }3830 #endif3831 3832 3866 int HtmlGenerator::hOffset(const Node *node) 3833 3867 { … … 3837 3871 return 2; 3838 3872 case Node::Fake: 3839 if (node->doc().briefText().isEmpty()) 3840 return 1; 3841 else 3842 return 2; 3873 return 1; 3843 3874 case Node::Enum: 3844 3875 case Node::Typedef: … … 3940 3971 else { 3941 3972 *node = marker->resolveTarget(first, myTree, relative); 3942 if (!*node) 3973 if (!*node) { 3943 3974 *node = myTree->findFakeNodeByTitle(first); 3944 if (!*node) 3975 } 3976 if (!*node) { 3945 3977 *node = myTree->findUnambiguousTarget(first, targetAtom); 3978 } 3946 3979 } 3947 3980 … … 4036 4069 case Node::Obsolete: 4037 4070 if (node->isInnerNode()) 4038 4071 Generator::generateStatus(node, marker); 4039 4072 break; 4040 4073 case Node::Compat: … … 4078 4111 } 4079 4112 4113 #ifdef GENERATE_MAC_REFS 4114 /* 4115 No longer valid. 4116 */ 4080 4117 void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) 4081 4118 { … … 4087 4124 out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n"; 4088 4125 } 4126 #endif 4089 4127 4090 4128 void HtmlGenerator::beginLink(const QString &link, … … 4138 4176 } 4139 4177 4140 QT_END_NAMESPACE4141 4142 4178 #ifdef QDOC_QML 4143 4179 4144 4180 /*! 4145 Generates the summary for forthe \a section. Only used for4181 Generates the summary for the \a section. Only used for 4146 4182 sections of QML element documentation. 4147 4183 … … 4153 4189 { 4154 4190 if (!section.members.isEmpty()) { 4191 out() << "<ul>\n"; 4155 4192 NodeList::ConstIterator m; 4156 int count = section.members.size();4157 bool twoColumn = false;4158 if (section.members.first()->type() == Node::QmlProperty) {4159 twoColumn = (count >= 5);4160 }4161 if (twoColumn)4162 out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""4163 " cellspacing=\"0\">\n"4164 << "<tr><td width=\"45%\" valign=\"top\">";4165 out() << "<ul>\n";4166 4167 int row = 0;4168 4193 m = section.members.begin(); 4169 4194 while (m != section.members.end()) { 4170 if (twoColumn && row == (int) (count + 1) / 2) 4171 out() << "</ul></td><td valign=\"top\"><ul>\n"; 4172 out() << "<li><div class=\"fn\"></div>"; 4195 out() << "<li class=\"fn\">"; 4173 4196 generateQmlItem(*m,relative,marker,true); 4174 4197 out() << "</li>\n"; 4175 row++;4176 4198 ++m; 4177 4199 } 4178 4200 out() << "</ul>\n"; 4179 if (twoColumn)4180 out() << "</td></tr>\n</table></p>\n";4181 4201 } 4182 4202 } … … 4191 4211 { 4192 4212 const QmlPropertyNode* qpn = 0; 4213 #ifdef GENERATE_MAC_REFS 4193 4214 generateMacRef(node, marker); 4215 #endif 4216 generateExtractionMark(node, MemberMark); 4194 4217 out() << "<div class=\"qmlitem\">"; 4195 4218 if (node->subType() == Node::QmlPropertyGroup) { … … 4197 4220 NodeList::ConstIterator p = qpgn->childNodes().begin(); 4198 4221 out() << "<div class=\"qmlproto\">"; 4199 out() << "<table width=\"100%\"class=\"qmlname\">";4222 out() << "<table class=\"qmlname\">"; 4200 4223 4201 4224 while (p != qpgn->childNodes().end()) { 4202 4225 if ((*p)->type() == Node::QmlProperty) { 4203 4226 qpn = static_cast<const QmlPropertyNode*>(*p); 4204 out() << "<tr><td>"; 4227 if (++numTableRows % 2 == 1) 4228 out() << "<tr class=\"odd\">"; 4229 else 4230 out() << "<tr class=\"even\">"; 4231 4232 out() << "<td class=\"tblQmlPropNode\"><p>"; 4233 4205 4234 out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; 4206 if (!qpn->isWritable()) 4235 4236 if (!qpn->isWritable(myTree)) { 4207 4237 out() << "<span class=\"qmlreadonly\">read-only</span>"; 4238 } 4239 if (qpgn->isDefault()) 4240 out() << "<span class=\"qmldefault\">default</span>"; 4208 4241 generateQmlItem(qpn, relative, marker, false); 4209 out() << "</td></tr>"; 4210 if (qpgn->isDefault()) { 4211 out() << "</table>" 4212 << "</div></div>" 4213 << "<div class=\"qmlitem\">" 4214 << "<div class=\"qmlproto\">" 4215 << "<table class=\"qmlname\">" 4216 << "<tr><td><font color=\"green\">" 4217 << "default</font></td></tr>"; 4218 } 4242 out() << "</p></td></tr>"; 4219 4243 } 4220 4244 ++p; … … 4227 4251 out() << "<div class=\"qmlproto\">"; 4228 4252 out() << "<table class=\"qmlname\">"; 4229 out() << "<tr><td>"; 4253 //out() << "<tr>"; 4254 if (++numTableRows % 2 == 1) 4255 out() << "<tr class=\"odd\">"; 4256 else 4257 out() << "<tr class=\"even\">"; 4258 out() << "<td class=\"tblQmlFuncNode\"><p>"; 4230 4259 out() << "<a name=\"" + refForNode(qsn) + "\"></a>"; 4231 4260 generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); 4232 4261 //generateQmlItem(qsn,relative,marker,false); 4233 out() << "</ td></tr>";4262 out() << "</p></td></tr>"; 4234 4263 out() << "</table>"; 4235 4264 out() << "</div>"; … … 4239 4268 out() << "<div class=\"qmlproto\">"; 4240 4269 out() << "<table class=\"qmlname\">"; 4241 out() << "<tr><td>"; 4270 //out() << "<tr>"; 4271 if (++numTableRows % 2 == 1) 4272 out() << "<tr class=\"odd\">"; 4273 else 4274 out() << "<tr class=\"even\">"; 4275 out() << "<td class=\"tblQmlFuncNode\"><p>"; 4242 4276 out() << "<a name=\"" + refForNode(qmn) + "\"></a>"; 4243 4277 generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); 4244 out() << "</ td></tr>";4278 out() << "</p></td></tr>"; 4245 4279 out() << "</table>"; 4246 4280 out() << "</div>"; … … 4254 4288 out() << "</div>"; 4255 4289 out() << "</div>"; 4290 generateExtractionMark(node, EndMark); 4256 4291 } 4257 4292 … … 4271 4306 if (n && n->subType() == Node::QmlClass) { 4272 4307 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n); 4273 out() << "<p style=\"text-align: center\">";4274 4308 Text text; 4275 text << "[Inherits ";4309 text << Atom::ParaLeft << "Inherits "; 4276 4310 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); 4277 4311 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); 4278 4312 text << Atom(Atom::String, linkPair.second); 4279 4313 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); 4280 text << "]";4314 text << Atom::ParaRight; 4281 4315 generateText(text, cn, marker); 4282 out() << "</p>"; 4283 } 4316 } 4317 } 4318 } 4319 } 4320 4321 /*! 4322 Output the "Inherit by" list for the QML element, 4323 if it is inherited by any other elements. 4324 */ 4325 void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, 4326 CodeMarker* marker) 4327 { 4328 if (cn) { 4329 NodeList subs; 4330 QmlClassNode::subclasses(cn->name(),subs); 4331 if (!subs.isEmpty()) { 4332 Text text; 4333 text << Atom::ParaLeft << "Inherited by "; 4334 appendSortedQmlNames(text,cn,subs,marker); 4335 text << Atom::ParaRight; 4336 generateText(text, cn, marker); 4284 4337 } 4285 4338 } … … 4298 4351 const ClassNode* cn = qcn->classNode(); 4299 4352 if (cn && (cn->status() != Node::Internal)) { 4300 out() << "<p style=\"text-align: center\">";4301 4353 Text text; 4302 text << "[";4354 text << Atom::ParaLeft; 4303 4355 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); 4304 4356 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); 4305 text << Atom(Atom::String, qcn->name()); 4357 QString name = qcn->name(); 4358 if (name.startsWith(QLatin1String("QML:"))) 4359 name = name.mid(4); // remove the "QML:" prefix 4360 text << Atom(Atom::String, name); 4306 4361 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); 4307 4362 text << " instantiates the C++ class "; … … 4310 4365 text << Atom(Atom::String, cn->name()); 4311 4366 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); 4312 text << "]";4367 text << Atom::ParaRight; 4313 4368 generateText(text, qcn, marker); 4314 out() << "</p>";4315 4369 } 4316 4370 } … … 4329 4383 const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake); 4330 4384 if (n && n->subType() == Node::QmlClass) { 4331 out() << "<p style=\"text-align: center\">";4332 4385 Text text; 4333 text << "[";4386 text << Atom::ParaLeft; 4334 4387 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); 4335 4388 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); … … 4341 4394 text << Atom(Atom::String, n->name()); 4342 4395 text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); 4343 text << "]";4396 text << Atom::ParaRight; 4344 4397 generateText(text, cn, marker); 4345 out() << "</p>"; 4346 } 4398 } 4399 } 4400 } 4401 4402 /*! 4403 Generate the <page> element for the given \a node using the \a writer. 4404 Return true if a <page> element was written; otherwise return false. 4405 */ 4406 bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer, 4407 const Node* node, 4408 CodeMarker* marker) const 4409 { 4410 if (node->pageType() == Node::NoPageType) 4411 return false; 4412 if (node->name().isEmpty()) 4413 return true; 4414 if (node->access() == Node::Private) 4415 return false; 4416 4417 QString guid = QUuid::createUuid().toString(); 4418 QString url = PageGenerator::fileName(node); 4419 QString title; 4420 QString rawTitle; 4421 QString fullTitle; 4422 QStringList pageWords; 4423 QXmlStreamAttributes attributes; 4424 4425 writer.writeStartElement("page"); 4426 4427 if (node->isInnerNode()) { 4428 const InnerNode* inner = static_cast<const InnerNode*>(node); 4429 if (!inner->pageKeywords().isEmpty()) 4430 pageWords << inner->pageKeywords(); 4431 4432 switch (node->type()) { 4433 case Node::Fake: 4434 { 4435 const FakeNode* fake = static_cast<const FakeNode*>(node); 4436 title = fake->fullTitle(); 4437 pageWords << title; 4438 break; 4439 } 4440 case Node::Class: 4441 { 4442 title = node->name() + " Class Reference"; 4443 pageWords << node->name() << "class" << "reference"; 4444 break; 4445 } 4446 case Node::Namespace: 4447 { 4448 rawTitle = marker->plainName(inner); 4449 fullTitle = marker->plainFullName(inner); 4450 title = rawTitle + " Namespace Reference"; 4451 pageWords << rawTitle << "namespace" << "reference"; 4452 break; 4453 } 4454 default: 4455 title = node->name(); 4456 pageWords << title; 4457 break; 4458 } 4459 } 4460 else { 4461 switch (node->type()) { 4462 case Node::Enum: 4463 { 4464 title = node->name() + " Enum Reference"; 4465 pageWords << node->name() << "enum" << "type"; 4466 url += "#" + node->name() + "-enum"; 4467 break; 4468 } 4469 case Node::Function: 4470 { 4471 title = node->name() + " Function Reference"; 4472 pageWords << node->name() << "function"; 4473 url += "#" + node->name(); 4474 break; 4475 } 4476 case Node::Property: 4477 { 4478 title = node->name() + " Property Reference"; 4479 pageWords << node->name() << "property"; 4480 url += "#" + node->name() + "-prop"; 4481 break; 4482 } 4483 case Node::Typedef: 4484 { 4485 title = node->name() + " Type Reference"; 4486 pageWords << node->name() << "typedef" << "type"; 4487 url += "#" + node->name(); 4488 break; 4489 } 4490 default: 4491 title = node->name(); 4492 pageWords << title; 4493 break; 4494 } 4495 4496 Node* parent = node->parent(); 4497 if (parent && ((parent->type() == Node::Class) || 4498 (parent->type() == Node::Namespace))) { 4499 pageWords << parent->name(); 4500 } 4501 } 4502 4503 writer.writeAttribute("id",guid); 4504 writer.writeStartElement("pageWords"); 4505 writer.writeCharacters(pageWords.join(" ")); 4506 4507 writer.writeEndElement(); 4508 writer.writeStartElement("pageTitle"); 4509 writer.writeCharacters(title); 4510 writer.writeEndElement(); 4511 writer.writeStartElement("pageUrl"); 4512 writer.writeCharacters(url); 4513 writer.writeEndElement(); 4514 writer.writeStartElement("pageType"); 4515 switch (node->pageType()) { 4516 case Node::ApiPage: 4517 writer.writeCharacters("APIPage"); 4518 break; 4519 case Node::ArticlePage: 4520 writer.writeCharacters("Article"); 4521 break; 4522 case Node::ExamplePage: 4523 writer.writeCharacters("Example"); 4524 break; 4525 default: 4526 break; 4527 } 4528 writer.writeEndElement(); 4529 writer.writeEndElement(); 4530 4531 if (node->type() == Node::Fake && node->doc().hasTableOfContents()) { 4532 QList<Atom*> toc = node->doc().tableOfContents(); 4533 if (!toc.isEmpty()) { 4534 for (int i = 0; i < toc.size(); ++i) { 4535 Text headingText = Text::sectionHeading(toc.at(i)); 4536 QString s = headingText.toString(); 4537 writer.writeStartElement("page"); 4538 guid = QUuid::createUuid().toString(); 4539 QString internalUrl = url + "#" + Doc::canonicalTitle(s); 4540 writer.writeAttribute("id",guid); 4541 writer.writeStartElement("pageWords"); 4542 writer.writeCharacters(pageWords.join(" ")); 4543 writer.writeCharacters(" "); 4544 writer.writeCharacters(s); 4545 writer.writeEndElement(); 4546 writer.writeStartElement("pageTitle"); 4547 writer.writeCharacters(s); 4548 writer.writeEndElement(); 4549 writer.writeStartElement("pageUrl"); 4550 writer.writeCharacters(internalUrl); 4551 writer.writeEndElement(); 4552 writer.writeStartElement("pageType"); 4553 writer.writeCharacters("Article"); 4554 writer.writeEndElement(); 4555 writer.writeEndElement(); 4556 } 4557 } 4558 } 4559 return true; 4560 } 4561 4562 /*! 4563 Traverse the tree recursively and generate the <keyword> 4564 elements. 4565 */ 4566 void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const 4567 { 4568 if (generatePageElement(writer, node, marker)) { 4569 4570 if (node->isInnerNode()) { 4571 const InnerNode *inner = static_cast<const InnerNode *>(node); 4572 4573 // Recurse to write an element for this child node and all its children. 4574 foreach (const Node *child, inner->childNodes()) 4575 generatePageElements(writer, child, marker); 4576 } 4577 } 4578 } 4579 4580 /*! 4581 Outputs the file containing the index used for searching the html docs. 4582 */ 4583 void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const 4584 { 4585 QFile file(fileName); 4586 if (!file.open(QFile::WriteOnly | QFile::Text)) 4587 return ; 4588 4589 QXmlStreamWriter writer(&file); 4590 writer.setAutoFormatting(true); 4591 writer.writeStartDocument(); 4592 writer.writeStartElement("qtPageIndex"); 4593 4594 generatePageElements(writer, myTree->root(), marker); 4595 4596 writer.writeEndElement(); // qtPageIndex 4597 writer.writeEndDocument(); 4598 file.close(); 4599 } 4600 4601 void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType markType) 4602 { 4603 if (markType != EndMark) { 4604 out() << "<!-- $$$" + node->name(); 4605 if (markType == MemberMark) { 4606 if (node->type() == Node::Function) { 4607 const FunctionNode *func = static_cast<const FunctionNode *>(node); 4608 if (!func->associatedProperty()) { 4609 if (func->overloadNumber() == 1) 4610 out() << "[overload1]"; 4611 out() << "$$$" + func->name() + func->rawParameters().remove(' '); 4612 } 4613 } else if (node->type() == Node::Property) { 4614 out() << "-prop"; 4615 const PropertyNode *prop = static_cast<const PropertyNode *>(node); 4616 const NodeList &list = prop->functions(); 4617 foreach (const Node *propFuncNode, list) { 4618 if (propFuncNode->type() == Node::Function) { 4619 const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode); 4620 out() << "$$$" + func->name() + func->rawParameters().remove(' '); 4621 } 4622 } 4623 } else if (node->type() == Node::Enum) { 4624 const EnumNode *enumNode = static_cast<const EnumNode *>(node); 4625 foreach (const EnumItem &item, enumNode->items()) 4626 out() << "$$$" + item.name(); 4627 } 4628 } else if (markType == BriefMark) { 4629 out() << "-brief"; 4630 } else if (markType == DetailedDescriptionMark) { 4631 out() << "-description"; 4632 } 4633 out() << " -->\n"; 4634 } else { 4635 out() << "<!-- @@@" + node->name() + " -->\n"; 4347 4636 } 4348 4637 } 4349 4638 4350 4639 #endif 4640 4641 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.