Index: src/translator_fa.h =================================================================== --- src/translator_fa.h (revision 642) +++ src/translator_fa.h (working copy) @@ -32,7 +32,7 @@ #define HtmlDivEnd QCString("") -class TranslatorPersian : public Translator +class TranslatorPersian : public TranslatorAdapter_1_5_4 { public: Index: src/translator_fi.h =================================================================== --- src/translator_fi.h (revision 642) +++ src/translator_fi.h (working copy) @@ -78,7 +78,7 @@ #ifndef TRANSLATOR_FI_H #define TRANSLATOR_FI_H -class TranslatorFinnish : public Translator +class TranslatorFinnish : public TranslatorAdapter_1_5_4 { public: /*! This method is used to generate a warning message to signal Index: src/translatordecoder.h =================================================================== --- src/translatordecoder.h (revision 642) +++ src/translatordecoder.h (working copy) @@ -707,7 +707,15 @@ QCString trTypeConstraints() { return toUtf8(m_translator->trTypeConstraints()); } + QCString trDefineLocalSearch() + { return toUtf8(m_translator->trDefineLocalSearch()); } + QCString trUseWebServer() + { return toUtf8(m_translator->trUseWebServer()); } + QCString trLocalSearchResults(int numDocuments) + { return toUtf8(m_translator->trLocalSearchResults(numDocuments)); } + + ////////////////////////////////////////////////////////////////////////// private: Translator *m_translator; Index: src/translator_hr.h =================================================================== --- src/translator_hr.h (revision 642) +++ src/translator_hr.h (working copy) @@ -71,7 +71,7 @@ #ifndef TRANSLATOR_HR_H #define TRANSLATOR_HR_H -class TranslatorCroatian : public Translator +class TranslatorCroatian : public TranslatorAdapter_1_5_4 { private: /*! to avoid macro redefinition from translator_cz.h */ Index: src/translator.h =================================================================== --- src/translator.h (revision 642) +++ src/translator.h (working copy) @@ -1,12 +1,12 @@ /****************************************************************************** * - * * + * * Copyright (C) 1997-2008 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 + * 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. * @@ -35,35 +35,35 @@ protected: /*! Returns the string converted from windows-1250 to iso-8859-2. */ QCString Win1250ToISO88592(const QCString & sInput); - + /*! Returns the string converted from iso-8859-2 to windows-1250. */ QCString ISO88592ToWin1250(const QCString & sInput); - + /*! Returns the string converted from koi8-r to windows-1251. */ QCString Koi8RToWindows1251( const QCString & sInput ); /*! Returns the string converted from windows-1251 to koi8-r. */ QCString Windows1251ToKoi8R( const QCString & sInput ); - + /*! Returns the string converted from Japanese-EUC to SJIS. */ QCString JapaneseEucToSjis( const QCString & sInput ); public: /*! This method is used to provide warning message that is displayed - * if the user chooses a language whose translation is not up to date. + * if the user chooses a language whose translation is not up to date. * It is implemented by the adapter classes. */ virtual QCString updateNeededMessage() { return ""; } virtual ~Translator() {} - + // Please, have a look at comments inside the translator_en.h file // to learn the meaning of the following methods. The translator_en.h - // file contains the TranslatorEnglish implementation, which is + // file contains the TranslatorEnglish implementation, which is // always up-to-date (by definition). - + // --- Language control methods ------------------- - + virtual QCString idLanguage() = 0; virtual QCString latexLanguageSupportCommand() = 0; virtual QCString idLanguageCharset() = 0; @@ -109,14 +109,14 @@ virtual QCString trRelatedPagesDescription() = 0; virtual QCString trModulesDescription() = 0; //virtual QCString trNoDescriptionAvailable() = 0; - - // index titles (the project name is prepended for these) + // index titles (the project name is prepended for these) + virtual QCString trDocumentation() = 0; virtual QCString trModuleIndex() = 0; virtual QCString trHierarchicalIndex() = 0; virtual QCString trCompoundIndex() = 0; - virtual QCString trFileIndex() = 0; + virtual QCString trFileIndex() = 0; virtual QCString trModuleDocumentation() = 0; virtual QCString trClassDocumentation() = 0; virtual QCString trFileDocumentation() = 0; @@ -155,17 +155,17 @@ ////////////////////////////////////////////////////////////////////////// // new since 0.49-990307 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trNamespaceList() = 0; virtual QCString trNamespaceListDescription(bool extractAll) = 0; virtual QCString trFriends() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 0.49-990405 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trRelatedFunctionDocumentation() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 0.49-990425 ////////////////////////////////////////////////////////////////////////// @@ -176,7 +176,7 @@ virtual QCString trFileReference(const char *fileName) = 0; virtual QCString trNamespaceReference(const char *namespaceName) = 0; - + virtual QCString trPublicMembers() = 0; virtual QCString trPublicSlots() = 0; virtual QCString trSignals() = 0; @@ -256,7 +256,7 @@ ////////////////////////////////////////////////////////////////////////// // new since 1.1.0 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trNote() = 0; virtual QCString trPublicTypes() = 0; virtual QCString trPublicAttribs() = 0; @@ -284,7 +284,7 @@ virtual QCString trAttention() = 0; virtual QCString trInclByDepGraph() = 0; virtual QCString trSince() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.1.5 ////////////////////////////////////////////////////////////////////////// @@ -292,11 +292,11 @@ virtual QCString trLegendTitle() = 0; virtual QCString trLegendDocs() = 0; virtual QCString trLegend() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.2.0 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trTest() = 0; virtual QCString trTestList() = 0; @@ -325,11 +325,11 @@ virtual QCString trPackages() = 0; //virtual QCString trPackageDocumentation() = 0; virtual QCString trDefineValue() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.2.5 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trBug() = 0; virtual QCString trBugList() = 0; @@ -340,7 +340,7 @@ virtual QCString trRTFansicp() = 0; virtual QCString trRTFCharSet() = 0; virtual QCString trRTFGeneralIndex() = 0; - + // Translation of the word virtual QCString trClass(bool first_capital, bool singular) = 0; @@ -355,7 +355,7 @@ ////////////////////////////////////////////////////////////////////////// // new since 1.2.7 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trAuthor(bool first_capital, bool singular) = 0; ////////////////////////////////////////////////////////////////////////// @@ -370,7 +370,7 @@ virtual QCString trImplementedFromList(int numEntries) = 0; virtual QCString trImplementedInList(int numEntries) = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.2.16 ////////////////////////////////////////////////////////////////////////// @@ -382,7 +382,7 @@ ////////////////////////////////////////////////////////////////////////// virtual QCString trDeprecatedList() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.2.18 ////////////////////////////////////////////////////////////////////////// @@ -399,7 +399,7 @@ virtual QCString trStaticPackageMembers() = 0; virtual QCString trPackageAttribs() = 0; virtual QCString trStaticPackageAttribs() = 0; - + ////////////////////////////////////////////////////////////////////////// // new since 1.3.1 ////////////////////////////////////////////////////////////////////////// @@ -414,6 +414,7 @@ virtual QCString trSearchForIndex() = 0; virtual QCString trSearchResultsTitle() = 0; virtual QCString trSearchResults(int numDocuments) = 0; + virtual QCString trLocalSearchResults(int numDocuments) = 0; virtual QCString trSearchMatches() = 0; ////////////////////////////////////////////////////////////////////////// @@ -442,14 +443,14 @@ ////////////////////////////////////////////////////////////////////////// // new since 1.4.6 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trCallerGraph() = 0; virtual QCString trEnumerationValueDocumentation() = 0; ////////////////////////////////////////////////////////////////////////// // new since 1.5.4 ////////////////////////////////////////////////////////////////////////// - + virtual QCString trMemberFunctionDocumentationFortran() = 0; virtual QCString trCompoundListFortran() = 0; virtual QCString trCompoundMembersFortran() = 0; @@ -476,6 +477,10 @@ virtual QCString trSubprogram(bool first_capital, bool singular) = 0; virtual QCString trTypeConstraints() = 0; + virtual QCString trDefineLocalSearch() = 0; + + virtual QCString trUseWebServer() = 0; + }; #endif Index: src/searchindex.h =================================================================== --- src/searchindex.h (revision 642) +++ src/searchindex.h (working copy) @@ -59,6 +59,7 @@ SearchIndex(); void setCurrentDoc(const char *name,const char *baseName,const char *anchor=0); void addWord(const char *word,bool hiPriority); + void writeJavaScriptIndex(const char *file); void write(const char *file); private: QDict m_words; Index: src/translator_cn.h =================================================================== --- src/translator_cn.h (revision 642) +++ src/translator_cn.h (working copy) @@ -24,7 +24,7 @@ */ #define CN_SPC -class TranslatorChinese : public Translator +class TranslatorChinese : public TranslatorAdapter_1_5_4 { public: /*! Used for identification of the language. The identification Index: src/libdoxygen.t =================================================================== --- src/libdoxygen.t (revision 642) +++ src/libdoxygen.t (working copy) @@ -108,6 +108,15 @@ search_php.h: search.php cat search.php | $(TO_C_CMD) >search_php.h +local-search_js.h: local-search.js + cat local-search.js | $(TO_C_CMD) >local-search_js.h + +choose-search_js.h: choose-search.js + cat choose-search.js | $(TO_C_CMD) > choose-search_js.h + +local-search-globals_js.h: local-search-globals.js + cat local-search-globals.js | $(TO_C_CMD) > local-search-globals_js.h + doxygen_css.h: doxygen.css cat doxygen.css | $(TO_C_CMD) >doxygen_css.h Index: src/translator_mk.h =================================================================== --- src/translator_mk.h (revision 642) +++ src/translator_mk.h (working copy) @@ -32,7 +32,7 @@ #ifndef TRANSLATOR_MK_H #define TRANSLATOR_MK_H -class TranslatorMacedonian : public Translator +class TranslatorMacedonian : public TranslatorAdapter_1_5_4 { public: Index: src/libdoxygen.pro.in =================================================================== --- src/libdoxygen.pro.in (revision 642) +++ src/libdoxygen.pro.in (working copy) @@ -1,6 +1,6 @@ # -# # +# # Copyright (C) 1997-2008 by Dimitri van Heesch. # # Permission to use, copy, modify, and distribute this software and its @@ -62,6 +62,9 @@ latexdocvisitor.h \ latexgen.h \ lockingptr.h \ + local-search_js.h \ + choose-search_js.h \ + local-search-globals_js.h \ logos.h \ mandocvisitor.h \ mangen.h \ Index: src/local-search.js =================================================================== --- src/local-search.js (revision 0) +++ src/local-search.js (revision 0) @@ -0,0 +1,560 @@ +/*! local-search.js + * Searches a Doxygen index file and displays matching pages, + * on a local filing system without HTTP. + * + * @author Mitchell Fraser + * + */ + + +/* give the short names used to reduce the size of + local-search-index.js more meaningful names */ +var theIndex = x; + +var words = w; + +var urls = u; + +function computeIndex(word) +{ + + // Simple hashing that allows for substring search + if (word.length <2) return -1; + // high char of the index + hi = word.charCodeAt(0); + if (hi == 0) return -1; + // low char of the index + lo = word.charCodeAt(1); + if (lo==0) return -1; + + + return hi*256+lo; +} + + +function getParam( param ) +{ + //function copied from + //http://www.netlobo.com/url_query_string_javascript.html + // use permitted by comment in + // http://www.netlobo.com/comments/url_query_string_javascript + + param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + + var regexS = "[\\?&]" + param + "=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( window.location.href ); + if( results == null ) + return ""; + else + return results[1]; +} + + +var g_header; + +var g_footer; + +var g_top; + +var scriptElements; + +function stringOf(obj) +{ + var theString = ""; + var attr; + for (attr in obj) + { + theString += attr + " : " + obj[attr] + "\n"; + } + return theString + +} + + +function saveHeader() +{ + headerElem = document.getElementsByTagName("head")[0]; + if (null == headerElem) + g_header = "Error, could not find \"head\" element."; + else + { + //we replace the "local-search-index.js" with "" + // to avoid loading and parsing the index again + g_header = (headerElem.innerHTML).replace("\"local-search-index.js\"", "\"\""); + + } + +} + + +function saveTop() +{ + topDiv = document.getElementById("top"); + if (null == topDiv) + g_top = "Error, no \"top\" div found.

