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

Javascript based search engine. More...

#include <array>
#include <functional>
#include <map>
#include <string>
#include <variant>
#include <vector>
#include "dstring.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

DString 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 32 of file searchindex_js.h.

Typedef Documentation

◆ SearchIndexList

using SearchIndexList = std::vector<SearchTerm>

List of search terms.

Definition at line 55 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 58 of file searchindex_js.h.

Function Documentation

◆ createJavaScriptSearchIndex()

void createJavaScriptSearchIndex ( )

Definition at line 334 of file searchindex_js.cpp.

335{
336 // index classes
337 for (const auto &cd : *Doxygen::classLinkedMap)
338 {
339 if (cd->isLinkable())
340 {
341 DString n = cd->localName();
343 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
344 {
345 if (cd->compoundType()==ClassDef::Interface)
346 {
348 }
349 else if (cd->compoundType()==ClassDef::Struct)
350 {
352 }
353 else if (cd->compoundType()==ClassDef::Exception)
354 {
356 }
357 else // cd->compoundType()==ClassDef::Class
358 {
360 }
361 }
362 else // non slice optimization: group all types under classes
363 {
365 }
366 }
367 }
368
369 // index namespaces
370 for (const auto &nd : *Doxygen::namespaceLinkedMap)
371 {
372 if (nd->isLinkable())
373 {
374 DString n = nd->name();
377 }
378 }
379
380 // index concepts
381 for (const auto &cd : *Doxygen::conceptLinkedMap)
382 {
383 if (cd->isLinkable())
384 {
385 DString n = cd->localName();
388 }
389 }
390
391 // index modules
392 for (const auto &mod : ModuleManager::instance().modules())
393 {
394 if (mod->isLinkable() && mod->isPrimaryInterface())
395 {
396 DString n = mod->name();
399 }
400 }
401
402 // index files
403 for (const auto &fn : *Doxygen::inputNameLinkedMap)
404 {
405 for (const auto &fd : *fn)
406 {
407 DString n = fd->name();
408 if (fd->isLinkable())
409 {
412 }
413 }
414 }
415
416 // index class members
417 {
418 // for each member name
419 for (const auto &mn : *Doxygen::memberNameLinkedMap)
420 {
421 // for each member definition
422 for (const auto &md : *mn)
423 {
424 addMemberToSearchIndex(md.get());
425 }
426 }
427 }
428
429 // index file/namespace members
430 {
431 // for each member name
432 for (const auto &mn : *Doxygen::functionNameLinkedMap)
433 {
434 // for each member definition
435 for (const auto &md : *mn)
436 {
437 addMemberToSearchIndex(md.get());
438 }
439 }
440 }
441
442 // index groups
443 for (const auto &gd : *Doxygen::groupLinkedMap)
444 {
445 if (gd->isLinkable())
446 {
447 DString title(filterTitle(gd->groupTitle()).str());
448 SizeVector tokenIndices;
449 splitSearchTokens(title,tokenIndices);
450 for (size_t index : tokenIndices)
451 {
452 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),gd.get()));
453 g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(SearchTerm(title.mid(index),gd.get()));
454 }
455 }
456 }
457
458 // index pages
459 for (const auto &pd : *Doxygen::pageLinkedMap)
460 {
461 if (pd->isLinkable())
462 {
463 DString title(filterTitle(pd->title()).str());
464 SizeVector tokenIndices;
465 splitSearchTokens(title,tokenIndices);
466 for (size_t index : tokenIndices)
467 {
468 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),pd.get()));
469 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),pd.get()));
470 }
471 }
472 }
473
474 // main page
476 {
477 DString title(filterTitle(Doxygen::mainPage->title()).str());
478 SizeVector tokenIndices;
479 splitSearchTokens(title,tokenIndices);
480 for (size_t index : tokenIndices)
481 {
484 }
485 }
486
487 // sections
488 const auto &sm = SectionManager::instance();
489 for (const auto &sectionInfo : sm)
490 {
491 if (sectionInfo->level()>0) // level 0 is for page titles
492 {
493 DString title = filterTitle(sectionInfo->title());
494 SizeVector tokenIndices;
495 splitSearchTokens(title,tokenIndices);
496 //printf("split(%s)=(%s) %zu\n",qPrint(sectionInfo->title()),qPrint(title),tokenIndices.size());
497 for (size_t index : tokenIndices)
498 {
499 g_searchIndexInfo[SEARCH_INDEX_ALL].add(SearchTerm(title.mid(index),sectionInfo.get()));
500 g_searchIndexInfo[SEARCH_INDEX_PAGES].add(SearchTerm(title.mid(index),sectionInfo.get()));
501 }
502 }
503 }
504
505 // sort all lists
506 for (auto &sii : g_searchIndexInfo) // for each index
507 {
508 for (auto &[name,symList] : sii.symbolMap) // for each symbol in the index
509 {
510 // sort the symbols (first on search term, and then on full name)
511 //
512 // `std::stable_sort` is used here due to reproducibility issues
513 // on key collisions
514 // https://github.com/doxygen/doxygen/issues/10445
515 std::stable_sort(symList.begin(),
516 symList.end(),
517 [](const auto &t1,const auto &t2)
518 {
519 int eq = dstricmp_sort(t1.word,t2.word); // search term first
520 return eq==0 ? dstricmp_sort(t1.title,t2.title)<0 : eq<0; // then full title
521 });
522 }
523 }
524}
@ Interface
Definition classdef.h:108
@ Exception
Definition classdef.h:111
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:88
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:322
const std::string & str() const
Definition dstring.h:649
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:108
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:90
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:93
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:97
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:88
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:105
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:92
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:104
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:107
static ModuleManager & instance()
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
#define Config_getBool(name)
Definition config.h:33
std::vector< size_t > SizeVector
Definition containers.h:39
static void addMemberToSearchIndex(const MemberDef *md)
#define SEARCH_INDEX_STRUCTS
#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
static void splitSearchTokens(DString &title, SizeVector &indices)
#define SEARCH_INDEX_MODULES
#define SEARCH_INDEX_CLASSES
#define SEARCH_INDEX_EXCEPTIONS
Searchable term.
DString filterTitle(const DString &title)
Definition util.cpp:4456

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, DString::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(), DString::str(), and ClassDef::Struct.

