Doxygen
Loading...
Searching...
No Matches
searchindex_js.h File Reference

Javascript based search engine. More...

#include <array>
#include <vector>
#include <map>
#include <string>
#include <functional>
#include <variant>
#include "qcstring.h"
#include "utf8.h"
Include dependency graph for searchindex_js.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  SearchTerm
 Searchable term. More...
struct  SearchIndexInfo
 Table entry to allow filtering the search results per category. More...

Macros

#define NUM_SEARCH_INDICES   22

Typedefs

using SearchIndexList = std::vector<SearchTerm>
 List of search terms.
using SearchIndexMap = std::map<std::string,SearchIndexList>
 Map of search terms for a given starting letter.

Functions

QCString searchName (const Definition *d)
void createJavaScriptSearchIndex ()
void writeJavaScriptSearchIndex ()
const std::array< SearchIndexInfo, NUM_SEARCH_INDICES > & getSearchIndices ()

Detailed Description

Javascript based search engine.

Definition in file searchindex_js.h.

Macro Definition Documentation

◆ NUM_SEARCH_INDICES

#define NUM_SEARCH_INDICES   22

Definition at line 33 of file searchindex_js.h.

Typedef Documentation

◆ SearchIndexList

using SearchIndexList = std::vector<SearchTerm>

List of search terms.

Definition at line 56 of file searchindex_js.h.

◆ SearchIndexMap

using SearchIndexMap = std::map<std::string,SearchIndexList>

Map of search terms for a given starting letter.

Definition at line 59 of file searchindex_js.h.

Function Documentation

◆ createJavaScriptSearchIndex()

void createJavaScriptSearchIndex ( )

Definition at line 369 of file searchindex_js.cpp.

