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