/****************************************************************************** * * * * Copyright (C) 1997-2014 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 #include #include #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 "searchindex.h" #include "pagedef.h" #include "debug.h" #include "dirdef.h" #include "vhdldocgen.h" #include "layout.h" #include "image.h" #include "ftvhelp.h" #include "bufstr.h" #include "resourcemgr.h" //#define DBG_HTML(x) x; #define DBG_HTML(x) static QCString g_header; static QCString g_footer; static QCString g_mathjax_code; static void writeClientSearchBox(FTextStream &t,const char *relPath) { t << "
\n"; t << " \n"; t << " \"\"/\n"; t << " trSearch() << "\" accesskey=\"S\"\n"; t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n"; t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n"; t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n"; t << " \n"; t << " " << "\"\"/\n"; t << " \n"; t << "
\n"; } static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch) { static bool externalSearch = Config_getBool("EXTERNAL_SEARCH"); t << "
\n"; t << "
\n"; t << "
\n"; t << " \"\"/\n"; if (!highlightSearch) { t << " trSearch() << "\" size=\"20\" accesskey=\"S\" \n"; t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n"; t << " onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n"; t << "
\n"; t << "
\n"; t << "
\n"; } } //------------------------------------------------------------------------ /// Clear a text block \a s from \a begin to \a end markers QCString clearBlock(const char *s,const char *begin,const char *end) { if (s==0 || begin==0 || end==0) return s; const char *p, *q; int beginLen = qstrlen(begin); int endLen = qstrlen(end); int resLen = 0; for (p=s; (q=strstr(p,begin))!=0; p=q+endLen) { resLen+=(int)(q-p); p=q+beginLen; if ((q=strstr(p,end))==0) { resLen+=beginLen; break; } } resLen+=qstrlen(p); // resLen is the length of the string without the marked block QCString result(resLen+1); char *r; for (r=result.data(), p=s; (q=strstr(p,begin))!=0; p=q+endLen) { int l = (int)(q-p); memcpy(r,p,l); r+=l; p=q+beginLen; if ((q=strstr(p,end))==0) { memcpy(r,begin,beginLen); r+=beginLen; break; } } qstrcpy(r,p); return result; } //---------------------------------------------------------------------- QCString selectBlock(const QCString& s,const QCString &name,bool enable) { // TODO: this is an expensive function that is called a lot -> optimize it const QCString begin = ""; const QCString end = ""; const QCString nobegin = ""; const QCString noend = ""; QCString result = s; if (enable) { result = substitute(result, begin, ""); result = substitute(result, end, ""); result = clearBlock(result, nobegin, noend); } else { result = substitute(result, nobegin, ""); result = substitute(result, noend, ""); result = clearBlock(result, begin, end); } return result; } static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch) { QGString result; FTextStream t(&result); if (serverSide) { writeServerSearchBox(t, relPath, highlightSearch); } else { writeClientSearchBox(t, relPath); } return QCString(result); } static QCString removeEmptyLines(const QCString &s) { BufStr out(s.length()+1); char *p=s.data(); if (p) { char c; while ((c=*p++)) { if (c=='\n') { char *e = p; while (*e==' ' || *e=='\t') e++; if (*e=='\n') { p=e; } else out.addChar(c); } else { out.addChar(c); } } } out.addChar('\0'); //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data()); return out.data(); } static QCString substituteHtmlKeywords(const QCString &s, const QCString &title, const QCString &relPath, const QCString &navPath=QCString()) { // Build CSS/Javascript tags depending on treeview, search engine settings QCString cssFile; QStrList extraCssFile; QCString generatedBy; QCString treeViewCssJs; QCString searchCssJs; QCString searchBox; QCString mathJaxJs; QCString extraCssText; static QCString projectName = Config_getString("PROJECT_NAME"); static bool timeStamp = Config_getBool("HTML_TIMESTAMP"); static bool treeView = Config_getBool("GENERATE_TREEVIEW"); static bool searchEngine = Config_getBool("SEARCHENGINE"); static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); static bool mathJax = Config_getBool("USE_MATHJAX"); static QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT"); static bool disableIndex = Config_getBool("DISABLE_INDEX"); static bool hasProjectName = !projectName.isEmpty(); static bool hasProjectNumber = !Config_getString("PROJECT_NUMBER").isEmpty(); static bool hasProjectBrief = !Config_getString("PROJECT_BRIEF").isEmpty(); static bool hasProjectLogo = !Config_getString("PROJECT_LOGO").isEmpty(); static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine)); cssFile = Config_getString("HTML_STYLESHEET"); if (cssFile.isEmpty()) { cssFile = "doxygen.css"; } else { QFileInfo cssfi(cssFile); if (cssfi.exists()) { cssFile = cssfi.fileName().utf8(); } else { cssFile = "doxygen.css"; } } extraCssText = ""; extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET"); for (uint i=0; i\n"; } } } if (timeStamp) { generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString("PROJECT_NAME"))); } else { generatedBy = theTranslator->trGeneratedBy(); } if (treeView) { treeViewCssJs = "\n" "\n" "\n" "\n" ""; } if (searchEngine) { searchCssJs = "\n"; if (!serverBasedSearch) { searchCssJs += "\n"; } searchCssJs += "\n"; if (!serverBasedSearch) { searchCssJs += ""; } else { searchCssJs += "\n"; // OPENSEARCH_PROVIDER { searchCssJs += ""; // OPENSEARCH_PROVIDER } } searchBox = getSearchBox(serverBasedSearch, relPath, FALSE); } if (mathJax) { QCString path = Config_getString("MATHJAX_RELPATH"); if (!path.isEmpty() && path.at(path.length()-1)!='/') { path+="/"; } if (path.isEmpty() || path.left(2)=="..") // relative path { path.prepend(relPath); } mathJaxJs = ""; mathJaxJs += "\n"; } // first substitute generic keywords QCString result = substituteKeywords(s,title, convertToHtml(Config_getString("PROJECT_NAME")), convertToHtml(Config_getString("PROJECT_NUMBER")), convertToHtml(Config_getString("PROJECT_BRIEF"))); // additional HTML only keywords result = substitute(result,"$navpath",navPath); result = substitute(result,"$stylesheet",cssFile); result = substitute(result,"$treeview",treeViewCssJs); result = substitute(result,"$searchbox",searchBox); result = substitute(result,"$search",searchCssJs); result = substitute(result,"$mathjax",mathJaxJs); result = substitute(result,"$generatedby",generatedBy); result = substitute(result,"$extrastylesheet",extraCssText); result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only result = substitute(result,"$relpath^",relPath); //<-- must be last // additional HTML only conditional blocks result = selectBlock(result,"DISABLE_INDEX",disableIndex); result = selectBlock(result,"GENERATE_TREEVIEW",treeView); result = selectBlock(result,"SEARCHENGINE",searchEngine); result = selectBlock(result,"TITLEAREA",titleArea); result = selectBlock(result,"PROJECT_NAME",hasProjectName); result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber); result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief); result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo); result = removeEmptyLines(result); return result; } //-------------------------------------------------------------------------- HtmlCodeGenerator::HtmlCodeGenerator() : m_streamSet(FALSE), m_col(0) { } HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath) : m_col(0), m_relPath(relPath) { setTextStream(t); } void HtmlCodeGenerator::setTextStream(FTextStream &t) { m_streamSet = t.device()!=0; m_t.setDevice(t.device()); } void HtmlCodeGenerator::setRelativePath(const QCString &path) { m_relPath = path; } void HtmlCodeGenerator::codify(const char *str) { static int tabSize = Config_getInt("TAB_SIZE"); if (str && m_streamSet) { const char *p=str; char c; int spacesToNextTabStop; while (*p) { c=*p++; switch(c) { case '\t': spacesToNextTabStop = tabSize - (m_col%tabSize); m_t << Doxygen::spaces.left(spacesToNextTabStop); m_col+=spacesToNextTabStop; break; case '\n': m_t << "\n"; m_col=0; break; case '\r': break; case '<': m_t << "<"; m_col++; break; case '>': m_t << ">"; m_col++; break; case '&': m_t << "&"; m_col++; break; case '\'': m_t << "'"; m_col++; // ' is not valid XHTML break; case '"': m_t << """; m_col++; break; case '\\': if (*p=='<') { m_t << "<"; p++; } else if (*p=='>') { m_t << ">"; p++; } else m_t << "\\"; m_col++; break; default: p=writeUtf8Char(m_t,p-1); m_col++; break; } } } } void HtmlCodeGenerator::docify(const char *str) { if (str && m_streamSet) { const char *p=str; char c; while (*p) { c=*p++; switch(c) { case '<': m_t << "<"; break; case '>': m_t << ">"; break; case '&': m_t << "&"; break; case '"': m_t << """; break; case '\\': if (*p=='<') { m_t << "<"; p++; } else if (*p=='>') { m_t << ">"; p++; } else m_t << "\\"; break; default: m_t << c; } } } } void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename, const char *anchor,int l) { if (!m_streamSet) return; const int maxLineNrStr = 10; char lineNumber[maxLineNrStr]; char lineAnchor[maxLineNrStr]; qsnprintf(lineNumber,maxLineNrStr,"%5d",l); qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l); m_t << "
"; m_t << ""; if (filename) { _writeCodeLink("line",ref,filename,anchor,lineNumber,0); } else { codify(lineNumber); } m_t << ""; m_t << " "; } void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f, const char *anchor, const char *name, const char *tooltip) { if (!m_streamSet) return; //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip); _writeCodeLink("code",ref,f,anchor,name,tooltip); } void HtmlCodeGenerator::_writeCodeLink(const char *className, const char *ref,const char *f, const char *anchor, const char *name, const char *tooltip) { if (ref) { m_t << ""; docify(name); m_t << ""; m_col+=qstrlen(name); } void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo, const char *decl, const char *desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo) { m_t << "
"; m_t << "
"; if (!docInfo.url.isEmpty()) { m_t << ""; } docify(docInfo.name); if (!docInfo.url.isEmpty()) { m_t << ""; } m_t << "
"; if (decl) { m_t << "
"; docify(decl); m_t << "
"; } if (desc) { m_t << "
"; m_t << desc; // desc is already HTML escaped m_t << "
"; } if (!defInfo.file.isEmpty()) { m_t << "
Definition: "; if (!defInfo.url.isEmpty()) { m_t << ""; } m_t << defInfo.file << ":" << defInfo.line; if (!defInfo.url.isEmpty()) { m_t << ""; } m_t << "
"; } if (!declInfo.file.isEmpty()) { m_t << "
Declaration: "; if (!declInfo.url.isEmpty()) { m_t << ""; } m_t << declInfo.file << ":" << declInfo.line; if (!declInfo.url.isEmpty()) { m_t << ""; } m_t << "
"; } m_t << "
" << endl; } void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers) { if (m_streamSet) { if (!hasLineNumbers) m_t << "
"; m_col=0; } } void HtmlCodeGenerator::endCodeLine() { if (m_streamSet) m_t << "
\n"; } void HtmlCodeGenerator::startFontClass(const char *s) { if (m_streamSet) m_t << ""; } void HtmlCodeGenerator::endFontClass() { if (m_streamSet) m_t << ""; } void HtmlCodeGenerator::writeCodeAnchor(const char *anchor) { if (m_streamSet) m_t << ""; } //-------------------------------------------------------------------------- HtmlGenerator::HtmlGenerator() : OutputGenerator() { dir=Config_getString("HTML_OUTPUT"); m_emptySection=FALSE; } 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")); //printf("g_header='%s'\n",g_header.data()); } else { g_header = ResourceMgr::instance().getAsString("header.html"); } if (!Config_getString("HTML_FOOTER").isEmpty()) { g_footer=fileToString(Config_getString("HTML_FOOTER")); //printf("g_footer='%s'\n",g_footer.data()); } else { g_footer = ResourceMgr::instance().getAsString("footer.html"); } if (Config_getBool("USE_MATHJAX")) { if (!Config_getString("MATHJAX_CODEFILE").isEmpty()) { g_mathjax_code=fileToString(Config_getString("MATHJAX_CODEFILE")); //printf("g_mathjax_code='%s'\n",g_mathjax_code.data()); } } createSubDirs(d); ResourceMgr &mgr = ResourceMgr::instance(); mgr.copyResource("tabs.css",dname); mgr.copyResource("jquery.js",dname); if (Config_getBool("INTERACTIVE_SVG")) { mgr.copyResource("svgpan.js",dname); } { QFile f(dname+"/dynsections.js"); if (f.open(IO_WriteOnly)) { const Resource *res = mgr.get("dynsections.js"); FTextStream t(&f); t << (const char *)res->data; if (Config_getBool("SOURCE_BROWSER") && Config_getBool("SOURCE_TOOLTIPS")) { t << endl << "$(document).ready(function() {\n" " $('.code,.codeRef').each(function() {\n" " $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n" " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n" " });\n" "});\n"; } } } } /// Additional initialization after indices have been created void HtmlGenerator::writeTabData() { Doxygen::indexList->addStyleSheetFile("tabs.css"); QCString dname=Config_getString("HTML_OUTPUT"); ResourceMgr &mgr = ResourceMgr::instance(); //writeColoredImgData(dname,colored_tab_data); mgr.copyResource("tab_a.lum",dname); mgr.copyResource("tab_b.lum",dname); mgr.copyResource("tab_h.lum",dname); mgr.copyResource("tab_s.lum",dname); mgr.copyResource("nav_h.lum",dname); mgr.copyResource("nav_f.lum",dname); mgr.copyResource("bc_s.luma",dname); mgr.copyResource("doxygen.luma",dname); mgr.copyResource("closed.luma",dname); mgr.copyResource("open.luma",dname); mgr.copyResource("bdwn.luma",dname); mgr.copyResource("sync_on.luma",dname); mgr.copyResource("sync_off.luma",dname); //{ // unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 }; // unsigned char shadow_alpha[6] = { 80, 60, 40, 20, 10, 0 }; // ColoredImage img(1,6,shadow,shadow_alpha,0,0,100); // img.save(dname+"/nav_g.png"); //} mgr.copyResource("nav_g.png",dname); } void HtmlGenerator::writeSearchData(const char *dir) { static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); //writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data); ResourceMgr &mgr = ResourceMgr::instance(); mgr.copyResource("search_l.png",dir); Doxygen::indexList->addImageFile("search/search_l.png"); mgr.copyResource("search_m.png",dir); Doxygen::indexList->addImageFile("search/search_m.png"); mgr.copyResource("search_r.png",dir); Doxygen::indexList->addImageFile("search/search_r.png"); if (serverBasedSearch) { mgr.copyResource("mag.png",dir); Doxygen::indexList->addImageFile("search/mag.png"); } else { mgr.copyResource("close.png",dir); Doxygen::indexList->addImageFile("search/close.png"); mgr.copyResource("mag_sel.png",dir); Doxygen::indexList->addImageFile("search/mag_sel.png"); } QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search"; QFile f(searchDirName+"/search.css"); if (f.open(IO_WriteOnly)) { const Resource *res = mgr.get("search.css"); if (res) { FTextStream t(&f); QCString searchCss = replaceColorMarkers((const char *)res->data); searchCss = substitute(searchCss,"$doxygenversion",versionString); if (Config_getBool("DISABLE_INDEX")) { // move up the search box if there are no tabs searchCss = substitute(searchCss,"margin-top: 8px;","margin-top: 0px;"); } t << searchCss; Doxygen::indexList->addStyleSheetFile("search/search.css"); } } } void HtmlGenerator::writeStyleSheetFile(QFile &file) { FTextStream t(&file); t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString)); } void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/) { FTextStream t(&file); t << "" << endl; t << ResourceMgr::instance().getAsString("header.html"); } void HtmlGenerator::writeFooterFile(QFile &file) { FTextStream t(&file); t << "" << endl; t << ResourceMgr::instance().getAsString("footer.html"); } void HtmlGenerator::startFile(const char *name,const char *, const char *title) { //printf("HtmlGenerator::startFile(%s)\n",name); QCString fileName=name; lastTitle=title; relPath = relativePathToRoot(fileName); if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) { fileName+=Doxygen::htmlFileExtension; } startPlainFile(fileName); m_codeGen.setTextStream(t); m_codeGen.setRelativePath(relPath); Doxygen::indexList->addIndexFile(fileName); lastFile = fileName; t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath); t << "" << endl; //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); static bool searchEngine = Config_getBool("SEARCHENGINE"); if (searchEngine /*&& !generateTreeView*/) { t << "\n"; } //generateDynamicSections(t,relPath); m_sectionCount=0; } void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath) { static bool searchEngine = Config_getBool("SEARCHENGINE"); static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); if (searchEngine && !serverBasedSearch) { (void)relPath; t << "\n"; t << "
\n"; writeSearchCategories(t); t << "
\n"; t << "\n"; t << "\n"; t << "
\n"; t << "\n"; t << "
\n"; t << "\n"; } } void HtmlGenerator::writeSearchInfo() { writeSearchInfo(t,relPath); } QCString HtmlGenerator::writeLogoAsString(const char *path) { static bool timeStamp = Config_getBool("HTML_TIMESTAMP"); QCString result; if (timeStamp) { result += theTranslator->trGeneratedAt( dateToString(TRUE), Config_getString("PROJECT_NAME") ); } else { result += theTranslator->trGeneratedBy(); } result += " \n\n" "\"doxygen\"/ "; result += versionString; result += " "; return result; } void HtmlGenerator::writeLogo() { t << writeLogoAsString(relPath); } void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle, const QCString &relPath,const QCString &navPath) { t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath); } void HtmlGenerator::writeFooter(const char *navPath) { writePageFooter(t,lastTitle,relPath,navPath); } void HtmlGenerator::endFile() { endPlainFile(); } void HtmlGenerator::startProjectNumber() { t << "

"; } void HtmlGenerator::endProjectNumber() { t << "

"; } 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 << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString)); endPlainFile(); Doxygen::indexList->addStyleSheetFile("doxygen.css"); } else // write user defined style sheet { QCString cssname=Config_getString("HTML_STYLESHEET"); QFileInfo cssfi(cssname); if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable()) { err("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().utf8()); t << fileStr; endPlainFile(); } Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8()); } static QStrList extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET"); for (uint i=0; iaddStyleSheetFile(fi.fileName().utf8()); } } } } } void HtmlGenerator::startDoxyAnchor(const char *,const char *, const char *anchor, const char *, const char *) { t << ""; } void HtmlGenerator::endDoxyAnchor(const char *,const char *) { } //void HtmlGenerator::newParagraph() //{ // t << endl << "