370{
371 // index classes
372 for (const auto &cd : *Doxygen::classLinkedMap)
373 {
374 if (cd->isLinkable())
375 {
376 QCString n = cd->localName();
378 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
379 {
380 if (cd->compoundType()==ClassDef::Interface)
381 {
383 }
384 else if (cd->compoundType()==ClassDef::Struct)
385 {
387 }
388 else if (cd->compoundType()==ClassDef::Exception)
389 {
391 }
392 else // cd->compoundType()==ClassDef::Class
393 {
395 }
396 }
397 else // non slice optimization: group all types under classes
398 {
400 }
401 }
402 }
403
404 // index namespaces
405 for (const auto &nd : *Doxygen::namespaceLinkedMap)
406 {
407 if (nd->isLinkable())
408 {
409 QCString n = nd->name();
412 }
413 }
414
415 // index concepts
416 for (const auto &cd : *Doxygen::conceptLinkedMap)
417 {
418 if (cd->isLinkable())
419 {
420 QCString n = cd->localName();
423 }
424 }
425
426 // index modules
427 for (const auto &mod : ModuleManager::instance().modules())
428 {
429 if (mod->isLinkable() && mod->isPrimaryInterface())
430 {
431 QCString n = mod->name();
434 }
435 }
436
437 // index files
438 for (const auto &fn : *Doxygen::inputNameLinkedMap)
439 {
440 for (const auto &fd : *fn)
441 {
442 QCString n = fd->name();
443 if (fd->isLinkable())
444 {
447 }
448 }
449 }
450
451 // index class members
452 {
453 // for each member name
454 for (const auto &mn : *Doxygen::memberNameLinkedMap)
455 {
456 // for each member definition
457 for (const auto &md : *mn)
458 {
459 addMemberToSearchIndex(md.get());
460 }
461 }
462 }
463
464 // index file/namespace members
465 {
466 // for each member name
467 for (const auto &mn : *Doxygen::functionNameLinkedMap)
468 {
469 // for each member definition
470 for (const auto &md : *mn)
471 {
472 addMemberToSearchIndex(md.get());
473 }
474 }
475 }
476
477 // index groups
478 for (const auto &gd : *Doxygen::groupLinkedMap)
479 {
480 if (gd->isLinkable())
481 {
482 QCString title(filterTitle(gd->groupTitle()).str());
483 IntVector tokenIndices;
484 splitSearchTokens(title,tokenIndices);
485 for (int index : tokenIndices)
486 {
487 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),gd.get()));
488 g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(SearchTerm(title.mid(index),gd.get()));
489 }
490 }
491 }
492
493 // index pages
494 for (const auto &pd : *Doxygen::pageLinkedMap)
495 {
496 if (pd->isLinkable())
497 {
498 QCString title(filterTitle(pd->title()).str());
499 IntVector tokenIndices;
500 splitSearchTokens(title,tokenIndices);
501 for (int index : tokenIndices)
502 {
503 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),pd.get()));
504 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),pd.get()));
505 }
506 }
507 }
508
509 // main page
511 {
512 QCString title(filterTitle(Doxygen::mainPage->title()).str());
513 IntVector tokenIndices;
514 splitSearchTokens(title,tokenIndices);
515 for (int index : tokenIndices)
516 {
519 }
520 }
521
522 // sections
523 const auto &sm = SectionManager::instance();
524 for (const auto &sectionInfo : sm)
525 {
526 if (sectionInfo->level()>0) // level 0 is for page titles
527 {
528 QCString title = filterTitle(sectionInfo->title());
529 IntVector tokenIndices;
530 splitSearchTokens(title,tokenIndices);
531 //printf("split(%s)=(%s) %zu\n",qPrint(sectionInfo->title()),qPrint(title),tokenIndices.size());
532 for (int index : tokenIndices)
533 {
534 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),sectionInfo.get()));
535 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),sectionInfo.get()));
536 }
537 }
538 }
539
540 // sort all lists
541 for (auto &sii : g_searchIndexInfo) // for each index
542 {
543 for (auto &[name,symList] : sii.symbolMap) // for each symbol in the index
544 {
545 // sort the symbols (first on search term, and then on full name)
546 //
547 // `std::stable_sort` is used here due to reproducibility issues
548 // on key collisions
549 // https://github.com/doxygen/doxygen/issues/10445
550 std::stable_sort(symList.begin(),
551 symList.end(),
552 [](const auto &t1,const auto &t2)
553 {
554 int eq = qstricmp_sort(t1.word,t2.word); // search term first
555 return eq==0 ? qstricmp_sort(t1.title,t2.title)<0 : eq<0; // then full title
556 });
557 }
558 }
559}
@ Interface
Definition classdef.h:112
@ Exception
Definition classdef.h:115
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:98
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:101
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
static ModuleManager & instance()
This is an alternative implementation of QCString.
Definition qcstring.h:101
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
const std::string & str() const
Definition qcstring.h:537
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
#define Config_getBool(name)
Definition config.h:33
std::vector< int > IntVector
Definition containers.h:38
static void addMemberToSearchIndex(const MemberDef *md)
#define SEARCH_INDEX_STRUCTS
static void splitSearchTokens(QCString &title, IntVector &indices)
#define SEARCH_INDEX_NAMESPACES
#define SEARCH_INDEX_CONCEPTS
static std::array< SearchIndexInfo, NUM_SEARCH_INDICES > g_searchIndexInfo
#define SEARCH_INDEX_FILES
#define SEARCH_INDEX_PAGES
#define SEARCH_INDEX_ALL
#define SEARCH_INDEX_GROUPS
#define SEARCH_INDEX_INTERFACES
#define SEARCH_INDEX_MODULES
#define SEARCH_INDEX_CLASSES
#define SEARCH_INDEX_EXCEPTIONS
Searchable term.
QCString filterTitle(const QCString &title)
Definition util.cpp:6093