Referenced by generateOutput().

◆ getSearchIndices()

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

Definition at line 870 of file searchindex_js.cpp.

871{
872 return g_searchIndexInfo;
873}

References g_searchIndexInfo.

◆ searchName()

DString searchName ( const Definition * d)

◆ writeJavaScriptSearchIndex()

void writeJavaScriptSearchIndex ( )

Definition at line 799 of file searchindex_js.cpp.

800{
801 // write index files
802 DString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
803
804 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
805 if (numThreads>1) // multi threaded version
806 {
807 ThreadPool threadPool(numThreads);
808 std::vector< std::future<int> > results;
809 for (auto &sii : g_searchIndexInfo)
810 {
811 int p=0;
812 for (const auto &[letter,symList] : sii.symbolMap)
813 {
814 DString baseName;
815 baseName.sprintf("%s_%x",sii.name.data(),p);
816 DString dataFileName = searchDirName + "/"+baseName+".js";
817 auto &list = symList;
818 auto processFile = [p,baseName,dataFileName,&list]()
819 {
820 writeJavasScriptSearchDataPage(baseName,dataFileName,list);
821 return p;
822 };
823 results.emplace_back(threadPool.queue(processFile));
824 p++;
825 }
826 }
827 // wait for the results
828 for (auto &f : results) f.get();
829 }
830 else // single threaded version
831 {
832 for (auto &sii : g_searchIndexInfo)
833 {
834 int p=0;
835 for (const auto &[letter,symList] : sii.symbolMap)
836 {
837 DString baseName;
838 baseName.sprintf("%s_%x",sii.name.data(),p);
839 DString dataFileName = searchDirName + "/"+baseName+".js";
840 writeJavasScriptSearchDataPage(baseName,dataFileName,symList);
841 p++;
842 }
843 }
844 }
845
846 writeJavascriptSearchData(searchDirName);
847 auto &mgr = ResourceMgr::instance();
848 {
849 std::ofstream fn = Portable::openOutputStream(searchDirName+"/search.js");
850 if (fn.is_open())
851 {
852 TextStream t(&fn);
853 t << substitute(mgr.getAsString("search.js"),"$PROJECTID",getProjectId());
854 }
855 }
856
857 Doxygen::indexList->addStyleSheetFile("search/searchdata.js");
858 Doxygen::indexList->addStyleSheetFile("search/search.js");
859}
DString & sprintf(const char *format,...)
Definition dstring.cpp:30
static IndexList * indexList
Definition doxygen.h:125
void addStyleSheetFile(const DString &name)
Definition indexlist.h:127
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
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:481
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:665
static void writeJavascriptSearchData(const DString &searchDirName)
static void writeJavasScriptSearchDataPage(const DString &baseName, const DString &dataFileName, const SearchIndexList &list)
DString getProjectId()
Definition util.cpp:5272

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

Referenced by generateOutput().