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