\n"; + else + g_top = topDiv.innerHTML; +} + + +function saveFooter() +{ + + footerDiv = document.getElementById("doxy-footer"); + + if (null == footerDiv) + g_footer = "


Error, no \"footer\"
found."; + else + g_footer = footerDiv.innerHTML; + +} + + +function writeTop() +{ + document.write("
"); + document.write("

"); +} + +function writeHeader() +{ + + + document.write(""); + document.write("\n"); + + document.write(g_header); + + document.write(""); + + + +} + + +function writeFooter(){ + + document.write("

\n"); + document.write(g_footer); + document.write("
\n"); + +} + + +function searchForWord( searchWord, statsList) +{ + + hashIndex = computeIndex(searchWord); + + + indexEntry = theIndex[hashIndex]; + + + var start = statsList.length; + var count = start; + + var totalHi = 0; + var totalFreqHi = 0; + var totalFreqLo = 0; + + + if (indexEntry != null) + { //found words matching the hash key + + for (var i = 0; i< indexEntry.length; i++) + { + foundWord = indexEntry[i]; + if (null == foundWord) + continue; + if ( foundWord.indexOf(searchWord) != -1) + { + //look up the words array for the document list + var multiplier = 1; + + var statInfo = new Object(); + statInfo.word = searchWord; + statInfo.match = foundWord; + if (foundWord.length == searchWord.length) + multiplier = 2; + + statInfo.docs = words[("#" + foundWord)]; + + if (null == statInfo.docs) + continue; + + for (var j = 0; j < statInfo.docs.length; j++) + { + var matchingDoc = statInfo.docs[j]; + if (matchingDoc == null) + { + //document.write("matchingDoc is NULL

