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