" << endl; //} void HtmlGenerator::startParagraph() { t << endl << "

"; } void HtmlGenerator::endParagraph() { t << "

" << endl; } void HtmlGenerator::writeString(const char *text) { t << text; } void HtmlGenerator::startIndexListItem() { t << "
  • "; } void HtmlGenerator::endIndexListItem() { t << "
  • " << endl; } void HtmlGenerator::startIndexItem(const char *ref,const char *f) { //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f); if (ref || f) { if (ref) { t << ""; } else { t << ""; } } void HtmlGenerator::endIndexItem(const char *ref,const char *f) { //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name); if (ref || f) { t << ""; } else { t << ""; } } void HtmlGenerator::writeStartAnnoItem(const char *,const char *f, const char *path,const char *name) { t << "
  • "; if (path) docify(path); t << ""; docify(name); t << " "; } void HtmlGenerator::writeObjectLink(const char *ref,const char *f, const char *anchor, const char *name) { if (ref) { t << ""; docify(name); t << ""; } void HtmlGenerator::startTextLink(const char *f,const char *anchor) { t << ""; } void HtmlGenerator::endTextLink() { t << ""; } void HtmlGenerator::startHtmlLink(const char *url) { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); t << ""; } void HtmlGenerator::endHtmlLink() { t << ""; } void HtmlGenerator::startGroupHeader(int extraIndentLevel) { if (extraIndentLevel==2) { t << "

    "; } else if (extraIndentLevel==1) { t << "

    "; } else // extraIndentLevel==0 { t << "

    "; } } void HtmlGenerator::endGroupHeader(int extraIndentLevel) { if (extraIndentLevel==2) { t << "

    " << endl; } else if (extraIndentLevel==1) { t << "" << endl; } else { t << "" << endl; } } void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type) { switch(type) { case SectionInfo::Page: t << "\n\n

    "; break; case SectionInfo::Section: t << "\n\n

    "; break; case SectionInfo::Subsection: t << "\n\n

    "; break; case SectionInfo::Subsubsection: t << "\n\n

    "; break; case SectionInfo::Paragraph: t << "\n\n

    "; break; default: ASSERT(0); break; } t << ""; } void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type) { switch(type) { case SectionInfo::Page: t << "
    "; break; case SectionInfo::Section: t << ""; break; case SectionInfo::Subsection: t << ""; break; case SectionInfo::Subsubsection: t << ""; break; case SectionInfo::Paragraph: t << ""; break; default: ASSERT(0); break; } } void HtmlGenerator::docify(const char *str) { docify(str,FALSE); } void HtmlGenerator::docify(const char *str,bool inHtmlComment) { if (str) { const char *p=str; char c; while (*p) { c=*p++; switch(c) { case '<': t << "<"; break; case '>': t << ">"; break; case '&': t << "&"; break; case '"': t << """; break; case '-': if (inHtmlComment) t << "-"; else t << "-"; break; case '\\': if (*p=='<') { t << "<"; p++; } else if (*p=='>') { t << ">"; p++; } else t << "\\"; break; default: t << c; } } } } void HtmlGenerator::writeChar(char c) { char cs[2]; cs[0]=c; cs[1]=0; docify(cs); } //--- helper function for dynamic sections ------------------------- static void startSectionHeader(FTextStream &t, const QCString &relPath,int sectionCount) { //t << ""; static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS"); if (dynamicSections) { t << "
    " << endl; t << " \"+\"/ "; } else { t << "
    " << endl; } } static void endSectionHeader(FTextStream &t) { //t << ""; t << "
    " << endl; } static void startSectionSummary(FTextStream &t,int sectionCount) { //t << ""; static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS"); if (dynamicSections) { t << "
    " << endl; } } static void endSectionSummary(FTextStream &t) { //t << ""; static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS"); if (dynamicSections) { t << "
    " << endl; } } static void startSectionContent(FTextStream &t,int sectionCount) { //t << ""; static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS"); if (dynamicSections) { t << "
    " << endl; } else { t << "
    " << endl; } } static void endSectionContent(FTextStream &t) { //t << ""; t << "
    " << endl; } //---------------------------- void HtmlGenerator::startClassDiagram() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endClassDiagram(const ClassDiagram &d, const char *fileName,const char *name) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); t << "
    " << endl; t << " \"\"/" << endl; t << " " << endl; d.writeImage(t,dir,relPath,fileName); t << "
    "; endSectionContent(t); m_sectionCount++; } void HtmlGenerator::startMemberList() { DBG_HTML(t << "" << endl) } void HtmlGenerator::endMemberList() { DBG_HTML(t << "" << endl) } // anonymous type: // 0 = single column right aligned // 1 = double column left aligned // 2 = single column left aligned void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId) { DBG_HTML(t << "" << endl) if (m_emptySection) { t << "" << endl; m_emptySection=FALSE; } t << ""; switch(annoType) { case 0: t << ""; t << endl; } void HtmlGenerator::startMemberTemplateParams() { } void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId) { t << "" << endl; t << "
    "; break; case 1: t << ""; break; case 2: t << ""; break; default: t << ""; break; } } void HtmlGenerator::endMemberItem() { t << "
    "; } void HtmlGenerator::insertMemberAlign(bool templ) { DBG_HTML(t << "" << endl) QCString className = templ ? "memTemplItemRight" : "memItemRight"; t << " "; } void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId) { DBG_HTML(t << "" << endl) if (m_emptySection) { t << "" << endl; m_emptySection=FALSE; } t << "" << endl; } void HtmlGenerator::startMemberSections() { DBG_HTML(t << "" << endl) m_emptySection=TRUE; // we postpone writing
     "; } void HtmlGenerator::endMemberDescription() { DBG_HTML(t << "" << endl) t << "
    until we actually // write a row to prevent empty tables, which // are not valid XHTML! } void HtmlGenerator::endMemberSections() { DBG_HTML(t << "" << endl) if (!m_emptySection) { t << "
    " << endl; } } void HtmlGenerator::startMemberHeader(const char *anchor) { DBG_HTML(t << "" << endl) if (!m_emptySection) { t << "
    "; m_emptySection=TRUE; } if (m_emptySection) { t << "" << endl; m_emptySection=FALSE; } t << "" << endl; } void HtmlGenerator::startMemberSubtitle() { DBG_HTML(t << "" << endl) t << "" << endl; } void HtmlGenerator::startIndexList() { t << "

    "; if (anchor) { t << "" << endl; } } void HtmlGenerator::endMemberHeader() { DBG_HTML(t << "" << endl) t << "

    "; } void HtmlGenerator::endMemberSubtitle() { DBG_HTML(t << "" << endl) t << "
    " << endl; } void HtmlGenerator::endIndexList() { t << "
    " << endl; } void HtmlGenerator::startIndexKey() { // inserted 'class = ...', 02 jan 2002, jh t << " "; } void HtmlGenerator::endIndexKey() { t << ""; } void HtmlGenerator::startIndexValue(bool) { // inserted 'class = ...', 02 jan 2002, jh t << ""; } void HtmlGenerator::endIndexValue(const char *,bool) { t << "" << endl; } void HtmlGenerator::startMemberDocList() { DBG_HTML(t << "" << endl;) } void HtmlGenerator::endMemberDocList() { DBG_HTML(t << "" << endl;) } void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool) { DBG_HTML(t << "" << endl;) t << "\n
    " << endl; t << "
    " << endl; } void HtmlGenerator::startMemberDocPrefixItem() { DBG_HTML(t << "" << endl;) t << "
    " << endl; } void HtmlGenerator::endMemberDocPrefixItem() { DBG_HTML(t << "" << endl;) t << "
    " << endl; } void HtmlGenerator::startMemberDocName(bool /*align*/) { DBG_HTML(t << "" << endl;) t << " " << endl; t << " " << endl; t << " " << endl; } void HtmlGenerator::startParameterList(bool openBracket) { DBG_HTML(t << "" << endl;) t << " " << endl; } void HtmlGenerator::startParameterType(bool first,const char *key) { if (first) { DBG_HTML(t << "" << endl;) t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; } void HtmlGenerator::startParameterName(bool /*oneArgOnly*/) { DBG_HTML(t << "" << endl;) t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; t << " " << endl; } } void HtmlGenerator::endParameterList() { DBG_HTML(t << "" << endl;) t << "" << endl; t << " " << endl; } void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket) { DBG_HTML(t << "" << endl;) t << "" << endl; t << " " << endl; t << " " << endl; t << " " << endl; } t << "
    "; } void HtmlGenerator::endMemberDocName() { DBG_HTML(t << "" << endl;) t << ""; if (openBracket) t << "("; t << ""; } else { DBG_HTML(t << "" << endl;) t << "
    "; if (key) t << key; t << ""; } } void HtmlGenerator::endParameterType() { DBG_HTML(t << "" << endl;) t << " "; } void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket) { DBG_HTML(t << "" << endl;) if (last) { if (emptyList) { if (closeBracket) t << ")"; t << ""; } else { t << " 
    "; if (closeBracket) t << ")"; t << ""; } } else { t << "
    "; // colspan 2 so it gets both parameter type and parameter name columns if (prefix) t << prefix << "("; else if (closeBracket) t << ")"; else t << ""; } void HtmlGenerator::endMemberDoc(bool hasArgs) { DBG_HTML(t << "" << endl;) if (!hasArgs) { t << "
    " << endl; // t << "
    " << endl; } void HtmlGenerator::startDotGraph() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endDotGraph(const DotClassGraph &g) { bool generateLegend = Config_getBool("GENERATE_LEGEND"); bool umlLook = Config_getBool("UML_LOOK"); endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount); if (generateLegend && !umlLook) { t << "
    ["; startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension); t << theTranslator->trLegend(); endHtmlLink(); t << "]
    "; } endSectionContent(t); m_sectionCount++; } void HtmlGenerator::startInclDepGraph() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount); endSectionContent(t); m_sectionCount++; } void HtmlGenerator::startGroupCollaboration() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount); endSectionContent(t); m_sectionCount++; } void HtmlGenerator::startCallGraph() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endCallGraph(const DotCallGraph &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount); endSectionContent(t); m_sectionCount++; } void HtmlGenerator::startDirDepGraph() { startSectionHeader(t,relPath,m_sectionCount); } void HtmlGenerator::endDirDepGraph(const DotDirDeps &g) { endSectionHeader(t); startSectionSummary(t,m_sectionCount); endSectionSummary(t); startSectionContent(t,m_sectionCount); g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount); endSectionContent(t); m_sectionCount++; } void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g) { g.writeGraph(t,dir,fileName); } void HtmlGenerator::startMemberGroupHeader(bool) { t << "
    "; } void HtmlGenerator::endMemberGroupHeader() { t << "
    " << endl; } void HtmlGenerator::startMemberGroupDocs() { t << "
    "; } void HtmlGenerator::endMemberGroupDocs() { t << "
    " << endl; } void HtmlGenerator::startMemberGroup() { } void HtmlGenerator::endMemberGroup(bool) { } void HtmlGenerator::startIndent() { DBG_HTML(t << "" << endl;) t << "
    \n"; } void HtmlGenerator::endIndent() { DBG_HTML(t << "" << endl;) t << endl << "
    " << endl << "
    " << endl; } void HtmlGenerator::addIndexItem(const char *,const char *) { } void HtmlGenerator::writeNonBreakableSpace(int n) { int i; for (i=0;i
    "; if (filename) { writeObjectLink(0,filename,anchor,title); } else { docify(title); } t << "
    "; } void HtmlGenerator::endSimpleSect() { t << ""; } void HtmlGenerator::startParamList(ParamListTypes, const char *title) { t << "
    "; docify(title); t << "
    "; } void HtmlGenerator::endParamList() { t << "
    "; } void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *) { HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx); n->accept(visitor); delete visitor; } //---------------- helpers for index generation ----------------------------- static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE) { if (compact) { if (topLevel) { t << "
    \n"; } else { t << "
    \n"; } t << "
      \n"; } else { t << "
        "; } } static void endQuickIndexList(FTextStream &t,bool compact) { if (compact) { t << "
      \n"; t << "
    \n"; } else { t << "\n"; } } static void startQuickIndexItem(FTextStream &t,const char *l, bool hl,bool /*compact*/, const QCString &relPath) { t << " "; if (l) t << ""; t << ""; } static void endQuickIndexItem(FTextStream &t,const char *l) { t << ""; if (l) t << ""; t << "
  • \n"; } static QCString fixSpaces(const QCString &s) { return substitute(s," "," "); } static bool quickLinkVisible(LayoutNavEntry::Kind kind) { static bool showFiles = Config_getBool("SHOW_FILES"); static bool showNamespaces = Config_getBool("SHOW_NAMESPACES"); switch (kind) { case LayoutNavEntry::MainPage: return TRUE; case LayoutNavEntry::User: return TRUE; case LayoutNavEntry::UserGroup: return TRUE; case LayoutNavEntry::Pages: return indexedPages>0; case LayoutNavEntry::Modules: return documentedGroups>0; case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; case LayoutNavEntry::Classes: return annotatedClasses>0; case LayoutNavEntry::ClassList: return annotatedClasses>0; case LayoutNavEntry::ClassIndex: return annotatedClasses>0; case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0; case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; //case LayoutNavEntry::Dirs: return documentedDirs>0; case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; } return FALSE; } static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root) { QListIterator li(root->children()); LayoutNavEntry *entry; int count=0; for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) count++; } if (count>0) // at least one item is visible { startQuickIndexList(t,FALSE); for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) { QCString url = entry->url(); t << "
  • "; t << fixSpaces(entry->title()); t << "\n"; // recursive into child list renderQuickLinksAsTree(t,relPath,entry); t << "
  • "; } } endQuickIndexList(t,FALSE); } } static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath, LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind, bool highlightParent,bool highlightSearch) { if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry { renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch); } if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry { bool topLevel = hlEntry->parent()->parent()==0; QListIterator li(hlEntry->parent()->children()); LayoutNavEntry *entry; int count=0; for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) count++; } if (count>0) // at least one item is visible { startQuickIndexList(t,TRUE,topLevel); for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) { QCString url = entry->url(); startQuickIndexItem(t,url, entry==hlEntry && (entry->children().count()>0 || (entry->kind()==kind && !highlightParent) ), TRUE,relPath); t << fixSpaces(entry->title()); endQuickIndexItem(t,url); } } if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box { static bool searchEngine = Config_getBool("SEARCHENGINE"); static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH"); if (searchEngine) { t << "
  • \n"; if (!serverBasedSearch) // pure client side search { writeClientSearchBox(t,relPath); t << "
  • \n"; } else // server based search { writeServerSearchBox(t,relPath,highlightSearch); if (!highlightSearch) { t << " \n"; } } } if (!highlightSearch) // on the search page the index will be ended by the // page itself { endQuickIndexList(t,TRUE); } } else // normal case for other rows than first one { endQuickIndexList(t,TRUE); } } } } static void writeDefaultQuickLinks(FTextStream &t,bool compact, HighlightedItem hli, const char *file, const QCString &relPath) { LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry(); LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1; LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file bool highlightParent=FALSE; switch (hli) // map HLI enums to LayoutNavEntry::Kind enums { case HLI_Main: kind = LayoutNavEntry::MainPage; break; case HLI_Modules: kind = LayoutNavEntry::Modules; break; //case HLI_Directories: kind = LayoutNavEntry::Dirs; break; case HLI_Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break; case HLI_Hierarchy: kind = LayoutNavEntry::ClassHierarchy; break; case HLI_Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break; case HLI_Annotated: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break; case HLI_Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break; case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break; case HLI_Functions: kind = LayoutNavEntry::ClassMembers; break; case HLI_Globals: kind = LayoutNavEntry::FileGlobals; break; case HLI_Pages: kind = LayoutNavEntry::Pages; break; case HLI_Examples: kind = LayoutNavEntry::Examples; break; case HLI_UserGroup: kind = LayoutNavEntry::UserGroup; break; case HLI_ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; highlightParent = TRUE; break; case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; highlightParent = TRUE; break; case HLI_FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; highlightParent = TRUE; break; case HLI_None: break; case HLI_Search: break; } if (compact) { // find highlighted index item LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0); if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; } if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index... { highlightParent=TRUE; hlEntry = root->children().getFirst(); if (hlEntry==0) { return; // argl, empty index! } } if (kind==LayoutNavEntry::UserGroup) { LayoutNavEntry *e = hlEntry->children().getFirst(); if (e) { hlEntry = e; } } renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search); } else { renderQuickLinksAsTree(t,relPath,root); } } void HtmlGenerator::endQuickIndices() { t << "
    " << endl; } QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath) { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); QCString result; // write split bar if (generateTreeView) { result = QCString( "
    \n" "
    \n" "
    \n" "
    \n" "
    \n" "
    \n" "
    \n" "
    \n" "
    \n" "\n" "
    \n"); } return result; } void HtmlGenerator::writeSplitBar(const char *name) { t << writeSplitBarAsString(name,relPath); } void HtmlGenerator::writeNavigationPath(const char *s) { t << substitute(s,"$relpath^",relPath); } void HtmlGenerator::startContents() { t << "
    " << endl; } void HtmlGenerator::endContents() { t << "
    " << endl; } void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file) { writeDefaultQuickLinks(t,compact,hli,file,relPath); } // PHP based search script void HtmlGenerator::writeSearchPage() { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); static bool disableIndex = Config_getBool("DISABLE_INDEX"); static QCString projectName = Config_getString("PROJECT_NAME"); static QCString htmlOutput = Config_getString("HTML_OUTPUT"); // OPENSEARCH_PROVIDER { QCString configFileName = htmlOutput+"/search_config.php"; QFile cf(configFileName); if (cf.open(IO_WriteOnly)) { FTextStream t(&cf); t << "\n"; } ResourceMgr::instance().copyResource("search_functions.php",htmlOutput); ResourceMgr::instance().copyResource("search_opensearch.php",htmlOutput); // OPENSEARCH_PROVIDER } QCString fileName = htmlOutput+"/search.php"; QFile f(fileName); if (f.open(IO_WriteOnly)) { FTextStream t(&f); t << substituteHtmlKeywords(g_header,"Search",""); t << "" << endl; t << "\n"; if (!Config_getBool("DISABLE_INDEX")) { writeDefaultQuickLinks(t,TRUE,HLI_Search,0,""); } else { t << "
    " << endl; } t << "\n"; // Write empty navigation path, to make footer connect properly if (generateTreeView) { t << "\n"; //t << "
    \n"; //t << "
      \n"; } writePageFooter(t,"Search","",""); } QCString scriptName = htmlOutput+"/search/search.js"; QFile sf(scriptName); if (sf.open(IO_WriteOnly)) { FTextStream t(&sf); t << ResourceMgr::instance().getAsString("extsearch.js"); } else { err("Failed to open file '%s' for writing...\n",scriptName.data()); } } void HtmlGenerator::writeExternalSearchPage() { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension; QFile f(fileName); if (f.open(IO_WriteOnly)) { FTextStream t(&f); t << substituteHtmlKeywords(g_header,"Search",""); t << "" << endl; t << "\n"; if (!Config_getBool("DISABLE_INDEX")) { writeDefaultQuickLinks(t,TRUE,HLI_Search,0,""); t << " \n"; t << " \n"; t << "
    \n"; t << " \n"; t << " \n"; t << " \n"; t << " \n"; t << "\n"; } else { t << "" << endl; } t << writeSplitBarAsString("search",""); t << "
    " << endl; t << "
    " << endl; t << "
    " << theTranslator->trSearchResultsTitle() << "
    " << endl; t << "
    " << endl; t << "
    " << endl; t << "
    " << endl; t << "
    " << endl; t << "
    " << endl; if (generateTreeView) { t << "" << endl; } writePageFooter(t,"Search","",""); } QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js"; QFile sf(scriptName); if (sf.open(IO_WriteOnly)) { FTextStream t(&sf); t << "var searchResultsText=[" << "\"" << theTranslator->trSearchResults(0) << "\"," << "\"" << theTranslator->trSearchResults(1) << "\"," << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl; t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl; t << "var tagMap = {" << endl; bool first=TRUE; // add search mappings QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS"); char *ml=extraSearchMappings.first(); while (ml) { QCString mapLine = ml; int eqPos = mapLine.find('='); if (eqPos!=-1) // tag command contains a destination { QCString tagName = mapLine.left(eqPos).stripWhiteSpace(); QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace(); if (!tagName.isEmpty()) { if (!first) t << "," << endl; t << " \"" << tagName << "\": \"" << destName << "\""; first=FALSE; } } ml=extraSearchMappings.next(); } if (!first) t << endl; t << "};" << endl << endl; t << ResourceMgr::instance().getAsString("extsearch.js"); t << endl; t << "$(document).ready(function() {" << endl; t << " var query = trim(getURLParameter('query'));" << endl; t << " if (query) {" << endl; t << " searchFor(query,0,20);" << endl; t << " } else {" << endl; t << " var results = $('#results');" << endl; t << " results.html('

    " << theTranslator->trSearchResults(0) << "

    ');" << endl; t << " }" << endl; t << "});" << endl; } else { err("Failed to open file '%s' for writing...\n",scriptName.data()); } } void HtmlGenerator::startConstraintList(const char *header) { t << "
    " << endl; t << "
    " << header << "
    " << endl; t << "" << endl; } void HtmlGenerator::startConstraintParam() { t << ""; } void HtmlGenerator::startConstraintType() { t << ""; } void HtmlGenerator::startConstraintDocs() { t << "" << endl; } void HtmlGenerator::endConstraintList() { t << "
    "; } void HtmlGenerator::endConstraintParam() { t << " :"; } void HtmlGenerator::endConstraintType() { t << " "; } void HtmlGenerator::endConstraintDocs() { t << "
    " << endl; t << "
    " << endl; t << "
    " << endl; } void HtmlGenerator::lineBreak(const char *style) { if (style) { t << "
    " << endl; } else { t << "
    " << endl; } } void HtmlGenerator::startHeaderSection() { t << "
    " << endl; } void HtmlGenerator::startTitleHead(const char *) { t << "
    " << endl; startTitle(); } void HtmlGenerator::endTitleHead(const char *,const char *) { endTitle(); t << "
    " << endl; } void HtmlGenerator::endHeaderSection() { t << "
    " << endl; } void HtmlGenerator::startInlineHeader() { if (m_emptySection) { t << "" << endl; m_emptySection=FALSE; } t << "" << endl; } void HtmlGenerator::startMemberDocSimple() { DBG_HTML(t << "" << endl;) t << "

    "; } void HtmlGenerator::endInlineHeader() { t << "

    " << endl; t << "" << endl; } void HtmlGenerator::endMemberDocSimple() { DBG_HTML(t << "" << endl;) t << "
    " << theTranslator->trCompoundMembers() << "
    " << endl; } void HtmlGenerator::startInlineMemberType() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::endInlineMemberType() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::startInlineMemberName() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::endInlineMemberName() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::startInlineMemberDoc() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::endInlineMemberDoc() { DBG_HTML(t << "" << endl;) t << "" << endl; } void HtmlGenerator::startLabels() { DBG_HTML(t << "" << endl;) t << ""; } void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/) { DBG_HTML(t << "" << endl;) //t << "[" << l << "]"; //if (!isLast) t << ", "; t << "" << l << ""; } void HtmlGenerator::endLabels() { DBG_HTML(t << "" << endl;) t << ""; } void HtmlGenerator::writeInheritedSectionTitle( const char *id, const char *ref, const char *file, const char *anchor, const char *title, const char *name) { DBG_HTML(t << "" << endl;) QCString a = anchor; if (!a.isEmpty()) a.prepend("#"); QCString classLink = QCString("")+convertToHtml(name,FALSE)+""; t << "" << "" << "\"-\"/ " << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink) << "" << endl; } void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first) { if (first) { t << "
    \n"; } else { t << " |\n"; } t << ""; t << title; t << ""; } void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId) { t << " \n"; } void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile) { if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile); } } void HtmlGenerator::addWord(const char *word,bool hiPriority) { if (Doxygen::searchIndex) { Doxygen::searchIndex->addWord(word,hiPriority); } }