"); + continue; + } + + //lsb of freq records whether it is high priority + matchingDoc.hi = matchingDoc.f&1; + + matchingDoc.f = matchingDoc.f>>1; + var freq = matchingDoc.f; + + matchingDoc.rank = 0.0; + + if (matchingDoc.hi) // word occurs in high priority doc + { + totalHi++; + totalFreqHi += freq*multiplier; + } + else // word occurs in low priority doc + { + totalFreqLo += freq*multiplier; + } + + matchingDoc.docName = (urls[matchingDoc.x]).n; + matchingDoc.docUrl = (urls[matchingDoc.x]).u; + + } + + statsList[count++] = statInfo; + + } + } + + totalFreq=(totalHi+1)* totalFreqLo + totalFreqHi; + for (count = start; count < statsList.length; count++) + { + statInfo = statsList[count]; + multiplier = 1; + // whole word matches have a double weight + if (statInfo.full) + multiplier=2; + for (i=0; i < statInfo.docs.length;i++) + { + docInfo = statInfo.docs; + // compute frequency rank of the word in each doc + + if (docInfo[i] == null) + continue; + + freq = docInfo[i].f; + if (docInfo[i].hi > 0) + { + statInfo.docs[i].rank= + (freq*multiplier+totalFreqLo)/totalFreq; + } + else + { + statInfo.docs[i].rank= + (freq*multiplier)/totalFreq; + } + }//for (i=0.. + }//for (count=... + } //if (indexEntry != null) + +} //searchForWord + + + +function report_results(docs, query) +{ + + + writeHeader(); + document.write(""); + writeTop(); + + document.write(" "); + document.write("