References addMemberToSearchIndex(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Config_getBool, ClassDef::Exception, filterTitle(), Doxygen::functionNameLinkedMap, g_searchIndexInfo, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), SectionManager::instance(), ClassDef::Interface, Doxygen::mainPage, Doxygen::memberNameLinkedMap, QCString::mid(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, SEARCH_INDEX_ALL, SEARCH_INDEX_CLASSES, SEARCH_INDEX_CONCEPTS, SEARCH_INDEX_EXCEPTIONS, SEARCH_INDEX_FILES, SEARCH_INDEX_GROUPS, SEARCH_INDEX_INTERFACES, SEARCH_INDEX_MODULES, SEARCH_INDEX_NAMESPACES, SEARCH_INDEX_PAGES, SEARCH_INDEX_STRUCTS, splitSearchTokens(), QCString::str(), and ClassDef::Struct.

Referenced by generateOutput().

◆ getSearchIndices()

const std::array< SearchIndexInfo, NUM_SEARCH_INDICES > & getSearchIndices ( )

Definition at line 903 of file searchindex_js.cpp.

904{
905 return g_searchIndexInfo;
906}

References g_searchIndexInfo.

◆ searchName()

QCString searchName ( const Definition * d)

◆ writeJavaScriptSearchIndex()

void writeJavaScriptSearchIndex ( )

Definition at line 832 of file searchindex_js.cpp.

833{
834 // write index files
835 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
836
837 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
838 if (numThreads>1) // multi threaded version
839 {
840 ThreadPool threadPool(numThreads);
841 std::vector< std::future<int> > results;
842 for (auto &sii : g_searchIndexInfo)
843 {
844 int p=0;
845 for (const auto &[letter,symList] : sii.symbolMap)
846 {
847 QCString baseName;
848 baseName.sprintf("%s_%x",sii.name.data(),p);
849 QCString dataFileName = searchDirName + "/"+baseName+".js";
850 auto &list = symList;
851 auto processFile = [p,baseName,dataFileName,&list]()
852 {
853 writeJavasScriptSearchDataPage(baseName,dataFileName,list);
854 return p;
855 };
856 results.emplace_back(threadPool.queue(processFile));
857 p++;
858 }
859 }
860 // wait for the results
861 for (auto &f : results) f.get();
862 }
863 else // single threaded version
864 {
865 for (auto &sii : g_searchIndexInfo)
866 {
867 int p=0;
868 for (const auto &[letter,symList] : sii.symbolMap)
869 {
870 QCString baseName;
871 baseName.sprintf("%s_%x",sii.name.data(),p);
872 QCString dataFileName = searchDirName + "/"+baseName+".js";
873 writeJavasScriptSearchDataPage(baseName,dataFileName,symList);
874 p++;
875 }
876 }
877 }
878
879 writeJavascriptSearchData(searchDirName);
880 auto &mgr = ResourceMgr::instance();
881 {
882 std::ofstream fn = Portable::openOutputStream(searchDirName+"/search.js");
883 if (fn.is_open())
884 {
885 TextStream t(&fn);
886 t << substitute(mgr.getAsString("search.js"),"$PROJECTID",getProjectId());
887 }
888 }
889
890 Doxygen::indexList->addStyleSheetFile("search/searchdata.js");
891 Doxygen::indexList->addStyleSheetFile("search/search.js");
892}
static IndexList * indexList
Definition doxygen.h:134
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
static ResourceMgr & instance()
Returns the one and only instance of this class.
Text streaming class that buffers data.
Definition textstream.h:36
Class managing a pool of worker threads.
Definition threadpool.h:48
#define Config_getInt(name)
Definition config.h:34
#define Config_getString(name)
Definition config.h:32
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
static void writeJavasScriptSearchDataPage(const QCString &baseName, const QCString &dataFileName, const SearchIndexList &list)
static void writeJavascriptSearchData(const QCString &searchDirName)
QCString getProjectId()
Definition util.cpp:7288

References Config_getInt, Config_getString, g_searchIndexInfo, getProjectId(), Doxygen::indexList, ResourceMgr::instance(), Portable::openOutputStream(), ThreadPool::queue(), QCString::sprintf(), substitute(), writeJavascriptSearchData(), and writeJavasScriptSearchDataPage().

Referenced by generateOutput().