tools/qdoc3/htmlgenerator.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    42 /*
    42 /*
    43   htmlgenerator.cpp
    43   htmlgenerator.cpp
    44 */
    44 */
    45 
    45 
    46 #include "codemarker.h"
    46 #include "codemarker.h"
       
    47 #include "codeparser.h"
    47 #include "helpprojectwriter.h"
    48 #include "helpprojectwriter.h"
    48 #include "htmlgenerator.h"
    49 #include "htmlgenerator.h"
    49 #include "node.h"
    50 #include "node.h"
    50 #include "separator.h"
    51 #include "separator.h"
    51 #include "tree.h"
    52 #include "tree.h"
    52 #include <ctype.h>
    53 #include <ctype.h>
    53 
    54 
    54 #include <qdebug.h>
    55 #include <qdebug.h>
    55 #include <qlist.h>
    56 #include <qlist.h>
    56 #include <qiterator.h>
    57 #include <qiterator.h>
       
    58 #include <qtextcodec.h>
    57 
    59 
    58 QT_BEGIN_NAMESPACE
    60 QT_BEGIN_NAMESPACE
    59 
    61 
    60 #define COMMAND_VERSION                 Doc::alias("version")
    62 #define COMMAND_VERSION                 Doc::alias("version")
       
    63 int HtmlGenerator::id = 0;
    61 
    64 
    62 QString HtmlGenerator::sinceTitles[] =
    65 QString HtmlGenerator::sinceTitles[] =
    63     {
    66     {
    64         "    New Namespaces",
    67         "    New Namespaces",
    65         "    New Classes",
    68         "    New Classes",
    69         "    New Macros",
    72         "    New Macros",
    70         "    New Enum Types",
    73         "    New Enum Types",
    71         "    New Typedefs",
    74         "    New Typedefs",
    72         "    New Properties",
    75         "    New Properties",
    73         "    New Variables",
    76         "    New Variables",
       
    77         "    New QML Elements",
    74         "    New Qml Properties",
    78         "    New Qml Properties",
    75         "    New Qml Signals",
    79         "    New Qml Signals",
    76         "    New Qml Methods",
    80         "    New Qml Methods",
    77         ""
    81         ""
    78     };
    82     };
   199     }
   203     }
   200 }
   204 }
   201 
   205 
   202 
   206 
   203 HtmlGenerator::HtmlGenerator()
   207 HtmlGenerator::HtmlGenerator()
   204     : helpProjectWriter(0), inLink(false), inContents(false),
   208     : helpProjectWriter(0),
   205       inSectionHeading(false), inTableHeader(false), numTableRows(0),
   209       inLink(false),
   206       threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"),
   210       inContents(false),
   207       myTree(0), slow(false), obsoleteLinks(false)
   211       inSectionHeading(false),
       
   212       inTableHeader(false),
       
   213       numTableRows(0),
       
   214       threeColumnEnumValueTable(true),
       
   215       offlineDocs(true),
       
   216       funcLeftParen("\\S(\\()"),
       
   217       myTree(0),
       
   218       slow(false),
       
   219       obsoleteLinks(false)
   208 {
   220 {
   209 }
   221 }
   210 
   222 
   211 HtmlGenerator::~HtmlGenerator()
   223 HtmlGenerator::~HtmlGenerator()
   212 {
   224 {
   246                              Config::dot +
   258                              Config::dot +
   247                              HTMLGENERATOR_STYLE);
   259                              HTMLGENERATOR_STYLE);
   248     postHeader = config.getString(HtmlGenerator::format() +
   260     postHeader = config.getString(HtmlGenerator::format() +
   249                                   Config::dot +
   261                                   Config::dot +
   250                                   HTMLGENERATOR_POSTHEADER);
   262                                   HTMLGENERATOR_POSTHEADER);
       
   263     postPostHeader = config.getString(HtmlGenerator::format() +
       
   264                                       Config::dot +
       
   265                                       HTMLGENERATOR_POSTPOSTHEADER);
   251     footer = config.getString(HtmlGenerator::format() +
   266     footer = config.getString(HtmlGenerator::format() +
   252                               Config::dot +
   267                               Config::dot +
   253                               HTMLGENERATOR_FOOTER);
   268                               HTMLGENERATOR_FOOTER);
   254     address = config.getString(HtmlGenerator::format() +
   269     address = config.getString(HtmlGenerator::format() +
   255                                Config::dot +
   270                                Config::dot +
   257     pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
   272     pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
   258                                           Config::dot +
   273                                           Config::dot +
   259                                           HTMLGENERATOR_GENERATEMACREFS);
   274                                           HTMLGENERATOR_GENERATEMACREFS);
   260 
   275 
   261     project = config.getString(CONFIG_PROJECT);
   276     project = config.getString(CONFIG_PROJECT);
   262 
   277     offlineDocs = !config.getBool(CONFIG_ONLINE);
   263     projectDescription = config.getString(CONFIG_DESCRIPTION);
   278     projectDescription = config.getString(CONFIG_DESCRIPTION);
   264     if (projectDescription.isEmpty() && !project.isEmpty())
   279     if (projectDescription.isEmpty() && !project.isEmpty())
   265         projectDescription = project + " Reference Documentation";
   280         projectDescription = project + " Reference Documentation";
   266 
   281 
   267     projectUrl = config.getString(CONFIG_URL);
   282     projectUrl = config.getString(CONFIG_URL);
       
   283 
       
   284     outputEncoding = config.getString(CONFIG_OUTPUTENCODING);
       
   285     if (outputEncoding.isEmpty())
       
   286         outputEncoding = QLatin1String("ISO-8859-1");
       
   287     outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit());
       
   288 
       
   289     naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE);
       
   290     if (naturalLanguage.isEmpty())
       
   291         naturalLanguage = QLatin1String("en");
   268 
   292 
   269     QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
   293     QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
   270     QSet<QString>::ConstIterator edition = editionNames.begin();
   294     QSet<QString>::ConstIterator edition = editionNames.begin();
   271     while (edition != editionNames.end()) {
   295     while (edition != editionNames.end()) {
   272         QString editionName = *edition;
   296         QString editionName = *edition;
   319   \note The html file generation is done in the base class,
   343   \note The html file generation is done in the base class,
   320   PageGenerator::generateTree().
   344   PageGenerator::generateTree().
   321  */
   345  */
   322 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
   346 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
   323 {
   347 {
       
   348 #if 0    
   324     // Copy the stylesheets from the directory containing the qdocconf file.
   349     // Copy the stylesheets from the directory containing the qdocconf file.
   325     // ### This should be changed to use a special directory in doc/src.
   350     // ### This should be changed to use a special directory in doc/src.
   326     QStringList::ConstIterator styleIter = stylesheets.begin();
   351     QStringList::ConstIterator styleIter = stylesheets.begin();
   327     QDir configPath = QDir::current();
   352     QDir configPath = QDir::current();
   328     while (styleIter != stylesheets.end()) {
   353     while (styleIter != stylesheets.end()) {
   329         QString filePath = configPath.absoluteFilePath(*styleIter);
   354         QString filePath = configPath.absoluteFilePath(*styleIter);
   330         Config::copyFile(Location(), filePath, filePath, outputDir());
   355         Config::copyFile(Location(), filePath, filePath, outputDir());
   331         ++styleIter;
   356         ++styleIter;
   332     }
   357     }
   333 
   358 #endif
   334     myTree = tree;
   359     myTree = tree;
   335     nonCompatClasses.clear();
   360     nonCompatClasses.clear();
   336     mainClasses.clear();
   361     mainClasses.clear();
   337     compatClasses.clear();
   362     compatClasses.clear();
   338     obsoleteClasses.clear();
   363     obsoleteClasses.clear();
   387     generateDcf("qmake",
   412     generateDcf("qmake",
   388                 "qmake-manual.html",
   413                 "qmake-manual.html",
   389                 "qmake Manual",
   414                 "qmake Manual",
   390                 dcfQmakeRoot);
   415                 dcfQmakeRoot);
   391 
   416 
   392     generateIndex(project.toLower().simplified().replace(" ", "-"),
   417     QString fileBase = project.toLower().simplified().replace(" ", "-");
   393                   projectUrl,
   418     generateIndex(fileBase, projectUrl, projectDescription);
   394                   projectDescription);
   419     generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker);
   395 
   420 
   396     helpProjectWriter->generate(myTree);
   421     helpProjectWriter->generate(myTree);
   397 }
   422 }
   398 
   423 
   399 void HtmlGenerator::startText(const Node * /* relative */,
   424 void HtmlGenerator::startText(const Node * /* relative */,
   429                 beginLink(link, node, relative, marker);
   454                 beginLink(link, node, relative, marker);
   430                 generateLink(atom, relative, marker);
   455                 generateLink(atom, relative, marker);
   431                 endLink();
   456                 endLink();
   432             }
   457             }
   433             else {
   458             else {
   434                 out() << protect(atom->string());
   459                 out() << protectEnc(atom->string());
   435             }
   460             }
   436         }
   461         }
   437         else {
   462         else {
   438             out() << protect(atom->string());
   463             out() << protectEnc(atom->string());
   439         }
   464         }
   440         break;
   465         break;
   441     case Atom::BaseName:
   466     case Atom::BaseName:
   442         break;
   467         break;
   443     case Atom::BriefLeft:
   468     case Atom::BriefLeft:
   481             out() << "</p>\n";
   506             out() << "</p>\n";
   482         break;
   507         break;
   483     case Atom::C:
   508     case Atom::C:
   484         out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
   509         out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
   485         if (inLink) {
   510         if (inLink) {
   486             out() << protect(plainCode(atom->string()));
   511             out() << protectEnc(plainCode(atom->string()));
   487         }
   512         }
   488         else {
   513         else {
   489             out() << highlightedCode(atom->string(), marker, relative);
   514             out() << highlightedCode(atom->string(), marker, relative);
   490         }
   515         }
   491         out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
   516         out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
   492         break;
   517         break;
   493     case Atom::Code:
   518     case Atom::Code:
   494 	out() << "<pre>"
   519 	out() << "<pre class=\"highlightedCode\">"
   495               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   520               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   496                                                  marker,relative))
   521                                                  marker,relative))
   497               << "</pre>\n";
   522               << "</pre>\n";
   498 	break;
   523 	break;
   499 #ifdef QDOC_QML
   524 #ifdef QDOC_QML
   500     case Atom::Qml:
   525     case Atom::Qml:
   501 	out() << "<pre>"
   526 	out() << "<pre class=\"highlightedCode\">"
   502               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   527               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   503                                                  marker,relative))
   528                                                  marker,relative))
   504               << "</pre>\n";
   529               << "</pre>\n";
   505 	break;
   530 	break;
   506 #endif
   531 #endif
   507     case Atom::CodeNew:
   532     case Atom::CodeNew:
   508         out() << "<p>you can rewrite it as</p>\n"
   533         out() << "<p>you can rewrite it as</p>\n"
   509               << "<pre>"
   534               << "<pre class=\"highlightedCode\">"
   510               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   535               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
   511                                                  marker,relative))
   536                                                  marker,relative))
   512               << "</pre>\n";
   537               << "</pre>\n";
   513         break;
   538         break;
   514     case Atom::CodeOld:
   539     case Atom::CodeOld:
   515         out() << "<p>For example, if you have code like</p>\n";
   540         out() << "<p>For example, if you have code like</p>\n";
   516         // fallthrough
   541         // fallthrough
   517     case Atom::CodeBad:
   542     case Atom::CodeBad:
   518         out() << "<pre><font color=\"#404040\">"
   543         out() << "<pre class=\"highlightedCode\">"
   519               << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
   544               << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
   520               << "</font></pre>\n";
   545               << "</pre>\n";
   521 	break;
   546 	break;
   522     case Atom::FootnoteLeft:
   547     case Atom::FootnoteLeft:
   523         // ### For now
   548         // ### For now
   524         if (in_para) {
   549         if (in_para) {
   525             out() << "</p>\n";
   550             out() << "</p>\n";
   572     case Atom::GeneratedList:
   597     case Atom::GeneratedList:
   573         if (atom->string() == "annotatedclasses") {
   598         if (atom->string() == "annotatedclasses") {
   574             generateAnnotatedList(relative, marker, nonCompatClasses);
   599             generateAnnotatedList(relative, marker, nonCompatClasses);
   575         }
   600         }
   576         else if (atom->string() == "classes") {
   601         else if (atom->string() == "classes") {
   577             generateCompactList(relative, marker, nonCompatClasses);
   602             generateCompactList(relative, marker, nonCompatClasses, true);
   578         }
   603         }
   579         else if (atom->string().contains("classesbymodule")) {
   604         else if (atom->string().contains("classesbymodule")) {
   580             QString arg = atom->string().trimmed();
   605             QString arg = atom->string().trimmed();
   581             QString moduleName = atom->string().mid(atom->string().indexOf(
   606             QString moduleName = atom->string().mid(atom->string().indexOf(
   582                 "classesbymodule") + 15).trimmed();
   607                 "classesbymodule") + 15).trimmed();
   620         }
   645         }
   621         else if (atom->string() == "classhierarchy") {
   646         else if (atom->string() == "classhierarchy") {
   622             generateClassHierarchy(relative, marker, nonCompatClasses);
   647             generateClassHierarchy(relative, marker, nonCompatClasses);
   623         }
   648         }
   624         else if (atom->string() == "compatclasses") {
   649         else if (atom->string() == "compatclasses") {
   625             generateCompactList(relative, marker, compatClasses);
   650             generateCompactList(relative, marker, compatClasses, false);
   626         }
   651         }
   627         else if (atom->string() == "obsoleteclasses") {
   652         else if (atom->string() == "obsoleteclasses") {
   628             generateCompactList(relative, marker, obsoleteClasses);
   653             generateCompactList(relative, marker, obsoleteClasses, false);
   629         }
   654         }
   630         else if (atom->string() == "functionindex") {
   655         else if (atom->string() == "functionindex") {
   631             generateFunctionIndex(relative, marker);
   656             generateFunctionIndex(relative, marker);
   632         }
   657         }
   633         else if (atom->string() == "legalese") {
   658         else if (atom->string() == "legalese") {
   634             generateLegaleseList(relative, marker);
   659             generateLegaleseList(relative, marker);
   635         }
   660         }
   636         else if (atom->string() == "mainclasses") {
   661         else if (atom->string() == "mainclasses") {
   637             generateCompactList(relative, marker, mainClasses);
   662             generateCompactList(relative, marker, mainClasses, true);
   638         }
   663         }
   639         else if (atom->string() == "services") {
   664         else if (atom->string() == "services") {
   640             generateCompactList(relative, marker, serviceClasses);
   665             generateCompactList(relative, marker, serviceClasses, false);
   641         }
   666         }
   642         else if (atom->string() == "overviews") {
   667         else if (atom->string() == "overviews") {
   643             generateOverviewList(relative, marker);
   668             generateOverviewList(relative, marker);
   644         }
   669         }
   645         else if (atom->string() == "namespaces") {
   670         else if (atom->string() == "namespaces") {
   674         {
   699         {
   675             NewSinceMaps::const_iterator nsmap;
   700             NewSinceMaps::const_iterator nsmap;
   676             nsmap = newSinceMaps.find(atom->string());
   701             nsmap = newSinceMaps.find(atom->string());
   677             NewClassMaps::const_iterator ncmap;
   702             NewClassMaps::const_iterator ncmap;
   678             ncmap = newClassMaps.find(atom->string());
   703             ncmap = newClassMaps.find(atom->string());
       
   704             NewClassMaps::const_iterator nqcmap;
       
   705             nqcmap = newQmlClassMaps.find(atom->string());
   679             if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
   706             if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
   680                 QList<Section> sections;
   707                 QList<Section> sections;
   681                 QList<Section>::ConstIterator s;
   708                 QList<Section>::ConstIterator s;
   682                 for (int i=0; i<LastSinceType; ++i)
   709                 for (int i=0; i<LastSinceType; ++i)
   683                     sections.append(Section(sinceTitle(i),QString(),QString()));
   710                     sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
   684 
   711 
   685                 NodeMultiMap::const_iterator n = nsmap.value().constBegin();
   712                 NodeMultiMap::const_iterator n = nsmap.value().constBegin();
   686                 while (n != nsmap.value().constEnd()) {
   713                 while (n != nsmap.value().constEnd()) {
   687                     const Node* node = n.value();
   714                     const Node* node = n.value();
   688                     switch (node->type()) {
   715                     switch (node->type()) {
       
   716                       case Node::Fake:
       
   717                           if (node->subType() == Node::QmlClass) {
       
   718                               sections[QmlClass].appendMember((Node*)node);
       
   719                           }
       
   720                           break;
   689                       case Node::Namespace:
   721                       case Node::Namespace:
   690                           sections[Namespace].appendMember((Node*)node);
   722                           sections[Namespace].appendMember((Node*)node);
   691                           break;
   723                           break;
   692                       case Node::Class: 
   724                       case Node::Class: 
   693                           sections[Class].appendMember((Node*)node);
   725                           sections[Class].appendMember((Node*)node);
   766                 while (s != sections.constEnd()) {
   798                 while (s != sections.constEnd()) {
   767                     if (!(*s).members.isEmpty()) {
   799                     if (!(*s).members.isEmpty()) {
   768                         out() << "<a name=\""
   800                         out() << "<a name=\""
   769                               << Doc::canonicalTitle((*s).name)
   801                               << Doc::canonicalTitle((*s).name)
   770                               << "\"></a>\n";
   802                               << "\"></a>\n";
   771                         out() << "<h3>" << protect((*s).name) << "</h3>\n";
   803                         out() << "<h3>" << protectEnc((*s).name) << "</h3>\n";
   772                         if (idx == Class)
   804                         if (idx == Class)
   773                             generateCompactList(0, marker, ncmap.value(), QString("Q"));
   805                             generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
       
   806                         else if (idx == QmlClass)
       
   807                             generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
   774                         else if (idx == MemberFunction) {
   808                         else if (idx == MemberFunction) {
   775                             ParentMaps parentmaps;
   809                             ParentMaps parentmaps;
   776                             ParentMaps::iterator pmap;
   810                             ParentMaps::iterator pmap;
   777                             NodeList::const_iterator i = s->members.constBegin();
   811                             NodeList::const_iterator i = s->members.constBegin();
   778                             while (i != s->members.constEnd()) {
   812                             while (i != s->members.constEnd()) {
   790 
   824 
   791                                 out() << "<a href=\""
   825                                 out() << "<a href=\""
   792                                       << linkForNode(pmap.key(), 0)
   826                                       << linkForNode(pmap.key(), 0)
   793                                       << "\">";
   827                                       << "\">";
   794                                 QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
   828                                 QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
   795                                 out() << protect(pieces.last());
   829                                 out() << protectEnc(pieces.last());
   796                                 out() << "</a>"  << ":</p>\n";
   830                                 out() << "</a>"  << ":</p>\n";
   797 
   831 
   798                                 generateSection(nlist, 0, marker, CodeMarker::Summary);
   832                                 generateSection(nlist, 0, marker, CodeMarker::Summary);
   799                                 out() << "<br />";
   833                                 out() << "<br/>";
   800                                 ++pmap;
   834                                 ++pmap;
   801                             }
   835                             }
   802                         }
   836                         }
   803                         else
   837                         else
   804                             generateSection(s->members, 0, marker, CodeMarker::Summary);
   838                             generateSection(s->members, 0, marker, CodeMarker::Summary);
   815             QString fileName = imageFileName(relative, atom->string());
   849             QString fileName = imageFileName(relative, atom->string());
   816             QString text;
   850             QString text;
   817             if (atom->next() != 0)
   851             if (atom->next() != 0)
   818                 text = atom->next()->string();
   852                 text = atom->next()->string();
   819             if (atom->type() == Atom::Image)
   853             if (atom->type() == Atom::Image)
   820                 out() << "<p align=\"center\">";
   854                 out() << "<p class=\"centerAlign\">";
   821             if (fileName.isEmpty()) {
   855             if (fileName.isEmpty()) {
   822                 out() << "<font color=\"red\">[Missing image "
   856                 out() << "<font color=\"red\">[Missing image "
   823                       << protect(atom->string()) << "]</font>";
   857                       << protectEnc(atom->string()) << "]</font>";
   824             }
   858             }
   825             else {
   859             else {
   826                 out() << "<img src=\"" << protect(fileName) << "\"";
   860                 out() << "<img src=\"" << protectEnc(fileName) << "\"";
   827                 if (!text.isEmpty())
   861                 if (!text.isEmpty())
   828                     out() << " alt=\"" << protect(text) << "\"";
   862                     out() << " alt=\"" << protectEnc(text) << "\"";
   829                 out() << " />";
   863                 out() << " />";
   830                 helpProjectWriter->addExtraFile(fileName);
   864                 helpProjectWriter->addExtraFile(fileName);
   831             }
   865             }
   832             if (atom->type() == Atom::Image)
   866             if (atom->type() == Atom::Image)
   833                 out() << "</p>";
   867                 out() << "</p>";
   834         }
   868         }
   835         break;
   869         break;
   836     case Atom::ImageText:
   870     case Atom::ImageText:
   837         break;
   871         break;
   838     case Atom::LegaleseLeft:
   872     case Atom::LegaleseLeft:
   839         out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";
   873         out() << "<div class=\"LegaleseLeft\">";
   840         break;
   874         break;
   841     case Atom::LegaleseRight:
   875     case Atom::LegaleseRight:
   842         out() << "</div>";
   876         out() << "</div>";
   843         break;
   877         break;
   844     case Atom::LineBreak:
   878     case Atom::LineBreak:
   845         out() << "<br />";
   879         out() << "<br/>";
   846         break;
   880         break;
   847     case Atom::Link:
   881     case Atom::Link:
   848         {
   882         {
   849             const Node *node = 0;
   883             const Node *node = 0;
   850             QString myLink = getLink(atom, relative, marker, &node);
   884             QString myLink = getLink(atom, relative, marker, &node);
   876             out() << "<dl>\n";
   910             out() << "<dl>\n";
   877         }
   911         }
   878         else if (atom->string() == ATOM_LIST_VALUE) {
   912         else if (atom->string() == ATOM_LIST_VALUE) {
   879             threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
   913             threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
   880             if (threeColumnEnumValueTable) {
   914             if (threeColumnEnumValueTable) {
   881                 out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
   915                 out() << "<table class=\"valuelist\">";
   882                       << "cellspacing=\"1\" width=\"100%\">\n"
   916                     //  << "<tr>"
   883                       << "<tr><th width=\"25%\">Constant</th>"
   917 				if (++numTableRows % 2 == 1)
   884                       << "<th width=\"15%\">Value</th>"
   918 					out() << "<tr class=\"odd\">";
   885                       << "<th width=\"60%\">Description</th></tr>\n";
   919 				else
       
   920 					out() << "<tr class=\"even\">";
       
   921 
       
   922 					out() << "<tr><th>Constant</th>"
       
   923                       << "<th>Value</th>"
       
   924                       << "<th>Description</th></tr>\n";
   886             }
   925             }
   887             else {
   926             else {
   888                 out() << "<p><table  class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
   927                 out() << "<table class=\"valuelist\">"
   889                       << "cellspacing=\"1\" width=\"40%\">\n"
   928                       << "<tr><th>Constant</th><th>Value</th></tr>\n";
   890                       << "<tr><th width=\"60%\">Constant</th><th "
       
   891                       << "width=\"40%\">Value</th></tr>\n";
       
   892             }
   929             }
   893         }
   930         }
   894         else {
   931         else {
   895             out() << "<ol type=";
   932             out() << "<ol type=";
   896             if (atom->string() == ATOM_LIST_UPPERALPHA) {
   933             if (atom->string() == ATOM_LIST_UPPERALPHA) {
   897                 out() << "\"A\"";
   934                 out() << "\"A\"";
   898             }
   935             } /* why type? */
   899             else if (atom->string() == ATOM_LIST_LOWERALPHA) {
   936             else if (atom->string() == ATOM_LIST_LOWERALPHA) {
   900                 out() << "\"a\"";
   937                 out() << "\"a\"";
   901             }
   938             }
   902             else if (atom->string() == ATOM_LIST_UPPERROMAN) {
   939             else if (atom->string() == ATOM_LIST_UPPERROMAN) {
   903                 out() << "\"I\"";
   940                 out() << "\"I\"";
   920             out() << "<dt>";
   957             out() << "<dt>";
   921         }
   958         }
   922         else { // (atom->string() == ATOM_LIST_VALUE)
   959         else { // (atom->string() == ATOM_LIST_VALUE)
   923             // ### Trenton
   960             // ### Trenton
   924 
   961 
   925             out() << "<tr><td valign=\"top\"><tt>"
   962             out() << "<tr><td  class=\"topAlign\"><tt>"
   926                   << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
   963                   << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
   927                                                                  relative)))
   964                                                                  relative)))
   928                   << "</tt></td><td align=\"center\" valign=\"top\">";
   965                   << "</tt></td><td class=\" topAlign\">";
   929 
   966 
   930             QString itemValue;
   967             QString itemValue;
   931             if (relative->type() == Node::Enum) {
   968             if (relative->type() == Node::Enum) {
   932                 const EnumNode *enume = static_cast<const EnumNode *>(relative);
   969                 const EnumNode *enume = static_cast<const EnumNode *>(relative);
   933                 itemValue = enume->itemValue(atom->next()->string());
   970                 itemValue = enume->itemValue(atom->next()->string());
   934             }
   971             }
   935 
   972 
   936             if (itemValue.isEmpty())
   973             if (itemValue.isEmpty())
   937                 out() << "?";
   974                 out() << "?";
   938             else
   975             else
   939                 out() << "<tt>" << protect(itemValue) << "</tt>";
   976                 out() << "<tt>" << protectEnc(itemValue) << "</tt>";
   940 
   977 
   941             skipAhead = 1;
   978             skipAhead = 1;
   942         }
   979         }
   943         break;
   980         break;
   944     case Atom::ListTagRight:
   981     case Atom::ListTagRight:
   949         if (atom->string() == ATOM_LIST_TAG) {
   986         if (atom->string() == ATOM_LIST_TAG) {
   950             out() << "<dd>";
   987             out() << "<dd>";
   951         }
   988         }
   952         else if (atom->string() == ATOM_LIST_VALUE) {
   989         else if (atom->string() == ATOM_LIST_VALUE) {
   953             if (threeColumnEnumValueTable) {
   990             if (threeColumnEnumValueTable) {
   954                 out() << "</td><td valign=\"top\">";
   991                 out() << "</td><td  class=\"topAlign\">";
   955                 if (matchAhead(atom, Atom::ListItemRight))
   992                 if (matchAhead(atom, Atom::ListItemRight))
   956                     out() << "&nbsp;";
   993                     out() << "&nbsp;";
   957             }
   994             }
   958         }
   995         }
   959         else {
   996         else {
   979         }
  1016         }
   980         else if (atom->string() == ATOM_LIST_TAG) {
  1017         else if (atom->string() == ATOM_LIST_TAG) {
   981             out() << "</dl>\n";
  1018             out() << "</dl>\n";
   982         }
  1019         }
   983         else if (atom->string() == ATOM_LIST_VALUE) {
  1020         else if (atom->string() == ATOM_LIST_VALUE) {
   984             out() << "</table></p>\n";
  1021             out() << "</table>\n";
   985         }
  1022         }
   986         else {
  1023         else {
   987             out() << "</ol>\n";
  1024             out() << "</ol>\n";
   988         }
  1025         }
   989         break;
  1026         break;
  1050     case Atom::String:
  1087     case Atom::String:
  1051         if (inLink && !inContents && !inSectionHeading) {
  1088         if (inLink && !inContents && !inSectionHeading) {
  1052             generateLink(atom, relative, marker);
  1089             generateLink(atom, relative, marker);
  1053         }
  1090         }
  1054         else {
  1091         else {
  1055             out() << protect(atom->string());
  1092             out() << protectEnc(atom->string());
  1056         }
  1093         }
  1057         break;
  1094         break;
  1058     case Atom::TableLeft:
  1095     case Atom::TableLeft:
  1059         if (in_para) {
  1096         if (in_para) {
  1060             out() << "</p>\n";
  1097             out() << "</p>\n";
  1061             in_para = false;
  1098             in_para = false;
  1062         }
  1099         }
  1063         if (!atom->string().isEmpty()) {
  1100         if (!atom->string().isEmpty()) {
  1064             if (atom->string().contains("%"))
  1101             if (atom->string().contains("%"))
  1065                 out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
  1102                 out() << "<table class=\"generic\">\n "; // width=\"" << atom->string() << "\">\n ";
  1066                       << "align=\"center\" cellpadding=\"2\" "
       
  1067                       << "cellspacing=\"1\" border=\"0\">\n";
       
  1068             else {
  1103             else {
  1069                 out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
  1104                 out() << "<table class=\"generic\">\n";
  1070                       << "cellspacing=\"1\" border=\"0\">\n";
       
  1071             }
  1105             }
  1072         }
  1106         }
  1073         else {
  1107         else {
  1074             out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
  1108             out() << "<table class=\"generic\">\n";
  1075                   << "cellspacing=\"1\" border=\"0\">\n";
       
  1076         }
  1109         }
  1077         numTableRows = 0;
  1110         numTableRows = 0;
  1078         break;
  1111         break;
  1079     case Atom::TableRight:
  1112     case Atom::TableRight:
  1080         out() << "</table></p>\n";
  1113         out() << "</table>\n";
  1081         break;
  1114         break;
  1082     case Atom::TableHeaderLeft:
  1115     case Atom::TableHeaderLeft:
  1083         out() << "<thead><tr valign=\"top\" class=\"qt-style\">";
  1116         out() << "<thead><tr class=\"qt-style topAlign\">";
  1084         inTableHeader = true;
  1117         inTableHeader = true;
  1085         break;
  1118         break;
  1086     case Atom::TableHeaderRight:
  1119     case Atom::TableHeaderRight:
  1087         out() << "</tr>";
  1120         out() << "</tr>";
  1088         if (matchAhead(atom, Atom::TableHeaderLeft)) {
  1121         if (matchAhead(atom, Atom::TableHeaderLeft)) {
  1089             skipAhead = 1;
  1122             skipAhead = 1;
  1090             out() << "\n<tr valign=\"top\" class=\"qt-style\">";
  1123             out() << "\n<tr class=\"qt-style topAlign\">";
  1091         }
  1124         }
  1092         else {
  1125         else {
  1093             out() << "</thead>\n";
  1126             out() << "</thead>\n";
  1094             inTableHeader = false;
  1127             inTableHeader = false;
  1095         }
  1128         }
  1096         break;
  1129         break;
  1097     case Atom::TableRowLeft:
  1130     case Atom::TableRowLeft:
  1098         if (++numTableRows % 2 == 1)
  1131         if (++numTableRows % 2 == 1)
  1099             out() << "<tr valign=\"top\" class=\"odd\">";
  1132             out() << "<tr class=\"odd topAlign\">";
  1100         else
  1133         else
  1101             out() << "<tr valign=\"top\" class=\"even\">";
  1134             out() << "<tr class=\"even topAlign\">";
  1102         break;
  1135         break;
  1103     case Atom::TableRowRight:
  1136     case Atom::TableRowRight:
  1104         out() << "</tr>\n";
  1137         out() << "</tr>\n";
  1105         break;
  1138         break;
  1106     case Atom::TableItemLeft:
  1139     case Atom::TableItemLeft:
  1114             if (spans.size() == 2) {
  1147             if (spans.size() == 2) {
  1115                 if (spans.at(0) != "1")
  1148                 if (spans.at(0) != "1")
  1116                     out() << " colspan=\"" << spans.at(0) << "\"";
  1149                     out() << " colspan=\"" << spans.at(0) << "\"";
  1117                 if (spans.at(1) != "1")
  1150                 if (spans.at(1) != "1")
  1118                     out() << " rowspan=\"" << spans.at(1) << "\"";
  1151                     out() << " rowspan=\"" << spans.at(1) << "\"";
       
  1152             if (inTableHeader)
  1119                 out() << ">";
  1153                 out() << ">";
       
  1154             else
       
  1155                 out() << "><p>"; 
  1120             }
  1156             }
  1121             if (matchAhead(atom, Atom::ParaLeft))
  1157             if (matchAhead(atom, Atom::ParaLeft))
  1122                 skipAhead = 1;
  1158                 skipAhead = 1;
  1123         }
  1159         }
  1124         break;
  1160         break;
  1125     case Atom::TableItemRight:
  1161     case Atom::TableItemRight:
  1126         if (inTableHeader)
  1162         if (inTableHeader)
  1127             out() << "</th>";
  1163             out() << "</th>";
  1128         else
  1164         else
  1129             out() << "</td>";
  1165             out() << "</p></td>";
  1130         if (matchAhead(atom, Atom::ParaLeft))
  1166         if (matchAhead(atom, Atom::ParaLeft))
  1131             skipAhead = 1;
  1167             skipAhead = 1;
  1132         break;
  1168         break;
  1133     case Atom::TableOfContents:
  1169     case Atom::TableOfContents:
  1134         {
  1170         {
  1161         break;
  1197         break;
  1162     case Atom::Target:
  1198     case Atom::Target:
  1163         out() << "<a name=\"" << Doc::canonicalTitle(atom->string()) << "\"></a>";
  1199         out() << "<a name=\"" << Doc::canonicalTitle(atom->string()) << "\"></a>";
  1164         break;
  1200         break;
  1165     case Atom::UnhandledFormat:
  1201     case Atom::UnhandledFormat:
  1166         out() << "<font color=\"red\"><b>&lt;Missing HTML&gt;</b></font>";
  1202         out() << "<b class=\"redFont\">&lt;Missing HTML&gt;</b>";
  1167         break;
  1203         break;
  1168     case Atom::UnknownCommand:
  1204     case Atom::UnknownCommand:
  1169         out() << "<font color=\"red\"><b><code>\\" << protect(atom->string())
  1205         out() << "<b class=\"redFont\"><code>\\" << protectEnc(atom->string())
  1170               << "</code></b></font>";
  1206               << "</code></b>";
  1171         break;
  1207         break;
  1172 #ifdef QDOC_QML
  1208 #ifdef QDOC_QML
  1173     case Atom::QmlText:
  1209     case Atom::QmlText:
  1174     case Atom::EndQmlText:
  1210     case Atom::EndQmlText:
  1175         // don't do anything with these. They are just tags.
  1211         // don't do anything with these. They are just tags.
  1195     QString fullTitle;
  1231     QString fullTitle;
  1196     if (inner->type() == Node::Namespace) {
  1232     if (inner->type() == Node::Namespace) {
  1197         namespasse = static_cast<const NamespaceNode *>(inner);
  1233         namespasse = static_cast<const NamespaceNode *>(inner);
  1198         rawTitle = marker->plainName(inner);
  1234         rawTitle = marker->plainName(inner);
  1199         fullTitle = marker->plainFullName(inner);
  1235         fullTitle = marker->plainFullName(inner);
  1200         title = rawTitle + " Namespace Reference";
  1236         title = rawTitle + " Namespace";
  1201     }
  1237     }
  1202     else if (inner->type() == Node::Class) {
  1238     else if (inner->type() == Node::Class) {
  1203         classe = static_cast<const ClassNode *>(inner);
  1239         classe = static_cast<const ClassNode *>(inner);
  1204         rawTitle = marker->plainName(inner);
  1240         rawTitle = marker->plainName(inner);
  1205         fullTitle = marker->plainFullName(inner);
  1241         fullTitle = marker->plainFullName(inner);
  1214     Text subtitleText;
  1250     Text subtitleText;
  1215     if (rawTitle != fullTitle)
  1251     if (rawTitle != fullTitle)
  1216         subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
  1252         subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
  1217                      << Atom(Atom::LineBreak);
  1253                      << Atom(Atom::LineBreak);
  1218 
  1254 
       
  1255 #if 0
       
  1256     // No longer used because the modeule name is a breadcrumb.
  1219     QString fixedModule = inner->moduleName();
  1257     QString fixedModule = inner->moduleName();
  1220     if (fixedModule == "Qt3SupportLight")
  1258     if (fixedModule == "Qt3SupportLight")
  1221         fixedModule = "Qt3Support";
  1259         fixedModule = "Qt3Support";
  1222     if (!fixedModule.isEmpty())
  1260     if (!fixedModule.isEmpty())
  1223         subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
  1261         subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
  1234                     subtitleText <<", ";
  1272                     subtitleText <<", ";
  1235             }
  1273             }
  1236             subtitleText << "]";
  1274             subtitleText << "]";
  1237         }
  1275         }
  1238     }
  1276     }
  1239 
  1277 #endif    
  1240     generateHeader(title, inner, marker, true);
  1278 
       
  1279     generateHeader(title, inner, marker);
       
  1280     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
       
  1281     generateTableOfContents(inner,marker,&sections);
  1241     generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
  1282     generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
  1242 
  1283 
  1243 #ifdef QDOC_QML
  1284 #ifdef QDOC_QML
  1244     if (classe && !classe->qmlElement().isEmpty()) {
  1285     if (classe && !classe->qmlElement().isEmpty()) {
  1245         generateInstantiatedBy(classe,marker);
  1286         generateInstantiatedBy(classe,marker);
  1248     
  1289     
  1249     generateBrief(inner, marker);
  1290     generateBrief(inner, marker);
  1250     generateIncludes(inner, marker);
  1291     generateIncludes(inner, marker);
  1251     generateStatus(inner, marker);
  1292     generateStatus(inner, marker);
  1252     if (classe) {
  1293     if (classe) {
  1253         generateModuleWarning(classe, marker);
       
  1254         generateInherits(classe, marker);
  1294         generateInherits(classe, marker);
  1255         generateInheritedBy(classe, marker);
  1295         generateInheritedBy(classe, marker);
  1256     }
  1296     }
  1257     generateThreadSafeness(inner, marker);
  1297     generateThreadSafeness(inner, marker);
  1258     generateSince(inner, marker);
  1298     generateSince(inner, marker);
  1280 
  1320 
  1281     out() << "</ul>\n";
  1321     out() << "</ul>\n";
  1282 
  1322 
  1283     bool needOtherSection = false;
  1323     bool needOtherSection = false;
  1284 
  1324 
  1285     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
  1325     /*
       
  1326       sections is built above for the call to generateTableOfContents().
       
  1327      */
  1286     s = sections.begin();
  1328     s = sections.begin();
  1287     while (s != sections.end()) {
  1329     while (s != sections.end()) {
  1288         if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
  1330         if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
  1289             if (!s->inherited.isEmpty())
  1331             if (!s->inherited.isEmpty())
  1290                 needOtherSection = true;
  1332                 needOtherSection = true;
  1293             if (!s->members.isEmpty()) {
  1335             if (!s->members.isEmpty()) {
  1294                 out() << "<hr />\n";
  1336                 out() << "<hr />\n";
  1295                 out() << "<a name=\""
  1337                 out() << "<a name=\""
  1296                       << registerRef((*s).name.toLower())
  1338                       << registerRef((*s).name.toLower())
  1297                       << "\"></a>\n";
  1339                       << "\"></a>\n";
  1298                 out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1340                 out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1299                 generateSection(s->members, inner, marker, CodeMarker::Summary);
  1341                 generateSection(s->members, inner, marker, CodeMarker::Summary);
  1300             }
  1342             }
  1301             if (!s->reimpMembers.isEmpty()) {
  1343             if (!s->reimpMembers.isEmpty()) {
  1302                 QString name = QString("Reimplemented ") + (*s).name;
  1344                 QString name = QString("Reimplemented ") + (*s).name;
  1303                 out() << "<hr />\n";
  1345                 out() << "<hr />\n";
  1304                 out() << "<a name=\""
  1346                 out() << "<a name=\""
  1305                       << registerRef(name.toLower())
  1347                       << registerRef(name.toLower())
  1306                       << "\"></a>\n";
  1348                       << "\"></a>\n";
  1307                 out() << "<h2>" << protect(name) << "</h2>\n";
  1349                 out() << "<h2>" << protectEnc(name) << "</h2>\n";
  1308                 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
  1350                 generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
  1309             }
  1351             }
  1310 
  1352 
  1311             if (!s->inherited.isEmpty()) {
  1353             if (!s->inherited.isEmpty()) {
  1312                 out() << "<ul>\n";
  1354                 out() << "<ul>\n";
  1332 
  1374 
  1333     out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1375     out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1334 
  1376 
  1335     if (!inner->doc().isEmpty()) {
  1377     if (!inner->doc().isEmpty()) {
  1336         out() << "<hr />\n"
  1378         out() << "<hr />\n"
       
  1379               << "<div class=\"descr\"/>\n" // QTBUG-9504
  1337               << "<h2>" << "Detailed Description" << "</h2>\n";
  1380               << "<h2>" << "Detailed Description" << "</h2>\n";
  1338         generateBody(inner, marker);
  1381         generateBody(inner, marker);
       
  1382         out() << "</div>\n"; // QTBUG-9504
  1339         generateAlsoList(inner, marker);
  1383         generateAlsoList(inner, marker);
  1340     }
  1384     }
  1341 
  1385 
  1342     sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
  1386     sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
  1343     s = sections.begin();
  1387     s = sections.begin();
  1344     while (s != sections.end()) {
  1388     while (s != sections.end()) {
  1345         out() << "<hr />\n";
  1389         out() << "<hr />\n";
  1346         out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1390         if (!(*s).divClass.isEmpty())
       
  1391             out() << "<div class=\"" << (*s).divClass << "\"/>\n"; // QTBUG-9504
       
  1392         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1347 
  1393 
  1348         NodeList::ConstIterator m = (*s).members.begin();
  1394         NodeList::ConstIterator m = (*s).members.begin();
  1349         while (m != (*s).members.end()) {
  1395         while (m != (*s).members.end()) {
  1350             if ((*m)->access() != Node::Private) { // ### check necessary?
  1396             if ((*m)->access() != Node::Private) { // ### check necessary?
  1351                 if ((*m)->type() != Node::Class)
  1397                 if ((*m)->type() != Node::Class)
  1390                 foreach (const QString &name, names)
  1436                 foreach (const QString &name, names)
  1391                     classSection.keywords += qMakePair(name,linkForNode(*m,0));
  1437                     classSection.keywords += qMakePair(name,linkForNode(*m,0));
  1392             }
  1438             }
  1393             ++m;
  1439             ++m;
  1394         }
  1440         }
       
  1441         if (!(*s).divClass.isEmpty())
       
  1442             out() << "</div>\n"; // QTBUG-9504
  1395         ++s;
  1443         ++s;
  1396     }
  1444     }
  1397     generateFooter(inner);
  1445     generateFooter(inner);
  1398 
  1446 
  1399     if (!membersLink.isEmpty()) {
  1447     if (!membersLink.isEmpty()) {
  1426     fakeSection.ref = linkForNode(fake, 0);
  1474     fakeSection.ref = linkForNode(fake, 0);
  1427 
  1475 
  1428     QList<Section> sections;
  1476     QList<Section> sections;
  1429     QList<Section>::const_iterator s;
  1477     QList<Section>::const_iterator s;
  1430 
  1478 
  1431     QString htmlTitle = fake->fullTitle();
  1479     QString fullTitle = fake->fullTitle();
       
  1480     QString htmlTitle = fullTitle;
  1432     if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
  1481     if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
  1433         subTitleSize = SmallSubTitle;
  1482         subTitleSize = SmallSubTitle;
  1434         htmlTitle += " (" + fake->subTitle() + ")";
  1483         htmlTitle += " (" + fake->subTitle() + ")";
  1435     }
  1484     }
  1436 
  1485     else if (fake->subType() == Node::QmlBasicType) {
  1437     generateHeader(htmlTitle, fake, marker, true);
  1486         fullTitle = "QML Basic Type: " + fullTitle;
  1438     generateTitle(fake->fullTitle(),
  1487         htmlTitle = fullTitle;
       
  1488     }
       
  1489 
       
  1490     generateHeader(htmlTitle, fake, marker);
       
  1491         
       
  1492     /*
       
  1493       Generate the TOC for the new doc format.
       
  1494       Don't generate a TOC for the home page.
       
  1495     */
       
  1496     if (fake->name() != QString("index.html"))
       
  1497         generateTableOfContents(fake,marker,0);
       
  1498 
       
  1499     generateTitle(fullTitle,
  1439                   Text() << fake->subTitle(),
  1500                   Text() << fake->subTitle(),
  1440                   subTitleSize,
  1501                   subTitleSize,
  1441                   fake,
  1502                   fake,
  1442                   marker);
  1503                   marker);
  1443 
  1504 
  1445         // Generate brief text and status for modules.
  1506         // Generate brief text and status for modules.
  1446         generateBrief(fake, marker);
  1507         generateBrief(fake, marker);
  1447         generateStatus(fake, marker);
  1508         generateStatus(fake, marker);
  1448 
  1509 
  1449         if (moduleNamespaceMap.contains(fake->name())) {
  1510         if (moduleNamespaceMap.contains(fake->name())) {
       
  1511             out() << "<a name=\"" << registerRef("namespaces") << "\"></a>\n";
  1450             out() << "<h2>Namespaces</h2>\n";
  1512             out() << "<h2>Namespaces</h2>\n";
  1451             generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
  1513             generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
  1452         }
  1514         }
  1453         if (moduleClassMap.contains(fake->name())) {
  1515         if (moduleClassMap.contains(fake->name())) {
       
  1516             out() << "<a name=\"" << registerRef("classes") << "\"></a>\n";
  1454             out() << "<h2>Classes</h2>\n";
  1517             out() << "<h2>Classes</h2>\n";
  1455             generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
  1518             generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
  1456         }
  1519         }
  1457     }
  1520     }
  1458     else if (fake->subType() == Node::HeaderFile) {
  1521     else if (fake->subType() == Node::HeaderFile) {
  1507         const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
  1570         const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
  1508         const ClassNode* cn = qml_cn->classNode();
  1571         const ClassNode* cn = qml_cn->classNode();
  1509         generateQmlInherits(qml_cn, marker);
  1572         generateQmlInherits(qml_cn, marker);
  1510         generateQmlInstantiates(qml_cn, marker);
  1573         generateQmlInstantiates(qml_cn, marker);
  1511         generateBrief(qml_cn, marker);
  1574         generateBrief(qml_cn, marker);
       
  1575         generateQmlInheritedBy(qml_cn, marker);
  1512         sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
  1576         sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
  1513         s = sections.begin();
  1577         s = sections.begin();
  1514         while (s != sections.end()) {
  1578         while (s != sections.end()) {
  1515             out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1579             out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1516             out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1580             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1517             generateQmlSummary(*s,fake,marker);
  1581             generateQmlSummary(*s,fake,marker);
  1518             ++s;
  1582             ++s;
  1519         }
  1583         }
  1520 
  1584 
  1521         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1585         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1527         out() << "<hr />\n";
  1591         out() << "<hr />\n";
  1528 
  1592 
  1529         sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
  1593         sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
  1530         s = sections.begin();
  1594         s = sections.begin();
  1531         while (s != sections.end()) {
  1595         while (s != sections.end()) {
  1532             out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1596             out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1533             NodeList::ConstIterator m = (*s).members.begin();
  1597             NodeList::ConstIterator m = (*s).members.begin();
  1534             while (m != (*s).members.end()) {
  1598             while (m != (*s).members.end()) {
  1535                 generateDetailedQmlMember(*m, fake, marker);
  1599                 generateDetailedQmlMember(*m, fake, marker);
  1536                 out() << "<br />\n";
  1600                 out() << "<br/>\n";
  1537                 fakeSection.keywords += qMakePair((*m)->name(),
  1601                 fakeSection.keywords += qMakePair((*m)->name(),
  1538                                                   linkForNode(*m,0));
  1602                                                   linkForNode(*m,0));
  1539                 ++m;
  1603                 ++m;
  1540             }
  1604             }
  1541             ++s;
  1605             ++s;
  1547     
  1611     
  1548     sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
  1612     sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
  1549     s = sections.begin();
  1613     s = sections.begin();
  1550     while (s != sections.end()) {
  1614     while (s != sections.end()) {
  1551         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1615         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
  1552         out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1616         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1553         generateSectionList(*s, fake, marker, CodeMarker::Summary);
  1617         generateSectionList(*s, fake, marker, CodeMarker::Summary);
  1554         ++s;
  1618         ++s;
  1555     }
  1619     }
  1556 
  1620 
  1557     Text brief = fake->doc().briefText();
  1621     Text brief = fake->doc().briefText();
  1558     if (fake->subType() == Node::Module && !brief.isEmpty()) {
  1622     if (fake->subType() == Node::Module && !brief.isEmpty()) {
  1559         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
  1623         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
       
  1624         out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
  1560         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1625         out() << "<h2>" << "Detailed Description" << "</h2>\n";
  1561     }
  1626     }
       
  1627     else
       
  1628         out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
  1562 
  1629 
  1563     generateBody(fake, marker);
  1630     generateBody(fake, marker);
       
  1631     out() << "</div>\n"; // QTBUG-9504
  1564     generateAlsoList(fake, marker);
  1632     generateAlsoList(fake, marker);
  1565 
  1633 
  1566     if (!fake->groupMembers().isEmpty()) {
  1634     if (!fake->groupMembers().isEmpty()) {
  1567         NodeMap groupMembersMap;
  1635         NodeMap groupMembersMap;
  1568         foreach (const Node *node, fake->groupMembers()) {
  1636         foreach (const Node *node, fake->groupMembers()) {
  1576 
  1644 
  1577     sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
  1645     sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
  1578     s = sections.begin();
  1646     s = sections.begin();
  1579     while (s != sections.end()) {
  1647     while (s != sections.end()) {
  1580         out() << "<hr />\n";
  1648         out() << "<hr />\n";
  1581         out() << "<h2>" << protect((*s).name) << "</h2>\n";
  1649         out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
  1582 
  1650 
  1583         NodeList::ConstIterator m = (*s).members.begin();
  1651         NodeList::ConstIterator m = (*s).members.begin();
  1584         while (m != (*s).members.end()) {
  1652         while (m != (*s).members.end()) {
  1585             generateDetailedMember(*m, fake, marker);
  1653             generateDetailedMember(*m, fake, marker);
  1586             fakeSection.keywords += qMakePair((*m)->name(), linkForNode(*m, 0));
  1654             fakeSection.keywords += qMakePair((*m)->name(), linkForNode(*m, 0));
  1612             appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
  1680             appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
  1613         }
  1681         }
  1614     }
  1682     }
  1615 }
  1683 }
  1616 
  1684 
  1617 QString HtmlGenerator::fileExtension(const Node * /* node */)
  1685 QString HtmlGenerator::fileExtension(const Node * /* node */) const
  1618 {
  1686 {
  1619     return "html";
  1687     return "html";
       
  1688 }
       
  1689 
       
  1690 /*!
       
  1691   Output breadcrumb list in the html file.
       
  1692  */
       
  1693 void HtmlGenerator::generateBreadCrumbs(const QString& title,
       
  1694                                         const Node *node,
       
  1695                                         CodeMarker *marker)
       
  1696 {
       
  1697     Text breadcrumb;
       
  1698     if (node->type() == Node::Class) {
       
  1699         const ClassNode* cn = static_cast<const ClassNode*>(node);
       
  1700         QString name =  node->moduleName();
       
  1701         out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
       
  1702         if (!name.isEmpty()) {
       
  1703             out() << "              <li>";
       
  1704             breadcrumb << Atom(Atom::AutoLink,name);
       
  1705             generateText(breadcrumb, node, marker);
       
  1706             out() << "</li>\n";
       
  1707         }
       
  1708         breadcrumb.clear();
       
  1709         if (!cn->name().isEmpty()) {
       
  1710             out() << "              <li>";
       
  1711             breadcrumb << Atom(Atom::AutoLink,cn->name());
       
  1712             generateText(breadcrumb, 0, marker);
       
  1713             out() << "</li>\n";
       
  1714         }
       
  1715     }
       
  1716     else if (node->type() == Node::Fake) {
       
  1717         const FakeNode* fn = static_cast<const FakeNode*>(node);
       
  1718         if (node->subType() == Node::Module) {
       
  1719             out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
       
  1720             QString name =  node->name();
       
  1721             if (!name.isEmpty()) {
       
  1722                 out() << "              <li>";
       
  1723                 breadcrumb << Atom(Atom::AutoLink,name);
       
  1724                 generateText(breadcrumb, 0, marker);
       
  1725                 out() << "</li>\n";
       
  1726             }
       
  1727         }
       
  1728         else if (node->subType() == Node::Group) {
       
  1729             if (fn->name() == QString("modules"))
       
  1730                 out() << "              <li><a href=\"modules.html\">All Modules</a></li>";
       
  1731             else {
       
  1732                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
       
  1733                       << "</a></li>";
       
  1734             }
       
  1735         }
       
  1736         else if (node->subType() == Node::Page) {
       
  1737             if (fn->name() == QString("examples.html")) {
       
  1738                 out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
       
  1739             }
       
  1740             else if (fn->name().startsWith("examples-")) {
       
  1741                 out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
       
  1742                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
       
  1743                       << "</a></li>";
       
  1744             }
       
  1745             else if (fn->name() == QString("namespaces.html")) {
       
  1746                 out() << "              <li><a href=\"namespaces.html\">All Namespaces</a></li>";
       
  1747             }
       
  1748             else {
       
  1749                 out() << "              <li><a href=\"" << fn->name() << "\">" << title
       
  1750                       << "</a></li>";
       
  1751             }
       
  1752         }
       
  1753         else if (node->subType() == Node::QmlClass) {
       
  1754             out() << "              <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>";
       
  1755             out() << "              <li><a href=\"" << fn->name() << "\">" << title
       
  1756                   << "</a></li>";
       
  1757         }
       
  1758         else if (node->subType() == Node::Example) {
       
  1759             out() << "              <li><a href=\"examples.html\">All Examples</a></li>";
       
  1760             QStringList sl = fn->name().split('/');
       
  1761             QString name = "examples-" + sl.at(0) + ".html";
       
  1762             QString t = CodeParser::titleFromName(name);
       
  1763             out() << "              <li><a href=\"" << name << "\">"
       
  1764                   << t << "</a></li>";
       
  1765             out() << "              <li><a href=\"" << sl.at(0)
       
  1766                   << "-" << sl.at(sl.size()-1) << ".html\">"
       
  1767                   << title << "</a></li>";
       
  1768         }
       
  1769     }
       
  1770     else if (node->type() == Node::Namespace) {
       
  1771         const NamespaceNode* nsn = static_cast<const NamespaceNode*>(node);
       
  1772         out() << "              <li><a href=\"namespaces.html\">All Namespaces</a></li>";
       
  1773         out() << "              <li><a href=\"" << fileName(nsn) << "\">" << title
       
  1774               << "</a></li>";
       
  1775     }
  1620 }
  1776 }
  1621 
  1777 
  1622 void HtmlGenerator::generateHeader(const QString& title,
  1778 void HtmlGenerator::generateHeader(const QString& title,
  1623                                    const Node *node,
  1779                                    const Node *node,
  1624                                    CodeMarker *marker,
  1780                                    CodeMarker *marker)
  1625                                    bool mainPage)
  1781 {
  1626 {
  1782     out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding);
  1627     out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
  1783     out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
  1628 
  1784     out() << "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
  1629     out() << "<!DOCTYPE html\n"
  1785     out() << "<head>\n";
  1630              "    PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
  1786     out() << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
  1631              "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
       
  1632 
       
  1633     QString shortVersion;
  1787     QString shortVersion;
  1634     if ((project != "Qtopia") && (project != "Qt Extended")) {
  1788     shortVersion = project + " " + shortVersion + ": ";
  1635         shortVersion = project + " " + shortVersion + ": ";
  1789     if (node && !node->doc().location().isEmpty())
  1636         if (node && !node->doc().location().isEmpty())
  1790         out() << "<!-- " << node->doc().location().fileName() << " -->\n";
  1637             out() << "<!-- " << node->doc().location().fileName() << " -->\n";
  1791 
  1638 
  1792     shortVersion = myTree->version();
  1639         shortVersion = myTree->version();
  1793     if (shortVersion.count(QChar('.')) == 2)
  1640         if (shortVersion.count(QChar('.')) == 2)
  1794         shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
  1641             shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
  1795     if (!shortVersion.isEmpty()) {
  1642         if (!shortVersion.isEmpty()) {
  1796         if (project == "QSA")
  1643             if (project == "QSA")
  1797             shortVersion = "QSA " + shortVersion + ": ";
  1644                 shortVersion = "QSA " + shortVersion + ": ";
  1798         else
  1645             else
  1799             shortVersion = "Qt " + shortVersion + ": ";
  1646                 shortVersion = "Qt " + shortVersion + ": ";
  1800     }
  1647         }
  1801 
  1648     }
  1802     out() << "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
  1649 
  1803 
  1650     out() << "<head>\n"
  1804 	out() << "  <!--[if IE]>";
  1651              "  <title>" << shortVersion << protect(title) << "</title>\n";
  1805 	out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">";
  1652     if (!style.isEmpty())
  1806 	out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">";
  1653         out() << "    <style type=\"text/css\">" << style << "</style>\n";
  1807 	out() << "<![endif]-->";
  1654 
  1808     out() << "<!--[if lt IE 7]>";
  1655     const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
  1809 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">";
  1656     if (!metaMap.isEmpty()) {
  1810 	out() << "<![endif]-->";
  1657         QMapIterator<QString, QString> i(metaMap);
  1811     out() << "<!--[if IE 7]>";
  1658         while (i.hasNext()) {
  1812 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">";
  1659             i.next();
  1813 	out() << "<![endif]-->";
  1660             out() << "    <meta name=\"" << protect(i.key()) << "\" contents=\""
  1814     out() << "<!--[if IE 8]>";
  1661                   << protect(i.value()) << "\" />\n";
  1815 	out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">";
  1662         }
  1816 	out() << "<![endif]-->";
  1663     }
  1817 
  1664 
  1818 
  1665     navigationLinks.clear();
  1819     //out() << "  <title>Qt Reference Documentation</title>";
  1666 
  1820     out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n";
  1667     if (node && !node->links().empty()) {
  1821     out() << "  <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n";
  1668         QPair<QString,QString> linkPair;
  1822     out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
  1669         QPair<QString,QString> anchorPair;
  1823     out() << "</head>\n";
  1670         const Node *linkNode;
  1824 
  1671 
  1825     if (offlineDocs)
  1672         if (node->links().contains(Node::PreviousLink)) {
  1826         out() << "<body class=\"offline\"  onload=\"CheckEmptyAndLoadList();\">\n";
  1673             linkPair = node->links()[Node::PreviousLink];
  1827     else
  1674             linkNode = findNodeForTarget(linkPair.first, node, marker);
  1828         out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n";
  1675             if (!linkNode || linkNode == node)
  1829 
  1676                 anchorPair = linkPair;
  1830 #ifdef GENERATE_MAC_REFS    
  1677             else
       
  1678                 anchorPair = anchorForNode(linkNode);
       
  1679 
       
  1680             out() << "  <link rel=\"prev\" href=\""
       
  1681                   << anchorPair.first << "\" />\n";
       
  1682 
       
  1683             navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">";
       
  1684             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  1685                 navigationLinks += protect(anchorPair.second);
       
  1686             else
       
  1687                 navigationLinks += protect(linkPair.second);
       
  1688             navigationLinks += "</a>]\n";
       
  1689         }
       
  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             else
       
  1696                 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             else
       
  1705                 navigationLinks += protect(linkPair.second);
       
  1706             navigationLinks += "</a>]\n";
       
  1707         }
       
  1708         if (node->links().contains(Node::NextLink)) {
       
  1709             linkPair = node->links()[Node::NextLink];
       
  1710             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  1711             if (!linkNode || linkNode == node)
       
  1712                 anchorPair = linkPair;
       
  1713             else
       
  1714                 anchorPair = anchorForNode(linkNode);
       
  1715 
       
  1716             out() << "  <link rel=\"next\" href=\""
       
  1717                   << anchorPair.first << "\" />\n";
       
  1718 
       
  1719             navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">";
       
  1720             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  1721                 navigationLinks += protect(anchorPair.second);
       
  1722             else
       
  1723                 navigationLinks += protect(linkPair.second);
       
  1724             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             else
       
  1732                 anchorPair = anchorForNode(linkNode);
       
  1733             out() << "  <link rel=\"index\" href=\""
       
  1734                   << anchorPair.first << "\" />\n";
       
  1735         }
       
  1736         if (node->links().contains(Node::StartLink)) {
       
  1737             linkPair = node->links()[Node::StartLink];
       
  1738             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  1739             if (!linkNode || linkNode == node)
       
  1740                 anchorPair = linkPair;
       
  1741             else
       
  1742                 anchorPair = anchorForNode(linkNode);
       
  1743             out() << "  <link rel=\"start\" href=\""
       
  1744                   << anchorPair.first << "\" />\n";
       
  1745         }
       
  1746     }
       
  1747 
       
  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)
  1831     if (mainPage)
  1760         generateMacRef(node, marker);
  1832         generateMacRef(node, marker);
       
  1833 #endif    
  1761     out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1834     out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
  1762 
  1835     generateBreadCrumbs(title,node,marker);
  1763 
  1836     out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
       
  1837 
       
  1838 #if 0 // Removed for new docf format. MWS
  1764     if (node && !node->links().empty())
  1839     if (node && !node->links().empty())
  1765         out() << "<p>\n" << navigationLinks << "</p>\n";
  1840         out() << "<p>\n" << navigationLinks << "</p>\n";
       
  1841 #endif    
  1766 }
  1842 }
  1767 
  1843 
  1768 void HtmlGenerator::generateTitle(const QString& title,
  1844 void HtmlGenerator::generateTitle(const QString& title,
  1769                                   const Text &subTitle,
  1845                                   const Text &subTitle,
  1770                                   SubTitleSize subTitleSize,
  1846                                   SubTitleSize subTitleSize,
  1771                                   const Node *relative,
  1847                                   const Node *relative,
  1772                                   CodeMarker *marker)
  1848                                   CodeMarker *marker)
  1773 {
  1849 {
  1774     out() << "<h1 class=\"title\">" << protect(title);
  1850     if (!title.isEmpty())
       
  1851         out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
  1775     if (!subTitle.isEmpty()) {
  1852     if (!subTitle.isEmpty()) {
  1776         out() << "<br />";
  1853  			out() << "<span";
  1777         if (subTitleSize == SmallSubTitle)
  1854        if (subTitleSize == SmallSubTitle)
  1778             out() << "<span class=\"small-subtitle\">";
  1855             out() << " class=\"small-subtitle\">";
  1779         else
  1856         else
  1780             out() << "<span class=\"subtitle\">";
  1857             out() << " class=\"subtitle\">";
  1781         generateText(subTitle, relative, marker);
  1858         generateText(subTitle, relative, marker);
  1782         out() << "</span>\n";
  1859         out() << "</span>\n";
  1783     }
  1860     }
  1784     out() << "</h1>\n";
       
  1785 }
  1861 }
  1786 
  1862 
  1787 void HtmlGenerator::generateFooter(const Node *node)
  1863 void HtmlGenerator::generateFooter(const Node *node)
  1788 {
  1864 {
  1789     if (node && !node->links().empty())
  1865     if (node && !node->links().empty())
  1790         out() << "<p>\n" << navigationLinks << "</p>\n";
  1866         out() << "<p>\n" << navigationLinks << "</p>\n";
  1791 
  1867 
  1792     out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
  1868     out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
  1793           << QString(address).replace("\\" + COMMAND_VERSION, myTree->version())
  1869           << QString(address).replace("\\" + COMMAND_VERSION, myTree->version());
  1794           << "</body>\n"
  1870 	      out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
  1795              "</html>\n";
  1871           out() << "</body>\n";
       
  1872           out() <<   "</html>\n";
  1796 }
  1873 }
  1797 
  1874 
  1798 void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
  1875 void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
  1799                                   const Node *relative)
  1876                                   const Node *relative)
  1800 {
  1877 {
  1811 }
  1888 }
  1812 
  1889 
  1813 void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
  1890 void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
  1814 {
  1891 {
  1815     if (!inner->includes().isEmpty()) {
  1892     if (!inner->includes().isEmpty()) {
  1816         out() << "<pre>"
  1893         out() << "<pre class=\"highlightedCode\">"
  1817               << trimmedTrailing(highlightedCode(indent(codeIndent,
  1894               << trimmedTrailing(highlightedCode(indent(codeIndent,
  1818                                                         marker->markedUpIncludes(inner->includes())),
  1895                                                         marker->markedUpIncludes(inner->includes())),
  1819                                                  marker,inner))
  1896                                                  marker,inner))
  1820               << "</pre>";
  1897               << "</pre>";
  1821     }
  1898     }
  1822 }
  1899 }
  1823 
  1900 
       
  1901 /*!
       
  1902   Generates a table of contents begining at \a node.
       
  1903  */
  1824 void HtmlGenerator::generateTableOfContents(const Node *node,
  1904 void HtmlGenerator::generateTableOfContents(const Node *node,
  1825                                             CodeMarker *marker,
  1905                                             CodeMarker *marker,
  1826                                             Doc::SectioningUnit sectioningUnit,
  1906                                             Doc::SectioningUnit sectioningUnit,
  1827                                             int numColumns,
  1907                                             int numColumns,
  1828                                             const Node *relative)
  1908                                             const Node *relative)
  1829 
  1909 
  1830 {
  1910 {
       
  1911     return;
  1831     if (!node->doc().hasTableOfContents())
  1912     if (!node->doc().hasTableOfContents())
  1832         return;
  1913         return;
  1833     QList<Atom *> toc = node->doc().tableOfContents();
  1914     QList<Atom *> toc = node->doc().tableOfContents();
  1834     if (toc.isEmpty())
  1915     if (toc.isEmpty())
  1835         return;
  1916         return;
  1841     QStringList sectionNumber;
  1922     QStringList sectionNumber;
  1842     int columnSize = 0;
  1923     int columnSize = 0;
  1843 
  1924 
  1844     QString tdTag;
  1925     QString tdTag;
  1845     if (numColumns > 1) {
  1926     if (numColumns > 1) {
  1846         tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
  1927         tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/
  1847         out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
  1928         out() << "<table class=\"toc\">\n<tr class=\"topAlign\">"
  1848               << tdTag << "\n";
  1929               << tdTag << "\n";
  1849     }
  1930     }
  1850 
  1931 
  1851     // disable nested links in table of contents
  1932     // disable nested links in table of contents
  1852     inContents = true;
  1933     inContents = true;
  1894         out() << "</ul>\n";
  1975         out() << "</ul>\n";
  1895         sectionNumber.removeLast();
  1976         sectionNumber.removeLast();
  1896     }
  1977     }
  1897 
  1978 
  1898     if (numColumns > 1)
  1979     if (numColumns > 1)
  1899         out() << "</td></tr></table></p>\n";
  1980         out() << "</td></tr></table>\n";
  1900 
  1981 
       
  1982     inContents = false;
       
  1983     inLink = false;
       
  1984 }
       
  1985 
       
  1986 /*!
       
  1987   Revised for the new doc format.
       
  1988   Generates a table of contents begining at \a node.
       
  1989  */
       
  1990 void HtmlGenerator::generateTableOfContents(const Node *node,
       
  1991                                             CodeMarker *marker,
       
  1992                                             QList<Section>* sections)
       
  1993 {
       
  1994     QList<Atom*> toc;
       
  1995     if (node->doc().hasTableOfContents()) 
       
  1996         toc = node->doc().tableOfContents();
       
  1997     if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
       
  1998         return;
       
  1999 
       
  2000     QStringList sectionNumber;
       
  2001     int detailsBase = 0;
       
  2002 
       
  2003     // disable nested links in table of contents
       
  2004     inContents = true;
       
  2005     inLink = true;
       
  2006 
       
  2007     out() << "<div class=\"toc\">\n";
       
  2008     out() << "<h3>Contents</h3>\n";
       
  2009     sectionNumber.append("1");
       
  2010     out() << "<ul>\n";
       
  2011 
       
  2012     if (node->subType() == Node::Module) {
       
  2013         if (moduleNamespaceMap.contains(node->name())) {
       
  2014             out() << "<li class=\"level"
       
  2015                   << sectionNumber.size()
       
  2016                   << "\"><a href=\"#"
       
  2017                   << registerRef("namespaces")
       
  2018                   << "\">Namespaces</a></li>\n";
       
  2019         }
       
  2020         if (moduleClassMap.contains(node->name())) {
       
  2021             out() << "<li class=\"level"
       
  2022                   << sectionNumber.size()
       
  2023                   << "\"><a href=\"#"
       
  2024                   << registerRef("classes")
       
  2025                   << "\">Classes</a></li>\n";
       
  2026         }
       
  2027         out() << "<li class=\"level"
       
  2028               << sectionNumber.size()
       
  2029               << "\"><a href=\"#"
       
  2030               << registerRef("details")
       
  2031               << "\">Detailed Description</a></li>\n";
       
  2032         for (int i = 0; i < toc.size(); ++i) {
       
  2033             if (toc.at(i)->string().toInt() == 1) {
       
  2034                 detailsBase = 1;
       
  2035                 break;
       
  2036             }
       
  2037         }
       
  2038     }
       
  2039     else if (sections && (node->type() == Node::Class)) {
       
  2040         QList<Section>::ConstIterator s = sections->begin();
       
  2041         while (s != sections->end()) {
       
  2042             if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
       
  2043                 out() << "<li class=\"level"
       
  2044                       << sectionNumber.size()
       
  2045                       << "\"><a href=\"#"
       
  2046                       << registerRef((*s).pluralMember)
       
  2047                       << "\">" << (*s).name
       
  2048                       << "</a></li>\n";
       
  2049             }
       
  2050             ++s;
       
  2051         }
       
  2052         out() << "<li class=\"level"
       
  2053               << sectionNumber.size()
       
  2054               << "\"><a href=\"#"
       
  2055               << registerRef("details")
       
  2056               << "\">Detailed Description</a></li>\n";
       
  2057         for (int i = 0; i < toc.size(); ++i) {
       
  2058             if (toc.at(i)->string().toInt() == 1) {
       
  2059                 detailsBase = 1;
       
  2060                 break;
       
  2061             }
       
  2062         }
       
  2063     }
       
  2064 
       
  2065     for (int i = 0; i < toc.size(); ++i) {
       
  2066         Atom *atom = toc.at(i);
       
  2067         int nextLevel = atom->string().toInt() + detailsBase;
       
  2068         if (sectionNumber.size() < nextLevel) {
       
  2069             do {
       
  2070                 sectionNumber.append("1");
       
  2071             } while (sectionNumber.size() < nextLevel);
       
  2072         }
       
  2073         else {
       
  2074             while (sectionNumber.size() > nextLevel) {
       
  2075                 sectionNumber.removeLast();
       
  2076             }
       
  2077             sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
       
  2078         }
       
  2079         int numAtoms;
       
  2080         Text headingText = Text::sectionHeading(atom);
       
  2081         QString s = headingText.toString();
       
  2082         out() << "<li class=\"level"
       
  2083               << sectionNumber.size()
       
  2084               << "\">";
       
  2085         out() << "<a href=\""
       
  2086               << "#"
       
  2087               << Doc::canonicalTitle(s)
       
  2088               << "\">";
       
  2089         generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
       
  2090         out() << "</a></li>\n";
       
  2091     }
       
  2092     while (!sectionNumber.isEmpty()) {
       
  2093         sectionNumber.removeLast();
       
  2094     }
       
  2095     out() << "</ul>\n";
       
  2096     out() << "</div>\n";
  1901     inContents = false;
  2097     inContents = false;
  1902     inLink = false;
  2098     inLink = false;
  1903 }
  2099 }
  1904 
  2100 
  1905 #if 0
  2101 #if 0
  1907                                            const Node *node,
  2103                                            const Node *node,
  1908                                            CodeMarker *marker)
  2104                                            CodeMarker *marker)
  1909 {
  2105 {
  1910     if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
  2106     if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
  1911          bar.next.begin() != 0) {
  2107          bar.next.begin() != 0) {
  1912         out() << "<p align=\"right\">";
  2108         out() << "<p class=\"rightAlign\">";
  1913         if (bar.prev.begin() != 0) {
  2109         if (bar.prev.begin() != 0) {
  1914 #if 0
  2110 #if 0
  1915             out() << "[<a href=\"" << section.previousBaseName()
  2111             out() << "[<a href=\"" << section.previousBaseName()
  1916                   << ".html\">Prev: ";
  2112                   << ".html\">Prev: ";
  1917             generateText(section.previousHeading(), node, marker);
  2113             generateText(section.previousHeading(), node, marker);
  1946         return QString();
  2142         return QString();
  1947 
  2143 
  1948     QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
  2144     QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
  1949     beginSubPage(inner->location(), fileName);
  2145     beginSubPage(inner->location(), fileName);
  1950     QString title = "List of All Members for " + inner->name();
  2146     QString title = "List of All Members for " + inner->name();
  1951     generateHeader(title, inner, marker, false);
  2147     generateHeader(title, inner, marker);
  1952     generateTitle(title, Text(), SmallSubTitle, inner, marker);
  2148     generateTitle(title, Text(), SmallSubTitle, inner, marker);
  1953     out() << "<p>This is the complete list of members for ";
  2149     out() << "<p>This is the complete list of members for ";
  1954     generateFullName(inner, 0, marker);
  2150     generateFullName(inner, 0, marker);
  1955     out() << ", including inherited members.</p>\n";
  2151     out() << ", including inherited members.</p>\n";
  1956 
  2152 
  1990         title = "Obsolete Members for " + inner->name();
  2186         title = "Obsolete Members for " + inner->name();
  1991         fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
  2187         fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
  1992     }
  2188     }
  1993 
  2189 
  1994     beginSubPage(inner->location(), fileName);
  2190     beginSubPage(inner->location(), fileName);
  1995     generateHeader(title, inner, marker, false);
  2191     generateHeader(title, inner, marker);
  1996     generateTitle(title, Text(), SmallSubTitle, inner, marker);
  2192     generateTitle(title, Text(), SmallSubTitle, inner, marker);
  1997 
  2193 
  1998     if (status == CodeMarker::Compat) {
  2194     if (status == CodeMarker::Compat) {
  1999         out() << "<p><b>The following class members are part of the "
  2195         out() << "<p><b>The following class members are part of the "
  2000                  "<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> "
  2196                  "<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> "
  2007               << "We strongly advise against using them in new code.</p>\n";
  2203               << "We strongly advise against using them in new code.</p>\n";
  2008     }
  2204     }
  2009 
  2205 
  2010     out() << "<p><ul><li><a href=\""
  2206     out() << "<p><ul><li><a href=\""
  2011           << linkForNode(inner, 0) << "\">"
  2207           << linkForNode(inner, 0) << "\">"
  2012           << protect(inner->name())
  2208           << protectEnc(inner->name())
  2013           << " class reference</a></li></ul></p>\n";
  2209           << " class reference</a></li></ul></p>\n";
  2014 
  2210 
  2015     for (i = 0; i < sections.size(); ++i) {
  2211     for (i = 0; i < sections.size(); ++i) {
  2016         out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
  2212         out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
  2017         generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
  2213         generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
  2018     }
  2214     }
  2019 
  2215 
  2020     sections = marker->sections(inner, CodeMarker::Detailed, status);
  2216     sections = marker->sections(inner, CodeMarker::Detailed, status);
  2021     for (i = 0; i < sections.size(); ++i) {
  2217     for (i = 0; i < sections.size(); ++i) {
  2022         out() << "<hr />\n";
  2218         out() << "<hr />\n";
  2023         out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
  2219         out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
  2024 
  2220 
  2025         NodeList::ConstIterator m = sections.at(i).members.begin();
  2221         NodeList::ConstIterator m = sections.at(i).members.begin();
  2026         while (m != sections.at(i).members.end()) {
  2222         while (m != sections.at(i).members.end()) {
  2027             if ((*m)->access() != Node::Private)
  2223             if ((*m)->access() != Node::Private)
  2028                 generateDetailedMember(*m, inner, marker);
  2224                 generateDetailedMember(*m, inner, marker);
  2083 
  2279 
  2084 void HtmlGenerator::generateAnnotatedList(const Node *relative,
  2280 void HtmlGenerator::generateAnnotatedList(const Node *relative,
  2085                                           CodeMarker *marker,
  2281                                           CodeMarker *marker,
  2086                                           const NodeMap &nodeMap)
  2282                                           const NodeMap &nodeMap)
  2087 {
  2283 {
  2088     out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
  2284     out() << "<table class=\"annotated\">\n";
  2089           << "cellspacing=\"1\" border=\"0\">\n";
       
  2090 
  2285 
  2091     int row = 0;
  2286     int row = 0;
  2092     foreach (const QString &name, nodeMap.keys()) {
  2287     foreach (const QString &name, nodeMap.keys()) {
  2093         const Node *node = nodeMap[name];
  2288         const Node *node = nodeMap[name];
  2094 
  2289 
  2095         if (node->status() == Node::Obsolete)
  2290         if (node->status() == Node::Obsolete)
  2096             continue;
  2291             continue;
  2097 
  2292 
  2098         if (++row % 2 == 1)
  2293         if (++row % 2 == 1)
  2099             out() << "<tr valign=\"top\" class=\"odd\">";
  2294             out() << "<tr class=\"odd topAlign\">";
  2100         else
  2295         else
  2101             out() << "<tr valign=\"top\" class=\"even\">";
  2296             out() << "<tr class=\"even topAlign\">";
  2102         out() << "<th>";
  2297         out() << "<td><p>";
  2103         generateFullName(node, relative, marker);
  2298         generateFullName(node, relative, marker);
  2104         out() << "</th>";
  2299         out() << "</p></td>";
  2105 
  2300 
  2106         if (!(node->type() == Node::Fake)) {
  2301         if (!(node->type() == Node::Fake)) {
  2107             Text brief = node->doc().trimmedBriefText(name);
  2302             Text brief = node->doc().trimmedBriefText(name);
  2108             if (!brief.isEmpty()) {
  2303             if (!brief.isEmpty()) {
  2109                 out() << "<td>";
  2304                 out() << "<td><p>";
  2110                 generateText(brief, node, marker);
  2305                 generateText(brief, node, marker);
  2111                 out() << "</td>";
  2306                 out() << "</p></td>";
  2112             }
  2307             }
  2113         }
  2308         }
  2114         else {
  2309         else {
  2115             out() << "<td>";
  2310             out() << "<td><p>";
  2116             out() << protect(node->doc().briefText().toString());
  2311             out() << protectEnc(node->doc().briefText().toString());
  2117             out() << "</td>";
  2312             out() << "</p></td>";
  2118         }
  2313         }
  2119         out() << "</tr>\n";
  2314         out() << "</tr>\n";
  2120     }
  2315     }
  2121     out() << "</table></p>\n";
  2316     out() << "</table>\n";
  2122 }
  2317 }
  2123 
  2318 
  2124 /*!
  2319 /*!
  2125   This function finds the common prefix of the names of all
  2320   This function finds the common prefix of the names of all
  2126   the classes in \a classMap and then generates a compact
  2321   the classes in \a classMap and then generates a compact
  2131   the name of the first and last classes in \a classMap.
  2326   the name of the first and last classes in \a classMap.
  2132  */
  2327  */
  2133 void HtmlGenerator::generateCompactList(const Node *relative,
  2328 void HtmlGenerator::generateCompactList(const Node *relative,
  2134                                         CodeMarker *marker,
  2329                                         CodeMarker *marker,
  2135                                         const NodeMap &classMap,
  2330                                         const NodeMap &classMap,
       
  2331                                         bool includeAlphabet,
  2136                                         QString commonPrefix)
  2332                                         QString commonPrefix)
  2137 {
  2333 {
  2138     const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
  2334     const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
  2139     const int NumColumns = 4; // number of columns in the result
  2335     const int NumColumns = 3; // number of columns in the result
  2140 
  2336 
  2141     if (classMap.isEmpty())
  2337     if (classMap.isEmpty())
  2142         return;
  2338         return;
  2143 
  2339 
  2144     /*
  2340     /*
  2203       QXtWidget in paragraph 33 (X). This is the only place where we
  2399       QXtWidget in paragraph 33 (X). This is the only place where we
  2204       assume that NumParagraphs is 37. Each paragraph is a NodeMap.
  2400       assume that NumParagraphs is 37. Each paragraph is a NodeMap.
  2205     */
  2401     */
  2206     NodeMap paragraph[NumParagraphs+1];
  2402     NodeMap paragraph[NumParagraphs+1];
  2207     QString paragraphName[NumParagraphs+1];
  2403     QString paragraphName[NumParagraphs+1];
       
  2404     QSet<char> usedParagraphNames;
  2208 
  2405 
  2209     NodeMap::ConstIterator c = classMap.begin();
  2406     NodeMap::ConstIterator c = classMap.begin();
  2210     while (c != classMap.end()) {
  2407     while (c != classMap.end()) {
  2211         QStringList pieces = c.key().split("::");
  2408         QStringList pieces = c.key().split("::");
  2212         QString key;
  2409         QString key;
  2226         else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
  2423         else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
  2227             paragraphNo = 10 + key[0].unicode() - 'a';
  2424             paragraphNo = 10 + key[0].unicode() - 'a';
  2228         }
  2425         }
  2229 
  2426 
  2230         paragraphName[paragraphNo] = key[0].toUpper();
  2427         paragraphName[paragraphNo] = key[0].toUpper();
       
  2428         usedParagraphNames.insert(key[0].toLower().cell());
  2231         paragraph[paragraphNo].insert(key, c.value());
  2429         paragraph[paragraphNo].insert(key, c.value());
  2232         ++c;
  2430         ++c;
  2233     }
  2431     }
  2234 
  2432 
  2235     /*
  2433     /*
  2245 
  2443 
  2246     paragraphOffset[0] = 0;
  2444     paragraphOffset[0] = 0;
  2247     for (j = 0; j < NumParagraphs; j++)         // j = 0..36
  2445     for (j = 0; j < NumParagraphs; j++)         // j = 0..36
  2248         paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
  2446         paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
  2249 
  2447 
  2250     int firstOffset[NumColumns + 1];            // 4 + 1
  2448     int firstOffset[NumColumns + 1];
  2251     int currentOffset[NumColumns];              // 4
  2449     int currentOffset[NumColumns];
  2252     int currentParagraphNo[NumColumns];         // 4
  2450     int currentParagraphNo[NumColumns];
  2253     int currentOffsetInParagraph[NumColumns];   // 4
  2451     int currentOffsetInParagraph[NumColumns];
  2254 
  2452 
  2255     int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
  2453     int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
  2256     int curParagNo = 0;
  2454     int curParagNo = 0;
  2257 
  2455 
  2258     for (i = 0; i < NumColumns; i++) {          // i = 0..3
  2456     for (i = 0; i < NumColumns; i++) {
  2259         firstOffset[i] = qMin(i * numRows, classMap.size());
  2457         firstOffset[i] = qMin(i * numRows, classMap.size());
  2260         currentOffset[i] = firstOffset[i];
  2458         currentOffset[i] = firstOffset[i];
  2261 
  2459 
  2262         for (j = curParagNo; j < NumParagraphs; j++) {
  2460         for (j = curParagNo; j < NumParagraphs; j++) {
  2263             if (paragraphOffset[j] > firstOffset[i])
  2461             if (paragraphOffset[j] > firstOffset[i])
  2269         currentOffsetInParagraph[i] = firstOffset[i] -
  2467         currentOffsetInParagraph[i] = firstOffset[i] -
  2270                                       paragraphOffset[curParagNo];
  2468                                       paragraphOffset[curParagNo];
  2271     }
  2469     }
  2272     firstOffset[NumColumns] = classMap.count();
  2470     firstOffset[NumColumns] = classMap.count();
  2273 
  2471 
  2274     out() << "<p><table class=\"generic\" width=\"100%\">\n";
  2472     if (includeAlphabet) {
       
  2473         out() << "<p  class=\"centerAlign functionIndex\"><b>";
       
  2474         for (int i = 0; i < 26; i++) {
       
  2475             QChar ch('a' + i);
       
  2476             if (usedParagraphNames.contains(char('a' + i)))
       
  2477                 out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
       
  2478         }
       
  2479         out() << "</b></p>\n";
       
  2480     }
       
  2481 
       
  2482     out() << "<table class=\"generic\">\n";
  2275     for (k = 0; k < numRows; k++) {
  2483     for (k = 0; k < numRows; k++) {
  2276         out() << "<tr>\n";
  2484         if (++numTableRows % 2 == 1)
       
  2485             out() << "<tr class=\"odd topAlign\">";
       
  2486         else
       
  2487             out() << "<tr class=\"even topAlign\">";
       
  2488         //break;
       
  2489 
       
  2490 //	out() << "<tr>\n";
  2277         for (i = 0; i < NumColumns; i++) {
  2491         for (i = 0; i < NumColumns; i++) {
  2278             if (currentOffset[i] >= firstOffset[i + 1]) {
  2492             if (currentOffset[i] >= firstOffset[i + 1]) {
  2279                 // this column is finished
  2493                 // this column is finished
  2280                 out() << "<td>\n</td>\n";
  2494                 out() << "<td>\n</td>\n"; // check why?
  2281             }
  2495             }
  2282             else {
  2496             else {
  2283                 while ((currentParagraphNo[i] < NumParagraphs) &&
  2497                 while ((currentParagraphNo[i] < NumParagraphs) &&
  2284                        (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) {
  2498                        (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) {
  2285                     ++currentParagraphNo[i];
  2499                     ++currentParagraphNo[i];
  2290                     qDebug() << "### Internal error ###" << __FILE__ << __LINE__
  2504                     qDebug() << "### Internal error ###" << __FILE__ << __LINE__
  2291                              << currentParagraphNo[i] << NumParagraphs;
  2505                              << currentParagraphNo[i] << NumParagraphs;
  2292                     currentParagraphNo[i] = NumParagraphs - 1;
  2506                     currentParagraphNo[i] = NumParagraphs - 1;
  2293                 }
  2507                 }
  2294 #endif
  2508 #endif
  2295                 out() << "<td align=\"right\">";
  2509                 out() << "<th  class=\"rightAlign alphaChar\"><p>";
  2296                 if (currentOffsetInParagraph[i] == 0) {
  2510                 if (currentOffsetInParagraph[i] == 0) {
  2297                     // start a new paragraph
  2511                     // start a new paragraph
       
  2512                     if (includeAlphabet) {
       
  2513                         QChar c = paragraphName[currentParagraphNo[i]][0].toLower();
       
  2514                         out() << QString("<a name=\"%1\"></a>").arg(c);
       
  2515                     }
  2298                     out() << "<b>"
  2516                     out() << "<b>"
  2299                           << paragraphName[currentParagraphNo[i]]
  2517                           << paragraphName[currentParagraphNo[i]]
  2300                           << "&nbsp;</b>";
  2518                           << "</b>";
  2301                 }
  2519                 }
  2302                 out() << "</td>\n";
  2520                 out() << "</p></th>\n";
  2303 
  2521 
  2304                 out() << "<td>";
  2522                 out() << "<td><p>";
  2305                 if ((currentParagraphNo[i] < NumParagraphs) &&
  2523                 if ((currentParagraphNo[i] < NumParagraphs) &&
  2306                     !paragraphName[currentParagraphNo[i]].isEmpty()) {
  2524                     !paragraphName[currentParagraphNo[i]].isEmpty()) {
  2307                     NodeMap::Iterator it;
  2525                     NodeMap::Iterator it;
  2308                     it = paragraph[currentParagraphNo[i]].begin();
  2526                     it = paragraph[currentParagraphNo[i]].begin();
  2309                     for (j = 0; j < currentOffsetInParagraph[i]; j++)
  2527                     for (j = 0; j < currentOffsetInParagraph[i]; j++)
  2312                     // Previously, we used generateFullName() for this, but we
  2530                     // Previously, we used generateFullName() for this, but we
  2313                     // require some special formatting.
  2531                     // require some special formatting.
  2314                     out() << "<a href=\""
  2532                     out() << "<a href=\""
  2315                         << linkForNode(it.value(), relative)
  2533                         << linkForNode(it.value(), relative)
  2316                         << "\">";
  2534                         << "\">";
  2317                     QStringList pieces = fullName(it.value(), relative, marker).split("::");
  2535                     QStringList pieces;
  2318                     out() << protect(pieces.last());
  2536                     if (it.value()->subType() == Node::QmlClass)
       
  2537                         pieces << it.value()->name();
       
  2538                     else
       
  2539                         pieces = fullName(it.value(), relative, marker).split("::");
       
  2540                     out() << protectEnc(pieces.last());
  2319                     out() << "</a>";
  2541                     out() << "</a>";
  2320                     if (pieces.size() > 1) {
  2542                     if (pieces.size() > 1) {
  2321                         out() << " (";
  2543                         out() << " (";
  2322                         generateFullName(it.value()->parent(), relative, marker);
  2544                         generateFullName(it.value()->parent(), relative, marker);
  2323                         out() << ")";
  2545                         out() << ")";
  2324                     }
  2546                     }
  2325                 }
  2547                 }
  2326                 out() << "</td>\n";
  2548                 out() << "</p></td>\n";
  2327 
  2549 
  2328                 currentOffset[i]++;
  2550                 currentOffset[i]++;
  2329                 currentOffsetInParagraph[i]++;
  2551                 currentOffsetInParagraph[i]++;
  2330             }
  2552             }
  2331         }
  2553         }
  2332         out() << "</tr>\n";
  2554         out() << "</tr>\n";
  2333     }
  2555     }
  2334     out() << "</table></p>\n";
  2556     out() << "</table>\n";
  2335 }
  2557 }
  2336 
  2558 
  2337 void HtmlGenerator::generateFunctionIndex(const Node *relative,
  2559 void HtmlGenerator::generateFunctionIndex(const Node *relative,
  2338                                           CodeMarker *marker)
  2560                                           CodeMarker *marker)
  2339 {
  2561 {
  2340     out() << "<p align=\"center\"><font size=\"+1\"><b>";
  2562     out() << "<p  class=\"centerAlign functionIndex\"><b>";
  2341     for (int i = 0; i < 26; i++) {
  2563     for (int i = 0; i < 26; i++) {
  2342         QChar ch('a' + i);
  2564         QChar ch('a' + i);
  2343         out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
  2565         out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
  2344     }
  2566     }
  2345     out() << "</b></font></p>\n";
  2567     out() << "</b></p>\n";
  2346 
  2568 
  2347     char nextLetter = 'a';
  2569     char nextLetter = 'a';
  2348     char currentLetter;
  2570     char currentLetter;
  2349 
  2571 
  2350 #if 1
  2572 #if 1
  2355 #if 1
  2577 #if 1
  2356         out() << "<li>";
  2578         out() << "<li>";
  2357 #else
  2579 #else
  2358         out() << "<p>";
  2580         out() << "<p>";
  2359 #endif
  2581 #endif
  2360         out() << protect(f.key()) << ":";
  2582         out() << protectEnc(f.key()) << ":";
  2361 
  2583 
  2362         currentLetter = f.key()[0].unicode();
  2584         currentLetter = f.key()[0].unicode();
  2363         while (islower(currentLetter) && currentLetter >= nextLetter) {
  2585         while (islower(currentLetter) && currentLetter >= nextLetter) {
  2364             out() << QString("<a name=\"%1\"></a>").arg(nextLetter);
  2586             out() << QString("<a name=\"%1\"></a>").arg(nextLetter);
  2365             nextLetter++;
  2587             nextLetter++;
  2409                                      CodeMarker::SynopsisStyle style)
  2631                                      CodeMarker::SynopsisStyle style)
  2410 {
  2632 {
  2411     QString marked = marker->markedUpSynopsis(node, relative, style);
  2633     QString marked = marker->markedUpSynopsis(node, relative, style);
  2412     QRegExp templateTag("(<[^@>]*>)");
  2634     QRegExp templateTag("(<[^@>]*>)");
  2413     if (marked.indexOf(templateTag) != -1) {
  2635     if (marked.indexOf(templateTag) != -1) {
  2414         QString contents = protect(marked.mid(templateTag.pos(1),
  2636         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  2415                                               templateTag.cap(1).length()));
  2637                                               templateTag.cap(1).length()));
  2416         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2638         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2417                         contents);
  2639                         contents);
  2418     }
  2640     }
  2419     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2641     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2448                                     bool summary)
  2670                                     bool summary)
  2449 { 
  2671 { 
  2450     QString marked = marker->markedUpQmlItem(node,summary);
  2672     QString marked = marker->markedUpQmlItem(node,summary);
  2451     QRegExp templateTag("(<[^@>]*>)");
  2673     QRegExp templateTag("(<[^@>]*>)");
  2452     if (marked.indexOf(templateTag) != -1) {
  2674     if (marked.indexOf(templateTag) != -1) {
  2453         QString contents = protect(marked.mid(templateTag.pos(1),
  2675         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  2454                                               templateTag.cap(1).length()));
  2676                                               templateTag.cap(1).length()));
  2455         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2677         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2456                         contents);
  2678                         contents);
  2457     }
  2679     }
  2458     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2680     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2461     marked.replace("</@param>", "</i>");
  2683     marked.replace("</@param>", "</i>");
  2462 
  2684 
  2463     if (summary)
  2685     if (summary)
  2464         marked.replace("@name>", "b>");
  2686         marked.replace("@name>", "b>");
  2465 
  2687 
  2466     marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
  2688     marked.replace("<@extra>", "<tt>");
  2467     marked.replace("</@extra>", "</tt>");
  2689     marked.replace("</@extra>", "</tt>");
  2468 
  2690 
  2469     if (summary) {
  2691     if (summary) {
  2470         marked.replace("<@type>", "");
  2692         marked.replace("<@type>", "");
  2471         marked.replace("</@type>", "");
  2693         marked.replace("</@type>", "");
  2554     if (!fakeNodeMap.isEmpty()) {
  2776     if (!fakeNodeMap.isEmpty()) {
  2555         foreach (const QString &groupTitle, groupTitlesMap.keys()) {
  2777         foreach (const QString &groupTitle, groupTitlesMap.keys()) {
  2556             const FakeNode *groupNode = groupTitlesMap[groupTitle];
  2778             const FakeNode *groupNode = groupTitlesMap[groupTitle];
  2557             out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
  2779             out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
  2558                         linkForNode(groupNode, relative)).arg(
  2780                         linkForNode(groupNode, relative)).arg(
  2559                         protect(groupNode->fullTitle()));
  2781                         protectEnc(groupNode->fullTitle()));
  2560 
  2782 
  2561             if (fakeNodeMap[groupNode].count() == 0)
  2783             if (fakeNodeMap[groupNode].count() == 0)
  2562                 continue;
  2784                 continue;
  2563 
  2785 
  2564             out() << "<ul>\n";
  2786             out() << "<ul>\n";
  2566             foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
  2788             foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
  2567                 QString title = fakeNode->fullTitle();
  2789                 QString title = fakeNode->fullTitle();
  2568                 if (title.startsWith("The "))
  2790                 if (title.startsWith("The "))
  2569                     title.remove(0, 4);
  2791                     title.remove(0, 4);
  2570                 out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
  2792                 out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
  2571                       << protect(title) << "</a></li>\n";
  2793                       << protectEnc(title) << "</a></li>\n";
  2572             }
  2794             }
  2573             out() << "</ul>\n";
  2795             out() << "</ul>\n";
  2574         }
  2796         }
  2575     }
  2797     }
  2576 
  2798 
  2580         foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
  2802         foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
  2581             QString title = fakeNode->fullTitle();
  2803             QString title = fakeNode->fullTitle();
  2582             if (title.startsWith("The "))
  2804             if (title.startsWith("The "))
  2583                 title.remove(0, 4);
  2805                 title.remove(0, 4);
  2584             out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
  2806             out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
  2585                   << protect(title) << "</a></li>\n";
  2807                   << protectEnc(title) << "</a></li>\n";
  2586         }
  2808         }
  2587         out() << "</ul>\n";
  2809         out() << "</ul>\n";
  2588     }
  2810     }
  2589 }
  2811 }
  2590 
  2812 
  2604         else if (nl.first()->type() == Node::Property) {
  2826         else if (nl.first()->type() == Node::Property) {
  2605             twoColumn = (nl.count() >= 5);
  2827             twoColumn = (nl.count() >= 5);
  2606             name_alignment = false;
  2828             name_alignment = false;
  2607         }
  2829         }
  2608         if (name_alignment) {
  2830         if (name_alignment) {
  2609             out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
  2831             out() << "<table class=\"alignedsummary\">\n";
  2610                   << "cellspacing=\"0\" width=\"100%\">\n";
       
  2611         }
  2832         }
  2612         else {
  2833         else {
  2613             if (twoColumn)
  2834             if (twoColumn)
  2614                 out() << "<p><table class=\"propsummary\" width=\"100%\" "
  2835                 out() << "<table class=\"propsummary\">\n"
  2615                       << "border=\"0\" cellpadding=\"0\""
  2836                       << "<tr><td  class=\"topAlign\">";
  2616                       << " cellspacing=\"0\">\n"
       
  2617                       << "<tr><td width=\"45%\" valign=\"top\">";
       
  2618             out() << "<ul>\n";
  2837             out() << "<ul>\n";
  2619         }
  2838         }
  2620 
  2839 
  2621         int i = 0;
  2840         int i = 0;
  2622         NodeList::ConstIterator m = nl.begin();
  2841         NodeList::ConstIterator m = nl.begin();
  2625                 ++m;
  2844                 ++m;
  2626                 continue;
  2845                 continue;
  2627             }
  2846             }
  2628 
  2847 
  2629             if (name_alignment) {
  2848             if (name_alignment) {
  2630                 out() << "<tr><td class=\"memItemLeft\" "
  2849                 out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
  2631                       << "align=\"right\" valign=\"top\">";
       
  2632             }
  2850             }
  2633             else {
  2851             else {
  2634                 if (twoColumn && i == (int) (nl.count() + 1) / 2)
  2852                 if (twoColumn && i == (int) (nl.count() + 1) / 2)
  2635                     out() << "</ul></td><td valign=\"top\"><ul>\n";
  2853                     out() << "</ul></td><td  class=\"topAlign\"><ul>\n";
  2636                 out() << "<li><div class=\"fn\">";
  2854                 out() << "<li class=\"fn\">";
  2637             }
  2855             }
  2638 
  2856 
  2639             generateSynopsis(*m, relative, marker, style, name_alignment);
  2857             generateSynopsis(*m, relative, marker, style, name_alignment);
  2640             if (name_alignment)
  2858             if (name_alignment)
  2641                 out() << "</td></tr>\n";
  2859                 out() << "</td></tr>\n";
  2642             else
  2860             else
  2643                 out() << "</div></li>\n";
  2861                 out() << "</li>\n";
  2644             i++;
  2862             i++;
  2645             ++m;
  2863             ++m;
  2646         }
  2864         }
  2647         if (name_alignment)
  2865         if (name_alignment)
  2648             out() << "</table>\n";
  2866             out() << "</table>\n";
  2649         else {
  2867         else {
  2650             out() << "</ul>\n";
  2868             out() << "</ul>\n";
  2651             if (twoColumn)
  2869             if (twoColumn)
  2652                 out() << "</td></tr>\n</table></p>\n";
  2870                 out() << "</td></tr>\n</table>\n";
  2653         }
  2871         }
  2654     }
  2872     }
  2655 }
  2873 }
  2656 
  2874 
  2657 void HtmlGenerator::generateSectionList(const Section& section,
  2875 void HtmlGenerator::generateSectionList(const Section& section,
  2669         else if (section.members.first()->type() == Node::Property) {
  2887         else if (section.members.first()->type() == Node::Property) {
  2670             twoColumn = (section.members.count() >= 5);
  2888             twoColumn = (section.members.count() >= 5);
  2671             name_alignment = false;
  2889             name_alignment = false;
  2672         }
  2890         }
  2673         if (name_alignment) {
  2891         if (name_alignment) {
  2674             out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
  2892             out() << "<table class=\"alignedsummary\">\n";
  2675                   << "cellspacing=\"0\" width=\"100%\">\n";
       
  2676         }
  2893         }
  2677         else {
  2894         else {
  2678             if (twoColumn)
  2895             if (twoColumn)
  2679                 out() << "<p><table class=\"propsummary\" width=\"100%\" "
  2896                 out() << "<table class=\"propsummary\">\n"
  2680                       << "border=\"0\" cellpadding=\"0\""
  2897                       << "<tr><td  class=\"topAlign\">";
  2681                       << " cellspacing=\"0\">\n"
       
  2682                       << "<tr><td width=\"45%\" valign=\"top\">";
       
  2683             out() << "<ul>\n";
  2898             out() << "<ul>\n";
  2684         }
  2899         }
  2685 
  2900 
  2686         int i = 0;
  2901         int i = 0;
  2687         NodeList::ConstIterator m = section.members.begin();
  2902         NodeList::ConstIterator m = section.members.begin();
  2690                 ++m;
  2905                 ++m;
  2691                 continue;
  2906                 continue;
  2692             }
  2907             }
  2693 
  2908 
  2694             if (name_alignment) {
  2909             if (name_alignment) {
  2695                 out() << "<tr><td class=\"memItemLeft\" "
  2910                 out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
  2696                       << "align=\"right\" valign=\"top\">";
       
  2697             }
  2911             }
  2698             else {
  2912             else {
  2699                 if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  2913                 if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  2700                     out() << "</ul></td><td valign=\"top\"><ul>\n";
  2914                     out() << "</ul></td><td class=\"topAlign\"><ul>\n";
  2701                 out() << "<li><div class=\"fn\">";
  2915                 out() << "<li class=\"fn\">";
  2702             }
  2916             }
  2703 
  2917 
  2704             generateSynopsis(*m, relative, marker, style, name_alignment);
  2918             generateSynopsis(*m, relative, marker, style, name_alignment);
  2705             if (name_alignment)
  2919             if (name_alignment)
  2706                 out() << "</td></tr>\n";
  2920                 out() << "</td></tr>\n";
  2707             else
  2921             else
  2708                 out() << "</div></li>\n";
  2922                 out() << "</li>\n";
  2709             i++;
  2923             i++;
  2710             ++m;
  2924             ++m;
  2711         }
  2925         }
  2712         if (name_alignment)
  2926         if (name_alignment)
  2713             out() << "</table>\n";
  2927             out() << "</table>\n";
  2714         else {
  2928         else {
  2715             out() << "</ul>\n";
  2929             out() << "</ul>\n";
  2716             if (twoColumn)
  2930             if (twoColumn)
  2717                 out() << "</td></tr>\n</table></p>\n";
  2931                 out() << "</td></tr>\n</table>\n";
  2718         }
  2932         }
  2719     }
  2933     }
  2720 
  2934 
  2721     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  2935     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  2722         out() << "<ul>\n";
  2936         out() << "<ul>\n";
  2731                                                  bool nameAlignment)
  2945                                                  bool nameAlignment)
  2732 {
  2946 {
  2733     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  2947     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  2734     while (p != section.inherited.end()) {
  2948     while (p != section.inherited.end()) {
  2735         if (nameAlignment)
  2949         if (nameAlignment)
  2736             out() << "<li><div bar=\"2\" class=\"fn\"></div>";
  2950             out() << "<li class=\"fn\">";
  2737         else
  2951         else
  2738             out() << "<li><div class=\"fn\"></div>";
  2952             out() << "<li class=\"fn\">";
  2739         out() << (*p).second << " ";
  2953         out() << (*p).second << " ";
  2740         if ((*p).second == 1) {
  2954         if ((*p).second == 1) {
  2741             out() << section.singularMember;
  2955             out() << section.singularMember;
  2742         }
  2956         }
  2743         else {
  2957         else {
  2744             out() << section.pluralMember;
  2958             out() << section.pluralMember;
  2745         }
  2959         }
  2746         out() << " inherited from <a href=\"" << fileName((*p).first)
  2960         out() << " inherited from <a href=\"" << fileName((*p).first)
  2747               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
  2961               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
  2748               << protect(marker->plainFullName((*p).first, relative))
  2962               << protectEnc(marker->plainFullName((*p).first, relative))
  2749               << "</a></li>\n";
  2963               << "</a></li>\n";
  2750         ++p;
  2964         ++p;
  2751     }
  2965     }
  2752 }
  2966 }
  2753 
  2967 
  2758                                      bool nameAlignment)
  2972                                      bool nameAlignment)
  2759 {
  2973 {
  2760     QString marked = marker->markedUpSynopsis(node, relative, style);
  2974     QString marked = marker->markedUpSynopsis(node, relative, style);
  2761     QRegExp templateTag("(<[^@>]*>)");
  2975     QRegExp templateTag("(<[^@>]*>)");
  2762     if (marked.indexOf(templateTag) != -1) {
  2976     if (marked.indexOf(templateTag) != -1) {
  2763         QString contents = protect(marked.mid(templateTag.pos(1),
  2977         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  2764                                               templateTag.cap(1).length()));
  2978                                               templateTag.cap(1).length()));
  2765         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2979         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  2766                         contents);
  2980                         contents);
  2767     }
  2981     }
  2768     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2982     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
  2778     if (style == CodeMarker::SeparateList) {
  2992     if (style == CodeMarker::SeparateList) {
  2779         QRegExp extraRegExp("<@extra>.*</@extra>");
  2993         QRegExp extraRegExp("<@extra>.*</@extra>");
  2780         extraRegExp.setMinimal(true);
  2994         extraRegExp.setMinimal(true);
  2781         marked.replace(extraRegExp, "");
  2995         marked.replace(extraRegExp, "");
  2782     } else {
  2996     } else {
  2783         marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
  2997         marked.replace("<@extra>", "<tt>");
  2784         marked.replace("</@extra>", "</tt>");
  2998         marked.replace("</@extra>", "</tt>");
  2785     }
  2999     }
  2786 
  3000 
  2787     if (style != CodeMarker::Detailed) {
  3001     if (style != CodeMarker::Detailed) {
  2788         marked.replace("<@type>", "");
  3002         marked.replace("<@type>", "");
  2809     static const QString linkTag("link");
  3023     static const QString linkTag("link");
  2810     bool done = false;
  3024     bool done = false;
  2811     for (int i = 0, n = src.size(); i < n;) {
  3025     for (int i = 0, n = src.size(); i < n;) {
  2812         if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
  3026         if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
  2813             if (nameAlignment && !done) {// && (i != 0)) Why was this here?
  3027             if (nameAlignment && !done) {// && (i != 0)) Why was this here?
  2814                 html += "</td><td class=\"memItemRight\" valign=\"bottom\">";
  3028                 html += "</td><td class=\"memItemRight bottomAlign\">";
  2815                 done = true;
  3029                 done = true;
  2816             }
  3030             }
  2817             i += 2;
  3031             i += 2;
  2818             if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
  3032             if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
  2819                 html += "<b>";
  3033                 html += "<b>";
  2974         }
  3188         }
  2975         else if (section.members.first()->type() == Node::Property) {
  3189         else if (section.members.first()->type() == Node::Property) {
  2976             twoColumn = (section.members.count() >= 5);
  3190             twoColumn = (section.members.count() >= 5);
  2977         }
  3191         }
  2978         if (twoColumn)
  3192         if (twoColumn)
  2979             out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "
  3193             out() << "<table class=\"generic\">\n";
  2980                   << "cellpadding=\"0\" cellspacing=\"0\">\n"
  3194         if (++numTableRows % 2 == 1)
  2981                   << "<tr><td width=\"45%\" valign=\"top\">";
  3195             out() << "<tr class=\"odd topAlign\">";
       
  3196         else
       
  3197             out() << "<tr class=\"even topAlign\">";
       
  3198 			
       
  3199 //                  << "<tr><td  class=\"topAlign\">";
  2982         out() << "<ul>\n";
  3200         out() << "<ul>\n";
  2983 
  3201 
  2984         int i = 0;
  3202         int i = 0;
  2985         NodeList::ConstIterator m = section.members.begin();
  3203         NodeList::ConstIterator m = section.members.begin();
  2986         while (m != section.members.end()) {
  3204         while (m != section.members.end()) {
  2988                 ++m;
  3206                 ++m;
  2989                 continue;
  3207                 continue;
  2990             }
  3208             }
  2991 
  3209 
  2992             if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  3210             if (twoColumn && i == (int) (section.members.count() + 1) / 2)
  2993                 out() << "</ul></td><td valign=\"top\"><ul>\n";
  3211                 out() << "</ul></td><td class=\"topAlign\"><ul>\n";
  2994 
  3212 
  2995             out() << "<li><div class=\"fn\"></div>";
  3213             out() << "<li class=\"fn\">";
  2996             if (style == CodeMarker::Accessors)
  3214             if (style == CodeMarker::Accessors)
  2997                 out() << "<b>";
  3215                 out() << "<b>";
  2998             generateSynopsis(*m, relative, marker, style);
  3216             generateSynopsis(*m, relative, marker, style);
  2999             if (style == CodeMarker::Accessors)
  3217             if (style == CodeMarker::Accessors)
  3000                 out() << "</b>";
  3218                 out() << "</b>";
  3002             i++;
  3220             i++;
  3003             ++m;
  3221             ++m;
  3004         }
  3222         }
  3005         out() << "</ul>\n";
  3223         out() << "</ul>\n";
  3006         if (twoColumn)
  3224         if (twoColumn)
  3007             out() << "</td></tr>\n</table></p>\n";
  3225             out() << "</td></tr>\n</table>\n";
  3008     }
  3226     }
  3009 
  3227 
  3010     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  3228     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
  3011         out() << "<ul>\n";
  3229         out() << "<ul>\n";
  3012         generateSectionInheritedList(section, relative, marker);
  3230         generateSectionInheritedList(section, relative, marker);
  3018                                                  const Node *relative,
  3236                                                  const Node *relative,
  3019                                                  CodeMarker *marker)
  3237                                                  CodeMarker *marker)
  3020 {
  3238 {
  3021     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  3239     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
  3022     while (p != section.inherited.end()) {
  3240     while (p != section.inherited.end()) {
  3023         out() << "<li><div bar=\"2\" class=\"fn\"></div>";
  3241         out() << "<li class=\"fn\">";
  3024         out() << (*p).second << " ";
  3242         out() << (*p).second << " ";
  3025         if ((*p).second == 1) {
  3243         if ((*p).second == 1) {
  3026             out() << section.singularMember;
  3244             out() << section.singularMember;
  3027         } else {
  3245         } else {
  3028             out() << section.pluralMember;
  3246             out() << section.pluralMember;
  3029         }
  3247         }
  3030         out() << " inherited from <a href=\"" << fileName((*p).first)
  3248         out() << " inherited from <a href=\"" << fileName((*p).first)
  3031               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
  3249               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
  3032               << protect(marker->plainFullName((*p).first, relative))
  3250               << protectEnc(marker->plainFullName((*p).first, relative))
  3033               << "</a></li>\n";
  3251               << "</a></li>\n";
  3034         ++p;
  3252         ++p;
  3035     }
  3253     }
  3036 }
  3254 }
  3037 
  3255 
  3041                                      CodeMarker::SynopsisStyle style)
  3259                                      CodeMarker::SynopsisStyle style)
  3042 {
  3260 {
  3043     QString marked = marker->markedUpSynopsis(node, relative, style);
  3261     QString marked = marker->markedUpSynopsis(node, relative, style);
  3044     QRegExp templateTag("(<[^@>]*>)");
  3262     QRegExp templateTag("(<[^@>]*>)");
  3045     if (marked.indexOf(templateTag) != -1) {
  3263     if (marked.indexOf(templateTag) != -1) {
  3046         QString contents = protect(marked.mid(templateTag.pos(1),
  3264         QString contents = protectEnc(marked.mid(templateTag.pos(1),
  3047                                               templateTag.cap(1).length()));
  3265                                               templateTag.cap(1).length()));
  3048         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  3266         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
  3049                         contents);
  3267                         contents);
  3050     }
  3268     }
  3051     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
  3269     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
  3058     if (style == CodeMarker::SeparateList) {
  3276     if (style == CodeMarker::SeparateList) {
  3059         QRegExp extraRegExp("<@extra>.*</@extra>");
  3277         QRegExp extraRegExp("<@extra>.*</@extra>");
  3060         extraRegExp.setMinimal(true);
  3278         extraRegExp.setMinimal(true);
  3061         marked.replace(extraRegExp, "");
  3279         marked.replace(extraRegExp, "");
  3062     } else {
  3280     } else {
  3063         marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
  3281         marked.replace("<@extra>", "<tt>");
  3064         marked.replace("</@extra>", "</tt>");
  3282         marked.replace("</@extra>", "</tt>");
  3065     }
  3283     }
  3066 
  3284 
  3067     if (style != CodeMarker::Detailed) {
  3285     if (style != CodeMarker::Detailed) {
  3068         marked.replace("<@type>", "");
  3286         marked.replace("<@type>", "");
  3239     static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
  3457     static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
  3240 
  3458 
  3241     if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
  3459     if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
  3242         // hack for C++: move () outside of link
  3460         // hack for C++: move () outside of link
  3243         int k = funcLeftParen.pos(1);
  3461         int k = funcLeftParen.pos(1);
  3244         out() << protect(atom->string().left(k));
  3462         out() << protectEnc(atom->string().left(k));
  3245         if (link.isEmpty()) {
  3463         if (link.isEmpty()) {
  3246             if (showBrokenLinks)
  3464             if (showBrokenLinks)
  3247                 out() << "</i>";
  3465                 out() << "</i>";
  3248         } else {
  3466         } else {
  3249             out() << "</a>";
  3467             out() << "</a>";
  3250         }
  3468         }
  3251         inLink = false;
  3469         inLink = false;
  3252         out() << protect(atom->string().mid(k));
  3470         out() << protectEnc(atom->string().mid(k));
  3253     } else if (marker->recognizeLanguage("Java")) {
  3471     } else if (marker->recognizeLanguage("Java")) {
  3254 	// hack for Java: remove () and use <tt> when appropriate
  3472 	// hack for Java: remove () and use <tt> when appropriate
  3255         bool func = atom->string().endsWith("()");
  3473         bool func = atom->string().endsWith("()");
  3256         bool tt = (func || atom->string().contains(camelCase));
  3474         bool tt = (func || atom->string().contains(camelCase));
  3257         if (tt)
  3475         if (tt)
  3258             out() << "<tt>";
  3476             out() << "<tt>";
  3259         if (func) {
  3477         if (func) {
  3260             out() << protect(atom->string().left(atom->string().length() - 2));
  3478             out() << protectEnc(atom->string().left(atom->string().length() - 2));
  3261         } else {
  3479         } else {
  3262             out() << protect(atom->string());
  3480             out() << protectEnc(atom->string());
  3263         }
  3481         }
  3264         out() << "</tt>";
  3482         out() << "</tt>";
  3265     } else {
  3483     } else {
  3266         out() << protect(atom->string());
  3484         out() << protectEnc(atom->string());
  3267     }
  3485     }
  3268 }
  3486 }
  3269 
  3487 
  3270 QString HtmlGenerator::cleanRef(const QString& ref)
  3488 QString HtmlGenerator::cleanRef(const QString& ref)
  3271 {
  3489 {
  3335         clean += "x";
  3553         clean += "x";
  3336     }
  3554     }
  3337     return clean;
  3555     return clean;
  3338 }
  3556 }
  3339 
  3557 
  3340 QString HtmlGenerator::protect(const QString& string)
  3558 QString HtmlGenerator::protectEnc(const QString &string)
       
  3559 {
       
  3560     return protect(string, outputEncoding);
       
  3561 }
       
  3562 
       
  3563 QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding)
  3341 {
  3564 {
  3342 #define APPEND(x) \
  3565 #define APPEND(x) \
  3343     if (html.isEmpty()) { \
  3566     if (html.isEmpty()) { \
  3344         html = string; \
  3567         html = string; \
  3345         html.truncate(i); \
  3568         html.truncate(i); \
  3358             APPEND("&lt;");
  3581             APPEND("&lt;");
  3359         } else if (ch == QLatin1Char('>')) {
  3582         } else if (ch == QLatin1Char('>')) {
  3360             APPEND("&gt;");
  3583             APPEND("&gt;");
  3361         } else if (ch == QLatin1Char('"')) {
  3584         } else if (ch == QLatin1Char('"')) {
  3362             APPEND("&quot;");
  3585             APPEND("&quot;");
  3363         } else if (ch.unicode() > 0x007F
  3586         } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F)
  3364                    || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
  3587                    || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
  3365                    || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
  3588                    || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
  3366             // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
  3589             // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
  3367             APPEND("&#x");
  3590             APPEND("&#x");
  3368             html += QString::number(ch.unicode(), 16);
  3591             html += QString::number(ch.unicode(), 16);
  3488 #endif        
  3711 #endif        
  3489     case Node::Variable:
  3712     case Node::Variable:
  3490         ref = node->name() + "-var";
  3713         ref = node->name() + "-var";
  3491         break;
  3714         break;
  3492     case Node::Target:
  3715     case Node::Target:
  3493         return protect(node->name());
  3716         return protectEnc(node->name());
  3494     }
  3717     }
  3495     return registerRef(ref);
  3718     return registerRef(ref);
  3496 }
  3719 }
  3497 
  3720 
  3498 QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
  3721 QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
  3562         default:
  3785         default:
  3563             ;
  3786             ;
  3564         }
  3787         }
  3565     }
  3788     }
  3566     out() << "\">";
  3789     out() << "\">";
  3567     out() << protect(fullName(apparentNode, relative, marker));
  3790     out() << protectEnc(fullName(apparentNode, relative, marker));
  3568     out() << "</a>";
  3791     out() << "</a>";
  3569 }
  3792 }
  3570 
  3793 
  3571 void HtmlGenerator::generateDetailedMember(const Node *node,
  3794 void HtmlGenerator::generateDetailedMember(const Node *node,
  3572                                            const InnerNode *relative,
  3795                                            const InnerNode *relative,
  3573                                            CodeMarker *marker)
  3796                                            CodeMarker *marker)
  3574 {
  3797 {
  3575     const EnumNode *enume;
  3798     const EnumNode *enume;
  3576 
  3799 
       
  3800 #ifdef GENERATE_MAC_REFS    
  3577     generateMacRef(node, marker);
  3801     generateMacRef(node, marker);
       
  3802 #endif    
  3578     if (node->type() == Node::Enum
  3803     if (node->type() == Node::Enum
  3579             && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
  3804             && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
       
  3805 #ifdef GENERATE_MAC_REFS    
  3580         generateMacRef(enume->flagsType(), marker);
  3806         generateMacRef(enume->flagsType(), marker);
       
  3807 #endif        
  3581         out() << "<h3 class=\"flags\">";
  3808         out() << "<h3 class=\"flags\">";
  3582         out() << "<a name=\"" + refForNode(node) + "\"></a>";
  3809         out() << "<a name=\"" + refForNode(node) + "\"></a>";
  3583         generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
  3810         generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
  3584         out() << "<br />";
  3811         out() << "<br/>";
  3585         generateSynopsis(enume->flagsType(),
  3812         generateSynopsis(enume->flagsType(),
  3586                          relative,
  3813                          relative,
  3587                          marker,
  3814                          marker,
  3588                          CodeMarker::Detailed);
  3815                          CodeMarker::Detailed);
  3589         out() << "</h3>\n";
  3816         out() << "</h3>\n";
  3623         }
  3850         }
  3624     }
  3851     }
  3625     else if (node->type() == Node::Enum) {
  3852     else if (node->type() == Node::Enum) {
  3626         const EnumNode *enume = static_cast<const EnumNode *>(node);
  3853         const EnumNode *enume = static_cast<const EnumNode *>(node);
  3627         if (enume->flagsType()) {
  3854         if (enume->flagsType()) {
  3628             out() << "<p>The " << protect(enume->flagsType()->name())
  3855             out() << "<p>The " << protectEnc(enume->flagsType()->name())
  3629                   << " type is a typedef for "
  3856                   << " type is a typedef for "
  3630                   << "<a href=\"qflags.html\">QFlags</a>&lt;"
  3857                   << "<a href=\"qflags.html\">QFlags</a>&lt;"
  3631                   << protect(enume->name())
  3858                   << protectEnc(enume->name())
  3632                   << "&gt;. It stores an OR combination of "
  3859                   << "&gt;. It stores an OR combination of "
  3633                   << protect(enume->name())
  3860                   << protectEnc(enume->name())
  3634                   << " values.</p>\n";
  3861                   << " values.</p>\n";
  3635         }
  3862         }
  3636     }
  3863     }
  3637     generateAlsoList(node, marker);
  3864     generateAlsoList(node, marker);
  3638 }
  3865 }
  3698             if (nsmap == newSinceMaps.end())
  3925             if (nsmap == newSinceMaps.end())
  3699                 nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap());
  3926                 nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap());
  3700             NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion);
  3927             NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion);
  3701             if (ncmap == newClassMaps.end())
  3928             if (ncmap == newClassMaps.end())
  3702                 ncmap = newClassMaps.insert(sinceVersion,NodeMap());
  3929                 ncmap = newClassMaps.insert(sinceVersion,NodeMap());
       
  3930             NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion);
       
  3931             if (nqcmap == newQmlClassMaps.end())
       
  3932                 nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap());
  3703  
  3933  
  3704             if ((*child)->type() == Node::Function) {
  3934             if ((*child)->type() == Node::Function) {
  3705                 FunctionNode *func = static_cast<FunctionNode *>(*child);
  3935                 FunctionNode *func = static_cast<FunctionNode *>(*child);
  3706                 if ((func->status() > Node::Obsolete) &&
  3936                 if ((func->status() > Node::Obsolete) &&
  3707                     (func->metaness() != FunctionNode::Ctor) &&
  3937                     (func->metaness() != FunctionNode::Ctor) &&
  3716                         (*child)->parent()->type() == Node::Namespace &&
  3946                         (*child)->parent()->type() == Node::Namespace &&
  3717                         !(*child)->parent()->name().isEmpty())
  3947                         !(*child)->parent()->name().isEmpty())
  3718                         className = (*child)->parent()->name()+"::"+className;
  3948                         className = (*child)->parent()->name()+"::"+className;
  3719                     nsmap.value().insert(className,(*child));
  3949                     nsmap.value().insert(className,(*child));
  3720                     ncmap.value().insert(className,(*child));
  3950                     ncmap.value().insert(className,(*child));
       
  3951                 }
       
  3952                 else if ((*child)->subType() == Node::QmlClass) {
       
  3953                     QString className = (*child)->name();
       
  3954                     if ((*child)->parent() &&
       
  3955                         (*child)->parent()->type() == Node::Namespace &&
       
  3956                         !(*child)->parent()->name().isEmpty())
       
  3957                         className = (*child)->parent()->name()+"::"+className;
       
  3958                     nsmap.value().insert(className,(*child));
       
  3959                     nqcmap.value().insert(className,(*child));
  3721                 }
  3960                 }
  3722             }
  3961             }
  3723             else {
  3962             else {
  3724                 QString name = (*child)->name();
  3963                 QString name = (*child)->name();
  3725                 if ((*child)->parent() &&
  3964                 if ((*child)->parent() &&
  3937         else if (first.endsWith(".html")) {
  4176         else if (first.endsWith(".html")) {
  3938             *node = myTree->root()->findNode(first, Node::Fake);
  4177             *node = myTree->root()->findNode(first, Node::Fake);
  3939         }
  4178         }
  3940         else {
  4179         else {
  3941             *node = marker->resolveTarget(first, myTree, relative);
  4180             *node = marker->resolveTarget(first, myTree, relative);
  3942             if (!*node)
  4181             if (!*node) {
  3943                 *node = myTree->findFakeNodeByTitle(first);
  4182                 *node = myTree->findFakeNodeByTitle(first);
  3944             if (!*node)
  4183             }
       
  4184             if (!*node) {
  3945                 *node = myTree->findUnambiguousTarget(first, targetAtom);
  4185                 *node = myTree->findUnambiguousTarget(first, targetAtom);
       
  4186             }
  3946         }
  4187         }
  3947 
  4188 
  3948         if (*node) {
  4189         if (*node) {
  3949             if (!(*node)->url().isEmpty())
  4190             if (!(*node)->url().isEmpty())
  3950                 return (*node)->url();
  4191                 return (*node)->url();
  4075     default:
  4316     default:
  4076         Generator::generateStatus(node, marker);
  4317         Generator::generateStatus(node, marker);
  4077     }
  4318     }
  4078 }
  4319 }
  4079 
  4320 
       
  4321 #ifdef GENERATE_MAC_REFS    
       
  4322 /*
       
  4323   No longer valid.
       
  4324  */
  4080 void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
  4325 void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
  4081 {
  4326 {
  4082     if (!pleaseGenerateMacRef || marker == 0)
  4327     if (!pleaseGenerateMacRef || marker == 0)
  4083         return;
  4328         return;
  4084 
  4329 
  4085     QStringList macRefs = marker->macRefsForNode(node);
  4330     QStringList macRefs = marker->macRefsForNode(node);
  4086     foreach (const QString &macRef, macRefs)
  4331     foreach (const QString &macRef, macRefs)
  4087         out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
  4332         out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
  4088 }
  4333 }
       
  4334 #endif
  4089 
  4335 
  4090 void HtmlGenerator::beginLink(const QString &link,
  4336 void HtmlGenerator::beginLink(const QString &link,
  4091                               const Node *node,
  4337                               const Node *node,
  4092                               const Node *relative,
  4338                               const Node *relative,
  4093                               CodeMarker *marker)
  4339                               CodeMarker *marker)
  4135     }
  4381     }
  4136     inLink = false;
  4382     inLink = false;
  4137     inObsoleteLink = false;
  4383     inObsoleteLink = false;
  4138 }
  4384 }
  4139 
  4385 
  4140 QT_END_NAMESPACE
       
  4141 
       
  4142 #ifdef QDOC_QML
  4386 #ifdef QDOC_QML
  4143 
  4387 
  4144 /*!
  4388 /*!
  4145   Generates the summary for for the \a section. Only used for
  4389   Generates the summary for the \a section. Only used for
  4146   sections of QML element documentation.
  4390   sections of QML element documentation.
  4147 
  4391 
  4148   Currently handles only the QML property group.
  4392   Currently handles only the QML property group.
  4149  */
  4393  */
  4150 void HtmlGenerator::generateQmlSummary(const Section& section,
  4394 void HtmlGenerator::generateQmlSummary(const Section& section,
  4157         bool twoColumn = false;
  4401         bool twoColumn = false;
  4158         if (section.members.first()->type() == Node::QmlProperty) {
  4402         if (section.members.first()->type() == Node::QmlProperty) {
  4159             twoColumn = (count >= 5);
  4403             twoColumn = (count >= 5);
  4160         }
  4404         }
  4161         if (twoColumn)
  4405         if (twoColumn)
  4162             out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
  4406             out() << "<table class=\"qmlsummary\">\n";
  4163                      " cellspacing=\"0\">\n"
  4407 			        if (++numTableRows % 2 == 1)
  4164                   << "<tr><td width=\"45%\" valign=\"top\">";
  4408 				out() << "<tr class=\"odd topAlign\">";
       
  4409 				else
       
  4410 				out() << "<tr class=\"even topAlign\">";
       
  4411             //      << "<tr><td class=\"topAlign\">";
  4165         out() << "<ul>\n";
  4412         out() << "<ul>\n";
  4166 
  4413 
  4167         int row = 0;
  4414         int row = 0;
  4168         m = section.members.begin();
  4415         m = section.members.begin();
  4169         while (m != section.members.end()) {
  4416         while (m != section.members.end()) {
  4170             if (twoColumn && row == (int) (count + 1) / 2)
  4417             if (twoColumn && row == (int) (count + 1) / 2)
  4171                 out() << "</ul></td><td valign=\"top\"><ul>\n";
  4418                 out() << "</ul></td><td class=\"topAlign\"><ul>\n";
  4172             out() << "<li><div class=\"fn\"></div>";
  4419             out() << "<li class=\"fn\">";
  4173             generateQmlItem(*m,relative,marker,true);
  4420             generateQmlItem(*m,relative,marker,true);
  4174             out() << "</li>\n";
  4421             out() << "</li>\n";
  4175             row++;
  4422             row++;
  4176             ++m;
  4423             ++m;
  4177         }
  4424         }
  4178         out() << "</ul>\n";
  4425         out() << "</ul>\n";
  4179         if (twoColumn)
  4426         if (twoColumn)
  4180             out() << "</td></tr>\n</table></p>\n";
  4427             out() << "</td></tr>\n</table>\n";
  4181     }
  4428     }
  4182 }
  4429 }
  4183 
  4430 
  4184 /*!
  4431 /*!
  4185   Outputs the html detailed documentation for a section
  4432   Outputs the html detailed documentation for a section
  4188 void HtmlGenerator::generateDetailedQmlMember(const Node *node,
  4435 void HtmlGenerator::generateDetailedQmlMember(const Node *node,
  4189                                               const InnerNode *relative,
  4436                                               const InnerNode *relative,
  4190                                               CodeMarker *marker)
  4437                                               CodeMarker *marker)
  4191 {
  4438 {
  4192     const QmlPropertyNode* qpn = 0;
  4439     const QmlPropertyNode* qpn = 0;
       
  4440 #ifdef GENERATE_MAC_REFS    
  4193     generateMacRef(node, marker);
  4441     generateMacRef(node, marker);
       
  4442 #endif    
  4194     out() << "<div class=\"qmlitem\">";
  4443     out() << "<div class=\"qmlitem\">";
  4195     if (node->subType() == Node::QmlPropertyGroup) {
  4444     if (node->subType() == Node::QmlPropertyGroup) {
  4196         const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
  4445         const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
  4197         NodeList::ConstIterator p = qpgn->childNodes().begin();
  4446         NodeList::ConstIterator p = qpgn->childNodes().begin();
  4198         out() << "<div class=\"qmlproto\">";
  4447         out() << "<div class=\"qmlproto\">";
  4199         out() << "<table width=\"100%\" class=\"qmlname\">";
  4448         out() << "<table class=\"qmlname\">";
  4200 
  4449 
  4201         while (p != qpgn->childNodes().end()) {
  4450         while (p != qpgn->childNodes().end()) {
  4202             if ((*p)->type() == Node::QmlProperty) {
  4451             if ((*p)->type() == Node::QmlProperty) {
  4203                 qpn = static_cast<const QmlPropertyNode*>(*p);
  4452                 qpn = static_cast<const QmlPropertyNode*>(*p);
  4204                 out() << "<tr><td>";
  4453                 
       
  4454 				if (++numTableRows % 2 == 1)
       
  4455 					out() << "<tr class=\"odd\">";
       
  4456 				else
       
  4457 					out() << "<tr class=\"even\">";
       
  4458 				
       
  4459 				out() << "<td><p>";
       
  4460                 //out() << "<tr><td>"; // old
  4205                 out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
  4461                 out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
  4206                 if (!qpn->isWritable())
  4462                 if (!qpn->isWritable())
  4207                     out() << "<span class=\"qmlreadonly\">read-only</span>";
  4463                     out() << "<span class=\"qmlreadonly\">read-only</span>";
       
  4464                 if (qpgn->isDefault())
       
  4465                     out() << "<span class=\"qmldefault\">default</span>";
  4208                 generateQmlItem(qpn, relative, marker, false);
  4466                 generateQmlItem(qpn, relative, marker, false);
  4209                 out() << "</td></tr>";
  4467                 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                 }
       
  4219             }
  4468             }
  4220             ++p;
  4469             ++p;
  4221         }
  4470         }
  4222         out() << "</table>";
  4471         out() << "</table>";
  4223         out() << "</div>";
  4472         out() << "</div>";
  4224     }
  4473     }
  4225     else if (node->type() == Node::QmlSignal) {
  4474     else if (node->type() == Node::QmlSignal) {
  4226         const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
  4475         const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
  4227         out() << "<div class=\"qmlproto\">";
  4476         out() << "<div class=\"qmlproto\">";
  4228         out() << "<table class=\"qmlname\">";
  4477         out() << "<table class=\"qmlname\">";
  4229         out() << "<tr><td>";
  4478         //out() << "<tr>";
       
  4479 		if (++numTableRows % 2 == 1)
       
  4480 			out() << "<tr class=\"odd\">";
       
  4481 		else
       
  4482 			out() << "<tr class=\"even\">";
       
  4483         out() << "<td><p>";
  4230         out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
  4484         out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
  4231         generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
  4485         generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
  4232         //generateQmlItem(qsn,relative,marker,false);
  4486         //generateQmlItem(qsn,relative,marker,false);
  4233         out() << "</td></tr>";
  4487         out() << "</p></td></tr>";
  4234         out() << "</table>";
  4488         out() << "</table>";
  4235         out() << "</div>";
  4489         out() << "</div>";
  4236     }
  4490     }
  4237     else if (node->type() == Node::QmlMethod) {
  4491     else if (node->type() == Node::QmlMethod) {
  4238         const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
  4492         const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
  4239         out() << "<div class=\"qmlproto\">";
  4493         out() << "<div class=\"qmlproto\">";
  4240         out() << "<table class=\"qmlname\">";
  4494         out() << "<table class=\"qmlname\">";
  4241         out() << "<tr><td>";
  4495         //out() << "<tr>";
       
  4496 		if (++numTableRows % 2 == 1)
       
  4497 			out() << "<tr class=\"odd\">";
       
  4498 		else
       
  4499 			out() << "<tr class=\"even\">";
       
  4500         out() << "<td><p>";
  4242         out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
  4501         out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
  4243         generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
  4502         generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
  4244         out() << "</td></tr>";
  4503         out() << "</p></td></tr>";
  4245         out() << "</table>";
  4504         out() << "</table>";
  4246         out() << "</div>";
  4505         out() << "</div>";
  4247     }
  4506     }
  4248     out() << "<div class=\"qmldoc\">";
  4507     out() << "<div class=\"qmldoc\">";
  4249     generateStatus(node, marker);
  4508     generateStatus(node, marker);
  4268             linkPair = cn->links()[Node::InheritsLink];
  4527             linkPair = cn->links()[Node::InheritsLink];
  4269             QStringList strList(linkPair.first);
  4528             QStringList strList(linkPair.first);
  4270             const Node* n = myTree->findNode(strList,Node::Fake);
  4529             const Node* n = myTree->findNode(strList,Node::Fake);
  4271             if (n && n->subType() == Node::QmlClass) {
  4530             if (n && n->subType() == Node::QmlClass) {
  4272                 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
  4531                 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
  4273                 out() << "<p style=\"text-align: center\">";
  4532                 out() << "<p class=\"centerAlign\">";
  4274                 Text text;
  4533                 Text text;
  4275                 text << "[Inherits ";
  4534                 text << "[Inherits ";
  4276                 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4535                 text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4277                 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4536                 text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4278                 text << Atom(Atom::String, linkPair.second);
  4537                 text << Atom(Atom::String, linkPair.second);
  4284         }
  4543         }
  4285     }
  4544     }
  4286 }
  4545 }
  4287 
  4546 
  4288 /*!
  4547 /*!
       
  4548   Output the "Inherit by" list for the QML element,
       
  4549   if it is inherited by any other elements.
       
  4550  */
       
  4551 void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn,
       
  4552                                            CodeMarker* marker)
       
  4553 {
       
  4554     if (cn) {
       
  4555         NodeList subs;
       
  4556         QmlClassNode::subclasses(cn->name(),subs);
       
  4557         if (!subs.isEmpty()) {
       
  4558             Text text;
       
  4559             text << Atom::ParaLeft << "Inherited by ";
       
  4560             appendSortedQmlNames(text,cn,subs,marker);
       
  4561             text << Atom::ParaRight;
       
  4562             generateText(text, cn, marker);
       
  4563         }
       
  4564     }
       
  4565 }
       
  4566 
       
  4567 /*!
  4289   Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]"
  4568   Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]"
  4290   line for the QML element, if there should be one.
  4569   line for the QML element, if there should be one.
  4291 
  4570 
  4292   If there is no class node, or if the class node status
  4571   If there is no class node, or if the class node status
  4293   is set to Node::Internal, do nothing. 
  4572   is set to Node::Internal, do nothing. 
  4295 void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
  4574 void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
  4296                                             CodeMarker* marker)
  4575                                             CodeMarker* marker)
  4297 {
  4576 {
  4298     const ClassNode* cn = qcn->classNode();
  4577     const ClassNode* cn = qcn->classNode();
  4299     if (cn && (cn->status() != Node::Internal)) {
  4578     if (cn && (cn->status() != Node::Internal)) {
  4300         out() << "<p style=\"text-align: center\">";
  4579         out() << "<p class=\"centerAlign\">";
  4301         Text text;
  4580         Text text;
  4302         text << "[";
  4581         text << "[";
  4303         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4582         text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
  4304         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4583         text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4305         text << Atom(Atom::String, qcn->name());
  4584         text << Atom(Atom::String, qcn->name());
  4326                                            CodeMarker* marker)
  4605                                            CodeMarker* marker)
  4327 {
  4606 {
  4328     if (cn &&  cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
  4607     if (cn &&  cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
  4329         const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
  4608         const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
  4330         if (n && n->subType() == Node::QmlClass) {
  4609         if (n && n->subType() == Node::QmlClass) {
  4331             out() << "<p style=\"text-align: center\">";
  4610             out() << "<p class=\"centerAlign\">";
  4332             Text text;
  4611             Text text;
  4333             text << "[";
  4612             text << "[";
  4334             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4613             text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
  4335             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4614             text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
  4336             text << Atom(Atom::String, cn->name());
  4615             text << Atom(Atom::String, cn->name());
  4345             out() << "</p>";
  4624             out() << "</p>";
  4346         }
  4625         }
  4347     }
  4626     }
  4348 }
  4627 }
  4349 
  4628 
       
  4629 /*!
       
  4630   Generate the <page> element for the given \a node using the \a writer.
       
  4631   Return true if a <page> element was written; otherwise return false.
       
  4632  */
       
  4633 bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer,
       
  4634                                         const Node* node,
       
  4635                                         CodeMarker* marker) const
       
  4636 {
       
  4637     if (node->pageType() == Node::NoPageType)
       
  4638         return false;
       
  4639     if (node->name().isEmpty())
       
  4640         return true;
       
  4641     if (node->access() == Node::Private)
       
  4642         return false;
       
  4643     if (!node->isInnerNode())
       
  4644         return false;
       
  4645 
       
  4646     QString title;
       
  4647     QString rawTitle;
       
  4648     QString fullTitle;
       
  4649     const InnerNode* inner = static_cast<const InnerNode*>(node);
       
  4650         
       
  4651     writer.writeStartElement("page");
       
  4652     QXmlStreamAttributes attributes;
       
  4653     QString t;
       
  4654     t.setNum(id++);
       
  4655     switch (node->type()) {
       
  4656     case Node::Fake:
       
  4657         {
       
  4658             const FakeNode* fake = static_cast<const FakeNode*>(node);
       
  4659             title = fake->fullTitle();
       
  4660             break;
       
  4661         }
       
  4662     case Node::Class:
       
  4663         {
       
  4664             title = node->name() + " Class Reference";
       
  4665             break;
       
  4666         }
       
  4667     case Node::Namespace:
       
  4668         {
       
  4669             rawTitle = marker->plainName(inner);
       
  4670             fullTitle = marker->plainFullName(inner);
       
  4671             title = rawTitle + " Namespace Reference";
       
  4672             break;
       
  4673         }
       
  4674     default:
       
  4675         title = node->name();
       
  4676         break;
       
  4677     }
       
  4678     writer.writeAttribute("id",t);
       
  4679     writer.writeStartElement("pageWords");
       
  4680     writer.writeCharacters(title);
       
  4681     if (!inner->pageKeywords().isEmpty()) {
       
  4682         const QStringList& w = inner->pageKeywords();
       
  4683         for (int i = 0; i < w.size(); ++i) {
       
  4684             writer.writeCharacters(" ");
       
  4685             writer.writeCharacters(w.at(i).toLocal8Bit().constData());
       
  4686         }
       
  4687     }
       
  4688     writer.writeEndElement();
       
  4689     writer.writeStartElement("pageTitle");
       
  4690     writer.writeCharacters(title);
       
  4691     writer.writeEndElement();
       
  4692     writer.writeStartElement("pageUrl");
       
  4693     writer.writeCharacters(PageGenerator::fileName(node));
       
  4694     writer.writeEndElement();
       
  4695     writer.writeStartElement("pageType");
       
  4696     switch (node->pageType()) {
       
  4697     case Node::ApiPage:
       
  4698         writer.writeCharacters("APIPage");
       
  4699         break;
       
  4700     case Node::ArticlePage:
       
  4701         writer.writeCharacters("Article");
       
  4702         break;
       
  4703     case Node::ExamplePage:
       
  4704         writer.writeCharacters("Example");
       
  4705         break;
       
  4706     default:
       
  4707         break;
       
  4708     }
       
  4709     writer.writeEndElement();
       
  4710     writer.writeEndElement();
       
  4711     return true;
       
  4712 }
       
  4713 
       
  4714 /*!
       
  4715   Traverse the tree recursively and generate the <keyword>
       
  4716   elements.
       
  4717  */
       
  4718 void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const
       
  4719 {
       
  4720     if (generatePageElement(writer, node, marker)) {
       
  4721 
       
  4722         if (node->isInnerNode()) {
       
  4723             const InnerNode *inner = static_cast<const InnerNode *>(node);
       
  4724 
       
  4725             // Recurse to write an element for this child node and all its children.
       
  4726             foreach (const Node *child, inner->childNodes())
       
  4727                 generatePageElements(writer, child, marker);
       
  4728         }
       
  4729     }
       
  4730 }
       
  4731 
       
  4732 /*!
       
  4733   Outputs the file containing the index used for searching the html docs.
       
  4734  */
       
  4735 void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const
       
  4736 {
       
  4737     QFile file(fileName);
       
  4738     if (!file.open(QFile::WriteOnly | QFile::Text))
       
  4739         return ;
       
  4740 
       
  4741     QXmlStreamWriter writer(&file);
       
  4742     writer.setAutoFormatting(true);
       
  4743     writer.writeStartDocument();
       
  4744     writer.writeStartElement("qtPageIndex");
       
  4745 
       
  4746     generatePageElements(writer, myTree->root(), marker);
       
  4747 
       
  4748     writer.writeEndElement(); // qtPageIndex
       
  4749     writer.writeEndDocument();
       
  4750     file.close();
       
  4751 }
       
  4752 
  4350 #endif
  4753 #endif
       
  4754 
       
  4755 #if 0 // fossil removed for new doc format MWS 19/04/2010
       
  4756     out() << "<!DOCTYPE html\n"
       
  4757              "    PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n";
       
  4758     out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
       
  4759 
       
  4760     QString shortVersion;
       
  4761     if ((project != "Qtopia") && (project != "Qt Extended")) {
       
  4762         shortVersion = project + " " + shortVersion + ": ";
       
  4763         if (node && !node->doc().location().isEmpty())
       
  4764             out() << "<!-- " << node->doc().location().fileName() << " -->\n";
       
  4765 
       
  4766         shortVersion = myTree->version();
       
  4767         if (shortVersion.count(QChar('.')) == 2)
       
  4768             shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
       
  4769         if (!shortVersion.isEmpty()) {
       
  4770             if (project == "QSA")
       
  4771                 shortVersion = "QSA " + shortVersion + ": ";
       
  4772             else
       
  4773                 shortVersion = "Qt " + shortVersion + ": ";
       
  4774         }
       
  4775     }
       
  4776 
       
  4777     out() << "<head>\n"
       
  4778              "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
       
  4779     out() << QString("<meta http-equiv=\"Content-type\" content=\"text/html; charset=%1\" />").arg(outputEncoding);
       
  4780 
       
  4781     if (!style.isEmpty())
       
  4782         out() << "    <style type=\"text/css\">" << style << "</style>\n";
       
  4783 
       
  4784     const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
       
  4785     if (!metaMap.isEmpty()) {
       
  4786         QMapIterator<QString, QString> i(metaMap);
       
  4787         while (i.hasNext()) {
       
  4788             i.next();
       
  4789             out() << "    <meta name=\"" << protectEnc(i.key()) << "\" contents=\""
       
  4790                   << protectEnc(i.value()) << "\" />\n";
       
  4791         }
       
  4792     }
       
  4793 
       
  4794     navigationLinks.clear();
       
  4795 
       
  4796     if (node && !node->links().empty()) {
       
  4797         QPair<QString,QString> linkPair;
       
  4798         QPair<QString,QString> anchorPair;
       
  4799         const Node *linkNode;
       
  4800 
       
  4801         if (node->links().contains(Node::PreviousLink)) {
       
  4802             linkPair = node->links()[Node::PreviousLink];
       
  4803             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4804             if (!linkNode || linkNode == node)
       
  4805                 anchorPair = linkPair;
       
  4806             else
       
  4807                 anchorPair = anchorForNode(linkNode);
       
  4808 
       
  4809             out() << "  <link rel=\"prev\" href=\""
       
  4810                   << anchorPair.first << "\" />\n";
       
  4811 
       
  4812             navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">";
       
  4813             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4814                 navigationLinks += protectEnc(anchorPair.second);
       
  4815             else
       
  4816                 navigationLinks += protectEnc(linkPair.second);
       
  4817             navigationLinks += "</a>]\n";
       
  4818         }
       
  4819         if (node->links().contains(Node::ContentsLink)) {
       
  4820             linkPair = node->links()[Node::ContentsLink];
       
  4821             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4822             if (!linkNode || linkNode == node)
       
  4823                 anchorPair = linkPair;
       
  4824             else
       
  4825                 anchorPair = anchorForNode(linkNode);
       
  4826 
       
  4827             out() << "  <link rel=\"contents\" href=\""
       
  4828                   << anchorPair.first << "\" />\n";
       
  4829 
       
  4830             navigationLinks += "[<a href=\"" + anchorPair.first + "\">";
       
  4831             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4832                 navigationLinks += protectEnc(anchorPair.second);
       
  4833             else
       
  4834                 navigationLinks += protectEnc(linkPair.second);
       
  4835             navigationLinks += "</a>]\n";
       
  4836         }
       
  4837         if (node->links().contains(Node::NextLink)) {
       
  4838             linkPair = node->links()[Node::NextLink];
       
  4839             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4840             if (!linkNode || linkNode == node)
       
  4841                 anchorPair = linkPair;
       
  4842             else
       
  4843                 anchorPair = anchorForNode(linkNode);
       
  4844 
       
  4845             out() << "  <link rel=\"next\" href=\""
       
  4846                   << anchorPair.first << "\" />\n";
       
  4847 
       
  4848             navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">";
       
  4849             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
       
  4850                 navigationLinks += protectEnc(anchorPair.second);
       
  4851             else
       
  4852                 navigationLinks += protectEnc(linkPair.second);
       
  4853             navigationLinks += "</a>]\n";
       
  4854         }
       
  4855         if (node->links().contains(Node::IndexLink)) {
       
  4856             linkPair = node->links()[Node::IndexLink];
       
  4857             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4858             if (!linkNode || linkNode == node)
       
  4859                 anchorPair = linkPair;
       
  4860             else
       
  4861                 anchorPair = anchorForNode(linkNode);
       
  4862             out() << "  <link rel=\"index\" href=\""
       
  4863                   << anchorPair.first << "\" />\n";
       
  4864         }
       
  4865         if (node->links().contains(Node::StartLink)) {
       
  4866             linkPair = node->links()[Node::StartLink];
       
  4867             linkNode = findNodeForTarget(linkPair.first, node, marker);
       
  4868             if (!linkNode || linkNode == node)
       
  4869                 anchorPair = linkPair;
       
  4870             else
       
  4871                 anchorPair = anchorForNode(linkNode);
       
  4872             out() << "  <link rel=\"start\" href=\""
       
  4873                   << anchorPair.first << "\" />\n";
       
  4874         }
       
  4875     }
       
  4876 
       
  4877     foreach (const QString &stylesheet, stylesheets) {
       
  4878         out() << "  <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "
       
  4879               << "type=\"text/css\" />\n";
       
  4880     }
       
  4881 
       
  4882     foreach (const QString &customHeadElement, customHeadElements) {
       
  4883         out() << "  " << customHeadElement << "\n";
       
  4884     }
       
  4885 
       
  4886     out() << "</head>\n"
       
  4887  #endif       
       
  4888 
       
  4889  QT_END_NAMESPACE