"); + + document.write("\n"); + document.write(" \n"); + document.write(" \n"); + document.write(" \n"); + + var numDocs = 0; + for (docsKey in docs) + numDocs++; + + if (numDocs==0) + { + document.write(" \n"); + document.write(" \n"); + document.write(" \n"); + } + else + { + document.write(" \n"); + document.write(" \n"); + document.write(" \n"); + num=1; + for (var i = 0; i < numDocs; i++) + { + doc = docs[i]; + document.write(" \n"); + document.write(" "); + document.write( "\n"); + document.write(" \n"); + document.write(" \n"); + document.write(" \n"); + num++; + } + } + document.write("

" + search_results() + "

" + matches_text(0, query) + "
" + matches_text(numDocs, query)); + document.write("\n"); + document.write("
" + num + "" + doc.docName + "
" + report_matches() + " "); + + numWords = doc.words.length; + + for (var j =0; j< numWords; j++) + { + wordInfo = doc.words[j]; + word = wordInfo.word; + matchRight = wordInfo.match.substr(word.length, wordInfo.match.length); + document.write("" + word + "" + matchRight +"(" + wordInfo.freq + ") "); + } + document.write("
\n"); + + document.write("
"); //contents + + writeFooter(); + +} + + + +function compare_rank(a,b) +{ + if (a.rank == b.rank) + { + return 0; + } + return (a.rank > b.rank) ? -1 : 1; +} + +function sort_results(docs) +{ + + return docs.sort(compare_rank); + +} + + + + + +function combine_results(results,docs) +{ + + numResults = results.length; + + keyedDocs = new Array(); + + for (var i =0; i< numResults; i++) + { + wordInfo = results[i]; + docsList = wordInfo.docs; + numDocs = docsList.length; + for (var j = 0; j< numDocs; j++) + { + di = docsList[j]; + if (di == null) + continue; + docKey = di.docUrl; + rank = di.rank; + + if (keyedDocs[docKey] != null) + { + keyedDocs[docKey].rank += rank; + + }else + { + docInfo = new Object(); + docInfo.docUrl = docKey; + docInfo.docName = di.docName; + docInfo.rank = rank; + docInfo.words = new Array(); + + keyedDocs[docKey] = docInfo; + } + + wi = new Object(); + wi.word = wordInfo.word; + wi.match = wordInfo.match; + wi.freq = di.f; + + idx = keyedDocs[docKey].words.length; + keyedDocs[docKey].words[idx] = wi; + } + + } + + + var i = 0; + for (docKey in keyedDocs) + { + // document.write("docKey = " + docKey + "

