/****************************************************************************** * * * * Copyright (C) 1997-2003 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ #include <stdlib.h> #include "qtbc.h" #include <qdir.h> #include "message.h" #include "htmlgen.h" #include "config.h" #include "util.h" #include "doxygen.h" #include "logos.h" #include "diagram.h" #include "version.h" #include "dot.h" #include "language.h" #include "htmlhelp.h" #include "docparser.h" #include "htmldocvisitor.h" #include "index.h" #include "pagedef.h" // #define GROUP_COLOR "#ff8080" //#define DBG_HTML(x) x; #define DBG_HTML(x) static const char *defaultStyleSheet = "H1 {\n" " text-align: center;\n" " font-family: Arial, Helvetica, sans-serif;\n" "}\n" "H2 {\n" " font-family: Geneva, Arial, Helvetica, sans-serif;\n" "}\n" "CAPTION { font-weight: bold }\n" "DIV.qindex { width: 100%;\n" " background-color: #eeeeff;\n" " border: 4px solid #eeeeff;\n" " text-align: center;\n" " margin-bottom: 2px\n" "}\n" "A.qindex { text-decoration: none; font-weight: bold; color: #0000ee }\n" "A.qindex:visited { text-decoration: none; font-weight: bold; color: #0000ee }\n" "A.qindex:hover { text-decoration: none; background-color: #ddddff }\n" "A.qindexHL { text-decoration: none; font-weight: bold;\n" " background-color: #6666cc;\n" " color: #ffffff\n" " }\n" "A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff }\n" "A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }\n" "A.el { text-decoration: none; font-weight: bold }\n" "A.elRef { font-weight: bold }\n" "A.code { text-decoration: none; font-weight: normal; color: #4444ee }\n" "A.codeRef { font-weight: normal; color: #4444ee }\n" "A:hover { text-decoration: none; background-color: #f2f2ff }\n" "DL.el { margin-left: -1cm }\n" "DIV.fragment {\n" " width: 98%;\n" " border: 1px solid #CCCCCC;\n" " background-color: #f5f5f5;\n" " padding-left: 4px;\n" " margin: 4px;\n" "}\n" "DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }\n" "TD.md { background-color: #f2f2ff; font-weight: bold; }\n" "TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }\n" "TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; }\n" "DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }\n" "DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }\n" "BODY {\n" " background: white;\n" " color: black;\n" " margin-right: 20px;\n" " margin-left: 20px;\n" "}\n" "TD.indexkey { \n" " background-color: #eeeeff; \n" " font-weight: bold; \n" " padding-right : 10px; \n" " padding-top : 2px; \n" " padding-left : 10px; \n" " padding-bottom : 2px; \n" " margin-left : 0px; \n" " margin-right : 0px; \n" " margin-top : 2px; \n" " margin-bottom : 2px \n" "}\n" "TD.indexvalue { \n" " background-color: #eeeeff; \n" " font-style: italic; \n" " padding-right : 10px; \n" " padding-top : 2px; \n" " padding-left : 10px; \n" " padding-bottom : 2px; \n" " margin-left : 0px; \n" " margin-right : 0px; \n" " margin-top : 2px; \n" " margin-bottom : 2px \n" "}\n" "TR.memlist {\n" " background-color: #f0f0f0; \n" "}\n" "P.formulaDsp { text-align: center; }\n" "IMG.formulaDsp { }\n" "IMG.formulaInl { vertical-align: middle; }\n" "SPAN.keyword { color: #008000 }\n" "SPAN.keywordtype { color: #604020 }\n" "SPAN.keywordflow { color: #e08000 }\n" "SPAN.comment { color: #800000 }\n" "SPAN.preprocessor { color: #806020 }\n" "SPAN.stringliteral { color: #002080 }\n" "SPAN.charliteral { color: #008080 }\n" ".mdTable {\n" " border: 1px solid #868686;\n" " background-color: #f2f2ff;\n" "}\n" ".mdRow {\n" " padding: 8px 20px;\n" "}\n" ".mdescLeft {\n" " font-size: smaller;\n" " font-family: Arial, Helvetica, sans-serif;\n" " background-color: #FAFAFA;\n" " padding-left: 8px;\n" " border-top: 1px none #E0E0E0;\n" " border-right: 1px none #E0E0E0;\n" " border-bottom: 1px none #E0E0E0;\n" " border-left: 1px none #E0E0E0;\n" " margin: 0px;\n" "}\n" ".mdescRight {\n" " font-size: smaller;\n" " font-family: Arial, Helvetica, sans-serif;\n" " font-style: italic;\n" " background-color: #FAFAFA;\n" " padding-left: 4px;\n" " border-top: 1px none #E0E0E0;\n" " border-right: 1px none #E0E0E0;\n" " border-bottom: 1px none #E0E0E0;\n" " border-left: 1px none #E0E0E0;\n" " margin: 0px;\n" " padding-bottom: 0px;\n" " padding-right: 8px;\n" "}\n" ".memItemLeft {\n" " padding: 1px 0px 0px 8px;\n" " margin: 4px;\n" " border-top-width: 1px;\n" " border-right-width: 1px;\n" " border-bottom-width: 1px;\n" " border-left-width: 1px;\n" " border-top-style: solid;\n" " border-top-color: #E0E0E0;\n" " border-right-color: #E0E0E0;\n" " border-bottom-color: #E0E0E0;\n" " border-left-color: #E0E0E0;\n" " border-right-style: none;\n" " border-bottom-style: none;\n" " border-left-style: none;\n" " background-color: #FAFAFA;\n" " font-family: Geneva, Arial, Helvetica, sans-serif;\n" " font-size: 12px;\n" "}\n" ".memItemRight {\n" " padding: 1px 0px 0px 8px;\n" " margin: 4px;\n" " border-top-width: 1px;\n" " border-right-width: 1px;\n" " border-bottom-width: 1px;\n" " border-left-width: 1px;\n" " border-top-style: solid;\n" " border-top-color: #E0E0E0;\n" " border-right-color: #E0E0E0;\n" " border-bottom-color: #E0E0E0;\n" " border-left-color: #E0E0E0;\n" " border-right-style: none;\n" " border-bottom-style: none;\n" " border-left-style: none;\n" " background-color: #FAFAFA;\n" " font-family: Geneva, Arial, Helvetica, sans-serif;\n" " font-size: 13px;\n" "}\n" ".search { color: #0000ee;\n" " font-weight: bold;\n" "}\n" "FORM.search {\n" " margin-bottom: 0px;\n" " margin-top: 0px;\n" "}\n" "INPUT.search { font-size: 75%;\n" " color: #000080;\n" " font-weight: normal;\n" " background-color: #eeeeff;\n" "}\n" "TD.tiny { font-size: 75%;\n" "}\n"; static QCString g_header; static QCString g_footer; const char search_script[]= #include "search_php.h" ; HtmlGenerator::HtmlGenerator() : OutputGenerator() { dir=Config_getString("HTML_OUTPUT"); col=0; } HtmlGenerator::~HtmlGenerator() { //printf("HtmlGenerator::~HtmlGenerator()\n"); } void HtmlGenerator::init() { QCString dname=Config_getString("HTML_OUTPUT"); QDir d(dname); if (!d.exists() && !d.mkdir(dname)) { err("Could not create output directory %s\n",dname.data()); exit(1); } writeLogo(dname); if (!Config_getString("HTML_HEADER").isEmpty()) g_header=fileToString(Config_getString("HTML_HEADER")); if (!Config_getString("HTML_FOOTER").isEmpty()) g_footer=fileToString(Config_getString("HTML_FOOTER")); } void HtmlGenerator::writeStyleSheetFile(QFile &file) { QTextStream t(&file); t << defaultStyleSheet; } static void writeDefaultHeaderFile(QTextStream &t, const char *title) { t << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" "<html><head>" "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=" << theTranslator->idLanguageCharset() << "\">\n" "<title>"; t << convertToHtml(title); t << "</title>\n"; t << "<link "; t << "href=\""; if (Config_getString("HTML_STYLESHEET").isEmpty()) { t << "doxygen.css"; } else { QCString cssname=Config_getString("HTML_STYLESHEET"); QFileInfo cssfi(cssname); if (!cssfi.exists()) { err("Error: user specified HTML style sheet file does not exist!\n"); } t << cssfi.fileName(); } t << "\" rel=\"stylesheet\" type=\"text/css\">\n" "</head><body>\n"; } void HtmlGenerator::writeHeaderFile(QFile &file) { QTextStream t(&file); #if QT_VERSION >= 200 t.setEncoding(QTextStream::Latin1); #endif writeDefaultHeaderFile(t,"$title"); } void HtmlGenerator::writeFooterFile(QFile &file) { QTextStream t(&file); t << "<hr size=\"1\"><address style=\"align: right;\"><small>\n"; t << theTranslator->trGeneratedAt( "$datetime", "$projectname" ); t << " <a href=\"http://www.doxygen.org/index.html\">\n" << "<img src=\"doxygen.png\" alt=\"doxygen\" " << "align=\"middle\" border=0>\n" << "</a> $doxygenversion"; t << "</small></address>\n" << "</body>\n" << "</html>\n"; } void HtmlGenerator::startFile(const char *name,const char *, const char *title) { //printf("HtmlGenerator::startFile(%s)\n",name); QCString fileName=name; lastTitle=title; if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) { fileName+=Doxygen::htmlFileExtension; } startPlainFile(fileName); if (Config_getBool("GENERATE_HTMLHELP")) { HtmlHelp::getInstance()->addIndexFile(fileName); } QCString dispTitle = title; QCString projName = Config_getString("PROJECT_NAME"); if (!projName.isEmpty()) { dispTitle.prepend(projName+": "); } lastFile = fileName; if (g_header.isEmpty()) { writeDefaultHeaderFile(t,dispTitle); } else { t << substituteKeywords(g_header,convertToHtml(lastTitle)); } t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " << versionString << " -->" << endl; } //void HtmlGenerator::startQuickIndexItem(const char *s,const char *l) //{ // QCString *dest; // if (s) // { // t << "<a class=\"qindexRef\" "; // t << "doxygen=\"" << s << ":"; // if ((dest=Doxygen::tagDestinationDict[s])) t << *dest; // if (strcmp(s,"_cgi")!=0) t << "/"; // small hack to get the cgi binary link right // t << "\" "; // } // else // { // t << "<a class=\"qindex\" "; // } // t << "href=\""; // if (s) // { // if ((dest=Doxygen::tagDestinationDict[s])) t << *dest; // if (strcmp(s,"_cgi")!=0) t << "/"; // } // t << l << "\">"; //} // //void HtmlGenerator::endQuickIndexItem() //{ // t << "</a> "; //} static void writePageFooter(QTextStream &t,const QCString lastTitle) { if (g_footer.isEmpty()) { t << "<hr size=\"1\"><address style=\"align: right;\"><small>"; t << theTranslator->trGeneratedAt( dateToString(TRUE), Config_getString("PROJECT_NAME") ); t << endl << "<a href=\"http://www.doxygen.org/index.html\">"; t << endl << "<img src=\"doxygen.png\" alt=\"doxygen\" " << "align=\"middle\" border=0 > " << endl << "</a>" << versionString <<" "; t << "</small></address>\n</body>\n</html>\n"; } else { t << substituteKeywords(g_footer,convertToHtml(lastTitle)); } } void HtmlGenerator::writeFooter() { writePageFooter(t,lastTitle); } void HtmlGenerator::endFile() { endPlainFile(); } void HtmlGenerator::startProjectNumber() { t << "<h3 align=\"center\">"; } void HtmlGenerator::endProjectNumber() { t << "</h3>"; } void HtmlGenerator::writeStyleInfo(int part) { //printf("writeStyleInfo(%d)\n",part); if (part==0) { if (Config_getString("HTML_STYLESHEET").isEmpty()) // write default style sheet { //printf("write doxygen.css\n"); startPlainFile("doxygen.css"); // alternative, cooler looking titles //t << "H1 { text-align: center; border-width: thin none thin none;" << endl; //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl; t << defaultStyleSheet; endPlainFile(); } else // write user defined style sheet { QCString cssname=Config_getString("HTML_STYLESHEET"); QFileInfo cssfi(cssname); if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable()) { err("Error: style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data()); } else { // convert style sheet to string QCString fileStr = fileToString(cssname); // write the string into the output dir startPlainFile(cssfi.fileName()); t << fileStr; endPlainFile(); } } } } void HtmlGenerator::startDoxyAnchor(const char *,const char *, const char *anchor, const char *name) { t << "<a class=\"anchor\" name=\"" << anchor << "\" doxytag=\"" << name << "\" ></a>"; } void HtmlGenerator::endDoxyAnchor(const char *,const char *) { } void HtmlGenerator::newParagraph() { t << endl << "<p>" << endl; } void HtmlGenerator::writeString(const char *text) { t << text; } void HtmlGenerator::writeIndexItem(const char *ref,const char *f, const char *name) { //printf("HtmlGenerator::writeIndexItem(%s,%s,%s)\n",ref,f,name); QCString *dest; t << "<li>"; if (ref || f) { if (ref) { t << "<a class=\"elRef\" "; t << "doxygen=\"" << ref << ":"; if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; t << "\" "; } else { t << "<a class=\"el\" "; } t << "href=\""; if (ref) { if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; } if (f) t << f << Doxygen::htmlFileExtension << "\">"; } else { t << "<b>"; } docify(name); if (ref || f) { t << "</a>" << endl; } else { t << "</b>"; } //if (Config_getBool("GENERATE_HTMLHELP") && f) //{ // htmlHelp->addItem(name,((QCString)f)+htmlFileExtension); //} } void HtmlGenerator::writeStartAnnoItem(const char *,const char *f, const char *path,const char *name) { t << "<li>"; if (path) docify(path); t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">"; docify(name); t << "</a> "; //if (Config_getBool("GENERATE_HTMLHELP") && f) //{ // htmlHelp->addItem(name, ((QCString)f)+htmlFileExtension); //} } void HtmlGenerator::writeObjectLink(const char *ref,const char *f, const char *anchor, const char *name) { QCString *dest; if (ref) { t << "<a class=\"elRef\" "; t << "doxygen=\"" << ref << ":"; if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; t << "\" "; } else { t << "<a class=\"el\" "; } t << "href=\""; if (ref) { if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; } if (f) t << f << Doxygen::htmlFileExtension; if (anchor) t << "#" << anchor; t << "\">"; docify(name); t << "</a>"; } void HtmlGenerator::writeCodeLink(const char *ref,const char *f, const char *anchor, const char *name) { QCString *dest; if (ref) { t << "<a class=\"codeRef\" "; t << "doxygen=\"" << ref << ":"; if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; t << "\" "; } else { t << "<a class=\"code\" "; } t << "href=\""; if (ref) { if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/"; } if (f) t << f << Doxygen::htmlFileExtension; if (anchor) t << "#" << anchor; t << "\">"; docify(name); t << "</a>"; col+=strlen(name); } void HtmlGenerator::startTextLink(const char *f,const char *anchor) { t << "<a href=\""; if (f) t << f << Doxygen::htmlFileExtension; if (anchor) t << "#" << anchor; t << "\">"; } void HtmlGenerator::endTextLink() { t << "</a>"; } void HtmlGenerator::startHtmlLink(const char *url) { t << "<a "; if (Config_getBool("GENERATE_TREEVIEW")) t << "target=\"top\" "; t << "href=\""; if (url) t << url; t << "\">"; } void HtmlGenerator::endHtmlLink() { t << "</a>"; } void HtmlGenerator::startGroupHeader() { t << "<h2>"; } void HtmlGenerator::endGroupHeader() { t << "</h2>" << endl; } void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) { switch(type) { case SectionInfo::Page: t << "<h1>"; break; case SectionInfo::Section: t << "<h2>"; break; case SectionInfo::Subsection: t << "<h3>"; break; case SectionInfo::Subsubsection: t << "<h4>"; break; case SectionInfo::Paragraph: t << "<h5>"; break; default: ASSERT(0); break; } t << "<a class=\"anchor\" name=\"" << lab << "\">"; } void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type) { t << "</a>"; switch(type) { case SectionInfo::Page: t << "</h1>"; break; case SectionInfo::Section: t << "</h2>"; break; case SectionInfo::Subsection: t << "</h3>"; break; case SectionInfo::Subsubsection: t << "</h4>"; break; case SectionInfo::Paragraph: t << "</h5>"; break; default: ASSERT(0); break; } } void HtmlGenerator::docify(const char *str) { if (str) { const char *p=str; char c; while (*p) { c=*p++; switch(c) { case '<': t << "<"; break; case '>': t << ">"; break; case '&': t << "&"; break; case '\\': if (*p=='<') { t << "<"; p++; } else if (*p=='>') { t << ">"; p++; } else t << "\\"; break; default: t << c; } } } } void HtmlGenerator::codify(const char *str) { //docify(str); //static char spaces[]=" "; if (str) { const char *p=str; char c; int spacesToNextTabStop; while (*p) { c=*p++; switch(c) { case '\t': spacesToNextTabStop = Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE")); t << spaces.left(spacesToNextTabStop); col+=spacesToNextTabStop; break; case '\n': t << '\n'; col=0; break; case '\r': break; case '<': t << "<"; col++; break; case '>': t << ">"; col++; break; case '&': t << "&"; col++; break; case '\\': if (*p=='<') { t << "<"; p++; } else if (*p=='>') { t << ">"; p++; } else t << "\\"; col++; break; default: t << c; col++; break; } } } } void HtmlGenerator::writeChar(char c) { char cs[2]; cs[0]=c; cs[1]=0; docify(cs); } void HtmlGenerator::startClassDiagram() { t << "<p>"; } void HtmlGenerator::endClassDiagram(ClassDiagram &d, const char *fileName,const char *name) { t << "\n<p><center><img src=\"" << fileName << ".png\" usemap=\"#" << name << "_map\"" << " border=\"0\" alt=\"\"></center>" << endl << "<map name=\"" << name << "_map\">" << endl; d.writeImage(t,dir,fileName); } void HtmlGenerator::startMemberList() { DBG_HTML(t << "<!-- startMemberList -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { } else { t << "<ul>" << endl; } } void HtmlGenerator::endMemberList() { DBG_HTML(t << "<!-- endMemberList -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { } else { t << "</ul>" << endl; } } // annonymous type: // 0 = single column right aligned // 1 = double column left aligned // 2 = single column left aligned void HtmlGenerator::startMemberItem(int annoType) { DBG_HTML(t << "<!-- startMemberItem() -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "<tr>"; switch(annoType) { case 0: t << "<td class=\"memItemLeft\" nowrap align=right valign=top>"; break; case 1: t << "<td class=\"memItemLeft\" nowrap>"; break; default: t << "<td class=\"memItemLeft\" nowrap valign=top>"; break; } } else { t << "<li>"; } } void HtmlGenerator::endMemberItem() { //DBG_HTML(t << "<!-- endMemberItem(" << (int)inGroup << "," << fileName << "," << headerName << " -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "</td></tr>\n"; } t << endl; } void HtmlGenerator::insertMemberAlign() { DBG_HTML(t << "<!-- insertMemberAlign -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << " </td><td class=\"memItemRight\" valign=bottom>"; } } void HtmlGenerator::startMemberDescription() { DBG_HTML(t << "<!-- startMemberDescription -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "<tr><td class=\"mdescLeft\"> </td><td class=\"mdescRight\">"; } else { t << "<dl class=\"el\"><dd class=\"mdescRight\">"; } } void HtmlGenerator::endMemberDescription() { DBG_HTML(t << "<!-- endMemberDescription -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "<br><br></td></tr>" << endl; } else { t << "<br><br></dl>"; } } void HtmlGenerator::startMemberSections() { DBG_HTML(t << "<!-- startMemberSections -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "<table border=0 cellpadding=0 cellspacing=0>" << endl; // HTML is not recursively decomposable, sorry t << "<tr><td></td></tr>" << endl; } } void HtmlGenerator::endMemberSections() { DBG_HTML(t << "<!-- endMemberSections -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "</table>" << endl; } } void HtmlGenerator::startMemberHeader() { DBG_HTML(t << "<!-- startMemberHeader -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "<tr><td colspan=2><br><h2>"; } else { startGroupHeader(); } } void HtmlGenerator::endMemberHeader() { DBG_HTML(t << "<!-- endMemberHeader -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) { t << "</h2></td></tr>" << endl; } else { endGroupHeader(); } } void HtmlGenerator::startMemberSubtitle() { DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) t << "<tr><td colspan=2>"; } void HtmlGenerator::endMemberSubtitle() { DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl) if (Config_getBool("HTML_ALIGN_MEMBERS")) t << "<br><br></td></tr>" << endl; } void HtmlGenerator::startIndexList() { t << "<table>" << endl; } void HtmlGenerator::endIndexList() { t << "</table>" << endl; } void HtmlGenerator::startIndexKey() { // inserted 'class = ...', 02 jan 2002, jh t << " <tr><td class=\"indexkey\">"; } void HtmlGenerator::endIndexKey() { t << "</td>"; } void HtmlGenerator::startIndexValue(bool) { // inserted 'class = ...', 02 jan 2002, jh t << "<td class=\"indexvalue\">"; } void HtmlGenerator::endIndexValue(const char *,bool) { t << "</td></tr>" << endl; } void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *) { DBG_HTML(t << "<!-- startMemberDoc -->" << endl;) t << "<p>" << endl; t << "<table class=\"mdTable\" width=\"100%\" cellpadding=\"2\" cellspacing=\"0\">" << endl; t << " <tr>" << endl; t << " <td class=\"mdRow\">" << endl; t << " <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" << endl; } void HtmlGenerator::startMemberDocPrefixItem() { DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;) t << " <tr>" << endl; t << " <td class=\"md\" colspan=\"4\">" << endl; } void HtmlGenerator::endMemberDocPrefixItem() { DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;) t << "</td>" << endl; t << " </tr>" << endl; } void HtmlGenerator::startMemberDocName() { DBG_HTML(t << "<!-- startMemberDocName -->" << endl;) t << " <tr>" << endl; t << " <td class=\"md\" nowrap valign=\"top\"> "; } void HtmlGenerator::endMemberDocName() { DBG_HTML(t << "<!-- endMemberDocName -->" << endl;) t << "</td>" << endl; } void HtmlGenerator::startParameterList() { DBG_HTML(t << "<!-- startParameterList -->" << endl;) t << " <td class=\"md\" valign=\"top\">( </td>" << endl; } void HtmlGenerator::startParameterType(bool first) { if (first) { DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;) t << " <td class=\"md\" nowrap valign=\"top\">"; } else { DBG_HTML(t << "<!-- startParameterType -->" << endl;) t << " <tr>" << endl; t << " <td></td>" << endl; t << " <td></td>" << endl; t << " <td class=\"md\" nowrap>"; } } void HtmlGenerator::endParameterType() { DBG_HTML(t << "<!-- endParameterType -->" << endl;) t << " </td>" << endl; } void HtmlGenerator::startParameterName(bool oneArgOnly) { DBG_HTML(t << "<!-- startParameterName -->" << endl;) t << " <td class=\"mdname"; if (oneArgOnly) { t << "1\" valign=\"top"; } t << "\" nowrap>"; // "; } void HtmlGenerator::endParameterName(bool last,bool emptyList) { DBG_HTML(t << "<!-- endParameterName -->" << endl;) if (last) { if (emptyList) { t << " </td>" << endl; t << " <td class=\"md\" valign=\"top\"> ) </td>" << endl; t << " <td class=\"md\" nowrap>"; } else { t << "</td>" << endl; t << " </tr>" << endl; t << " <tr>" << endl; t << " <td></td>" << endl; t << " <td class=\"md\">) </td>" << endl; t << " <td class=\"md\" colspan=\"2\">"; } } else { t << "</td>" << endl; t << " </tr>" << endl; } } void HtmlGenerator::endParameterList() { DBG_HTML(t << "<!-- endParameterList -->" << endl;) t << "</td>" << endl; t << " </tr>" << endl; } void HtmlGenerator::endMemberDoc() { DBG_HTML(t << "<!-- endMemberDoc -->" << endl;) t << endl; t << " </table>" << endl; t << " </td>" << endl; t << " </tr>" << endl; t << "</table>" << endl; } void HtmlGenerator::startDotGraph() { } void HtmlGenerator::endDotGraph(DotClassGraph &g) { g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT")); } void HtmlGenerator::startInclDepGraph() { } void HtmlGenerator::endInclDepGraph(DotInclDepGraph &g) { g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT")); } void HtmlGenerator::startCallGraph() { } void HtmlGenerator::endCallGraph(DotCallGraph &g) { g.writeGraph(t,BITMAP,Config_getString("HTML_OUTPUT")); } void HtmlGenerator::writeGraphicalHierarchy(DotGfxHierarchyTable &g) { g.writeGraph(t,Config_getString("HTML_OUTPUT")); } void HtmlGenerator::startMemberGroupHeader(bool) { t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">"; } void HtmlGenerator::endMemberGroupHeader() { t << "</div></td></tr>" << endl; } void HtmlGenerator::startMemberGroupDocs() { t << "<tr><td colspan=\"2\"><div class=\"groupText\">"; } void HtmlGenerator::endMemberGroupDocs() { t << "<br><br></div></td></tr>" << endl; } void HtmlGenerator::startMemberGroup() { } void HtmlGenerator::endMemberGroup(bool) { } void HtmlGenerator::startIndent() { // I really wanted to use CSS here to provide an indented section, but // alas, Netscape is buggy enough to sometimes "forget" to end the // indent cause a staircase effect where the indent continuously increases. // It's back to abusing tables :-( //t << "<div class=\"in\">" << endl; t << "<table cellspacing=5 cellpadding=0 border=0>\n" " <tr>\n" " <td>\n" " \n" " </td>\n" " <td>\n"; } void HtmlGenerator::endIndent() { t << " </td>\n" " </tr>\n" "</table>\n"; //t << "</div>" << endl; } void HtmlGenerator::addIndexItem(const char *,const char *) { } void HtmlGenerator::writeNonBreakableSpace(int n) { int i; for (i=0;i<n;i++) { t << " "; } } void HtmlGenerator::writeLineNumber(const char *ref,const char *file, const char *anchor,int l) { QCString lineNumber,lineAnchor; lineNumber.sprintf("%05d",l); lineAnchor.sprintf("l%05d",l); if (file) { startCodeAnchor(lineAnchor); writeCodeLink(ref,file,anchor,lineNumber); endCodeAnchor(); } else { codify(lineNumber); } codify(" "); } void HtmlGenerator::startSimpleSect(SectionTypes, const char *file,const char *anchor, const char *title) { t << "<dl compact><dt><b>"; if (file) { writeObjectLink(0,file,anchor,title); } else { docify(title); } t << "</b></dt>"; } void HtmlGenerator::endSimpleSect() { t << "</dl>"; } void HtmlGenerator::startParamList(ParamListTypes, const char *title) { t << "<dl compact><dt><b>"; docify(title); t << "</b></dt>"; } void HtmlGenerator::endParamList() { t << "</dl>"; } void HtmlGenerator::printDoc(DocNode *n) { HtmlDocVisitor *visitor = new HtmlDocVisitor(t,*this); n->accept(visitor); delete visitor; } static void startQuickIndexItem(QTextStream &t,const char *l, bool hl,bool compact,bool &first) { if (!first && compact) t << " | "; first=FALSE; if (!compact) t << "<li>"; if (hl && compact) { t << "<a class=\"qindexHL\" "; } else { t << "<a class=\"qindex\" "; } t << "href=\"" << l << "\">"; } static void endQuickIndexItem(QTextStream &t) { t << "</a>"; } static QCString fixSpaces(const QCString &s) { return substitute(s," "," "); } static void writeDefaultQuickLinks(QTextStream &t,bool compact,HighlightedItem hli) { bool first=TRUE; if (compact) { t << "<div class=\"qindex\">"; } else { t << "<ul>"; } if (Config_getBool("SEARCHENGINE")) { t << " <form class=\"search\" action=\"search.php\" method=\"get\">\n"; } if (Config_getBool("GENERATE_TREEVIEW")) { startQuickIndexItem(t,"main"+Doxygen::htmlFileExtension, hli==HLI_Main,compact,first); } else { startQuickIndexItem(t,"index"+Doxygen::htmlFileExtension, hli==HLI_Main,compact,first); } t << fixSpaces(theTranslator->trMainPage()); endQuickIndexItem(t); if (documentedGroups>0) { startQuickIndexItem(t,"modules"+Doxygen::htmlFileExtension, hli==HLI_Modules,compact,first); t << fixSpaces(theTranslator->trModules()); endQuickIndexItem(t); } if (documentedNamespaces>0) { startQuickIndexItem(t,"namespaces"+Doxygen::htmlFileExtension, hli==HLI_Namespaces,compact,first); if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) { t << fixSpaces(theTranslator->trPackages()); } else { t << theTranslator->trNamespaceList(); } endQuickIndexItem(t); } if (hierarchyClasses>0) { startQuickIndexItem(t,"hierarchy"+Doxygen::htmlFileExtension, hli==HLI_Hierarchy,compact,first); t << fixSpaces(theTranslator->trClassHierarchy()); endQuickIndexItem(t); } if (annotatedClasses>0) { if (Config_getBool("ALPHABETICAL_INDEX")) { startQuickIndexItem(t,"classes"+Doxygen::htmlFileExtension, hli==HLI_Classes,compact,first); t << fixSpaces(theTranslator->trAlphabeticalList()); endQuickIndexItem(t); } startQuickIndexItem(t,"annotated"+Doxygen::htmlFileExtension, hli==HLI_Annotated,compact,first); t << fixSpaces(theTranslator->trCompoundList()); endQuickIndexItem(t); } if (documentedHtmlFiles>0) { startQuickIndexItem(t,"files"+Doxygen::htmlFileExtension, hli==HLI_Files,compact,first); t << fixSpaces(theTranslator->trFileList()); endQuickIndexItem(t); } if (documentedNamespaceMembers[NMHL_All]>0) { startQuickIndexItem(t,"namespacemembers"+Doxygen::htmlFileExtension, hli==HLI_NamespaceMembers,compact,first); t << fixSpaces(theTranslator->trNamespaceMembers()); endQuickIndexItem(t); } if (documentedClassMembers[CMHL_All]>0) { startQuickIndexItem(t,"functions"+Doxygen::htmlFileExtension, hli==HLI_Functions,compact,first); t << fixSpaces(theTranslator->trCompoundMembers()); endQuickIndexItem(t); } if (documentedFileMembers[FMHL_All]>0) { startQuickIndexItem(t,"globals"+Doxygen::htmlFileExtension, hli==HLI_Globals,compact,first); t << fixSpaces(theTranslator->trFileMembers()); endQuickIndexItem(t); } if (indexedPages>0) { startQuickIndexItem(t,"pages"+Doxygen::htmlFileExtension, hli==HLI_Pages,compact,first); t << fixSpaces(theTranslator->trRelatedPages()); endQuickIndexItem(t); } if (Doxygen::exampleSDict->count()>0) { startQuickIndexItem(t,"examples"+Doxygen::htmlFileExtension, hli==HLI_Examples,compact,first); t << fixSpaces(theTranslator->trExamples()); endQuickIndexItem(t); } if (Config_getBool("SEARCHENGINE")) { if (compact) { t << " | "; } else { t << "<li>"; } t << "<span class=\"search"; if (hli==HLI_Search) t << "HL"; QCString searchFor = fixSpaces(theTranslator->trSearchForIndex()); if (searchFor.at(0)=='S') searchFor="<u>S</u>"+searchFor.mid(1); t << "\">" << searchFor << " "; if (hli!=HLI_Search) { t << "<input class=\"search\" type=\"text\" name=\"query\" value=\"\" size=\"20\" accesskey=\"s\"/>" "</span></form>"; } } if (hli!=HLI_Search) { if (compact) { t << "</div>\n"; } else { t << "</ul>\n"; } } } void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli) { writeDefaultQuickLinks(t,compact,hli); } void HtmlGenerator::writeSearchPage() { if (Config_getBool("SEARCHENGINE") && Config_getBool("GENERATE_HTML")) { QCString fileName = Config_getString("HTML_OUTPUT")+"/search.php"; QFile f(fileName); if (f.open(IO_WriteOnly)) { QTextStream t(&f); if (g_header.isEmpty()) { writeDefaultHeaderFile(t,"Search"); } else { t << substituteKeywords(g_header,"Search"); } t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " << versionString << " -->" << endl; writeDefaultQuickLinks(t,TRUE,HLI_Search); t << "<?php \n\n"; t << "function search_results()\n"; t << "{\n"; t << " return \"" << theTranslator->trSearchResultsTitle() << "\";\n"; t << "}\n"; t << "\n"; t << "function matches_text($num)\n"; t << "{\n"; t << " if ($num==0)\n"; t << " {\n"; t << " return \"" << theTranslator->trSearchResults(0) << "\";\n"; t << " }\n"; t << " else if ($num==1)\n"; t << " {\n"; t << " return \"" << theTranslator->trSearchResults(1) << "\";\n"; t << " }\n"; t << " else // $num>1\n"; t << " {\n"; t << " return \"" << theTranslator->trSearchResults(2) << "\";\n"; t << " }\n"; t << "}\n"; t << "\n"; t << "function report_matches()\n"; t << "{\n"; t << " return \"" << theTranslator->trSearchMatches() << " \";\n"; t << "}\n"; t << "\n"; t << search_script; t << "\n"; t << "?>\n"; writePageFooter(t,"Search"); } } }