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