"); + docs[i] = keyedDocs[docKey]; + i++; + } + return docs; + +} + + + + +function filter_results(docs, requiredWords, forbiddenWords) +{ + filteredDocs = new Array(); + var numPassed = 0; + + + for (var i = 0; i < docs.length; i++) + { + copyIt = true; + words = docs[i].words; + + + for (var j = 0; j< requiredWords.length; j++) + { + reqWord = requiredWords[j]; + found = false; + + for (var k = 0; k < words.length; k++) + { + found = (words[k].word == reqWord); + if (found) + break; + } + if (!found) + { + copyIt = false; // document fails to contain one of the + // required words. + break; + } + } + + if (copyIt) + { //don't bother checking for forbidden words + //if it has failed the required words test + + for (var j = 0; j< forbiddenWords.length; j++) + { + forbiddenWord = forbiddenWords[j]; + found = false; + for (var k = 0; k < words.length; k++) + { + found = (words[k].word == forbiddenWord); + if (found) + { + copyIt = false; + break; + } + } + } + } + + if (copyIt) + { + filteredDocs[numPassed] = docs[i]; + numPassed++; + } + + } + return filteredDocs; + +} + + + + + +function doSearch( theIndex, param) +{ + + saveHeader(); + saveTop(); + saveFooter(); + indexArray = theIndex; + + searchTerms = getParam(param); + + + + //indexText = document.getElementById("index").innerHTML; + //window.alert(indexText); + + var statsList = new Array(); + + requiredWords = new Array(); + forbiddenWords = new Array(); + searchWords = searchTerms.split("+"); + + foundWords = new Array(); + + for (var i = 0; i< searchWords.length; i++) + { + word = unescape(searchWords[i]); + word = word.toLowerCase(); + if (word[0] == '+') + { + word = word.substr(1); + requiredWords[requiredWords.length] = word; + // document.write("required = " + word + "

"); + } + if (word[0] == '-') + { + word = word.substr(1); + forbiddenWords[forbiddenWords.length] = word; + // document.write("forbidden = " + word + "

