Doxygen
Loading...
Searching...
No Matches
htmlgen.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2023 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <stdlib.h>
17#include <assert.h>
18
19#include <mutex>
20
21#include "message.h"
22#include "htmlgen.h"
23#include "config.h"
24#include "util.h"
25#include "doxygen.h"
26#include "diagram.h"
27#include "version.h"
28#include "dot.h"
29#include "dotcallgraph.h"
30#include "dotclassgraph.h"
31#include "dotdirdeps.h"
34#include "dotincldepgraph.h"
35#include "language.h"
36#include "htmlhelp.h"
37#include "docparser.h"
38#include "docnode.h"
39#include "htmldocvisitor.h"
40#include "searchindex.h"
41#include "pagedef.h"
42#include "debug.h"
43#include "dirdef.h"
44#include "vhdldocgen.h"
45#include "layout.h"
46#include "image.h"
47#include "ftvhelp.h"
48#include "resourcemgr.h"
49#include "tooltip.h"
50#include "growbuf.h"
51#include "fileinfo.h"
52#include "dir.h"
53#include "utf8.h"
54#include "textstream.h"
55#include "indexlist.h"
56#include "datetime.h"
57#include "portable.h"
58#include "outputlist.h"
59#include "stringutil.h"
60
61//#define DBG_HTML(x) x;
62#define DBG_HTML(x)
63
68static constexpr auto hex="0123456789ABCDEF";
69
70static const SelectionMarkerInfo htmlMarkerInfo = { '<', "<!--BEGIN ",10,"<!--END ",8,"-->",3 };
71
72// note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this
73// part will be rendered inside menu.js
74static void writeClientSearchBox(TextStream &t,const QCString &relPath)
75{
76 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
77 t << " <span class=\"left\">\n";
78 t << " <span id=\"MSearchSelect\" ";
79 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\" ";
80 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\">&#160;</span>\n";
81 t << " <input type=\"text\" id=\"MSearchField\" value=\"\" placeholder=\""
82 << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
83 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
84 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
85 t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
86 t << " </span><span class=\"right\">\n";
87 t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
88 << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.svg\" alt=\"\"/></a>\n";
89 t << " </span>\n";
90 t << " </div>\n";
91}
92
93// note: this is only active if DISABLE_INDEX=YES. if DISABLE_INDEX is disabled, this
94// part will be rendered inside menu.js
95static void writeServerSearchBox(TextStream &t,const QCString &relPath,bool highlightSearch)
96{
97 bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
98 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
99 t << " <div class=\"left\">\n";
100 t << " <form id=\"FSearchBox\" action=\"" << relPath;
101 if (externalSearch)
102 {
103 t << "search" << Doxygen::htmlFileExtension;
104 }
105 else
106 {
107 t << "search.php";
108 }
109 t << "\" method=\"get\">\n";
110 t << " <span id=\"MSearchSelectExt\">&#160;</span>\n";
111 if (!highlightSearch || !Config_getBool(HTML_DYNAMIC_MENUS))
112 {
113 t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" placeholder=\""
114 << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
115 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
116 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
117 t << " </form>\n";
118 t << " </div><div class=\"right\"></div>\n";
119 t << " </div>\n";
120 }
121}
122
123//------------------------------------------------------------------------
124/// Convert a set of LaTeX commands `\‍(re)newcommand` to a form readable by MathJax
125/// LaTeX syntax:
126/// ```
127/// \newcommand{\cmd}{replacement}
128/// or
129/// \renewcommand{\cmd}{replacement}
130/// ```
131/// MathJax syntax:
132/// ```
133/// cmd: "{replacement}"
134/// ```
135///
136/// LaTeX syntax:
137/// ```
138/// \newcommand{\cmd}[nr]{replacement}
139/// or
140/// \renewcommand{\cmd}[nr]{replacement}
141/// ```
142/// MathJax syntax:
143/// ```
144/// cmd: ["{replacement}",nr]
145/// ```
147{
148 QCString macrofile = Config_getString(FORMULA_MACROFILE);
149 if (macrofile.isEmpty()) return "";
150 QCString s = fileToString(macrofile);
151 macrofile = FileInfo(macrofile.str()).absFilePath();
152 size_t size = s.length();
153 GrowBuf out(size);
154 const char *data = s.data();
155 int line = 1;
156 int cnt = 0;
157 size_t i = 0;
158 QCString nr;
159 while (i < size)
160 {
161 nr = "";
162 // skip initial white space, but count lines
163 while (i < size && (data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))
164 {
165 if (data[i] == '\n') line++;
166 i++;
167 }
168 if (i >= size) break;
169 // check for \newcommand or \renewcommand
170 if (data[i] != '\\')
171 {
172 warn(macrofile,line, "file contains non valid code, expected '\\' got '{:c}'",data[i]);
173 return "";
174 }
175 i++;
176 if (literal_at(data+i,"newcommand"))
177 {
178 i += strlen("newcommand");
179 }
180 else if (literal_at(data+i,"renewcommand"))
181 {
182 i += strlen("renewcommand");
183 }
184 else
185 {
186 warn(macrofile,line, "file contains non valid code, expected 'newcommand' or 'renewcommand'");
187 return "";
188 }
189 // handle {cmd}
190 if (data[i] != '{')
191 {
192 warn(macrofile,line, "file contains non valid code, expected '{{' got '{:c}'",data[i]);
193 return "";
194 }
195 i++;
196 if (data[i] != '\\')
197 {
198 warn(macrofile,line, "file contains non valid code, expected '\\' got '{:c}'",data[i]);
199 return "";
200 }
201 i++;
202 // run till }, i.e. cmd
203 out.addStr(" ");
204 while (i < size && (data[i] != '}')) out.addChar(data[i++]);
205 if (i >= size)
206 {
207 warn(macrofile,line, "file contains non valid code, no closing '}}' for command");
208 return "";
209 }
210 out.addChar(':');
211 out.addChar(' ');
212 i++;
213
214 if (data[i] == '[')
215 {
216 // handle [nr]
217 // run till ]
218 out.addChar('[');
219 i++;
220 while (i < size && (data[i] != ']')) nr += data[i++];
221 if (i >= size)
222 {
223 warn(macrofile,line, "file contains non valid code, no closing ']'");
224 return "";
225 }
226 i++;
227 }
228 else if (data[i] != '{')
229 {
230 warn(macrofile,line, "file contains non valid code, expected '[' or '{{' got '{:c}'",data[i]);
231 return "";
232 }
233 // handle {replacement}
234 // retest as the '[' part might have advanced so we can have a new '{'
235 if (data[i] != '{')
236 {
237 warn(macrofile,line, "file contains non valid code, expected '{{' got '{:c}'",data[i]);
238 return "";
239 }
240 out.addChar('"');
241 out.addChar('{');
242 i++;
243 // run till }
244 cnt = 1;
245 while (i < size && cnt)
246 {
247 switch(data[i])
248 {
249 case '\\':
250 out.addChar('\\'); // need to escape it for MathJax js code
251 out.addChar('\\');
252 i++;
253 if (data[i] == '\\') // we have an escaped backslash
254 {
255 out.addChar('\\');
256 out.addChar('\\');
257 i++;
258 }
259 else if (data[i] != '"') out.addChar(data[i++]); // double quote handled separately
260 break;
261 case '{':
262 cnt++;
263 out.addChar(data[i++]);
264 break;
265 case '}':
266 cnt--;
267 if (cnt) out.addChar(data[i]);
268 i++;
269 break;
270 case '"':
271 out.addChar('\\'); // need to escape it for MathJax js code
272 out.addChar(data[i++]);
273 break;
274 case '\n':
275 line++;
276 out.addChar(data[i++]);
277 break;
278 default:
279 out.addChar(data[i++]);
280 break;
281 }
282 }
283 if (i > size)
284 {
285 warn(macrofile,line, "file contains non valid code, no closing '}}' for replacement");
286 return "";
287 }
288 out.addChar('}');
289 out.addChar('"');
290 if (!nr.isEmpty())
291 {
292 out.addChar(',');
293 out.addStr(nr);
294 }
295 if (!nr.isEmpty())
296 {
297 out.addChar(']');
298 }
299 out.addChar(',');
300 out.addChar('\n');
301 }
302 out.addChar(0);
303 return out.get();
304}
305
306static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
307{
308 TextStream t;
309 if (serverSide)
310 {
311 writeServerSearchBox(t, relPath, highlightSearch);
312 }
313 else
314 {
315 writeClientSearchBox(t, relPath);
316 }
317 return t.str();
318}
319
321 const QCString &title,
322 const QCString &relPath,
323 const QCString &navPath=QCString())
324{
325 // Build CSS/JavaScript tags depending on treeview, search engine settings
326 QCString cssFile;
327 QCString generatedBy;
328 QCString treeViewCssJs;
329 QCString searchCssJs;
330 QCString searchBox;
331 QCString mathJaxJs;
332 QCString extraCssText;
333
334 QCString projectName = Config_getString(PROJECT_NAME);
335 bool treeView = Config_getBool(GENERATE_TREEVIEW);
336 bool searchEngine = Config_getBool(SEARCHENGINE);
337 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
338 bool mathJax = Config_getBool(USE_MATHJAX);
339 QCString mathJaxFormat = Config_getEnumAsString(MATHJAX_FORMAT);
340 bool disableIndex = Config_getBool(DISABLE_INDEX);
341 bool hasProjectName = !projectName.isEmpty();
342 bool hasProjectNumber = !Config_getString(PROJECT_NUMBER).isEmpty();
343 bool hasProjectBrief = !Config_getString(PROJECT_BRIEF).isEmpty();
344 bool hasProjectLogo = !Config_getString(PROJECT_LOGO).isEmpty();
345 bool hasProjectIcon = !Config_getString(PROJECT_ICON).isEmpty();
346 bool hasFullSideBar = Config_getBool(FULL_SIDEBAR) && /*disableIndex &&*/ treeView;
347 bool hasCopyClipboard = Config_getBool(HTML_COPY_CLIPBOARD);
348 bool hasCookie = treeView || searchEngine || Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE;
349 static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
350
351 cssFile = Config_getString(HTML_STYLESHEET);
352 if (cssFile.isEmpty())
353 {
354 cssFile = "doxygen.css";
355 }
356 else
357 {
358 if (!cssFile.startsWith("http:") && !cssFile.startsWith("https:"))
359 {
360 FileInfo cssfi(cssFile.str());
361 if (cssfi.exists())
362 {
363 cssFile = cssfi.fileName();
364 }
365 else
366 {
367 cssFile = "doxygen.css";
368 }
369 }
370 }
371
372 extraCssText = "";
373 const StringVector &extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
374 for (const auto &fileName : extraCssFile)
375 {
376 if (!fileName.empty())
377 {
378 QCString htmlStyleSheet = fileName.c_str();
379 if (htmlStyleSheet.startsWith("http:") || htmlStyleSheet.startsWith("https:"))
380 {
381 extraCssText += "<link href=\""+htmlStyleSheet+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
382 }
383 else
384 {
385 FileInfo fi(fileName);
386 if (fi.exists())
387 {
388 extraCssText += "<link href=\"$relpath^"+stripPath(fileName.c_str())+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
389 }
390 }
391 }
392 }
393
394 switch (Config_getEnum(TIMESTAMP))
395 {
396 case TIMESTAMP_t::YES:
397 case TIMESTAMP_t::DATETIME:
398 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::DateTime),
399 convertToHtml(Config_getString(PROJECT_NAME)));
400 break;
401 case TIMESTAMP_t::DATE:
402 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::Date),
403 convertToHtml(Config_getString(PROJECT_NAME)));
404 break;
405 case TIMESTAMP_t::NO:
406 generatedBy = theTranslator->trGeneratedBy();
407 break;
408 }
409 treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
410 if (treeView)
411 {
412 treeViewCssJs += "<script type=\"text/javascript\" src=\"$relpath^navtreedata.js\"></script>\n"
413 "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n";
414 }
415 treeViewCssJs += "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n";
416
417 if (searchEngine)
418 {
419 searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
420 if (!serverBasedSearch)
421 {
422 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/searchdata.js\"></script>\n";
423 }
424 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
425
426 if (!serverBasedSearch)
427 {
428 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS) || Config_getBool(FULL_SIDEBAR))
429 {
430 searchCssJs += "<script type=\"text/javascript\">\n"
431 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
432 " $(function() { init_search(); });\n"
433 "/* @license-end */\n"
434 "</script>";
435 }
436 }
437 else
438 {
439 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS))
440 {
441 searchCssJs += "<script type=\"text/javascript\">\n"
442 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
443 " $(function() {\n"
444 " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
445 " });\n"
446 " /* @license-end */\n"
447 "</script>\n";
448 }
449
450 // OPENSEARCH_PROVIDER {
451 searchCssJs += "<link rel=\"search\" href=\"" + relPath +
452 "search_opensearch.php?v=opensearch.xml\" "
453 "type=\"application/opensearchdescription+xml\" title=\"" +
454 (hasProjectName ? projectName : QCString("Doxygen")) +
455 "\"/>";
456 // OPENSEARCH_PROVIDER }
457 }
458 searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
459 }
460
461 if (mathJax)
462 {
463 auto mathJaxVersion = Config_getEnum(MATHJAX_VERSION);
464 QCString path = Config_getString(MATHJAX_RELPATH);
465 if (path.isEmpty() || path.startsWith("..")) // relative path
466 {
467 path.prepend(relPath);
468 }
469
470 switch (mathJaxVersion)
471 {
472 case MATHJAX_VERSION_t::MathJax_3:
473 {
474 mathJaxJs += // "<script src=\"https://polyfill.io/v3/polyfill.min.js?features=es6\"></script>\n" // needed for IE11 only, see #10354
475 "<script type=\"text/javascript\">\n"
476 "window.MathJax = {\n"
477 " options: {\n"
478 " ignoreHtmlClass: 'tex2jax_ignore',\n"
479 " processHtmlClass: 'tex2jax_process'\n"
480 " }";
481 const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
482 if (!mathJaxExtensions.empty() || !g_latex_macro.isEmpty())
483 {
484 mathJaxJs+= ",\n";
485 if (!mathJaxExtensions.empty())
486 {
487 bool first = true;
488 mathJaxJs+= " loader: {\n"
489 " load: [";
490 for (const auto &s : mathJaxExtensions)
491 {
492 if (!first) mathJaxJs+= ",";
493 mathJaxJs+= "'[tex]/"+QCString(s.c_str())+"'";
494 first = false;
495 }
496 mathJaxJs+= "]\n"
497 " },\n";
498 }
499 mathJaxJs+= " tex: {\n"
500 " macros: {";
501 if (!g_latex_macro.isEmpty())
502 {
503 mathJaxJs += g_latex_macro+" ";
504 }
505 mathJaxJs+="},\n"
506 " packages: ['base','configmacros'";
507 if (!g_latex_macro.isEmpty())
508 {
509 mathJaxJs+= ",'newcommand'";
510 }
511 for (const auto &s : mathJaxExtensions)
512 {
513 mathJaxJs+= ",'"+QCString(s.c_str())+"'";
514 }
515 mathJaxJs += "]\n"
516 " }\n";
517 }
518 else
519 {
520 mathJaxJs += "\n";
521 }
522 mathJaxJs += "};\n";
523 // MATHJAX_CODEFILE
524 if (!g_mathjax_code.isEmpty())
525 {
526 mathJaxJs += g_mathjax_code;
527 mathJaxJs += "\n";
528 }
529 mathJaxJs += "</script>\n";
530 mathJaxJs += "<script type=\"text/javascript\" id=\"MathJax-script\" async=\"async\" src=\"" +
531 path + "es5/tex-" + mathJaxFormat.lower() + ".js\">";
532 mathJaxJs+="</script>\n";
533 }
534 break;
535 case MATHJAX_VERSION_t::MathJax_2:
536 {
537 mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
538 "MathJax.Hub.Config({\n"
539 " extensions: [\"tex2jax.js\"";
540 const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
541 for (const auto &s : mathJaxExtensions)
542 {
543 mathJaxJs+= ", \""+QCString(s.c_str())+".js\"";
544 }
545 if (mathJaxFormat.isEmpty())
546 {
547 mathJaxFormat = "HTML-CSS";
548 }
549 mathJaxJs += "],\n"
550 " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n";
551 if (!g_latex_macro.isEmpty())
552 {
553 mathJaxJs += " TeX: { Macros: {\n";
554 mathJaxJs += g_latex_macro;
555 mathJaxJs += "\n"
556 " } }\n";
557 }
558 mathJaxJs += "});\n";
559 if (!g_mathjax_code.isEmpty())
560 {
561 mathJaxJs += g_mathjax_code;
562 mathJaxJs += "\n";
563 }
564 mathJaxJs += "</script>\n";
565 mathJaxJs += "<script type=\"text/javascript\" async=\"async\" src=\"" + path + "MathJax.js\"></script>\n";
566 }
567 break;
568 }
569 }
570
571 QCString darkModeJs;
572 if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
573 {
574 darkModeJs="<script type=\"text/javascript\" src=\"$relpath^darkmode_toggle.js\"></script>\n";
575 }
576
577 if (hasCookie) // extend the $treeview tag to avoid breaking old files used with HTML_HEADER
578 {
579 treeViewCssJs+="<script type=\"text/javascript\" src=\"$relpath^cookie.js\"></script>\n";
580 }
581
582 // first substitute generic keywords
583 QCString result = substituteKeywords(str,title,
584 convertToHtml(Config_getString(PROJECT_NAME)),
585 convertToHtml(Config_getString(PROJECT_NUMBER)),
586 convertToHtml(Config_getString(PROJECT_BRIEF)));
587
588 // then do the HTML specific keywords
589 result = substituteKeywords(result,
590 {
591 // keyword value getter
592 { "$navpath", [&]() { return navPath; } },
593 { "$stylesheet", [&]() { return cssFile; } },
594 { "$treeview", [&]() { return treeViewCssJs; } },
595 { "$searchbox", [&]() { return searchBox; } },
596 { "$search", [&]() { return searchCssJs; } },
597 { "$mathjax", [&]() { return mathJaxJs; } },
598 { "$darkmode", [&]() { return darkModeJs; } },
599 { "$generatedby", [&]() { return generatedBy; } },
600 { "$extrastylesheet",[&]() { return extraCssText; } },
601 { "$relpath$", [&]() { return relPath; } } //<-- obsolete: for backwards compatibility only
602 });
603
604 result = substitute(result,"$relpath^",relPath); //<-- must be done after the previous substitutions
605
606 // remove conditional blocks
607 result = selectBlocks(result,
608 {
609 // keyword, is enabled
610 { "FULL_SIDEBAR", hasFullSideBar },
611 { "DISABLE_INDEX", disableIndex },
612 { "GENERATE_TREEVIEW", treeView },
613 { "SEARCHENGINE", searchEngine },
614 { "TITLEAREA", titleArea },
615 { "PROJECT_NAME", hasProjectName },
616 { "PROJECT_NUMBER", hasProjectNumber },
617 { "PROJECT_BRIEF", hasProjectBrief },
618 { "PROJECT_LOGO", hasProjectLogo },
619 { "PROJECT_ICON", hasProjectIcon },
620 { "COPY_CLIPBOARD", hasCopyClipboard },
622
623 result = removeEmptyLines(result);
624
625 return result;
626}
627
628//---------------------------------------------------------------------------------------------
629
632
633static void fillColorStyleMap(const QCString &definitions,StringUnorderedMap &map)
634{
635 int p=0,i=0;
636 while ((i=definitions.find('\n',p))!=-1)
637 {
638 QCString line = definitions.mid(p,i-p);
639 if (line.startsWith("--"))
640 {
641 int separator = line.find(':');
642 assert(separator!=-1);
643 std::string key = line.left(separator).str();
644 int semi = line.findRev(';');
645 assert(semi!=-1);
646 std::string value = line.mid(separator+1,semi-separator-1).stripWhiteSpace().str();
647 map.emplace(key,value);
648 //printf("var(%s)=%s\n",qPrint(key),qPrint(value));
649 }
650 p=i+1;
651 }
652}
653
655{
657 auto colorStyle = Config_getEnum(HTML_COLORSTYLE);
658 if (colorStyle==HTML_COLORSTYLE_t::LIGHT)
659 {
660 fillColorStyleMap(replaceColorMarkers(mgr.getAsString("lightmode_settings.css")),g_lightMap);
661 }
662 else if (colorStyle==HTML_COLORSTYLE_t::DARK)
663 {
664 fillColorStyleMap(replaceColorMarkers(mgr.getAsString("darkmode_settings.css")),g_darkMap);
665 }
666}
667
669{
670 auto doReplacements = [&input](const StringUnorderedMap &mapping) -> QCString
671 {
672 GrowBuf output;
673 int p=0,i=0;
674 while ((i=input.find("var(",p))!=-1)
675 {
676 output.addStr(input.data()+p,i-p);
677 int j=input.find(")",i+4);
678 assert(j!=-1);
679 auto it = mapping.find(input.mid(i+4,j-i-4).str()); // find variable
680 assert(it!=mapping.end()); // should be found
681 output.addStr(it->second); // add it value
682 //printf("replace '%s' by '%s'\n",qPrint(input.mid(i+4,j-i-4)),qPrint(it->second));
683 p=j+1;
684 }
685 output.addStr(input.data()+p,input.length()-p);
686 output.addChar(0);
687 return output.get();
688 };
689
690 auto colorStyle = Config_getEnum(HTML_COLORSTYLE);
691 if (colorStyle==HTML_COLORSTYLE_t::LIGHT)
692 {
693 return doReplacements(g_lightMap);
694 }
695 else if (colorStyle==HTML_COLORSTYLE_t::DARK)
696 {
697 return doReplacements(g_darkMap);
698 }
699 else
700 {
701 return input;
702 }
703}
704
705//----------------------------------------------------------------------------------------------
706
707
708//--------------------------------------------------------------------------
709
711{
712 //printf("%p:HtmlCodeGenerator()\n",(void*)this);
713}
714
716 : m_t(t), m_relPath(relPath)
717{
718 //printf("%p:HtmlCodeGenerator()\n",(void*)this);
719}
720
722{
723 m_relPath = path;
724}
725
727{
728 if (!str.isEmpty())
729 {
730 int tabSize = Config_getInt(TAB_SIZE);
731 const char *p=str.data();
732 if (m_hide) // only update column count
733 {
735 }
736 else // actually output content and keep track of m_col
737 {
738 while (*p)
739 {
740 char c=*p++;
741 switch(c)
742 {
743 case '\t': {
744 int spacesToNextTabStop = tabSize - (m_col%tabSize);
745 while (spacesToNextTabStop--)
746 {
747 if (m_col>=m_stripIndentAmount) *m_t << " ";
748 m_col++;
749 }
750 }
751 break;
752 case ' ': if (m_col>=m_stripIndentAmount) *m_t << " ";
753 m_col++;
754 break;
755 case '\n': *m_t << "\n"; m_col=0;
756 break;
757 case '\r': break;
758 case '<': *m_t << "&lt;"; m_col++;
759 break;
760 case '>': *m_t << "&gt;"; m_col++;
761 break;
762 case '&': *m_t << "&amp;"; m_col++;
763 break;
764 case '\'': *m_t << "&#39;"; m_col++; // &apos; is not valid XHTML
765 break;
766 case '"': *m_t << "&quot;"; m_col++;
767 break;
768 case '\\':
769 if (*p=='<')
770 { *m_t << "&lt;"; p++; }
771 else if (*p=='>')
772 { *m_t << "&gt;"; p++; }
773 else if (*p=='(')
774 { *m_t << "\\&zwj;("; m_col++;p++; }
775 else if (*p==')')
776 { *m_t << "\\&zwj;)"; m_col++;p++; }
777 else
778 *m_t << "\\";
779 m_col++;
780 break;
781 default:
782 {
783 uint8_t uc = static_cast<uint8_t>(c);
784 if (uc<32)
785 {
786 *m_t << "&#x24" << hex[uc>>4] << hex[uc&0xF] << ";";
787 m_col++;
788 }
789 else if (uc<0x80) // printable ASCII char
790 {
791 *m_t << c;
792 m_col++;
793 }
794 else // multibyte UTF-8 char
795 {
796 p=writeUTF8Char(*m_t,p-1);
797 m_col++;
798 }
799 }
800 break;
801 }
802 }
803 }
804 }
805}
806
811
813{
815 //*m_t << "[START]";
816}
817
819{
820 //*m_t << "[END]";
821 m_hide = false;
822}
823
825{
826 m_stripIndentAmount = amount;
827}
828
830 const QCString &anchor,int l,bool writeLineAnchor)
831{
832 m_lastLineInfo = LineInfo(ref,filename,anchor,l,writeLineAnchor);
833 if (m_hide) return;
834 const int maxLineNrStr = 10;
835 char lineNumber[maxLineNrStr];
836 char lineAnchor[maxLineNrStr];
837 qsnprintf(lineNumber,maxLineNrStr,"%5d",l);
838 qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l);
839
840 if (!m_lineOpen)
841 {
842 *m_t << "<div class=\"line\">";
844 }
845
846 if (writeLineAnchor) *m_t << "<a id=\"" << lineAnchor << "\" name=\"" << lineAnchor << "\"></a>";
847 *m_t << "<span class=\"lineno\">";
848 if (!filename.isEmpty())
849 {
850 _writeCodeLink("line",ref,filename,anchor,lineNumber,QCString());
851 }
852 else
853 {
854 codify(lineNumber);
855 }
856 *m_t << "</span>";
857 m_col=0;
858}
859
861 const QCString &ref,const QCString &f,
862 const QCString &anchor, const QCString &name,
863 const QCString &tooltip)
864{
865 if (m_hide) return;
866 const char *hl = codeSymbolType2Str(type);
867 QCString hlClass = "code";
868 if (hl)
869 {
870 hlClass+=" hl_";
871 hlClass+=hl;
872 }
873 _writeCodeLink(hlClass,ref,f,anchor,name,tooltip);
874}
875
877 const QCString &ref,const QCString &f,
878 const QCString &anchor, const QCString &name,
879 const QCString &tooltip)
880{
881 m_col+=name.length();
882 if (m_hide) return;
883 if (!ref.isEmpty())
884 {
885 *m_t << "<a class=\"" << className << "Ref\" ";
887 }
888 else
889 {
890 *m_t << "<a class=\"" << className << "\" ";
891 }
892 *m_t << "href=\"";
893 QCString fn = f;
895 *m_t << createHtmlUrl(m_relPath,ref,true,
896 fileName()==fn,fn,anchor);
897 *m_t << "\"";
898 if (!tooltip.isEmpty()) *m_t << " title=\"" << convertToHtml(tooltip) << "\"";
899 *m_t << ">";
900 codify(name);
901 *m_t << "</a>";
902}
903
905 const QCString &decl, const QCString &desc,
906 const SourceLinkInfo &defInfo,
907 const SourceLinkInfo &declInfo)
908{
909 if (m_hide) return;
910 *m_t << "<div class=\"ttc\" id=\"" << id << "\">";
911 *m_t << "<div class=\"ttname\">";
912 if (!docInfo.url.isEmpty())
913 {
914 *m_t << "<a href=\"";
915 QCString fn = docInfo.url;
917 *m_t << createHtmlUrl(m_relPath,docInfo.ref,true,
918 fileName()==fn,fn,docInfo.anchor);
919 *m_t << "\">";
920 }
921 codify(docInfo.name);
922 if (!docInfo.url.isEmpty())
923 {
924 *m_t << "</a>";
925 }
926 *m_t << "</div>";
927
928 if (!decl.isEmpty())
929 {
930 *m_t << "<div class=\"ttdeci\">";
931 codify(decl);
932 *m_t << "</div>";
933 }
934
935 if (!desc.isEmpty())
936 {
937 *m_t << "<div class=\"ttdoc\">";
938 codify(desc);
939 *m_t << "</div>";
940 }
941
942 if (!defInfo.file.isEmpty())
943 {
944 *m_t << "<div class=\"ttdef\"><b>" << theTranslator->trDefinition() << "</b> ";
945 if (!defInfo.url.isEmpty())
946 {
947 *m_t << "<a href=\"";
948 QCString fn = defInfo.url;
950 *m_t << createHtmlUrl(m_relPath,defInfo.ref,true,
951 fileName()==fn,fn,defInfo.anchor);
952 *m_t << "\">";
953 }
954 *m_t << defInfo.file << ":" << defInfo.line;
955 if (!defInfo.url.isEmpty())
956 {
957 *m_t << "</a>";
958 }
959 *m_t << "</div>";
960 }
961 if (!declInfo.file.isEmpty())
962 {
963 *m_t << "<div class=\"ttdecl\"><b>" << theTranslator->trDeclaration() << "</b> ";
964 if (!declInfo.url.isEmpty())
965 {
966 *m_t << "<a href=\"";
967 QCString fn = declInfo.url;
969 *m_t << createHtmlUrl(m_relPath,declInfo.ref,true,
970 fileName()==fn,fn,declInfo.anchor);
971 *m_t << "\">";
972 }
973 *m_t << declInfo.file << ":" << declInfo.line;
974 if (!declInfo.url.isEmpty())
975 {
976 *m_t << "</a>";
977 }
978 *m_t << "</div>";
979 }
980 *m_t << "</div>\n";
981}
982
983
985{
986 m_col=0;
987 if (m_hide) return;
988 if (!m_lineOpen)
989 {
990 *m_t << "<div class=\"line\">";
992 }
993}
994
996{
997 if (m_hide) return;
998 if (m_col == 0)
999 {
1000 *m_t << " ";
1001 m_col++;
1002 }
1003 if (m_lineOpen)
1004 {
1005 *m_t << "</div>\n";
1006 m_lineOpen = FALSE;
1007 }
1008}
1009
1011{
1012 if (m_hide) return;
1013 *m_t << "<span class=\"" << s << "\">";
1014}
1015
1017{
1018 if (m_hide) return;
1019 *m_t << "</span>";
1020}
1021
1023{
1024 if (m_hide) return;
1025 *m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>";
1026}
1027
1029{
1030 *m_t << "<div class=\"fragment\">";
1031}
1032
1034{
1035 //endCodeLine checks is there is still an open code line, if so closes it.
1036 endCodeLine();
1037
1038 *m_t << "</div><!-- fragment -->";
1039}
1040
1041void HtmlCodeGenerator::startFold(int lineNr,const QCString &startMarker,const QCString &endMarker)
1042{
1043 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to end the line
1044 {
1045 *m_t << "</div>\n";
1046 }
1047 const int maxLineNrStr = 10;
1048 char lineNumber[maxLineNrStr];
1049 qsnprintf(lineNumber,maxLineNrStr,"%05d",lineNr);
1050 *m_t << "<div class=\"foldopen\" id=\"foldopen" << lineNumber <<
1051 "\" data-start=\"" << startMarker <<
1052 "\" data-end=\"" << endMarker <<
1053 "\">\n";
1054 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to restart the line
1055 {
1056 *m_t << "<div class=\"line\">";
1057 }
1058 m_hide=false;
1059}
1060
1062{
1063 *m_t << "<div class=\"line\">";
1064 bool wasHidden=m_hide;
1065 m_hide = false;
1066 m_lineOpen = true;
1068 m_lastLineInfo.fileName,
1069 m_lastLineInfo.anchor,
1070 m_lastLineInfo.line+1,
1071 m_lastLineInfo.writeAnchor);
1072 m_hide = wasHidden;
1073}
1074
1076{
1077 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to end the line
1078 {
1079 *m_t << "</div>\n";
1080 }
1081 *m_t << "</div>\n";
1082 if (m_lineOpen)
1083 {
1085 }
1086}
1087
1088//--------------------------------------------------------------------------
1089
1091 : OutputGenerator(Config_getString(HTML_OUTPUT))
1092 , m_codeList(std::make_unique<OutputCodeList>())
1093{
1094 //printf("%p:HtmlGenerator()\n",(void*)this);
1096}
1097
1099{
1100 //printf("%p:HtmlGenerator(copy %p)\n",(void*)this,(void*)&og);
1101 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
1103 m_codeGen->setTextStream(&m_t);
1106 m_relPath = og.m_relPath;
1109}
1110
1112{
1113 //printf("%p:HtmlGenerator(copy assign %p)\n",(void*)this,(void*)&og);
1114 if (this!=&og)
1115 {
1116 m_dir = og.m_dir;
1117 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
1119 m_codeGen->setTextStream(&m_t);
1122 m_relPath = og.m_relPath;
1125 }
1126 return *this;
1127}
1128
1130
1135
1137{
1138 QCString dname = Config_getString(HTML_OUTPUT);
1139 Dir d(dname.str());
1140 if (!d.exists() && !d.mkdir(dname.str()))
1141 {
1142 term("Could not create output directory {}\n",dname);
1143 }
1144 //writeLogo(dname);
1145 if (!Config_getString(HTML_HEADER).isEmpty())
1146 {
1148 //printf("g_header='%s'\n",qPrint(g_header));
1150 checkBlocks(result,Config_getString(HTML_HEADER),htmlMarkerInfo);
1151 }
1152 else
1153 {
1154 g_header = ResourceMgr::instance().getAsString("header.html");
1156 checkBlocks(result,"<default header.html>",htmlMarkerInfo);
1157 }
1158
1159 if (!Config_getString(HTML_FOOTER).isEmpty())
1160 {
1162 //printf("g_footer='%s'\n",qPrint(g_footer));
1164 checkBlocks(result,Config_getString(HTML_FOOTER),htmlMarkerInfo);
1165 }
1166 else
1167 {
1168 g_footer = ResourceMgr::instance().getAsString("footer.html");
1170 checkBlocks(result,"<default footer.html>",htmlMarkerInfo);
1171 }
1172
1173 if (Config_getBool(USE_MATHJAX))
1174 {
1175 if (!Config_getString(MATHJAX_CODEFILE).isEmpty())
1176 {
1177 g_mathjax_code=fileToString(Config_getString(MATHJAX_CODEFILE));
1178 //printf("g_mathjax_code='%s'\n",qPrint(g_mathjax_code));
1179 }
1181 //printf("converted g_latex_macro='%s'\n",qPrint(g_latex_macro));
1182 }
1183 createSubDirs(d);
1184
1186
1188
1189 {
1190 QCString tabsCss;
1191 if (Config_getBool(HTML_DYNAMIC_MENUS))
1192 {
1193 tabsCss = mgr.getAsString("tabs.css");
1194 }
1195 else // stylesheet for the 'old' static tabs
1196 {
1197 tabsCss = mgr.getAsString("fixed_tabs.css");
1198 }
1199
1200 std::ofstream f = Portable::openOutputStream(dname+"/tabs.css");
1201 if (f.is_open())
1202 {
1203 TextStream t(&f);
1204 t << replaceVariables(tabsCss);
1205 }
1206 }
1207
1208
1209 mgr.copyResource("jquery.js",dname);
1210 if (Config_getBool(INTERACTIVE_SVG))
1211 {
1212 mgr.copyResource("svg.min.js",dname);
1213 }
1214
1215 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
1216 {
1217 mgr.copyResource("menu.js",dname);
1218 }
1219
1220 // copy navtree.css
1221 {
1222 std::ofstream f = Portable::openOutputStream(dname+"/navtree.css");
1223 if (f.is_open())
1224 {
1225 TextStream t(&f);
1226 t << getNavTreeCss();
1227 }
1228 }
1229
1230 // copy resize.js
1231 {
1232 std::ofstream f = Portable::openOutputStream(dname+"/resize.js");
1233 if (f.is_open())
1234 {
1235 TextStream t(&f);
1236 t << substitute(
1237 substitute(mgr.getAsString("resize.js"),
1238 "$TREEVIEW_WIDTH", QCString().setNum(Config_getInt(TREEVIEW_WIDTH))),
1239 "$PROJECTID", getProjectId());
1240 }
1241 }
1242
1243 if (Config_getBool(HTML_COPY_CLIPBOARD))
1244 {
1245 std::ofstream f = Portable::openOutputStream(dname+"/clipboard.js");
1246 if (f.is_open())
1247 {
1248 TextStream t(&f);
1249 t << substitute(mgr.getAsString("clipboard.js"),"$copy_to_clipboard_text",theTranslator->trCopyToClipboard());
1250 }
1251 }
1252
1253 bool hasCookie = Config_getBool(GENERATE_TREEVIEW) || Config_getBool(SEARCHENGINE) || Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE;
1254 if (hasCookie)
1255 {
1256 mgr.copyResource("cookie.js",dname);
1257 }
1258
1259 if (Config_getBool(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1260 {
1261 std::ofstream f = Portable::openOutputStream(dname+"/darkmode_toggle.js");
1262 if (f.is_open())
1263 {
1264 TextStream t(&f);
1265 t << substitute(replaceColorMarkers(mgr.getAsString("darkmode_toggle.js")),
1266 "$PROJECTID",getProjectId());
1267 }
1268 }
1269
1270 {
1271 std::ofstream f = Portable::openOutputStream(dname+"/dynsections.js");
1272 if (f.is_open())
1273 {
1274 TextStream t(&f);
1275 t << replaceVariables(mgr.getAsString("dynsections.js"));
1276 if (Config_getBool(SOURCE_BROWSER) && Config_getBool(SOURCE_TOOLTIPS))
1277 {
1278 t << replaceVariables(mgr.getAsString("dynsections_tooltips.js"));
1279 }
1280 }
1281 }
1282}
1283
1285{
1286 QCString dname = Config_getString(HTML_OUTPUT);
1287 Dir d(dname.str());
1288 clearSubDirs(d);
1289}
1290
1291/// Additional initialization after indices have been created
1293{
1294 Doxygen::indexList->addStyleSheetFile("tabs.css");
1295 QCString dname=Config_getString(HTML_OUTPUT);
1297 //writeColoredImgData(dname,colored_tab_data);
1298 mgr.copyResource("tab_a.lum",dname); // active, light mode
1299 mgr.copyResource("tab_b.lum",dname); // normal, light mode
1300 mgr.copyResource("tab_h.lum",dname); // highlight, light mode
1301 mgr.copyResource("tab_s.lum",dname); // separator, light mode
1302 mgr.copyResource("tab_ad.lum",dname); // active, dark mode
1303 mgr.copyResource("tab_bd.lum",dname); // normal, dark mode
1304 mgr.copyResource("tab_hd.lum",dname); // highlight, dark mode
1305 mgr.copyResource("tab_sd.lum",dname); // separator, light mode
1306 mgr.copyResource("nav_h.lum",dname); // header gradient, light mode
1307 mgr.copyResource("nav_hd.lum",dname); // header gradient, dark mode
1308 mgr.copyResource("nav_f.lum",dname); // member definition header, light mode
1309 mgr.copyResource("nav_fd.lum",dname); // member definition header, dark mode
1310 mgr.copyResource("bc_s.luma",dname); // breadcrumb separator, light mode
1311 mgr.copyResource("bc_sd.luma",dname); // breadcrumb separator, dark mode
1312 mgr.copyResource("doxygen.svg",dname);
1313 Doxygen::indexList->addImageFile("doxygen.svg");
1314 mgr.copyResource("closed.luma",dname);
1315 mgr.copyResource("open.luma",dname);
1316 mgr.copyResource("sync_on.luma",dname);
1317 mgr.copyResource("sync_off.luma",dname);
1318 mgr.copyResource("nav_g.png",dname);
1319 Doxygen::indexList->addImageFile("nav_g.png");
1320 mgr.copyResource("plus.svg",dname);
1321 Doxygen::indexList->addImageFile("plus.svg");
1322 mgr.copyResource("minus.svg",dname);
1323 Doxygen::indexList->addImageFile("minus.svg");
1324 mgr.copyResource("plusd.svg",dname);
1325 Doxygen::indexList->addImageFile("plusd.svg");
1326 mgr.copyResource("minusd.svg",dname);
1327 Doxygen::indexList->addImageFile("minusd.svg");
1328}
1329
1331{
1332 //bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
1333 //writeImgData(dname,serverBasedSearch ? search_server_data : search_client_data);
1335
1336 // server side search resources
1337 mgr.copyResource("mag.svg",dname);
1338 mgr.copyResource("mag_d.svg",dname);
1339 Doxygen::indexList->addImageFile("search/mag.svg");
1340 Doxygen::indexList->addImageFile("search/mag_d.svg");
1341
1342 // client side search resources
1343 mgr.copyResource("close.svg",dname);
1344 Doxygen::indexList->addImageFile("search/close.svg");
1345 mgr.copyResource("mag_sel.svg",dname);
1346 mgr.copyResource("mag_seld.svg",dname);
1347 Doxygen::indexList->addImageFile("search/mag_sel.svg");
1348 Doxygen::indexList->addImageFile("search/mag_seld.svg");
1349
1350 QCString searchDirName = dname;
1351 std::ofstream f = Portable::openOutputStream(searchDirName+"/search.css");
1352 if (f.is_open())
1353 {
1354 TextStream t(&f);
1355 QCString searchCss;
1356 // the position of the search box depends on a number of settings.
1357 // Insert the right piece of CSS code depending on which options are selected
1358 if (Config_getBool(DISABLE_INDEX))
1359 {
1360 if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(FULL_SIDEBAR))
1361 {
1362 searchCss = mgr.getAsString("search_sidebar.css"); // we have a full height side bar
1363 }
1364 else if (Config_getBool(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1365 {
1366 searchCss = mgr.getAsString("search_nomenu_toggle.css"); // we have no tabs but do have a darkmode button
1367 }
1368 else
1369 {
1370 searchCss = mgr.getAsString("search_nomenu.css"); // we have no tabs and no darkmode button
1371 }
1372 }
1373 else if (!Config_getBool(HTML_DYNAMIC_MENUS))
1374 {
1375 searchCss = mgr.getAsString("search_fixedtabs.css"); // we have tabs, but they are static
1376 }
1377 else
1378 {
1379 searchCss = mgr.getAsString("search.css"); // default case with a dynamic menu bar
1380 }
1381 // and then add the option independent part of the styling
1382 searchCss += mgr.getAsString("search_common.css");
1383 searchCss = substitute(searchCss,"$doxygenversion",getDoxygenVersion());
1384 t << replaceVariables(searchCss);
1385 Doxygen::indexList->addStyleSheetFile("search/search.css");
1386 }
1387}
1388
1390{
1391 t << "/* The standard CSS for doxygen " << getDoxygenVersion() << "*/\n\n";
1392 switch (Config_getEnum(HTML_COLORSTYLE))
1393 {
1394 case HTML_COLORSTYLE_t::LIGHT:
1395 case HTML_COLORSTYLE_t::DARK:
1396 /* variables will be resolved while writing to the CSS file */
1397 break;
1398 case HTML_COLORSTYLE_t::AUTO_LIGHT:
1399 case HTML_COLORSTYLE_t::TOGGLE:
1400 t << "html {\n";
1401 t << replaceColorMarkers(ResourceMgr::instance().getAsString("lightmode_settings.css"));
1402 t << "}\n\n";
1403 break;
1404 case HTML_COLORSTYLE_t::AUTO_DARK:
1405 t << "html {\n";
1406 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1407 t << "}\n\n";
1408 break;
1409 }
1410 if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::AUTO_LIGHT)
1411 {
1412 t << "@media (prefers-color-scheme: dark) {\n";
1413 t << " html:not(.dark-mode) {\n";
1414 t << " color-scheme: dark;\n\n";
1415 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1416 t << "}}\n";
1417 }
1418 else if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::AUTO_DARK)
1419 {
1420 t << "@media (prefers-color-scheme: light) {\n";
1421 t << " html:not(.light-mode) {\n";
1422 t << " color-scheme: light;\n\n";
1423 t << replaceColorMarkers(ResourceMgr::instance().getAsString("lightmode_settings.css"));
1424 t << "}}\n";
1425 }
1426 else if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1427 {
1428 t << "html.dark-mode {\n";
1429 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1430 t << "}\n\n";
1431 }
1432
1433 t << replaceVariables(ResourceMgr::instance().getAsString("doxygen.css"));
1434
1435 // For Webkit based the scrollbar styling cannot be overruled (bug in chromium?).
1436 // To allow the user to style the scrollbars differently we should only add it in case
1437 // the user did not specify any extra stylesheets.
1438 bool addScrollbarStyling = Config_getList(HTML_EXTRA_STYLESHEET).empty();
1439 if (addScrollbarStyling)
1440 {
1441 t << replaceVariables(ResourceMgr::instance().getAsString("scrollbar.css"));
1442 }
1443
1444}
1445
1451
1453{
1454 t << "<!-- HTML header for doxygen " << getDoxygenVersion() << "-->\n";
1455 t << ResourceMgr::instance().getAsString("header.html");
1456}
1457
1459{
1460 t << "<!-- HTML footer for doxygen " << getDoxygenVersion() << "-->\n";
1461 t << ResourceMgr::instance().getAsString("footer.html");
1462}
1463
1464static std::mutex g_indexLock;
1465
1467 const QCString &title,int /*id*/, int /*hierarchyLevel*/)
1468{
1469 //printf("HtmlGenerator::startFile(%s)\n",qPrint(name));
1471 QCString fileName = name;
1473 m_lastTitle=title;
1474
1476 m_codeGen->setFileName(fileName);
1477 m_codeGen->setRelativePath(m_relPath);
1478 {
1479 std::lock_guard<std::mutex> lock(g_indexLock);
1480 Doxygen::indexList->addIndexFile(fileName);
1481 }
1482
1485
1486 m_t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
1487 << getDoxygenVersion() << " -->\n";
1488 bool searchEngine = Config_getBool(SEARCHENGINE);
1489 if (searchEngine /*&& !generateTreeView*/)
1490 {
1491 m_t << "<script type=\"text/javascript\">\n";
1492 m_t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
1493 m_t << "var searchBox = new SearchBox(\"searchBox\", \""
1494 << m_relPath<< "search/\",'" << Doxygen::htmlFileExtension << "');\n";
1495 m_t << "/* @license-end */\n";
1496 m_t << "</script>\n";
1497 }
1498 if (Config_getBool(HTML_CODE_FOLDING))
1499 {
1500 m_t << "<script type=\"text/javascript\">\n";
1501 m_t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
1502 m_t << "$(function() { codefold.init(" << (m_relPath.isEmpty() ? "0" : "1") << "); });\n";
1503 m_t << "/* @license-end */\n";
1504 m_t << "</script>\n";
1505 }
1507}
1508
1510{
1511 bool searchEngine = Config_getBool(SEARCHENGINE);
1512 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
1513 if (searchEngine && !serverBasedSearch)
1514 {
1515 t << "<!-- window showing the filter options -->\n";
1516 t << "<div id=\"MSearchSelectWindow\"\n";
1517 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
1518 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
1519 t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
1520 t << "</div>\n";
1521 t << "\n";
1522 t << "<!-- iframe showing the search results (closed by default) -->\n";
1523 t << "<div id=\"MSearchResultsWindow\">\n";
1524 t << "<div id=\"MSearchResults\">\n";
1525 t << "<div class=\"SRPage\">\n";
1526 t << "<div id=\"SRIndex\">\n";
1527 t << "<div id=\"SRResults\"></div>\n"; // here the results will be inserted
1528 t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>\n";
1529 t << "<div class=\"SRStatus\" id=\"Searching\">" << theTranslator->trSearching() << "</div>\n";
1530 t << "<div class=\"SRStatus\" id=\"NoMatches\">" << theTranslator->trNoMatches() << "</div>\n";
1531 t << "</div>\n"; // SRIndex
1532 t << "</div>\n"; // SRPage
1533 t << "</div>\n"; // MSearchResults
1534 t << "</div>\n"; // MSearchResultsWindow
1535 t << "\n";
1536 }
1537}
1538
1543
1544
1546{
1547 QCString result;
1548 switch (Config_getEnum(TIMESTAMP))
1549 {
1550 case TIMESTAMP_t::YES:
1551 case TIMESTAMP_t::DATETIME:
1552 result += theTranslator->trGeneratedAt(
1554 Config_getString(PROJECT_NAME)
1555 );
1556 break;
1557 case TIMESTAMP_t::DATE:
1558 result += theTranslator->trGeneratedAt(
1560 Config_getString(PROJECT_NAME)
1561 );
1562 break;
1563 case TIMESTAMP_t::NO:
1564 result += theTranslator->trGeneratedBy();
1565 break;
1566 }
1567 result += "&#160;\n<a href=\"https://www.doxygen.org/index.html\">\n"
1568 "<img class=\"footer\" src=\"";
1569 result += path;
1570 result += "doxygen.svg\" width=\"104\" height=\"31\" alt=\"doxygen\"/></a> ";
1571 result += getDoxygenVersion();
1572 result += " ";
1573 return result;
1574}
1575
1580
1582 const QCString &relPath,const QCString &navPath)
1583{
1584 t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
1585}
1586
1588{
1590}
1591
1593{
1594 endPlainFile();
1595}
1596
1598{
1599 m_t << "<h3 class=\"version\">";
1600}
1601
1603{
1604 m_t << "</h3>";
1605}
1606
1608{
1609 //printf("writeStyleInfo(%d)\n",part);
1610 if (part==0)
1611 {
1612 if (Config_getString(HTML_STYLESHEET).isEmpty()) // write default style sheet
1613 {
1614 //printf("write doxygen.css\n");
1615 startPlainFile("doxygen.css");
1617 endPlainFile();
1618 Doxygen::indexList->addStyleSheetFile("doxygen.css");
1619 }
1620 else // write user defined style sheet
1621 {
1622 QCString cssName=Config_getString(HTML_STYLESHEET);
1623 if (!cssName.startsWith("http:") && !cssName.startsWith("https:"))
1624 {
1625 FileInfo cssfi(cssName.str());
1626 if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1627 {
1628 err("style sheet {} does not exist or is not readable!\n", Config_getString(HTML_STYLESHEET));
1629 }
1630 else
1631 {
1632 // convert style sheet to string
1633 QCString fileStr = fileToString(cssName);
1634 // write the string into the output dir
1635 startPlainFile(cssfi.fileName().c_str());
1636 m_t << fileStr;
1637 endPlainFile();
1638 }
1639 Doxygen::indexList->addStyleSheetFile(cssfi.fileName().c_str());
1640 }
1641 }
1642 const StringVector &extraCssFiles = Config_getList(HTML_EXTRA_STYLESHEET);
1643 for (const auto &fileName : extraCssFiles)
1644 {
1645 if (!fileName.empty())
1646 {
1647 FileInfo fi(fileName);
1648 if (fi.exists())
1649 {
1650 Doxygen::indexList->addStyleSheetFile(fi.fileName().c_str());
1651 }
1652 }
1653 }
1654
1655 Doxygen::indexList->addStyleSheetFile("jquery.js");
1656 Doxygen::indexList->addStyleSheetFile("resize.js");
1657 Doxygen::indexList->addStyleSheetFile("navtree.css");
1658
1659 Doxygen::indexList->addStyleSheetFile("dynsections.js");
1660
1661 if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1662 {
1663 Doxygen::indexList->addStyleSheetFile("darkmode_toggle.js");
1664 }
1665
1666 if (Config_getBool(INTERACTIVE_SVG))
1667 {
1668 Doxygen::indexList->addStyleSheetFile("svg.min.js");
1669 }
1670
1671 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
1672 {
1673 Doxygen::indexList->addStyleSheetFile("menu.js");
1674 Doxygen::indexList->addStyleSheetFile("menudata.js");
1675 }
1676 }
1677}
1678
1680 const QCString &anchor, const QCString &,
1681 const QCString &)
1682{
1683 m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>";
1684}
1685
1687{
1688}
1689
1691{
1692}
1693
1695{
1696 if (!classDef.isEmpty())
1697 m_t << "\n<p class=\"" << classDef << "\">";
1698 else
1699 m_t << "\n<p>";
1700}
1701
1703{
1704 m_t << "</p>\n";
1705}
1706
1708{
1709 m_t << text;
1710}
1711
1713{
1714 m_t << "<li>";
1715}
1716
1718{
1719 m_t << "</li>\n";
1720}
1721
1723{
1724 //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1725 if (!ref.isEmpty() || !f.isEmpty())
1726 {
1727 if (!ref.isEmpty())
1728 {
1729 m_t << "<a class=\"elRef\" ";
1731 }
1732 else
1733 {
1734 m_t << "<a class=\"el\" ";
1735 }
1736 m_t << "href=\"";
1737 m_t << externalRef(m_relPath,ref,TRUE);
1738 if (!f.isEmpty())
1739 {
1740 QCString fn=f;
1742 m_t << fn;
1743 }
1744 m_t << "\">";
1745 }
1746 else
1747 {
1748 m_t << "<b>";
1749 }
1750}
1751
1753{
1754 //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1755 if (!ref.isEmpty() || !f.isEmpty())
1756 {
1757 m_t << "</a>";
1758 }
1759 else
1760 {
1761 m_t << "</b>";
1762 }
1763}
1764
1766 const QCString &path,const QCString &name)
1767{
1768 m_t << "<li>";
1769 if (!path.isEmpty()) docify(path);
1770 QCString fn = f;
1772 m_t << "<a class=\"el\" href=\"" << fn << "\">";
1773 docify(name);
1774 m_t << "</a> ";
1775}
1776
1778 const QCString &anchor, const QCString &name)
1779{
1780 if (!ref.isEmpty())
1781 {
1782 m_t << "<a class=\"elRef\" ";
1784 }
1785 else
1786 {
1787 m_t << "<a class=\"el\" ";
1788 }
1789 m_t << "href=\"";
1790 QCString fn = f;
1792 m_t << createHtmlUrl(m_relPath,ref,true,
1793 fileName() == Config_getString(HTML_OUTPUT)+"/"+fn,
1794 fn,
1795 anchor);
1796 m_t << "\">";
1797 docify(name);
1798 m_t << "</a>";
1799}
1800
1802{
1803 m_t << "<a href=\"";
1804 QCString fn = f;
1806 m_t << createHtmlUrl(m_relPath,"",true,
1807 fileName() == Config_getString(HTML_OUTPUT)+"/"+fn,
1808 fn,
1809 anchor);
1810 m_t << "\">";
1811}
1812
1814{
1815 m_t << "</a>";
1816}
1817
1818void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1819{
1820 if (extraIndentLevel==2)
1821 {
1822 m_t << "<h4 class=\"groupheader\">";
1823 }
1824 else if (extraIndentLevel==1)
1825 {
1826 m_t << "<h3 class=\"groupheader\">";
1827 }
1828 else // extraIndentLevel==0
1829 {
1830 m_t << "<h2 class=\"groupheader\">";
1831 }
1832}
1833
1834void HtmlGenerator::endGroupHeader(int extraIndentLevel)
1835{
1836 if (extraIndentLevel==2)
1837 {
1838 m_t << "</h4>\n";
1839 }
1840 else if (extraIndentLevel==1)
1841 {
1842 m_t << "</h3>\n";
1843 }
1844 else
1845 {
1846 m_t << "</h2>\n";
1847 }
1848}
1849
1851{
1852 switch(type.level())
1853 {
1854 case SectionType::Page: m_t << "\n\n<h1>"; break;
1855 case SectionType::Section: m_t << "\n\n<h2>"; break;
1856 case SectionType::Subsection: m_t << "\n\n<h3>"; break;
1857 case SectionType::Subsubsection: m_t << "\n\n<h4>"; break;
1858 case SectionType::Paragraph: m_t << "\n\n<h5>"; break;
1859 case SectionType::Subparagraph: m_t << "\n\n<h6>"; break;
1860 case SectionType::Subsubparagraph: m_t << "\n\n<h6>"; break;
1861 default: ASSERT(0); break;
1862 }
1863 m_t << "<a id=\"" << lab << "\" name=\"" << lab << "\"></a>";
1864}
1865
1867{
1868 switch(type.level())
1869 {
1870 case SectionType::Page: m_t << "</h1>"; break;
1871 case SectionType::Section: m_t << "</h2>"; break;
1872 case SectionType::Subsection: m_t << "</h3>"; break;
1873 case SectionType::Subsubsection: m_t << "</h4>"; break;
1874 case SectionType::Paragraph: m_t << "</h5>"; break;
1875 case SectionType::Subparagraph: m_t << "</h6>"; break;
1876 case SectionType::Subsubparagraph: m_t << "</h6>"; break;
1877 default: ASSERT(0); break;
1878 }
1879}
1880
1882{
1883 docify_(str,FALSE);
1884}
1885
1886void HtmlGenerator::docify_(const QCString &str,bool inHtmlComment)
1887{
1888 if (!str.isEmpty())
1889 {
1890 const char *p=str.data();
1891 while (*p)
1892 {
1893 char c=*p++;
1894 switch(c)
1895 {
1896 case '<': m_t << "&lt;"; break;
1897 case '>': m_t << "&gt;"; break;
1898 case '&': m_t << "&amp;"; break;
1899 case '"': m_t << "&quot;"; break;
1900 case '-': if (inHtmlComment) m_t << "&#45;"; else m_t << "-"; break;
1901 case '\\':
1902 if (*p=='<')
1903 { m_t << "&lt;"; p++; }
1904 else if (*p=='>')
1905 { m_t << "&gt;"; p++; }
1906 else if (*p=='(')
1907 { m_t << "\\&zwj;("; p++; }
1908 else if (*p==')')
1909 { m_t << "\\&zwj;)"; p++; }
1910 else
1911 m_t << "\\";
1912 break;
1913 default: m_t << c;
1914 }
1915 }
1916 }
1917}
1918
1920{
1921 char cs[2];
1922 cs[0]=c;
1923 cs[1]=0;
1924 docify(cs);
1925}
1926
1927//--- helper function for dynamic sections -------------------------
1928
1930 const QCString &relPath,int sectionCount)
1931{
1932 //t << "<!-- startSectionHeader -->";
1933 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1934 if (dynamicSections)
1935 {
1936 t << "<div id=\"dynsection-" << sectionCount << "\" "
1937 "onclick=\"return dynsection.toggleVisibility(this)\" "
1938 "class=\"dynheader closed\" "
1939 "style=\"cursor:pointer;\">\n";
1940 t << " <img id=\"dynsection-" << sectionCount << "-trigger\" src=\""
1941 << relPath << "closed.png\" alt=\"+\"/> ";
1942 }
1943 else
1944 {
1945 t << "<div class=\"dynheader\">\n";
1946 }
1947}
1948
1950{
1951 //t << "<!-- endSectionHeader -->";
1952 t << "</div>\n";
1953}
1954
1955static void startSectionSummary(TextStream &t,int sectionCount)
1956{
1957 //t << "<!-- startSectionSummary -->";
1958 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1959 if (dynamicSections)
1960 {
1961 t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
1962 "class=\"dynsummary\" "
1963 "style=\"display:block;\">\n";
1964 }
1965}
1966
1968{
1969 //t << "<!-- endSectionSummary -->";
1970 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1971 if (dynamicSections)
1972 {
1973 t << "</div>\n";
1974 }
1975}
1976
1977static void startSectionContent(TextStream &t,int sectionCount)
1978{
1979 //t << "<!-- startSectionContent -->";
1980 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1981 if (dynamicSections)
1982 {
1983 t << "<div id=\"dynsection-" << sectionCount << "-content\" "
1984 "class=\"dyncontent\" "
1985 "style=\"display:none;\">\n";
1986 }
1987 else
1988 {
1989 t << "<div class=\"dyncontent\">\n";
1990 }
1991}
1992
1994{
1995 //t << "<!-- endSectionContent -->";
1996 t << "</div>\n";
1997}
1998
1999//----------------------------
2000
2005
2007 const QCString &fileName,const QCString &name)
2008{
2013 TextStream tt;
2015 if (!tt.empty())
2016 {
2017 m_t << " <div class=\"center\">\n";
2018 m_t << " <img src=\"";
2019 m_t << m_relPath << fileName << ".png\" usemap=\"#" << convertToId(name);
2020 m_t << "_map\" alt=\"\"/>\n";
2021 m_t << " <map id=\"" << convertToId(name);
2022 m_t << "_map\" name=\"" << convertToId(name);
2023 m_t << "_map\">\n";
2024 m_t << tt.str();
2025 m_t << " </map>\n";
2026 m_t << "</div>";
2027 }
2028 else
2029 {
2030 m_t << " <div class=\"center\">\n";
2031 m_t << " <img src=\"";
2032 m_t << m_relPath << fileName << ".png\" alt=\"\"/>\n";
2033 m_t << " </div>";
2034 }
2037}
2038
2039
2041{
2042 DBG_HTML(m_t << "<!-- startMemberList -->\n")
2043}
2044
2046{
2047 DBG_HTML(m_t << "<!-- endMemberList -->\n")
2048}
2049
2050// anonymous type:
2051// 0 = single column right aligned
2052// 1 = double column left aligned
2053// 2 = single column left aligned
2055{
2056 DBG_HTML(m_t << "<!-- startMemberItem() -->\n")
2057 if (m_emptySection)
2058 {
2059 m_t << "<table class=\"memberdecls\">\n";
2061 }
2062 m_t << "<tr class=\"memitem:" << anchor;
2063 if (!inheritId.isEmpty())
2064 {
2065 m_t << " inherit " << inheritId;
2066 }
2067 m_t << "\"";
2068 if (!anchor.isEmpty())
2069 {
2070 m_t << " id=\"r_" << anchor << "\"";
2071 }
2072 m_t << ">";
2074}
2075
2077{
2079 {
2080 insertMemberAlign(false);
2081 }
2082 m_t << "</td></tr>\n";
2083}
2084
2088
2090{
2091 m_t << "</td></tr>\n";
2092 m_t << "<tr class=\"memitem:" << anchor;
2093 if (!inheritId.isEmpty())
2094 {
2095 m_t << " inherit " << inheritId;
2096 }
2097 m_t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
2098}
2099
2101{
2102 m_t << "<div class=\"compoundTemplParams\">";
2103}
2104
2106{
2107 m_t << "</div>";
2108}
2109
2111{
2112 DBG_HTML(m_t << "<!-- insertMemberAlign -->\n")
2113 QCString className = templ ? "memTemplItemRight" : "memItemRight";
2114 m_t << "&#160;</td><td class=\"" << className << "\" valign=\"bottom\">";
2115}
2116
2118{
2119 if (!initTag) m_t << "&#160;</td>";
2120 switch (type)
2121 {
2122 case MemberItemType::Normal: m_t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
2123 case MemberItemType::AnonymousStart: m_t << "<td class=\"memItemLeft\" >"; break;
2124 case MemberItemType::AnonymousEnd: m_t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
2125 case MemberItemType::Templated: m_t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
2126 }
2127}
2128
2129void HtmlGenerator::startMemberDescription(const QCString &anchor,const QCString &inheritId, bool typ)
2130{
2131 DBG_HTML(m_t << "<!-- startMemberDescription -->\n")
2132 if (m_emptySection)
2133 {
2134 m_t << "<table class=\"memberdecls\">\n";
2136 }
2137 m_t << "<tr class=\"memdesc:" << anchor;
2138 if (!inheritId.isEmpty())
2139 {
2140 m_t << " inherit " << inheritId;
2141 }
2142 m_t << "\">";
2143 m_t << "<td class=\"mdescLeft\">&#160;</td>";
2144 if (typ) m_t << "<td class=\"mdescLeft\">&#160;</td>";
2145 m_t << "<td class=\"mdescRight\">";
2146}
2147
2149{
2150 DBG_HTML(m_t << "<!-- endMemberDescription -->\n")
2151 m_t << "<br /></td></tr>\n";
2152}
2153
2155{
2156 DBG_HTML(m_t << "<!-- startMemberSections -->\n")
2157 m_emptySection=TRUE; // we postpone writing <table> until we actually
2158 // write a row to prevent empty tables, which
2159 // are not valid XHTML!
2160}
2161
2163{
2164 DBG_HTML(m_t << "<!-- endMemberSections -->\n")
2165 if (!m_emptySection)
2166 {
2167 m_t << "</table>\n";
2168 }
2169}
2170
2171void HtmlGenerator::startMemberHeader(const QCString &anchor, int typ)
2172{
2173 DBG_HTML(m_t << "<!-- startMemberHeader -->\n")
2174 if (!m_emptySection)
2175 {
2176 m_t << "</table>";
2178 }
2179 if (m_emptySection)
2180 {
2181 m_t << "<table class=\"memberdecls\">\n";
2183 }
2184 m_t << "<tr class=\"heading\"><td colspan=\"" << typ << "\"><h2 class=\"groupheader\">";
2185 if (!anchor.isEmpty())
2186 {
2187 m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>\n";
2188 }
2189}
2190
2192{
2193 DBG_HTML(m_t << "<!-- endMemberHeader -->\n")
2194 m_t << "</h2></td></tr>\n";
2195}
2196
2198{
2199 DBG_HTML(m_t << "<!-- startMemberSubtitle -->\n")
2200 m_t << "<tr><td class=\"ititle\" colspan=\"2\">";
2201}
2202
2204{
2205 DBG_HTML(m_t << "<!-- endMemberSubtitle -->\n")
2206 m_t << "</td></tr>\n";
2207}
2208
2210{
2211 m_t << "<table>\n";
2212}
2213
2215{
2216 m_t << "</table>\n";
2217}
2218
2220{
2221 //m_t << " <tr><td class=\"indexkey\">";
2222}
2223
2225{
2226 //m_t << "</td>";
2227}
2228
2230{
2231 //m_t << "<td class=\"indexvalue\">";
2232}
2233
2235{
2236 //m_t << "</td></tr>\n";
2237}
2238
2240{
2241 DBG_HTML(m_t << "<!-- startMemberDocList -->\n";)
2242}
2243
2245{
2246 DBG_HTML(m_t << "<!-- endMemberDocList -->\n";)
2247}
2248
2249void HtmlGenerator::startMemberDoc( const QCString &/* clName */, const QCString &/* memName */,
2250 const QCString &anchor, const QCString &title,
2251 int memCount, int memTotal, bool /* showInline */)
2252{
2253 DBG_HTML(m_t << "<!-- startMemberDoc -->\n";)
2254 m_t << "\n<h2 class=\"memtitle\">"
2255 << "<span class=\"permalink\"><a href=\"#" << anchor << "\">&#9670;&#160;</a></span>";
2256 docify(title);
2257 if (memTotal>1)
2258 {
2259 m_t << " <span class=\"overload\">[" << memCount << "/" << memTotal <<"]</span>";
2260 }
2261 m_t << "</h2>\n";
2262 m_t << "\n<div class=\"memitem\">\n";
2263 m_t << "<div class=\"memproto\">\n";
2264}
2265
2267{
2268 DBG_HTML(m_t << "<!-- startMemberDocPrefixItem -->\n";)
2269 m_t << "<div class=\"memtemplate\">\n";
2270}
2271
2273{
2274 DBG_HTML(m_t << "<!-- endMemberDocPrefixItem -->\n";)
2275 m_t << "</div>\n";
2276}
2277
2279{
2280 DBG_HTML(m_t << "<!-- startMemberDocName -->\n";)
2281
2282 m_t << " <table class=\"memname\">\n";
2283
2284 m_t << " <tr>\n";
2285 m_t << " <td class=\"memname\">";
2286}
2287
2289{
2290 DBG_HTML(m_t << "<!-- endMemberDocName -->\n";)
2291 m_t << "</td>\n";
2292}
2293
2295{
2296 DBG_HTML(m_t << "<!-- startParameterList -->\n";)
2297 m_t << " <td>";
2298 if (openBracket) m_t << "(";
2299 m_t << "</td>\n";
2300}
2301
2303{
2304 if (first)
2305 {
2306 DBG_HTML(m_t << "<!-- startFirstParameterType -->\n";)
2307 m_t << " <td class=\"paramtype\">";
2308 }
2309 else
2310 {
2311 DBG_HTML(m_t << "<!-- startParameterType -->\n";)
2312 m_t << " <tr>\n";
2313 m_t << " <td class=\"paramkey\">" << key << "</td>\n";
2314 m_t << " <td></td>\n";
2315 m_t << " <td class=\"paramtype\">";
2316 }
2317}
2318
2320{
2321 DBG_HTML(m_t << "<!-- endParameterType -->\n";)
2322 m_t << "</td>";
2323}
2324
2325void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
2326{
2327 DBG_HTML(m_t << "<!-- startParameterName -->\n";)
2328 m_t << " <td class=\"paramname\"><span class=\"paramname\"><em>";
2329}
2330
2332{
2333 DBG_HTML(m_t << "<!-- endParameterName -->\n";)
2334 m_t << "</em></span>";
2335}
2336
2338{
2339 DBG_HTML(m_t << "<!-- startParameterExtra -->\n";)
2340}
2341
2342void HtmlGenerator::endParameterExtra(bool last,bool emptyList, bool closeBracket)
2343{
2344 DBG_HTML(m_t << "<!-- endParameterExtra -->\n";)
2345 if (last)
2346 {
2347 if (emptyList)
2348 {
2349 if (closeBracket) m_t << "</td><td>)";
2350 m_t << "</td>\n";
2351 m_t << " <td>";
2352 }
2353 else
2354 {
2355 m_t << "&#160;";
2356 if (closeBracket) m_t << ")";
2357 }
2358 }
2359 else
2360 {
2361 m_t << "</td>\n";
2362 m_t << " </tr>\n";
2363 }
2364}
2365
2367{
2368 m_t << "<span class=\"paramdefsep\">";
2369 docify(s);
2370 m_t << "</span><span class=\"paramdefval\">";
2371}
2372
2374{
2375 m_t << "</span>";
2376}
2377
2379{
2380 DBG_HTML(m_t << "<!-- endParameterList -->\n";)
2381 m_t << "</td>\n";
2382 m_t << " </tr>\n";
2383}
2384
2385void HtmlGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2386{
2387 DBG_HTML(m_t << "<!-- exceptionEntry -->\n";)
2388 if (!closeBracket)
2389 {
2390 m_t << "</td>\n";
2391 m_t << " </tr>\n";
2392 m_t << " <tr>\n";
2393 m_t << " <td align=\"right\">";
2394 }
2395 // colspan 2 so it gets both parameter type and parameter name columns
2396 if (!prefix.isEmpty())
2397 m_t << prefix << "</td><td>(</td><td colspan=\"2\">";
2398 else if (closeBracket)
2399 m_t << "&#160;)</td><td></td><td></td><td>";
2400 else
2401 m_t << "</td><td></td><td colspan=\"2\">";
2402}
2403
2405{
2406 DBG_HTML(m_t << "<!-- endMemberDoc -->\n";)
2407 if (!hasArgs)
2408 {
2409 m_t << " </tr>\n";
2410 }
2411 m_t << " </table>\n";
2412 // m_t << "</div>\n";
2413}
2414
2419
2421{
2422 bool generateLegend = Config_getBool(GENERATE_LEGEND);
2423 bool umlLook = Config_getBool(UML_LOOK);
2428
2430 if (generateLegend && !umlLook)
2431 {
2432 QCString url = m_relPath+"graph_legend"+Doxygen::htmlFileExtension;
2433 m_t << "<center><span class=\"legend\">[";
2434 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2435 m_t << "<a ";
2436 if (generateTreeView) m_t << "target=\"top\" ";
2437 m_t << "href=\"";
2438 if (!url.isEmpty()) m_t << url;
2439 m_t << "\">";
2440 m_t << theTranslator->trLegend();
2441 m_t << "</a>";
2442 m_t << "]</span></center>";
2443 }
2444
2447}
2448
2453
2466
2471
2484
2489
2502
2507
2520
2525
2527{
2528 m_t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
2529}
2530
2532{
2533 m_t << "</div></td></tr>\n";
2534}
2535
2537{
2538 m_t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
2539}
2540
2542{
2543 m_t << "</div></td></tr>\n";
2544}
2545
2549
2551{
2552}
2553
2555{
2556 DBG_HTML(m_t << "<!-- startIndent -->\n";)
2557
2558 m_t << "<div class=\"memdoc\">\n";
2559}
2560
2562{
2563 DBG_HTML(m_t << "<!-- endIndent -->\n";)
2564 m_t << "\n</div>\n" << "</div>\n";
2565}
2566
2568{
2569}
2570
2572{
2573 for (int i=0; i<n; i++)
2574 {
2575 m_t << "&#160;";
2576 }
2577}
2578
2579void HtmlGenerator::startDescTable(const QCString &title,const bool hasInits)
2580{
2581 m_t << "<table class=\"fieldtable\">\n"
2582 << "<tr><th colspan=\"" << (hasInits?3:2) << "\">" << title << "</th></tr>";
2583}
2585{
2586 m_t << "</table>\n";
2587}
2588
2590{
2591 m_t << "<tr>";
2592}
2593
2595{
2596 m_t << "</tr>\n";
2597}
2598
2600{
2601 m_t << "<td class=\"fieldname\">";
2602}
2603
2605{
2606 m_t << "&#160;</td>";
2607}
2608
2610{
2611 m_t << "<td class=\"fieldinit\">";
2612}
2613
2615{
2616 m_t << "&#160;</td>";
2617}
2618
2620{
2621 m_t << "<td class=\"fielddoc\">";
2622}
2623
2625{
2626 m_t << "</td>";
2627}
2628
2630{
2631 m_t << "<dl class=\"section examples\"><dt>";
2632 docify(theTranslator->trExamples());
2633 m_t << "</dt>";
2634}
2635
2637{
2638 m_t << "</dl>\n";
2639}
2640
2641void HtmlGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int id)
2642{
2643 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2644 if (astImpl)
2645 {
2646 m_codeList->setId(id);
2647 HtmlDocVisitor visitor(m_t,*m_codeList,ctx,fileName());
2648 std::visit(visitor,astImpl->root);
2649 }
2650}
2651
2652//---------------- helpers for index generation -----------------------------
2653
2654static void startQuickIndexList(TextStream &t,bool topLevel=TRUE)
2655{
2656 if (!Config_getBool(DISABLE_INDEX))
2657 {
2658 if (topLevel)
2659 {
2660 t << " <div id=\"navrow1\" class=\"tabs\">\n";
2661 }
2662 else
2663 {
2664 t << " <div id=\"navrow2\" class=\"tabs2\">\n";
2665 }
2666 t << " <ul class=\"tablist\">\n";
2667 }
2668 else
2669 {
2670 t << "<ul>";
2671 }
2672}
2673
2675{
2676 if (!Config_getBool(DISABLE_INDEX))
2677 {
2678 t << " </ul>\n";
2679 t << " </div>\n";
2680 }
2681 else
2682 {
2683 t << "</ul>\n";
2684 }
2685}
2686
2688 bool hl,bool /*compact*/,
2689 const QCString &relPath)
2690{
2691 t << " <li";
2692 if (hl)
2693 {
2694 t << " class=\"current\"";
2695 }
2696 t << ">";
2697 if (!l.isEmpty()) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2698 t << "<span>";
2699}
2700
2701static void endQuickIndexItem(TextStream &t,const QCString &l)
2702{
2703 t << "</span>";
2704 if (!l.isEmpty()) t << "</a>";
2705 t << "</li>\n";
2706}
2707
2709{
2710 const auto &index = Index::instance();
2711 bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
2712 bool showFiles = Config_getBool(SHOW_FILES);
2713 switch (kind)
2714 {
2715 case LayoutNavEntry::MainPage: return TRUE;
2716 case LayoutNavEntry::User: return TRUE;
2717 case LayoutNavEntry::UserGroup: return TRUE;
2718 case LayoutNavEntry::Pages: return index.numIndexedPages()>0;
2719 case LayoutNavEntry::Topics: return index.numDocumentedGroups()>0;
2720 case LayoutNavEntry::Modules: return index.numDocumentedModules()>0;
2721 case LayoutNavEntry::ModuleList: return index.numDocumentedModules()>0;
2722 case LayoutNavEntry::ModuleMembers: return index.numDocumentedModuleMembers(ModuleMemberHighlight::All)>0;
2723 case LayoutNavEntry::Namespaces: return showNamespaces && index.numDocumentedNamespaces()>0;
2724 case LayoutNavEntry::NamespaceList: return showNamespaces && index.numDocumentedNamespaces()>0;
2725 case LayoutNavEntry::NamespaceMembers: return showNamespaces && index.numDocumentedNamespaceMembers(NamespaceMemberHighlight::All)>0;
2726 case LayoutNavEntry::Concepts: return index.numDocumentedConcepts()>0;
2727 case LayoutNavEntry::Classes: return index.numAnnotatedClasses()>0;
2728 case LayoutNavEntry::ClassList: return index.numAnnotatedClasses()>0;
2729 case LayoutNavEntry::ClassIndex: return index.numAnnotatedClasses()>0;
2730 case LayoutNavEntry::ClassHierarchy: return index.numHierarchyClasses()>0;
2731 case LayoutNavEntry::ClassMembers: return index.numDocumentedClassMembers(ClassMemberHighlight::All)>0;
2732 case LayoutNavEntry::Files: return showFiles && index.numDocumentedFiles()>0;
2733 case LayoutNavEntry::FileList: return showFiles && index.numDocumentedFiles()>0;
2734 case LayoutNavEntry::FileGlobals: return showFiles && index.numDocumentedFileMembers(FileMemberHighlight::All)>0;
2735 case LayoutNavEntry::Examples: return !Doxygen::exampleLinkedMap->empty();
2736 case LayoutNavEntry::Interfaces: return index.numAnnotatedInterfaces()>0;
2737 case LayoutNavEntry::InterfaceList: return index.numAnnotatedInterfaces()>0;
2738 case LayoutNavEntry::InterfaceIndex: return index.numAnnotatedInterfaces()>0;
2739 case LayoutNavEntry::InterfaceHierarchy: return index.numHierarchyInterfaces()>0;
2740 case LayoutNavEntry::Structs: return index.numAnnotatedStructs()>0;
2741 case LayoutNavEntry::StructList: return index.numAnnotatedStructs()>0;
2742 case LayoutNavEntry::StructIndex: return index.numAnnotatedStructs()>0;
2743 case LayoutNavEntry::Exceptions: return index.numAnnotatedExceptions()>0;
2744 case LayoutNavEntry::ExceptionList: return index.numAnnotatedExceptions()>0;
2745 case LayoutNavEntry::ExceptionIndex: return index.numAnnotatedExceptions()>0;
2746 case LayoutNavEntry::ExceptionHierarchy: return index.numHierarchyExceptions()>0;
2747 case LayoutNavEntry::None: // should never happen, means not properly initialized
2748 assert(kind != LayoutNavEntry::None);
2749 return FALSE;
2750 }
2751 return FALSE;
2752}
2753
2754static void renderQuickLinksAsTree(TextStream &t,const QCString &relPath,LayoutNavEntry *root)
2755
2756{
2757 int count=0;
2758 for (const auto &entry : root->children())
2759 {
2760 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2761 }
2762 if (count>0) // at least one item is visible
2763 {
2765 for (const auto &entry : root->children())
2766 {
2767 if (entry->visible() && quickLinkVisible(entry->kind()))
2768 {
2769 QCString url = entry->url();
2770 t << "<li><a href=\"" << relPath << url << "\"><span>";
2771 t << fixSpaces(entry->title());
2772 t << "</span></a>\n";
2773 // recursive into child list
2774 renderQuickLinksAsTree(t,relPath,entry.get());
2775 t << "</li>";
2776 }
2777 }
2779 }
2780}
2781
2782
2783static void renderQuickLinksAsTabs(TextStream &t,const QCString &relPath,
2785 bool highlightParent,bool highlightSearch)
2786{
2787 if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2788 {
2789 renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2790 }
2791 if (hlEntry->parent() && !hlEntry->parent()->children().empty()) // draw tabs for row containing hlEntry
2792 {
2793 bool topLevel = hlEntry->parent()->parent()==nullptr;
2794 int count=0;
2795 for (const auto &entry : hlEntry->parent()->children())
2796 {
2797 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2798 }
2799 if (count>0) // at least one item is visible
2800 {
2801 startQuickIndexList(t,topLevel);
2802 for (const auto &entry : hlEntry->parent()->children())
2803 {
2804 if (entry->visible() && quickLinkVisible(entry->kind()))
2805 {
2806 QCString url = entry->url();
2807 startQuickIndexItem(t,url,
2808 entry.get()==hlEntry &&
2809 (!entry->children().empty() ||
2810 (entry->kind()==kind && !highlightParent)
2811 ),
2812 TRUE,relPath);
2813 t << fixSpaces(entry->title());
2814 endQuickIndexItem(t,url);
2815 }
2816 }
2817 if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2818 {
2819 bool searchEngine = Config_getBool(SEARCHENGINE);
2820 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2821 bool disableIndex = Config_getBool(DISABLE_INDEX);
2822 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2823 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
2824 // case where DISABLE_INDEX=NO & GENERATE_TREEVIEW=YES & FULL_SIDEBAR=YES has search box in the side panel
2825 if (searchEngine)
2826 {
2827 t << " <li>\n";
2828 if (disableIndex || !generateTreeView || !fullSidebar)
2829 {
2830 if (!serverBasedSearch) // pure client side search
2831 {
2832 writeClientSearchBox(t,relPath);
2833 t << " </li>\n";
2834 }
2835 else // server based search
2836 {
2837 writeServerSearchBox(t,relPath,highlightSearch);
2838 if (!highlightSearch)
2839 {
2840 t << " </li>\n";
2841 }
2842 }
2843 }
2844 else
2845 {
2846 t << " </li>\n";
2847 }
2848 }
2849 if (!highlightSearch || Config_getBool(FULL_SIDEBAR))
2850 // on the search page the index will be ended by the page itself if the search box is part of the navigation bar
2851 {
2853 }
2854 }
2855 else // normal case for other rows than first one
2856 {
2858 }
2859 }
2860 }
2861}
2862
2864 HighlightedItem hli,
2865 const QCString &file,
2866 const QCString &relPath)
2867{
2868 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2869 bool searchEngine = Config_getBool(SEARCHENGINE);
2870 bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
2871 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2872 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
2873 bool disableIndex = Config_getBool(DISABLE_INDEX);
2875 LayoutNavEntry::Kind kind = LayoutNavEntry::None;
2876 LayoutNavEntry::Kind altKind = LayoutNavEntry::None; // fall back for the old layout file
2877 bool highlightParent=false;
2878 switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2879 {
2880 case HighlightedItem::Main: kind = LayoutNavEntry::MainPage; break;
2881 case HighlightedItem::Topics: kind = LayoutNavEntry::Topics; break;
2882 case HighlightedItem::Modules: kind = LayoutNavEntry::ModuleList; altKind = LayoutNavEntry::Modules; break;
2883 case HighlightedItem::Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break;
2884 case HighlightedItem::ClassHierarchy: kind = LayoutNavEntry::ClassHierarchy; break;
2885 case HighlightedItem::InterfaceHierarchy: kind = LayoutNavEntry::InterfaceHierarchy; break;
2886 case HighlightedItem::ExceptionHierarchy: kind = LayoutNavEntry::ExceptionHierarchy; break;
2887 case HighlightedItem::Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break;
2888 case HighlightedItem::Concepts: kind = LayoutNavEntry::Concepts; break;
2889 case HighlightedItem::Interfaces: kind = LayoutNavEntry::InterfaceIndex; altKind = LayoutNavEntry::Interfaces; break;
2890 case HighlightedItem::Structs: kind = LayoutNavEntry::StructIndex; altKind = LayoutNavEntry::Structs; break;
2891 case HighlightedItem::Exceptions: kind = LayoutNavEntry::ExceptionIndex; altKind = LayoutNavEntry::Exceptions; break;
2892 case HighlightedItem::AnnotatedClasses: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break;
2893 case HighlightedItem::AnnotatedInterfaces: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces; break;
2894 case HighlightedItem::AnnotatedStructs: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs; break;
2895 case HighlightedItem::AnnotatedExceptions: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions; break;
2896 case HighlightedItem::Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break;
2897 case HighlightedItem::NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2898 case HighlightedItem::ModuleMembers: kind = LayoutNavEntry::ModuleMembers; break;
2899 case HighlightedItem::Functions: kind = LayoutNavEntry::ClassMembers; break;
2900 case HighlightedItem::Globals: kind = LayoutNavEntry::FileGlobals; break;
2901 case HighlightedItem::Pages: kind = LayoutNavEntry::Pages; break;
2902 case HighlightedItem::Examples: kind = LayoutNavEntry::Examples; break;
2903 case HighlightedItem::UserGroup: kind = LayoutNavEntry::UserGroup; break;
2904 case HighlightedItem::ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes;
2905 highlightParent = true; break;
2906 case HighlightedItem::ConceptVisible: kind = LayoutNavEntry::Concepts;
2907 highlightParent = true; break;
2908 case HighlightedItem::ModuleVisible: kind = LayoutNavEntry::ModuleList; altKind = LayoutNavEntry::Modules;
2909 highlightParent = true; break;
2910 case HighlightedItem::InterfaceVisible: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces;
2911 highlightParent = true; break;
2912 case HighlightedItem::StructVisible: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs;
2913 highlightParent = true; break;
2914 case HighlightedItem::ExceptionVisible: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions;
2915 highlightParent = true; break;
2916 case HighlightedItem::NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces;
2917 highlightParent = true; break;
2918 case HighlightedItem::FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files;
2919 highlightParent = true; break;
2920 case HighlightedItem::None: break;
2921 case HighlightedItem::Search: break;
2922 }
2923
2924 if (!disableIndex && Config_getBool(HTML_DYNAMIC_MENUS))
2925 {
2926 QCString searchPage;
2927 if (externalSearch)
2928 {
2929 searchPage = "search" + Doxygen::htmlFileExtension;
2930 }
2931 else
2932 {
2933 searchPage = "search.php";
2934 }
2935 t << "<script type=\"text/javascript\" src=\"" << relPath << "menudata.js\"></script>\n";
2936 t << "<script type=\"text/javascript\" src=\"" << relPath << "menu.js\"></script>\n";
2937 t << "<script type=\"text/javascript\">\n";
2938 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
2939 t << "$(function() {\n";
2940 t << " initMenu('" << relPath << "',"
2941 << (searchEngine && !(generateTreeView && fullSidebar)?"true":"false") << ","
2942 << (serverBasedSearch?"true":"false") << ",'"
2943 << searchPage << "','"
2944 << theTranslator->trSearch() << "',"
2945 << (generateTreeView?"true":"false")
2946 << ");\n";
2947 if (Config_getBool(SEARCHENGINE))
2948 {
2949 if (!serverBasedSearch)
2950 {
2951 t << " $(function() { init_search(); });\n";
2952 }
2953 else
2954 {
2955 t << " $(function() {\n"
2956 << " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n";
2957 t << " });\n";
2958 }
2959 }
2960 t << "});\n";
2961 t << "/* @license-end */\n";
2962 t << "</script>\n";
2963 t << "<div id=\"main-nav\"></div>\n";
2964 }
2965 else if (!disableIndex) // && !Config_getBool(HTML_DYNAMIC_MENUS)
2966 {
2967 // find highlighted index item
2968 LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : QCString());
2969 if (!hlEntry && altKind!=LayoutNavEntry::None) { hlEntry=root->find(altKind); kind=altKind; }
2970 if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2971 {
2972 highlightParent=TRUE;
2973 hlEntry = root->children().front().get();
2974 if (hlEntry==nullptr)
2975 {
2976 return; // argl, empty index!
2977 }
2978 }
2979 if (kind==LayoutNavEntry::UserGroup)
2980 {
2981 LayoutNavEntry *e = hlEntry->children().front().get();
2982 if (e)
2983 {
2984 hlEntry = e;
2985 }
2986 }
2987 t << "<div id=\"main-nav\">\n";
2988 renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HighlightedItem::Search);
2989 t << "</div>\n";
2990 }
2991 else if (!generateTreeView)
2992 {
2993 renderQuickLinksAsTree(t,relPath,root);
2994 }
2995 if (generateTreeView && !disableIndex && fullSidebar)
2996 {
2997 t << "<div id=\"doc-content\">\n";
2998 }
2999}
3000
3002{
3003 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3004 m_t << "</div><!-- top -->\n";
3005 if (!generateTreeView)
3006 {
3007 m_t << "<div id=\"doc-content\">\n";
3008 }
3009}
3010
3012{
3013 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3014 QCString result;
3015 // write split bar
3016 if (generateTreeView)
3017 {
3018 QCString fn = name;
3020 if (/*!Config_getBool(DISABLE_INDEX) ||*/ !Config_getBool(FULL_SIDEBAR))
3021 {
3022 result += QCString(
3023 "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n");
3024 }
3025 result+=
3026 " <div id=\"nav-tree\">\n"
3027 " <div id=\"nav-tree-contents\">\n"
3028 " <div id=\"nav-sync\" class=\"sync\"></div>\n"
3029 " </div>\n"
3030 " </div>\n"
3031 " <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
3032 " class=\"ui-resizable-handle\">\n"
3033 " </div>\n"
3034 "</div>\n"
3035 "<script type=\"text/javascript\">\n"
3036 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
3037 "$(function(){initNavTree('" + fn +
3038 "','" + relpath +
3039 "'); initResizable(true); });\n"
3040 "/* @license-end */\n"
3041 "</script>\n";
3042 if (Config_getBool(DISABLE_INDEX) || !Config_getBool(FULL_SIDEBAR))
3043 {
3044 result+="<div id=\"doc-content\">\n";
3045 }
3046 }
3047 else
3048 {
3049 result += "<script type=\"text/javascript\">\n"
3050 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
3051 "$(function(){ initResizable(false); });\n"
3052 "/* @license-end */\n"
3053 "</script>\n";
3054 }
3055 return result;
3056}
3057
3059{
3061}
3062
3064{
3065 m_t << substitute(s,"$relpath^",m_relPath);
3066}
3067
3069{
3070 m_t << "<div class=\"contents\">\n";
3071}
3072
3074{
3075 m_t << "</div><!-- contents -->\n";
3076}
3077
3078void HtmlGenerator::startPageDoc(const QCString &/* pageTitle */)
3079{
3080 m_t << "<div>";
3081}
3082
3084{
3085 m_t << "</div><!-- PageDoc -->\n";
3086}
3087
3092
3093// PHP based search script
3095{
3096 bool disableIndex = Config_getBool(DISABLE_INDEX);
3097 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3098 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
3099 bool quickLinksAfterSplitbar = !disableIndex && generateTreeView && fullSidebar;
3100 QCString projectName = Config_getString(PROJECT_NAME);
3101 QCString htmlOutput = Config_getString(HTML_OUTPUT);
3102
3103 // OPENSEARCH_PROVIDER {
3104 QCString configFileName = htmlOutput+"/search_config.php";
3105 std::ofstream f = Portable::openOutputStream(configFileName);
3106 if (f.is_open())
3107 {
3108 TextStream t(&f);
3109 t << "<?php\n\n";
3110 t << "$config = array(\n";
3111 t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
3112 t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
3113 t << " 'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
3114 t << " 'FULL_SIDEBAR' => " << (fullSidebar?"true":"false") << ",\n";
3115 t << ");\n\n";
3116 t << "$translator = array(\n";
3117 t << " 'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
3118 t << " 'search_results' => array(\n";
3119 t << " 0 => \"" << theTranslator->trSearchResults(0) << "\",\n";
3120 t << " 1 => \"" << theTranslator->trSearchResults(1) << "\",\n";
3121 t << " 2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";
3122 t << " ),\n";
3123 t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
3124 t << " 'search' => \"" << theTranslator->trSearch() << "\",\n";
3125 t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
3126 t << ");\n\n";
3127 t << "?>\n";
3128 }
3129 f.close();
3130
3131 ResourceMgr::instance().copyResource("search_functions.php",htmlOutput);
3132 ResourceMgr::instance().copyResource("search_opensearch.php",htmlOutput);
3133 // OPENSEARCH_PROVIDER }
3134
3135 QCString fileName = htmlOutput+"/search.php";
3137 if (f.is_open())
3138 {
3139 TextStream t(&f);
3140 t << substituteHtmlKeywords(g_header,"Search","");
3141
3142 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
3143 << getDoxygenVersion() << " -->\n";
3144 t << "<script type=\"text/javascript\">\n";
3145 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
3146 t << "var searchBox = new SearchBox(\"searchBox\", \""
3147 << "search/\",'" << Doxygen::htmlFileExtension << "');\n";
3148 t << "/* @license-end */\n";
3149 t << "</script>\n";
3150
3151 if (!disableIndex && !quickLinksAfterSplitbar)
3152 {
3154 }
3155 if (generateTreeView)
3156 {
3157 t << "</div><!-- top -->\n";
3158 }
3159 t << writeSplitBarAsString("search.php",QCString());
3160 if (quickLinksAfterSplitbar)
3161 {
3163 }
3164 t << "<!-- generated -->\n";
3165
3166 t << "<?php\n";
3167 t << "require_once \"search_functions.php\";\n";
3168 t << "main();\n";
3169 t << "?>\n";
3170
3171 // Write empty navigation path, to make footer connect properly
3172 if (generateTreeView)
3173 {
3174 t << "</div><!-- doc-content -->\n";
3175 }
3176
3177 writePageFooter(t,"Search","","");
3178 }
3179 f.close();
3180
3181 QCString scriptName = htmlOutput+"/search/search.js";
3182 f = Portable::openOutputStream(scriptName);
3183 if (f.is_open())
3184 {
3185 TextStream t(&f);
3186 t << ResourceMgr::instance().getAsString("extsearch.js");
3187 }
3188 else
3189 {
3190 err("Failed to open file '{}' for writing...\n",scriptName);
3191 }
3192}
3193
3195{
3196 bool disableIndex = Config_getBool(DISABLE_INDEX);
3197 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3198 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
3199 bool quickLinksAfterSplitbar = !disableIndex && generateTreeView && fullSidebar;
3200 QCString dname = Config_getString(HTML_OUTPUT);
3202 std::ofstream f = Portable::openOutputStream(fileName);
3203 if (f.is_open())
3204 {
3205 TextStream t(&f);
3206 t << substituteHtmlKeywords(g_header,"Search","");
3207
3208 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
3209 << getDoxygenVersion() << " -->\n";
3210 t << "<script type=\"text/javascript\">\n";
3211 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
3212 t << "var searchBox = new SearchBox(\"searchBox\", \""
3213 << "search/\",'" << Doxygen::htmlFileExtension << "');\n";
3214 t << "/* @license-end */\n";
3215 t << "</script>\n";
3216
3217 if (!disableIndex && !quickLinksAfterSplitbar)
3218 {
3220 }
3221 if (generateTreeView)
3222 {
3223 t << "</div><!-- top -->\n";
3224 }
3225 t << writeSplitBarAsString("search.php",QCString());
3226 if (quickLinksAfterSplitbar)
3227 {
3229 }
3230
3231 t << "<div class=\"header\">\n";
3232 t << " <div class=\"headertitle\">\n";
3233 t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>\n";
3234 t << " </div>\n";
3235 t << "</div>\n";
3236 t << "<div class=\"contents\">\n";
3237
3238 t << "<div id=\"searchresults\"></div>\n";
3239 t << "</div>\n";
3240
3241 if (generateTreeView)
3242 {
3243 t << "</div><!-- doc-content -->\n";
3244 }
3245
3246 writePageFooter(t,"Search","","");
3247
3248 }
3249 f.close();
3250
3251 QCString scriptName = dname+"/search/search.js";
3252 f = Portable::openOutputStream(scriptName);
3253 if (f.is_open())
3254 {
3255 TextStream t(&f);
3256 t << "var searchResultsText=["
3257 << "\"" << theTranslator->trSearchResults(0) << "\","
3258 << "\"" << theTranslator->trSearchResults(1) << "\","
3259 << "\"" << theTranslator->trSearchResults(2) << "\"];\n";
3260 t << "var serverUrl=\"" << Config_getString(SEARCHENGINE_URL) << "\";\n";
3261 t << "var tagMap = {\n";
3262 bool first=TRUE;
3263 // add search mappings
3264 const StringVector &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
3265 for (const auto &ml : extraSearchMappings)
3266 {
3267 QCString mapLine = ml.c_str();
3268 int eqPos = mapLine.find('=');
3269 if (eqPos!=-1) // tag command contains a destination
3270 {
3271 QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
3272 QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
3273 if (!tagName.isEmpty())
3274 {
3275 if (!first) t << ",\n";
3276 t << " \"" << tagName << "\": \"" << destName << "\"";
3277 first=FALSE;
3278 }
3279 }
3280 }
3281 if (!first) t << "\n";
3282 t << "};\n\n";
3283 t << ResourceMgr::instance().getAsString("extsearch.js");
3284 t << "\n";
3285 t << "$(function() {\n";
3286 t << " var query = trim(getURLParameter('query'));\n";
3287 t << " if (query) {\n";
3288 t << " searchFor(query,0,20);\n";
3289 t << " } else {\n";
3290 t << " var results = $('#results');\n";
3291 t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');\n";
3292 t << " }\n";
3293 t << "});\n";
3294 }
3295 else
3296 {
3297 err("Failed to open file '{}' for writing...\n",scriptName);
3298 }
3299}
3300
3302{
3303 m_t << "<div class=\"typeconstraint\">\n";
3304 m_t << "<dl><dt><b>" << header << "</b></dt><dd>\n";
3305 m_t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">\n";
3306}
3307
3309{
3310 m_t << "<tr><td valign=\"top\"><em>";
3311}
3312
3314{
3315 m_t << "</em></td>";
3316}
3317
3319{
3320 m_t << "<td>&#160;:</td><td valign=\"top\"><em>";
3321}
3322
3324{
3325 m_t << "</em></td>";
3326}
3327
3329{
3330 m_t << "<td>&#160;";
3331}
3332
3334{
3335 m_t << "</td></tr>\n";
3336}
3337
3339{
3340 m_t << "</table>\n";
3341 m_t << "</dd>\n";
3342 m_t << "</dl>\n";
3343 m_t << "</div>\n";
3344}
3345
3347{
3348 if (!style.isEmpty())
3349 {
3350 m_t << "<br class=\"" << style << "\" />\n";
3351 }
3352 else
3353 {
3354 m_t << "<br />\n";
3355 }
3356}
3357
3359{
3360 m_t << "<div class=\"header\">\n";
3361}
3362
3364{
3365 m_t << " <div class=\"headertitle\">";
3366 startTitle();
3367}
3368
3370{
3371 endTitle();
3372 m_t << "</div>\n";
3373}
3374
3376{
3377 m_t << "</div><!--header-->\n";
3378}
3379
3381{
3382 if (m_emptySection)
3383 {
3384 m_t << "<table class=\"memberdecls\">\n";
3386 }
3387 m_t << "<tr><td colspan=\"2\"><h3>";
3388}
3389
3391{
3392 m_t << "</h3></td></tr>\n";
3393}
3394
3396{
3397 DBG_HTML(m_t << "<!-- startMemberDocSimple -->\n";)
3398 m_t << "<table class=\"fieldtable\">\n";
3399 m_t << "<tr><th colspan=\"" << (isEnum?"2":"3") << "\">";
3400 m_t << (isEnum? theTranslator->trEnumerationValues() :
3401 theTranslator->trCompoundMembers()) << "</th></tr>\n";
3402}
3403
3405{
3406 DBG_HTML(m_t << "<!-- endMemberDocSimple -->\n";)
3407 m_t << "</table>\n";
3408}
3409
3411{
3412 DBG_HTML(m_t << "<!-- startInlineMemberType -->\n";)
3413 m_t << "<tr><td class=\"fieldtype\">\n";
3414}
3415
3417{
3418 DBG_HTML(m_t << "<!-- endInlineMemberType -->\n";)
3419 m_t << "</td>\n";
3420}
3421
3423{
3424 DBG_HTML(m_t << "<!-- startInlineMemberName -->\n";)
3425 m_t << "<td class=\"fieldname\">\n";
3426}
3427
3429{
3430 DBG_HTML(m_t << "<!-- endInlineMemberName -->\n";)
3431 m_t << "</td>\n";
3432}
3433
3435{
3436 DBG_HTML(m_t << "<!-- startInlineMemberDoc -->\n";)
3437 m_t << "<td class=\"fielddoc\">\n";
3438}
3439
3441{
3442 DBG_HTML(m_t << "<!-- endInlineMemberDoc -->\n";)
3443 m_t << "</td></tr>\n";
3444}
3445
3447{
3448 DBG_HTML(m_t << "<!-- startLabels -->\n";)
3449 m_t << "<span class=\"mlabels\">";
3450}
3451
3452void HtmlGenerator::writeLabel(const QCString &label,bool /*isLast*/)
3453{
3454 DBG_HTML(m_t << "<!-- writeLabel(" << label << ") -->\n";)
3455
3456 auto convertLabelToClass = [](const std::string &lab) {
3457 QCString input = convertUTF8ToLower(lab);
3458 QCString result;
3459 size_t l=input.length();
3460 result.reserve(l);
3461
3462 // Create valid class selector, see 10.2 here https://www.w3.org/TR/selectors-3/#w3cselgrammar
3463 // ident [-]?{nmstart}{nmchar}*
3464 // nmstart [_a-z]|{nonascii}
3465 // nonascii [^\0-\177]
3466 // nmchar [_a-z0-9-]|{nonascii}
3467
3468 bool nmstart=false;
3469 for (size_t i=0; i<l; i++)
3470 {
3471 char c = input.at(i);
3472 if (c<0 || (c>='a' && c<='z') || c=='_') // nmstart pattern
3473 {
3474 nmstart=true;
3475 result+=c;
3476 }
3477 else if (nmstart && (c<0 || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_')) // nmchar pattern
3478 {
3479 result+=c;
3480 }
3481 else if (nmstart && (c==' ' || c=='-')) // show whitespace as -
3482 {
3483 result+='-';
3484 }
3485 }
3486 return result;
3487 };
3488
3489 m_t << "<span class=\"mlabel " << convertLabelToClass(label.stripWhiteSpace().str()) << "\">" << label << "</span>";
3490}
3491
3493{
3494 DBG_HTML(m_t << "<!-- endLabels -->\n";)
3495 m_t << "</span>";
3496}
3497
3499 const QCString &id, const QCString &ref,
3500 const QCString &file, const QCString &anchor,
3501 const QCString &title, const QCString &name)
3502{
3503 DBG_HTML(m_t << "<!-- writeInheritedSectionTitle -->\n";)
3504 QCString a = anchor;
3505 if (!a.isEmpty()) a.prepend("#");
3506 QCString classLink = QCString("<a class=\"el\" ");
3507 if (!ref.isEmpty())
3508 {
3509 classLink+= externalLinkTarget();
3510 classLink += " href=\"";
3511 classLink+= externalRef(m_relPath,ref,TRUE);
3512 }
3513 else
3514 {
3515 classLink += "href=\"";
3516 classLink+=m_relPath;
3517 }
3518 QCString fn = file;
3520 classLink=classLink+fn+a;
3521 classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
3522 m_t << "<tr class=\"inherit_header " << id << "\">"
3523 << "<td colspan=\"2\" onclick=\"javascript:dynsection.toggleInherit('" << id << "')\">"
3524 << "<img src=\"" << m_relPath << "closed.png\" alt=\"-\"/>&#160;"
3525 << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
3526 << "</td></tr>\n";
3527}
3528
3529void HtmlGenerator::writeSummaryLink(const QCString &file,const QCString &anchor,const QCString &title,bool first)
3530{
3531 if (first)
3532 {
3533 m_t << " <div class=\"summary\">\n";
3534 }
3535 else
3536 {
3537 m_t << " &#124;\n";
3538 }
3539 m_t << "<a href=\"";
3540 if (!file.isEmpty())
3541 {
3542 QCString fn = file;
3544 m_t << m_relPath << fn;
3545 }
3546 else if (!anchor.isEmpty())
3547 {
3548 m_t << "#";
3549 m_t << anchor;
3550 }
3551 m_t << "\">";
3552 m_t << title;
3553 m_t << "</a>";
3554}
3555
3556void HtmlGenerator::endMemberDeclaration(const QCString &anchor,const QCString &inheritId)
3557{
3558 m_t << "<tr class=\"separator:" << anchor;
3559 if (!inheritId.isEmpty())
3560 {
3561 m_t << " inherit " << inheritId;
3562 }
3563 m_t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
3564}
3565
3570
3572{
3574 return replaceVariables(mgr.getAsString("navtree.css"));
3575}
3576
3577void HtmlGenerator::writeLocalToc(const SectionRefs &sectionRefs,const LocalToc &localToc)
3578{
3579 if (localToc.isHtmlEnabled())
3580 {
3581 int level=0;
3582 int indent=0;
3583 auto writeIndent = [&]() { for (int i=0;i<indent*2;i++) m_t << " "; };
3584 auto incIndent = [&](const QCString &text) { writeIndent(); m_t << text << "\n"; indent++; };
3585 auto decIndent = [&](const QCString &text) { indent--; writeIndent(); m_t << text << "\n"; };
3586 m_t << "<div class=\"toc\">";
3587 m_t << "<h3>" << theTranslator->trRTFTableOfContents() << "</h3>\n";
3588 int maxLevel = localToc.htmlLevel();
3589 char cs[2];
3590 cs[1]='\0';
3591 BoolVector inLi(maxLevel+1,false);
3592 for (const SectionInfo *si : sectionRefs)
3593 {
3594 //printf("Section: label=%s type=%d isSection()=%d\n",qPrint(si->label()),si->type(),isSection(si->type()));
3595 SectionType type = si->type();
3596 if (type.isSection())
3597 {
3598 //printf(" level=%d title=%s maxLevel=%d\n",level,qPrint(si->title()),maxLevel);
3599 int nextLevel = type.level();
3600 if (nextLevel>level)
3601 {
3602 for (int l=level;l<nextLevel;l++)
3603 {
3604 if (l < maxLevel)
3605 {
3606 incIndent("<ul>");
3607 cs[0]=static_cast<char>('0'+l+1);
3608 const char *empty = (l!=nextLevel-1) ? " empty" : "";
3609 incIndent("<li class=\"level" + QCString(cs) + empty + "\">");
3610 }
3611 }
3612 }
3613 else if (nextLevel<level)
3614 {
3615 for (int l=level;l>nextLevel;l--)
3616 {
3617 if (l <= maxLevel) decIndent("</li>");
3618 inLi[l] = false;
3619 if (l <= maxLevel) decIndent("</ul>");
3620 }
3621 }
3622 if (nextLevel <= maxLevel)
3623 {
3624 if (inLi[nextLevel] || level>nextLevel)
3625 {
3626 decIndent("</li>");
3627 cs[0]=static_cast<char>('0'+nextLevel);
3628 incIndent("<li class=\"level" + QCString(cs) + "\">");
3629 }
3630 QCString titleDoc = si->title();
3631 QCString label = si->label();
3632 if (titleDoc.isEmpty()) titleDoc = label;
3633 writeIndent();
3634 m_t << "<a href=\"#"+label+"\">"
3635 << convertToHtml(filterTitle(titleDoc))
3636 << "</a>\n";
3637 inLi[nextLevel]=true;
3638 level = nextLevel;
3639 }
3640 }
3641 }
3642 if (level > maxLevel) level = maxLevel;
3643 while (level>0)
3644 {
3645 decIndent("</li>");
3646 decIndent("</ul>");
3647 level--;
3648 }
3649 m_t << "</div>\n";
3650 }
3651}
3652
constexpr auto prefix
Definition anchor.cpp:44
Class representing a built-in class diagram.
Definition diagram.h:31
void writeImage(TextStream &t, const QCString &path, const QCString &relPath, const QCString &file, bool generateMap=true) const
Definition diagram.cpp:1369
The common base class of all entity definitions found in the sources.
Definition definition.h:76
Class representing a directory in the file system.
Definition dir.h:75
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
bool exists() const
Definition dir.cpp:257
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1460
DocNodeVariant root
Definition docnode.h:1481
Representation of an call graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
Representation of a class inheritance or dependency graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool TBRank=TRUE, bool imageMap=TRUE, int graphId=-1)
Representation of an directory dependency graph.
Definition dotdirdeps.h:26
QCString writeGraph(TextStream &out, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1, bool linkRelations=TRUE)
Represents a graphical class hierarchy.
void writeGraph(TextStream &t, const QCString &path, const QCString &fileName)
Representation of a group collaboration graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
Representation of an include dependency graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
static IndexList * indexList
Definition doxygen.h:134
static QCString htmlFileExtension
Definition doxygen.h:122
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
bool exists() const
Definition fileinfo.cpp:30
std::string fileName() const
Definition fileinfo.cpp:118
bool isReadable() const
Definition fileinfo.cpp:44
bool isFile() const
Definition fileinfo.cpp:63
std::string absFilePath() const
Definition fileinfo.cpp:101
Class representing a string buffer optimized for growing.
Definition growbuf.h:28
void addChar(char c)
Definition growbuf.h:69
void addStr(const QCString &s)
Definition growbuf.h:72
char * get()
Definition growbuf.h:114
Generator for HTML code fragments.
Definition htmlgen.h:25
void codify(const QCString &text) override
Definition htmlgen.cpp:726
bool m_stripCodeComments
Definition htmlgen.h:76
void startSpecialComment() override
Definition htmlgen.cpp:812
void endCodeLine() override
Definition htmlgen.cpp:995
void startFontClass(const QCString &s) override
Definition htmlgen.cpp:1010
void writeCodeAnchor(const QCString &anchor) override
Definition htmlgen.cpp:1022
QCString fileName()
Definition htmlgen.h:32
size_t m_stripIndentAmount
Definition htmlgen.h:90
QCString m_relPath
Definition htmlgen.h:73
void writeCodeLink(CodeSymbolType type, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip) override
Definition htmlgen.cpp:860
void startFold(int, const QCString &, const QCString &) override
Definition htmlgen.cpp:1041
void writeLineNumber(const QCString &, const QCString &, const QCString &, int, bool) override
Definition htmlgen.cpp:829
void startCodeLine(int) override
Definition htmlgen.cpp:984
void endFold() override
Definition htmlgen.cpp:1075
void _writeCodeLink(const QCString &className, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip)
Definition htmlgen.cpp:876
void setRelativePath(const QCString &path)
Definition htmlgen.cpp:721
void setStripIndentAmount(size_t amount) override
Definition htmlgen.cpp:824
void endSpecialComment() override
Definition htmlgen.cpp:818
HtmlCodeGenerator(TextStream *t, const QCString &relPath)
Definition htmlgen.cpp:715
void writeTooltip(const QCString &id, const DocLinkInfo &docInfo, const QCString &decl, const QCString &desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo) override
Definition htmlgen.cpp:904
void endFontClass() override
Definition htmlgen.cpp:1016
void startCodeFragment(const QCString &style) override
Definition htmlgen.cpp:1028
TextStream * m_t
Definition htmlgen.h:71
LineInfo m_lastLineInfo
Definition htmlgen.h:89
void endCodeFragment(const QCString &) override
Definition htmlgen.cpp:1033
void stripCodeComments(bool b) override
Definition htmlgen.cpp:807
OutputType type() const override
Definition htmlgen.h:34
Concrete visitor implementation for HTML output.
void startClassDiagram() override
Definition htmlgen.cpp:2001
void writeLogo() override
Definition htmlgen.cpp:1576
void endFile() override
Definition htmlgen.cpp:1592
void endParameterExtra(bool last, bool emptyList, bool closeBracket) override
Definition htmlgen.cpp:2342
static void init()
Definition htmlgen.cpp:1136
void startInlineMemberName() override
Definition htmlgen.cpp:3422
void endDescTableInit() override
Definition htmlgen.cpp:2614
void startTitle()
Definition htmlgen.h:333
void startTextLink(const QCString &file, const QCString &anchor) override
Definition htmlgen.cpp:1801
void startInlineMemberType() override
Definition htmlgen.cpp:3410
void endDescTable() override
Definition htmlgen.cpp:2584
void startParameterDefVal(const char *sep) override
Definition htmlgen.cpp:2366
void endMemberGroupHeader() override
Definition htmlgen.cpp:2531
void startIndexKey() override
Definition htmlgen.cpp:2219
void lineBreak(const QCString &style) override
Definition htmlgen.cpp:3346
void startParameterName(bool) override
Definition htmlgen.cpp:2325
void startMemberItem(const QCString &anchor, MemberItemType, const QCString &inheritId) override
Definition htmlgen.cpp:2054
static void writeSearchPage()
Definition htmlgen.cpp:3094
void startInclDepGraph() override
Definition htmlgen.cpp:2449
void insertMemberAlignLeft(MemberItemType, bool) override
Definition htmlgen.cpp:2117
void startMemberSubtitle() override
Definition htmlgen.cpp:2197
HtmlGenerator & operator=(const HtmlGenerator &)
Definition htmlgen.cpp:1111
void writeFooter(const QCString &navPath) override
Definition htmlgen.cpp:1587
int m_sectionCount
Definition htmlgen.h:341
void startMemberDocName(bool) override
Definition htmlgen.cpp:2278
void endParameterType() override
Definition htmlgen.cpp:2319
void startLabels() override
Definition htmlgen.cpp:3446
void startCallGraph() override
Definition htmlgen.cpp:2485
void endMemberList() override
Definition htmlgen.cpp:2045
static QCString getNavTreeCss()
Definition htmlgen.cpp:3571
void startParagraph(const QCString &classDef) override
Definition htmlgen.cpp:1694
void endIndexList() override
Definition htmlgen.cpp:2214
void writeSearchInfo() override
Definition htmlgen.cpp:1539
void startContents() override
Definition htmlgen.cpp:3068
void startMemberDoc(const QCString &clName, const QCString &memName, const QCString &anchor, const QCString &title, int memCount, int memTotal, bool showInline) override
Definition htmlgen.cpp:2249
void startDescTableRow() override
Definition htmlgen.cpp:2589
void startDoxyAnchor(const QCString &fName, const QCString &manName, const QCString &anchor, const QCString &name, const QCString &args) override
Definition htmlgen.cpp:1679
void startDirDepGraph() override
Definition htmlgen.cpp:2503
void startCompoundTemplateParams() override
Definition htmlgen.cpp:2100
void startConstraintParam() override
Definition htmlgen.cpp:3308
void endGroupHeader(int) override
Definition htmlgen.cpp:1834
QCString m_lastFile
Definition htmlgen.h:339
void writeNavigationPath(const QCString &s) override
Definition htmlgen.cpp:3063
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name) override
Definition htmlgen.cpp:1777
void startMemberDescription(const QCString &anchor, const QCString &inheritId, bool typ) override
Definition htmlgen.cpp:2129
void writeChar(char c) override
Definition htmlgen.cpp:1919
void endConstraintList() override
Definition htmlgen.cpp:3338
void endParameterList() override
Definition htmlgen.cpp:2378
void writeDoc(const IDocNodeAST *node, const Definition *, const MemberDef *, int id) override
Definition htmlgen.cpp:2641
void startDotGraph() override
Definition htmlgen.cpp:2415
void endIndent() override
Definition htmlgen.cpp:2561
void endParameterName() override
Definition htmlgen.cpp:2331
void endPageDoc() override
Definition htmlgen.cpp:3083
void startMemberDocList() override
Definition htmlgen.cpp:2239
static QCString writeLogoAsString(const QCString &path)
Definition htmlgen.cpp:1545
void endDescTableRow() override
Definition htmlgen.cpp:2594
void writeSplitBar(const QCString &name) override
Definition htmlgen.cpp:3058
void startParameterType(bool first, const QCString &key) override
Definition htmlgen.cpp:2302
void startDescTableInit() override
Definition htmlgen.cpp:2609
void startMemberList() override
Definition htmlgen.cpp:2040
void endQuickIndices() override
Definition htmlgen.cpp:3001
void startHeaderSection() override
Definition htmlgen.cpp:3358
void startDescTableTitle() override
Definition htmlgen.cpp:2599
void endDirDepGraph(DotDirDeps &g) override
Definition htmlgen.cpp:2508
void startIndexList() override
Definition htmlgen.cpp:2209
void endParameterDefVal() override
Definition htmlgen.cpp:2373
void endMemberGroup(bool) override
Definition htmlgen.cpp:2550
void endInlineHeader() override
Definition htmlgen.cpp:3390
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1458
void endMemberDescription() override
Definition htmlgen.cpp:2148
void startGroupCollaboration() override
Definition htmlgen.cpp:2467
void endClassDiagram(const ClassDiagram &, const QCString &, const QCString &) override
Definition htmlgen.cpp:2006
void startConstraintList(const QCString &) override
Definition htmlgen.cpp:3301
void startDescTable(const QCString &title, const bool hasInits) override
Definition htmlgen.cpp:2579
void endConstraintDocs() override
Definition htmlgen.cpp:3333
void writeNonBreakableSpace(int) override
Definition htmlgen.cpp:2571
void writeQuickLinks(HighlightedItem hli, const QCString &file) override
Definition htmlgen.cpp:3088
void startInlineMemberDoc() override
Definition htmlgen.cpp:3434
void exceptionEntry(const QCString &, bool) override
Definition htmlgen.cpp:2385
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1292
void endExamples() override
Definition htmlgen.cpp:2636
void endIndexKey() override
Definition htmlgen.cpp:2224
void writeString(const QCString &text) override
Definition htmlgen.cpp:1707
void endMemberDocName() override
Definition htmlgen.cpp:2288
void endContents() override
Definition htmlgen.cpp:3073
void endInlineMemberType() override
Definition htmlgen.cpp:3416
void startMemberGroupDocs() override
Definition htmlgen.cpp:2536
void startMemberDocSimple(bool) override
Definition htmlgen.cpp:3395
void startIndexItem(const QCString &ref, const QCString &file) override
Definition htmlgen.cpp:1722
OutputType type() const override
Definition htmlgen.h:121
void endHeaderSection() override
Definition htmlgen.cpp:3375
void startIndent() override
Definition htmlgen.cpp:2554
void writeStyleInfo(int part) override
Definition htmlgen.cpp:1607
void addIndexItem(const QCString &, const QCString &) override
Definition htmlgen.cpp:2567
void docify_(const QCString &text, bool inHtmlComment)
Definition htmlgen.cpp:1886
void endMemberGroupDocs() override
Definition htmlgen.cpp:2541
void cleanup() override
Definition htmlgen.cpp:1284
void endDotGraph(DotClassGraph &g) override
Definition htmlgen.cpp:2420
void endMemberHeader() override
Definition htmlgen.cpp:2191
void endTextLink() override
Definition htmlgen.cpp:1813
void writeLabel(const QCString &l, bool isLast) override
Definition htmlgen.cpp:3452
void startMemberSections() override
Definition htmlgen.cpp:2154
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1330
static QCString writeSplitBarAsString(const QCString &name, const QCString &relpath)
Definition htmlgen.cpp:3011
void endMemberSections() override
Definition htmlgen.cpp:2162
void endMemberDocList() override
Definition htmlgen.cpp:2244
void endCompoundTemplateParams() override
Definition htmlgen.cpp:2105
static void writeExternalSearchPage()
Definition htmlgen.cpp:3194
void endDescTableData() override
Definition htmlgen.cpp:2624
void startDescTableData() override
Definition htmlgen.cpp:2619
void writeStartAnnoItem(const QCString &type, const QCString &file, const QCString &path, const QCString &name) override
Definition htmlgen.cpp:1765
static void writePageFooter(TextStream &t, const QCString &, const QCString &, const QCString &)
Definition htmlgen.cpp:1581
void endParagraph() override
Definition htmlgen.cpp:1702
void insertMemberAlign(bool) override
Definition htmlgen.cpp:2110
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1446
void endDoxyAnchor(const QCString &fName, const QCString &anchor) override
Definition htmlgen.cpp:1686
void startMemberTemplateParams() override
Definition htmlgen.cpp:2085
void endLabels() override
Definition htmlgen.cpp:3492
void startPageDoc(const QCString &pageTitle) override
Definition htmlgen.cpp:3078
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId) override
Definition htmlgen.cpp:3556
HtmlCodeGenerator * m_codeGen
Definition htmlgen.h:344
void startIndexValue(bool) override
Definition htmlgen.cpp:2229
void endGroupCollaboration(DotGroupCollaboration &g) override
Definition htmlgen.cpp:2472
QCString m_relPath
Definition htmlgen.h:340
static void writeSearchInfoStatic(TextStream &t, const QCString &relPath)
Definition htmlgen.cpp:1509
std::unique_ptr< OutputCodeList > m_codeList
Definition htmlgen.h:343
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1452
void startConstraintType() override
Definition htmlgen.cpp:3318
void endConstraintParam() override
Definition htmlgen.cpp:3313
void startTitleHead(const QCString &) override
Definition htmlgen.cpp:3363
void startFile(const QCString &name, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition htmlgen.cpp:1466
void endIndexValue(const QCString &, bool) override
Definition htmlgen.cpp:2234
void addCodeGen(OutputCodeList &list) override
Definition htmlgen.cpp:1131
void startConstraintDocs() override
Definition htmlgen.cpp:3328
void endMemberTemplateParams(const QCString &anchor, const QCString &inheritId) override
Definition htmlgen.cpp:2089
void endPlainFile() override
Definition htmlgen.h:330
void startIndexListItem() override
Definition htmlgen.cpp:1712
void endProjectNumber() override
Definition htmlgen.cpp:1602
void writeSummaryLink(const QCString &file, const QCString &anchor, const QCString &title, bool first) override
Definition htmlgen.cpp:3529
void endMemberDocPrefixItem() override
Definition htmlgen.cpp:2272
void endDescTableTitle() override
Definition htmlgen.cpp:2604
void addLabel(const QCString &, const QCString &) override
Definition htmlgen.cpp:1690
void endInclDepGraph(DotInclDepGraph &g) override
Definition htmlgen.cpp:2454
void startParameterExtra() override
Definition htmlgen.cpp:2337
void writeLocalToc(const SectionRefs &sr, const LocalToc &lt) override
Definition htmlgen.cpp:3577
void startProjectNumber() override
Definition htmlgen.cpp:1597
void writeGraphicalHierarchy(DotGfxHierarchyTable &g) override
Definition htmlgen.cpp:2521
void startExamples() override
Definition htmlgen.cpp:2629
void docify(const QCString &text) override
Definition htmlgen.cpp:1881
bool m_emptySection
Definition htmlgen.h:342
void endInlineMemberDoc() override
Definition htmlgen.cpp:3440
void endCallGraph(DotCallGraph &g) override
Definition htmlgen.cpp:2490
void endConstraintType() override
Definition htmlgen.cpp:3323
void endMemberSubtitle() override
Definition htmlgen.cpp:2203
void endTitle()
Definition htmlgen.h:334
void startGroupHeader(int) override
Definition htmlgen.cpp:1818
void startMemberDocPrefixItem() override
Definition htmlgen.cpp:2266
void startSection(const QCString &, const QCString &, SectionType) override
Definition htmlgen.cpp:1850
void endMemberItem(MemberItemType) override
Definition htmlgen.cpp:2076
void startMemberGroup() override
Definition htmlgen.cpp:2546
void endMemberDoc(bool) override
Definition htmlgen.cpp:2404
void endIndexItem(const QCString &ref, const QCString &file) override
Definition htmlgen.cpp:1752
void startMemberHeader(const QCString &, int) override
Definition htmlgen.cpp:2171
void endTitleHead(const QCString &, const QCString &) override
Definition htmlgen.cpp:3369
void endSection(const QCString &, SectionType) override
Definition htmlgen.cpp:1866
void startInlineHeader() override
Definition htmlgen.cpp:3380
void endInlineMemberName() override
Definition htmlgen.cpp:3428
void endMemberDocSimple(bool) override
Definition htmlgen.cpp:3404
void writeInheritedSectionTitle(const QCString &id, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &title, const QCString &name) override
Definition htmlgen.cpp:3498
void endIndexListItem() override
Definition htmlgen.cpp:1717
static QCString getMathJaxMacros()
Definition htmlgen.cpp:3566
void startParameterList(bool) override
Definition htmlgen.cpp:2294
QCString m_lastTitle
Definition htmlgen.h:338
void startMemberGroupHeader(bool) override
Definition htmlgen.cpp:2526
void startPlainFile(const QCString &name) override
Definition htmlgen.h:329
opaque representation of the abstract syntax tree (AST)
Definition docparser.h:49
static Index & instance()
Definition index.cpp:106
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1435
LayoutNavEntry * rootNavEntry() const
returns the (invisible) root of the navigation tree.
Definition layout.cpp:1446
bool isHtmlEnabled() const
Definition types.h:453
int htmlLevel() const
Definition types.h:458
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
Class representing a list of different code generators.
Definition outputlist.h:164
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:194
Abstract interface for output generators.
Definition outputgen.h:127
QCString dir() const
Definition outputgen.cpp:52
QCString m_dir
Definition outputgen.h:117
TextStream m_t
Definition outputgen.h:116
QCString fileName() const
Definition outputgen.cpp:57
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:407
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool startsWith(const char *s) const
Definition qcstring.h:492
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
QCString lower() const
Definition qcstring.h:234
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
const std::string & str() const
Definition qcstring.h:537
QCString right(size_t len) const
Definition qcstring.h:219
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:172
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
QCString left(size_t len) const
Definition qcstring.h:214
Singleton for managing resources compiled into an executable.
Definition resourcemgr.h:37
static ResourceMgr & instance()
Returns the one and only instance of this class.
bool copyResource(const QCString &name, const QCString &targetDir) const
Copies a registered resource to a given target directory.
QCString getAsString(const QCString &name) const
Gets the resource data as a C string.
class that provide information about a section.
Definition section.h:57
class that represents a list of constant references to sections.
Definition section.h:102
static constexpr int Section
Definition section.h:33
static constexpr int Subsection
Definition section.h:34
static constexpr int Subsubsection
Definition section.h:35
static constexpr int Page
Definition section.h:31
static constexpr int Paragraph
Definition section.h:36
static constexpr int Subsubparagraph
Definition section.h:38
static constexpr int Subparagraph
Definition section.h:37
Text streaming class that buffers data.
Definition textstream.h:36
bool empty() const
Returns true iff the buffer is empty.
Definition textstream.h:253
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
#define Config_getInt(name)
Definition config.h:34
#define Config_getList(name)
Definition config.h:38
#define Config_getEnumAsString(name)
Definition config.h:36
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::vector< std::string > StringVector
Definition containers.h:33
std::unordered_map< std::string, std::string > StringUnorderedMap
Definition containers.h:28
std::vector< bool > BoolVector
Definition containers.h:36
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
static constexpr auto hex
#define DBG_HTML(x)
Definition htmlgen.cpp:62
static QCString replaceVariables(const QCString &input)
Definition htmlgen.cpp:668
static void fillColorStyleMap(const QCString &definitions, StringUnorderedMap &map)
Definition htmlgen.cpp:633
static QCString g_header
Definition htmlgen.cpp:64
static void startSectionContent(TextStream &t, int sectionCount)
Definition htmlgen.cpp:1977
static void endQuickIndexList(TextStream &t)
Definition htmlgen.cpp:2674
static QCString g_mathjax_code
Definition htmlgen.cpp:66
static void writeServerSearchBox(TextStream &t, const QCString &relPath, bool highlightSearch)
Definition htmlgen.cpp:95
static void startQuickIndexList(TextStream &t, bool topLevel=TRUE)
Definition htmlgen.cpp:2654
static void startSectionSummary(TextStream &t, int sectionCount)
Definition htmlgen.cpp:1955
static void startQuickIndexItem(TextStream &t, const QCString &l, bool hl, bool, const QCString &relPath)
Definition htmlgen.cpp:2687
static void renderQuickLinksAsTabs(TextStream &t, const QCString &relPath, LayoutNavEntry *hlEntry, LayoutNavEntry::Kind kind, bool highlightParent, bool highlightSearch)
Definition htmlgen.cpp:2783
static QCString g_footer
Definition htmlgen.cpp:65
static const SelectionMarkerInfo htmlMarkerInfo
Definition htmlgen.cpp:70
static QCString getConvertLatexMacro()
Convert a set of LaTeX commands \‍(re)newcommand to a form readable by MathJax LaTeX syntax:
Definition htmlgen.cpp:146
static void endSectionContent(TextStream &t)
Definition htmlgen.cpp:1993
static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
Definition htmlgen.cpp:306
static void writeDefaultQuickLinks(TextStream &t, HighlightedItem hli, const QCString &file, const QCString &relPath)
Definition htmlgen.cpp:2863
static QCString g_latex_macro
Definition htmlgen.cpp:67
static void fillColorStyleMaps()
Definition htmlgen.cpp:654
static QCString substituteHtmlKeywords(const QCString &str, const QCString &title, const QCString &relPath, const QCString &navPath=QCString())
Definition htmlgen.cpp:320
static void endQuickIndexItem(TextStream &t, const QCString &l)
Definition htmlgen.cpp:2701
static StringUnorderedMap g_lightMap
Definition htmlgen.cpp:630
static void startSectionHeader(TextStream &t, const QCString &relPath, int sectionCount)
Definition htmlgen.cpp:1929
static void writeDefaultStyleSheet(TextStream &t)
Definition htmlgen.cpp:1389
static void renderQuickLinksAsTree(TextStream &t, const QCString &relPath, LayoutNavEntry *root)
Definition htmlgen.cpp:2754
static bool quickLinkVisible(LayoutNavEntry::Kind kind)
Definition htmlgen.cpp:2708
static std::mutex g_indexLock
Definition htmlgen.cpp:1464
static StringUnorderedMap g_darkMap
Definition htmlgen.cpp:631
static void endSectionHeader(TextStream &t)
Definition htmlgen.cpp:1949
static void writeClientSearchBox(TextStream &t, const QCString &relPath)
Definition htmlgen.cpp:74
static void endSectionSummary(TextStream &t)
Definition htmlgen.cpp:1967
HighlightedItem
Definition index.h:59
@ AnnotatedExceptions
Definition index.h:76
@ InterfaceVisible
Definition index.h:89
@ InterfaceHierarchy
Definition index.h:66
@ AnnotatedInterfaces
Definition index.h:74
@ NamespaceMembers
Definition index.h:78
@ AnnotatedClasses
Definition index.h:73
@ AnnotatedStructs
Definition index.h:75
@ ExceptionVisible
Definition index.h:91
@ NamespaceVisible
Definition index.h:92
@ ExceptionHierarchy
Definition index.h:67
Translator * theTranslator
Definition language.cpp:71
#define warn(file, line, fmt,...)
Definition message.h:97
#define err(fmt,...)
Definition message.h:127
#define term(fmt,...)
Definition message.h:137
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
OutputCodeDefer< HtmlCodeGenerator > HtmlCodeGeneratorDefer
Definition outputlist.h:101
Portable versions of functions that are platform dependent.
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
#define qsnprintf
Definition qcstring.h:49
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
static void writeIndent(TextStream &t, int indent)
Definition qhp.cpp:37
Web server based search engine.
Some helper functions for std::string.
bool literal_at(const char *data, const char(&str)[N])
returns TRUE iff data points to a substring that matches string literal str
Definition stringutil.h:98
Base class for the layout of a navigation item at the top of the HTML pages.
Definition layout.h:156
const LayoutNavEntryList & children() const
Definition layout.h:219
LayoutNavEntry * parent() const
Definition layout.h:212
LayoutNavEntry * find(LayoutNavEntry::Kind k, const QCString &file=QCString()) const
Definition layout.cpp:133
Kind
Definition layout.h:193
constexpr const char * codeSymbolType2Str(CodeSymbolType type)
Definition types.h:353
CodeSymbolType
Definition types.h:319
std::string convertUTF8ToLower(const std::string &input)
Converts the input string into a lower case version, also taking into account non-ASCII characters th...
Definition utf8.cpp:187
const char * writeUTF8Char(TextStream &t, const char *s)
Writes the UTF8 character pointed to by s to stream t and returns a pointer to the next character.
Definition utf8.cpp:197
Various UTF8 related helper functions.
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6222
size_t updateColumnCount(const char *s, size_t col)
Definition util.cpp:7367
QCString convertToHtml(const QCString &s, bool keepEntities)
Definition util.cpp:4463
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
Definition util.cpp:7009
QCString correctURL(const QCString &url, const QCString &relPath)
Corrects URL url according to the relative path relPath.
Definition util.cpp:6414
QCString stripPath(const QCString &s)
Definition util.cpp:5448
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:7073
QCString selectBlocks(const QCString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
remove disabled blocks and all block markers from s and return the result as a string
Definition util.cpp:6896
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:4079
void clearSubDirs(const Dir &d)
Definition util.cpp:4167
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1441
QCString filterTitle(const QCString &title)
Definition util.cpp:6077
void createSubDirs(const Dir &d)
Definition util.cpp:4140
QCString substituteKeywords(const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3564
QCString getProjectId()
Definition util.cpp:7298
QCString externalLinkTarget(const bool parent)
Definition util.cpp:6178
QCString replaceColorMarkers(const QCString &str)
Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC,...
Definition util.cpp:6275
QCString convertToId(const QCString &s)
Definition util.cpp:4372
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5399
QCString createHtmlUrl(const QCString &relPath, const QCString &ref, bool href, bool isLocalFile, const QCString &targetFileName, const QCString &anchor)
Definition util.cpp:6189
A bunch of utility functions.
QCString fixSpaces(const QCString &s)
Definition util.h:471