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