"); + } + + if (foundWords[word] == null) + { + searchForWord( word, statsList); + foundWords[word] = i; + } + + } + + + docs = new Array(); + combine_results(statsList, docs); + + filteredDocs = filter_results(docs, requiredWords, forbiddenWords); + + + + + filteredDocs = sort_results(filteredDocs); + + report_results(filteredDocs, unescape(searchWords.join(" "))); + + + + +} + + + +function fillSearchBox(param) +{ + searchTerms = getParam(param); + searchWords = searchTerms.split("+"); + searchQuery = searchWords.join(" "); + + queryElement = document.getElementById("query"); + if (null != queryElement) + queryElement.value = unescape(searchQuery); + else + window.alert("queryElement is null"); + +} + + + + Property changes on: src/local-search.js ___________________________________________________________________ Name: svn:executable + * Index: src/translator_cz.h =================================================================== --- src/translator_cz.h (revision 642) +++ src/translator_cz.h (working copy) @@ -77,7 +77,7 @@ // something else. It is difficult to find the general translation // for all kinds in the Czech language. -class TranslatorCzech : public Translator +class TranslatorCzech : public TranslatorAdapter_1_5_4 { public: // --- Language control methods ------------------- Index: src/translator_kr.h =================================================================== --- src/translator_kr.h (revision 642) +++ src/translator_kr.h (working copy) @@ -50,7 +50,7 @@ Translator class (by the local maintainer) when the localized translator is made up-to-date again. */ -class TranslatorKorean : public Translator +class TranslatorKorean : public TranslatorAdapter_1_5_4 { protected: friend class TranslatorAdapterBase; Index: src/translator_sr.h =================================================================== --- src/translator_sr.h (revision 642) +++ src/translator_sr.h (working copy) @@ -24,7 +24,7 @@ // UTF-8 patch by Nenad Bulatovic // translation update by Andrija M. Bosnjakovic -class TranslatorSerbian : public Translator +class TranslatorSerbian : public TranslatorAdapter_1_5_4 { private: QCString decode(const QCString& sInput) Index: src/translator_de.h =================================================================== --- src/translator_de.h (revision 642) +++ src/translator_de.h (working copy) @@ -120,7 +120,7 @@ #ifndef TRANSLATOR_DE_H #define TRANSLATOR_DE_H -class TranslatorGerman : public Translator +class TranslatorGerman : public TranslatorAdapter_1_5_4 { public: Index: src/choose-search.js =================================================================== --- src/choose-search.js (revision 0) +++ src/choose-search.js (revision 0) @@ -0,0 +1,27 @@ +/*! choose-search.js + * + * Choose whether to use PHP or JavaScript search. + * + * @author Mitchell Fraser + * + */ + +function usingServer() +{ + return (document.URL.indexOf("http") == 0); +} + + +function chooseSearch() +{ + if (usingServer() ) + { + document.searchForm.action = "search.php" + } + else + { + document.searchForm.action = "local-search.html" + } + + return true; +} Property changes on: src/choose-search.js ___________________________________________________________________ Name: svn:executable + * Index: src/translator_sc.h =================================================================== --- src/translator_sc.h (revision 642) +++ src/translator_sc.h (working copy) @@ -40,7 +40,7 @@ Translator class (by the local maintainer) when the localized translator is made up-to-date again. */ -class TranslatorSerbianCyrilic : public Translator +class TranslatorSerbianCyrilic : public TranslatorAdapter_1_5_4 { public: Index: src/doxygen.cpp =================================================================== --- src/doxygen.cpp (revision 642) +++ src/doxygen.cpp (working copy) @@ -10201,6 +10201,12 @@ msg("Generating search index\n"); HtmlGenerator::writeSearchPage(); Doxygen::searchIndex->write(Config_getString("HTML_OUTPUT")+"/search.idx"); + + if (Config_getBool("LOCALSEARCH")) + { + HtmlGenerator::writeLocalSearchPages(); + Doxygen::searchIndex->writeJavaScriptIndex(Config_getString("HTML_OUTPUT")+"/local-search-index.js"); + } } if (Debug::isFlagSet(Debug::Time)) { Index: src/config.l =================================================================== --- src/config.l (revision 642) +++ src/config.l (working copy) @@ -3177,6 +3177,18 @@ "used. If set to NO the values of all tags below this one will be ignored. \n", FALSE ); + cb = addBool( + "LOCALSEARCH", + "The LOCALSEARCH tag specifies whether or not Doxygen should \n" + "produce a search engine capable of searching the HTML output without an HTTP server.\n" + "It will use Javascript to allow searching for keywords using a normal browser." + "If set to NO, search will only be possible if the environment can run PHP scripts," + "which is typical of pages served from HTTP web sites, but not locally stored files." + "To use LOCALSEARCH, SEARCHENGINE must be set to YES.", + TRUE + ); + cb->addDependency("SEARCHENGINE"); + addObsolete("CGI_NAME"); addObsolete("CGI_URL"); addObsolete("DOC_URL"); @@ -3205,7 +3217,7 @@ while ((size=f.readBlock(contents.data()+totalSize,bSize))==bSize) { totalSize+=bSize; - contents.resize(totalSize+bSize); + contents.resize(totalSize+bSize); } totalSize+=size+2; contents.resize(totalSize); Index: src/translator_ru.h =================================================================== --- src/translator_ru.h (revision 642) +++ src/translator_ru.h (working copy) @@ -26,7 +26,7 @@ #ifndef TRANSLATOR_RU_H #define TRANSLATOR_RU_H -class TranslatorRussian : public Translator +class TranslatorRussian : public TranslatorAdapter_1_5_4 { public: /*! Used for identification of the language. */ Index: src/searchindex.cpp =================================================================== --- src/searchindex.cpp (revision 642) +++ src/searchindex.cpp (working copy) @@ -20,6 +20,7 @@ #include "config.h" #include #include +#include // file format: (all multi-byte values are stored in big endian format) @@ -136,6 +137,78 @@ f.putch(0); } + +static QCString escape(const QCString &input) +{ + QCString output(input); + output = output.replace(QRegExp("\\"), "\\\\"); // '\' -> '\\' + return output.replace(QRegExp("\""), "\\\""); // '"' -> '\"' +} + +void SearchIndex::writeJavaScriptIndex(const char *fileName) +{ + int i; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + QTextStream stream( &f ); + for (i=0; i < numIndexEntries; i++) + { + QList *wlist = m_index[i]; + if (!wlist->isEmpty()) + { + stream << "x[" << i << "] = ["; + QListIterator iwi(*wlist); + IndexWord *iw; + for (iwi.toFirst();(iw=iwi.current());++iwi) + { + stream << "\"" << escape(iw->word()) << "\""; + stream << ","; + } + stream << "];"; + stream << "\n"; + } + } + + QDictIterator wordIter(m_words); + IndexWord *word; + + for (wordIter.toFirst(); (word=wordIter.current());++wordIter) + { + stream <<"w[\"#" << escape(word->word()) << "\"] = "; + QIntDictIterator urlIter = word->urls(); + URLInfo *url; + + stream << "["; + for (urlIter.toFirst(); (url=urlIter.current()); ++urlIter) + { + stream << "{x: " << url->urlIdx << "," << "f:" << url->freq << "},"; + + + } + stream << "];\n"; + + + + } + + + + + QIntDictIterator udi(m_urls); + URL *url; + int urlIdx = 0; + for (udi.toFirst();(url=udi.current());++udi) + { + stream << "u[" << udi.currentKey() << "] = { n: \"" << url->name << "\", u: \"" << url->url << "\"};\n"; + urlIdx++; + } + + } +} + + + void SearchIndex::write(const char *fileName) { int i; Index: src/htmlgen.cpp =================================================================== --- src/htmlgen.cpp (revision 642) +++ src/htmlgen.cpp (working copy) @@ -51,6 +51,27 @@ #include "search_php.h" ; +static const char local_search_globals[]= +#include "local-search-globals_js.h" +; + +static const char choose_search[]= +#include "choose-search_js.h" +; + + +static const char local_search_script[]= +#include "local-search_js.h" +; + + +static const char locals_search_script_elements[] = + "\n" + "" + "" + "\n"; + + static QCString g_header; static QCString g_footer; @@ -542,6 +563,9 @@ if (!Config_getString("HTML_FOOTER").isEmpty()) { g_footer=fileToString(Config_getString("HTML_FOOTER")); + + //to close off the the

\n"; + t << "
\n"; + + writePageFooter(t,"Search",""); + } + + } +} + + void HtmlGenerator::writeSearchPage() { if (Config_getBool("SEARCHENGINE") && Config_getBool("GENERATE_HTML")) @@ -2091,16 +2274,16 @@ t.setEncoding(QTextStream::UnicodeUTF8); if (g_header.isEmpty()) { - writeDefaultHeaderFile(t,theTranslator->trSearch().data(),0,FALSE); + writeDefaultHeaderFile(t,theTranslator->trSearch().data(),0,FALSE, FALSE); } else { t << substituteKeywords(g_header,"Search",""); } - t << "" << endl; - if (!Config_getBool("DISABLE_INDEX")) - { + if (!Config_getBool("DISABLE_INDEX")) + { writeDefaultQuickLinks(t,TRUE,HLI_Search,""); } else @@ -2110,7 +2293,29 @@ << "method=\"get\">\n"; } + + t << "\n \n"; + t << "# \n"; + t << "# \n"; + t << "# \n"; + t << "#
\n"; + t << "#

\n"; + t << "#

" << theTranslator->trUseWebServer() << "

\n"; + t << "#

" << theTranslator->trDefineLocalSearch() << "

\n"; + t << "#

\n"; + + + //put the PHP code in an HTML comment, so it doesn't + // appear to a user who has tried to search when accessing + // the files directly + t << "# "; //end the HTML comment that hides the PHP source; t << "?>\n"; writePageFooter(t,"Search",""); } } } + void HtmlGenerator::generateSectionImages() { { Index: src/local-search-globals.js =================================================================== --- src/local-search-globals.js (revision 0) +++ src/local-search-globals.js (revision 0) @@ -0,0 +1,18 @@ + +/*! local-search-globals.js + * + * Globals variables used in local search of doxygen HTML output. + * + * @author Mitchell Fraser + * + */ + + +//the hash table +var x = new Array(); + +//the urls +var u = new Array(); + +//the words +var w = new Array(); \ No newline at end of file Property changes on: src/local-search-globals.js ___________________________________________________________________ Name: svn:executable + * Index: src/translator_br.h =================================================================== --- src/translator_br.h (revision 642) +++ src/translator_br.h (working copy) @@ -32,7 +32,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian : public Translator +class TranslatorBrazilian : public TranslatorAdapter_1_5_4 { public: Index: src/translator_nl.h =================================================================== --- src/translator_nl.h (revision 642) +++ src/translator_nl.h (working copy) @@ -18,7 +18,7 @@ #ifndef TRANSLATOR_NL_H #define TRANSLATOR_NL_H -class TranslatorDutch : public Translator +class TranslatorDutch : public TranslatorAdapter_1_5_4 { public: QCString idLanguage() Index: src/translator_adapter.h =================================================================== --- src/translator_adapter.h (revision 642) +++ src/translator_adapter.h (working copy) @@ -115,6 +115,15 @@ virtual QCString trTypeConstraints() { return english.trTypeConstraints(); } + + virtual QCString trDefineLocalSearch() + { return english.trDefineLocalSearch(); } + + virtual QCString trUseWebServer() + { return english.trUseWebServer(); } + + virtual QCString trLocalSearchResults(int numDocuments) + { return english.trLocalSearchResults(numDocuments); } }; class TranslatorAdapter_1_4_6 : public TranslatorAdapter_1_5_4 Index: src/htmlgen.h =================================================================== --- src/htmlgen.h (revision 642) +++ src/htmlgen.h (working copy) @@ -240,6 +240,7 @@ { t << ""; } void linkableSymbol(int,const char *,Definition *,Definition *) {} + static void writeLocalSearchPages(); static void writeSearchPage(); static void generateSectionImages(); Index: src/translator_tw.h =================================================================== --- src/translator_tw.h (revision 642) +++ src/translator_tw.h (working copy) @@ -41,7 +41,7 @@ // Translator class (by the local maintainer) when the localized // translator is made up-to-date again. -class TranslatorChinesetraditional : public Translator +class TranslatorChinesetraditional : public TranslatorAdapter_1_5_4 { public: Index: src/translator_en.h =================================================================== --- src/translator_en.h (revision 642) +++ src/translator_en.h (working copy) @@ -1774,7 +1774,42 @@ { return "Type Constraints"; } + + + virtual QCString trLocalSearchResults(int numDocuments) + { + if (numDocuments==0) + { + return "Sorry, no documents matching \\\"\" + query + \"\\\"."; + } + else if (numDocuments==1) + { + return "Found 1 document matching \\\"\" + query + \"\\\"."; + } + else + { + return "Found \" + num + \" documents matching \\\"\" + query + \"\\\". " + "Showing best matches first."; + } + } + + /*! Error message comment in the search.php visible when the user tries + * to search when accessing the files directly from the filesystem. + */ + virtual QCString trUseWebServer() + { + return "You must access these documents from a Web server to use search."; + } + /*! Advice on how to make search work when accessing the HTML output directly + * from the filesystem. + */ + virtual QCString trDefineLocalSearch() + { + return "To search without a Web server, please define \"LOCALSEARCH = Yes\" in the Doxyfile used to create this documentation."; + } + + }; #endif Index: src/translator_it.h =================================================================== --- src/translator_it.h (revision 642) +++ src/translator_it.h (working copy) @@ -80,7 +80,7 @@ #ifndef TRANSLATOR_IT_H #define TRANSLATOR_IT_H -class TranslatorItalian : public Translator +class TranslatorItalian : public TranslatorAdapter_1_5_4 { public: