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 assert(it!=mapping.end()); // should be found
685 output.addStr(it->second); // add it value
686 //printf("replace '%s' by '%s'\n",qPrint(input.mid(i+4,j-i-4)),qPrint(it->second));
687 p=j+1;
688 }
689 output.addStr(input.data()+p,input.length()-p);
690 output.addChar(0);
691 return output.get();
692 };
693
694 auto colorStyle = Config_getEnum(HTML_COLORSTYLE);
695 if (colorStyle==HTML_COLORSTYLE_t::LIGHT)
696 {
697 return doReplacements(g_lightMap);
698 }
699 else if (colorStyle==HTML_COLORSTYLE_t::DARK)
700 {
701 return doReplacements(g_darkMap);
702 }
703 else
704 {
705 return input;
706 }
707}
708
709//----------------------------------------------------------------------------------------------
710
711
712//--------------------------------------------------------------------------
713
715{
716 //printf("%p:HtmlCodeGenerator()\n",(void*)this);
717}
718
720 : m_t(t), m_relPath(relPath)
721{
722 //printf("%p:HtmlCodeGenerator()\n",(void*)this);
723}
724
726{
727 m_relPath = path;
728}
729
731{
732 if (!str.isEmpty())
733 {
734 int tabSize = Config_getInt(TAB_SIZE);
735 const char *p=str.data();
736 if (m_hide) // only update column count
737 {
739 }
740 else // actually output content and keep track of m_col
741 {
742 while (*p)
743 {
744 char c=*p++;
745 switch(c)
746 {
747 case '\t': {
748 int spacesToNextTabStop = tabSize - (m_col%tabSize);
749 while (spacesToNextTabStop--)
750 {
751 if (m_col>=m_stripIndentAmount) *m_t << " ";
752 m_col++;
753 }
754 }
755 break;
756 case ' ': if (m_col>=m_stripIndentAmount) *m_t << " ";
757 m_col++;
758 break;
759 case '\n': *m_t << "\n"; m_col=0;
760 break;
761 case '\r': break;
762 case '<': *m_t << "&lt;"; m_col++;
763 break;
764 case '>': *m_t << "&gt;"; m_col++;
765 break;
766 case '&': *m_t << "&amp;"; m_col++;
767 break;
768 case '\'': *m_t << "&#39;"; m_col++; // &apos; is not valid XHTML
769 break;
770 case '"': *m_t << "&quot;"; m_col++;
771 break;
772 case '\\':
773 if (*p=='<')
774 { *m_t << "&lt;"; p++; }
775 else if (*p=='>')
776 { *m_t << "&gt;"; p++; }
777 else if (*p=='(')
778 { *m_t << "\\&zwj;("; m_col++;p++; }
779 else if (*p==')')
780 { *m_t << "\\&zwj;)"; m_col++;p++; }
781 else
782 *m_t << "\\";
783 m_col++;
784 break;
785 default:
786 {
787 uint8_t uc = static_cast<uint8_t>(c);
788 if (uc<32)
789 {
790 *m_t << "&#x24" << hex[uc>>4] << hex[uc&0xF] << ";";
791 m_col++;
792 }
793 else if (uc<0x80) // printable ASCII char
794 {
795 *m_t << c;
796 m_col++;
797 }
798 else // multibyte UTF-8 char
799 {
800 p=writeUTF8Char(*m_t,p-1);
801 m_col++;
802 }
803 }
804 break;
805 }
806 }
807 }
808 }
809}
810
815
817{
819 //*m_t << "[START]";
820}
821
823{
824 //*m_t << "[END]";
825 m_hide = false;
826}
827
829{
830 m_stripIndentAmount = amount;
831}
832
834 const QCString &anchor,int l,bool writeLineAnchor)
835{
836 m_lastLineInfo = LineInfo(ref,filename,anchor,l,writeLineAnchor);
837 if (m_hide) return;
838 const int maxLineNrStr = 10;
839 char lineNumber[maxLineNrStr];
840 char lineAnchor[maxLineNrStr];
841 qsnprintf(lineNumber,maxLineNrStr,"%5d",l);
842 qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l);
843
844 if (!m_lineOpen)
845 {
846 *m_t << "<div class=\"line\">";
848 }
849
850 if (writeLineAnchor) *m_t << "<a id=\"" << lineAnchor << "\" name=\"" << lineAnchor << "\"></a>";
851 *m_t << "<span class=\"lineno\">";
852 if (!filename.isEmpty())
853 {
854 _writeCodeLink("line",ref,filename,anchor,lineNumber,QCString());
855 }
856 else
857 {
858 codify(lineNumber);
859 }
860 *m_t << "</span>";
861 m_col=0;
862}
863
865 const QCString &ref,const QCString &f,
866 const QCString &anchor, const QCString &name,
867 const QCString &tooltip)
868{
869 if (m_hide) return;
870 const char *hl = codeSymbolType2Str(type);
871 QCString hlClass = "code";
872 if (hl)
873 {
874 hlClass+=" hl_";
875 hlClass+=hl;
876 }
877 _writeCodeLink(hlClass,ref,f,anchor,name,tooltip);
878}
879
881 const QCString &ref,const QCString &f,
882 const QCString &anchor, const QCString &name,
883 const QCString &tooltip)
884{
885 m_col+=name.length();
886 if (m_hide) return;
887 if (!ref.isEmpty())
888 {
889 *m_t << "<a class=\"" << className << "Ref\" ";
891 }
892 else
893 {
894 *m_t << "<a class=\"" << className << "\" ";
895 }
896 *m_t << "href=\"";
897 QCString fn = f;
899 *m_t << createHtmlUrl(m_relPath,ref,true,
900 fileName()==fn,fn,anchor);
901 *m_t << "\"";
902 if (!tooltip.isEmpty()) *m_t << " title=\"" << convertToHtml(tooltip) << "\"";
903 *m_t << ">";
904 codify(name);
905 *m_t << "</a>";
906}
907
909 const QCString &decl, const QCString &desc,
910 const SourceLinkInfo &defInfo,
911 const SourceLinkInfo &declInfo)
912{
913 if (m_hide) return;
914 *m_t << "<div class=\"ttc\" id=\"" << id << "\">";
915 *m_t << "<div class=\"ttname\">";
916 if (!docInfo.url.isEmpty())
917 {
918 *m_t << "<a href=\"";
919 QCString fn = docInfo.url;
921 *m_t << createHtmlUrl(m_relPath,docInfo.ref,true,
922 fileName()==fn,fn,docInfo.anchor);
923 *m_t << "\">";
924 }
925 codify(docInfo.name);
926 if (!docInfo.url.isEmpty())
927 {
928 *m_t << "</a>";
929 }
930 *m_t << "</div>";
931
932 if (!decl.isEmpty())
933 {
934 *m_t << "<div class=\"ttdeci\">";
935 codify(decl);
936 *m_t << "</div>";
937 }
938
939 if (!desc.isEmpty())
940 {
941 *m_t << "<div class=\"ttdoc\">";
942 codify(desc);
943 *m_t << "</div>";
944 }
945
946 if (!defInfo.file.isEmpty())
947 {
948 *m_t << "<div class=\"ttdef\"><b>" << theTranslator->trDefinition() << "</b> ";
949 if (!defInfo.url.isEmpty())
950 {
951 *m_t << "<a href=\"";
952 QCString fn = defInfo.url;
954 *m_t << createHtmlUrl(m_relPath,defInfo.ref,true,
955 fileName()==fn,fn,defInfo.anchor);
956 *m_t << "\">";
957 }
958 *m_t << defInfo.file << ":" << defInfo.line;
959 if (!defInfo.url.isEmpty())
960 {
961 *m_t << "</a>";
962 }
963 *m_t << "</div>";
964 }
965 if (!declInfo.file.isEmpty())
966 {
967 *m_t << "<div class=\"ttdecl\"><b>" << theTranslator->trDeclaration() << "</b> ";
968 if (!declInfo.url.isEmpty())
969 {
970 *m_t << "<a href=\"";
971 QCString fn = declInfo.url;
973 *m_t << createHtmlUrl(m_relPath,declInfo.ref,true,
974 fileName()==fn,fn,declInfo.anchor);
975 *m_t << "\">";
976 }
977 *m_t << declInfo.file << ":" << declInfo.line;
978 if (!declInfo.url.isEmpty())
979 {
980 *m_t << "</a>";
981 }
982 *m_t << "</div>";
983 }
984 *m_t << "</div>\n";
985}
986
987
989{
990 m_col=0;
991 if (m_hide) return;
992 if (!m_lineOpen)
993 {
994 *m_t << "<div class=\"line\">";
996 }
997}
998
1000{
1001 if (m_hide) return;
1002 if (m_col == 0)
1003 {
1004 *m_t << " ";
1005 m_col++;
1006 }
1007 if (m_lineOpen)
1008 {
1009 *m_t << "</div>\n";
1010 m_lineOpen = FALSE;
1011 }
1012}
1013
1015{
1016 if (m_hide) return;
1017 *m_t << "<span class=\"" << s << "\">";
1018}
1019
1021{
1022 if (m_hide) return;
1023 *m_t << "</span>";
1024}
1025
1027{
1028 if (m_hide) return;
1029 *m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>";
1030}
1031
1033{
1034 *m_t << "<div class=\"fragment\">";
1035}
1036
1038{
1039 //endCodeLine checks is there is still an open code line, if so closes it.
1040 endCodeLine();
1041
1042 *m_t << "</div><!-- fragment -->";
1043}
1044
1045void HtmlCodeGenerator::startFold(int lineNr,const QCString &startMarker,const QCString &endMarker)
1046{
1047 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to end the line
1048 {
1049 *m_t << "</div>\n";
1050 }
1051 const int maxLineNrStr = 10;
1052 char lineNumber[maxLineNrStr];
1053 qsnprintf(lineNumber,maxLineNrStr,"%05d",lineNr);
1054 *m_t << "<div class=\"foldopen\" id=\"foldopen" << lineNumber <<
1055 "\" data-start=\"" << startMarker <<
1056 "\" data-end=\"" << endMarker <<
1057 "\">\n";
1058 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to restart the line
1059 {
1060 *m_t << "<div class=\"line\">";
1061 }
1062 m_hide=false;
1063}
1064
1066{
1067 *m_t << "<div class=\"line\">";
1068 bool wasHidden=m_hide;
1069 m_hide = false;
1070 m_lineOpen = true;
1072 m_lastLineInfo.fileName,
1073 m_lastLineInfo.anchor,
1074 m_lastLineInfo.line+1,
1075 m_lastLineInfo.writeAnchor);
1076 m_hide = wasHidden;
1077}
1078
1080{
1081 if (m_lineOpen) // if we have a hidden comment in a code fold, we need to end the line
1082 {
1083 *m_t << "</div>\n";
1084 }
1085 *m_t << "</div>\n";
1086 if (m_lineOpen)
1087 {
1089 }
1090}
1091
1092//--------------------------------------------------------------------------
1093
1095 : OutputGenerator(Config_getString(HTML_OUTPUT))
1096 , m_codeList(std::make_unique<OutputCodeList>())
1097{
1098 //printf("%p:HtmlGenerator()\n",(void*)this);
1100}
1101
1103{
1104 //printf("%p:HtmlGenerator(copy %p)\n",(void*)this,(void*)&og);
1105 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
1107 m_codeGen->setTextStream(&m_t);
1110 m_relPath = og.m_relPath;
1113}
1114
1116{
1117 //printf("%p:HtmlGenerator(copy assign %p)\n",(void*)this,(void*)&og);
1118 if (this!=&og)
1119 {
1120 m_dir = og.m_dir;
1121 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
1123 m_codeGen->setTextStream(&m_t);
1126 m_relPath = og.m_relPath;
1129 }
1130 return *this;
1131}
1132
1134
1139
1141{
1142 QCString dname = Config_getString(HTML_OUTPUT);
1143 Dir d(dname.str());
1144 if (!d.exists() && !d.mkdir(dname.str()))
1145 {
1146 term("Could not create output directory {}\n",dname);
1147 }
1148 //writeLogo(dname);
1149 if (!Config_getString(HTML_HEADER).isEmpty())
1150 {
1151 g_header_file=Config_getString(HTML_HEADER);
1153 //printf("g_header='%s'\n",qPrint(g_header));
1155 checkBlocks(result,Config_getString(HTML_HEADER),htmlMarkerInfo);
1156 }
1157 else
1158 {
1159 g_header_file="header.html";
1162 checkBlocks(result,"<default header.html>",htmlMarkerInfo);
1163 }
1164
1165 if (!Config_getString(HTML_FOOTER).isEmpty())
1166 {
1167 g_footer_file=Config_getString(HTML_FOOTER);
1169 //printf("g_footer='%s'\n",qPrint(g_footer));
1171 checkBlocks(result,Config_getString(HTML_FOOTER),htmlMarkerInfo);
1172 }
1173 else
1174 {
1175 g_footer_file = "footer.html";
1178 checkBlocks(result,"<default footer.html>",htmlMarkerInfo);
1179 }
1180
1181 if (Config_getBool(USE_MATHJAX))
1182 {
1183 if (!Config_getString(MATHJAX_CODEFILE).isEmpty())
1184 {
1185 g_mathjax_code=fileToString(Config_getString(MATHJAX_CODEFILE));
1186 //printf("g_mathjax_code='%s'\n",qPrint(g_mathjax_code));
1187 }
1189 //printf("converted g_latex_macro='%s'\n",qPrint(g_latex_macro));
1190 }
1191 createSubDirs(d);
1192
1194
1196
1197 {
1198 QCString tabsCss;
1199 if (Config_getBool(HTML_DYNAMIC_MENUS))
1200 {
1201 tabsCss = mgr.getAsString("tabs.css");
1202 }
1203 else // stylesheet for the 'old' static tabs
1204 {
1205 tabsCss = mgr.getAsString("fixed_tabs.css");
1206 }
1207
1208 std::ofstream f = Portable::openOutputStream(dname+"/tabs.css");
1209 if (f.is_open())
1210 {
1211 TextStream t(&f);
1212 t << replaceVariables(tabsCss);
1213 }
1214 }
1215
1216
1217 mgr.copyResource("jquery.js",dname);
1218 if (Config_getBool(INTERACTIVE_SVG))
1219 {
1220 mgr.copyResource("svg.min.js",dname);
1221 }
1222
1223 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
1224 {
1225 mgr.copyResource("menu.js",dname);
1226 }
1227
1228 // copy navtree.css
1229 {
1230 std::ofstream f = Portable::openOutputStream(dname+"/navtree.css");
1231 if (f.is_open())
1232 {
1233 TextStream t(&f);
1234 t << getNavTreeCss();
1235 }
1236 }
1237
1238 // copy resize.js
1239 {
1240 std::ofstream f = Portable::openOutputStream(dname+"/resize.js");
1241 if (f.is_open())
1242 {
1243 TextStream t(&f);
1244 t << substitute(
1245 substitute(mgr.getAsString("resize.js"),
1246 "$TREEVIEW_WIDTH", QCString().setNum(Config_getInt(TREEVIEW_WIDTH))),
1247 "$PROJECTID", getProjectId());
1248 }
1249 }
1250
1251 if (Config_getBool(HTML_COPY_CLIPBOARD))
1252 {
1253 std::ofstream f = Portable::openOutputStream(dname+"/clipboard.js");
1254 if (f.is_open())
1255 {
1256 TextStream t(&f);
1257 t << substitute(mgr.getAsString("clipboard.js"),"$copy_to_clipboard_text",theTranslator->trCopyToClipboard());
1258 }
1259 }
1260
1261 bool hasCookie = Config_getBool(GENERATE_TREEVIEW) || Config_getBool(SEARCHENGINE) || Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE;
1262 if (hasCookie)
1263 {
1264 mgr.copyResource("cookie.js",dname);
1265 }
1266
1267 if (Config_getBool(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1268 {
1269 std::ofstream f = Portable::openOutputStream(dname+"/darkmode_toggle.js");
1270 if (f.is_open())
1271 {
1272 TextStream t(&f);
1273 t << substitute(replaceColorMarkers(mgr.getAsString("darkmode_toggle.js")),
1274 "$PROJECTID",getProjectId());
1275 }
1276 }
1277
1278 {
1279 std::ofstream f = Portable::openOutputStream(dname+"/dynsections.js");
1280 if (f.is_open())
1281 {
1282 TextStream t(&f);
1283 t << replaceVariables(mgr.getAsString("dynsections.js"));
1284 if (Config_getBool(SOURCE_BROWSER) && Config_getBool(SOURCE_TOOLTIPS))
1285 {
1286 t << replaceVariables(mgr.getAsString("dynsections_tooltips.js"));
1287 }
1288 }
1289 }
1290}
1291
1293{
1294 QCString dname = Config_getString(HTML_OUTPUT);
1295 Dir d(dname.str());
1296 clearSubDirs(d);
1297}
1298
1299/// Additional initialization after indices have been created
1301{
1302 Doxygen::indexList->addStyleSheetFile("tabs.css");
1303 QCString dname=Config_getString(HTML_OUTPUT);
1305 //writeColoredImgData(dname,colored_tab_data);
1306 mgr.copyResource("doxygen.svg",dname);
1307 Doxygen::indexList->addImageFile("doxygen.svg");
1308 mgr.copyResource("sync_on.luma",dname);
1309 mgr.copyResource("sync_off.luma",dname);
1310}
1311
1313{
1314 //bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
1315 //writeImgData(dname,serverBasedSearch ? search_server_data : search_client_data);
1317
1318 QCString searchDirName = dname;
1319 std::ofstream f = Portable::openOutputStream(searchDirName+"/search.css");
1320 if (f.is_open())
1321 {
1322 TextStream t(&f);
1323 QCString searchCss;
1324 // the position of the search box depends on a number of settings.
1325 // Insert the right piece of CSS code depending on which options are selected
1326 if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(FULL_SIDEBAR))
1327 {
1328 searchCss = mgr.getAsString("search_sidebar.css"); // we have a full height side bar
1329 }
1330 else if (Config_getBool(DISABLE_INDEX))
1331 {
1332 if (Config_getBool(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1333 {
1334 searchCss = mgr.getAsString("search_nomenu_toggle.css"); // we have no tabs but do have a darkmode button
1335 }
1336 else
1337 {
1338 searchCss = mgr.getAsString("search_nomenu.css"); // we have no tabs and no darkmode button
1339 }
1340 }
1341 else if (!Config_getBool(HTML_DYNAMIC_MENUS))
1342 {
1343 searchCss = mgr.getAsString("search_fixedtabs.css"); // we have tabs, but they are static
1344 }
1345 else
1346 {
1347 searchCss = mgr.getAsString("search.css"); // default case with a dynamic menu bar
1348 }
1349 // and then add the option independent part of the styling
1350 searchCss += mgr.getAsString("search_common.css");
1351 searchCss = substitute(searchCss,"$doxygenversion",getDoxygenVersion());
1352 t << replaceVariables(searchCss);
1353 Doxygen::indexList->addStyleSheetFile("search/search.css");
1354 }
1355}
1356
1358{
1359 t << "/* The standard CSS for doxygen " << getDoxygenVersion() << "*/\n\n";
1360 switch (Config_getEnum(HTML_COLORSTYLE))
1361 {
1362 case HTML_COLORSTYLE_t::LIGHT:
1363 case HTML_COLORSTYLE_t::DARK:
1364 /* variables will be resolved while writing to the CSS file */
1365 break;
1366 case HTML_COLORSTYLE_t::AUTO_LIGHT:
1367 case HTML_COLORSTYLE_t::TOGGLE:
1368 t << "html {\n";
1369 t << replaceColorMarkers(ResourceMgr::instance().getAsString("lightmode_settings.css"));
1370 t << "}\n\n";
1371 break;
1372 case HTML_COLORSTYLE_t::AUTO_DARK:
1373 t << "html {\n";
1374 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1375 t << "}\n\n";
1376 break;
1377 }
1378 if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::AUTO_LIGHT)
1379 {
1380 t << "@media (prefers-color-scheme: dark) {\n";
1381 t << " html:not(.dark-mode) {\n";
1382 t << " color-scheme: dark;\n\n";
1383 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1384 t << "}}\n";
1385 }
1386 else if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::AUTO_DARK)
1387 {
1388 t << "@media (prefers-color-scheme: light) {\n";
1389 t << " html:not(.light-mode) {\n";
1390 t << " color-scheme: light;\n\n";
1391 t << replaceColorMarkers(ResourceMgr::instance().getAsString("lightmode_settings.css"));
1392 t << "}}\n";
1393 }
1394 else if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1395 {
1396 t << "html.dark-mode {\n";
1397 t << replaceColorMarkers(ResourceMgr::instance().getAsString("darkmode_settings.css"));
1398 t << "}\n\n";
1399 }
1400
1401 QCString cssStr = ResourceMgr::instance().getAsString("doxygen.css");
1402 bool hasFullSidebar = Config_getBool(FULL_SIDEBAR) && Config_getBool(GENERATE_TREEVIEW);
1403 if (hasFullSidebar)
1404 {
1405 cssStr+="\n"
1406 "#titlearea {\n"
1407 " border-bottom: none;\n"
1408 " background-color: var(--nav-background-color);\n"
1409 " border-right: 1px solid var(--nav-border-color);\n"
1410 "}\n";
1411 }
1412 t << replaceVariables(cssStr);
1413
1414 // For Webkit based the scrollbar styling cannot be overruled (bug in chromium?).
1415 // To allow the user to style the scrollbars differently we should only add it in case
1416 // the user did not specify any extra stylesheets.
1417 bool addScrollbarStyling = Config_getList(HTML_EXTRA_STYLESHEET).empty();
1418 if (addScrollbarStyling)
1419 {
1420 t << replaceVariables(ResourceMgr::instance().getAsString("scrollbar.css"));
1421 }
1422
1423}
1424
1430
1432{
1433 t << "<!-- HTML header for doxygen " << getDoxygenVersion() << "-->\n";
1434 t << ResourceMgr::instance().getAsString("header.html");
1435}
1436
1438{
1439 t << "<!-- HTML footer for doxygen " << getDoxygenVersion() << "-->\n";
1440 t << ResourceMgr::instance().getAsString("footer.html");
1441}
1442
1443static std::mutex g_indexLock;
1444
1446 const QCString &title,int /*id*/, int /*hierarchyLevel*/)
1447{
1448 //printf("HtmlGenerator::startFile(%s)\n",qPrint(name));
1450 QCString fileName = name;
1452 m_lastTitle=title;
1453
1455 m_codeGen->setFileName(fileName);
1456 m_codeGen->setRelativePath(m_relPath);
1457 {
1458 std::lock_guard<std::mutex> lock(g_indexLock);
1459 Doxygen::indexList->addIndexFile(fileName);
1460 }
1461
1464
1465 m_t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
1466 << getDoxygenVersion() << " -->\n";
1467 bool searchEngine = Config_getBool(SEARCHENGINE);
1468 if (searchEngine /*&& !generateTreeView*/)
1469 {
1470 m_t << "<script type=\"text/javascript\">\n";
1471 m_t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
1472 m_t << "var searchBox = new SearchBox(\"searchBox\", \""
1473 << m_relPath<< "search/\",'" << Doxygen::htmlFileExtension << "');\n";
1474 m_t << "/* @license-end */\n";
1475 m_t << "</script>\n";
1476 }
1477 if (Config_getBool(HTML_CODE_FOLDING))
1478 {
1479 m_t << "<script type=\"text/javascript\">\n";
1480 m_t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
1481 m_t << "$(function() { codefold.init(); });\n";
1482 m_t << "/* @license-end */\n";
1483 m_t << "</script>\n";
1484 }
1486}
1487
1489{
1490 bool searchEngine = Config_getBool(SEARCHENGINE);
1491 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
1492 if (searchEngine && !serverBasedSearch)
1493 {
1494 t << "<!-- window showing the filter options -->\n";
1495 t << "<div id=\"MSearchSelectWindow\"\n";
1496 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
1497 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
1498 t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
1499 t << "</div>\n";
1500 t << "\n";
1501 t << "<!-- iframe showing the search results (closed by default) -->\n";
1502 t << "<div id=\"MSearchResultsWindow\">\n";
1503 t << "<div id=\"MSearchResults\">\n";
1504 t << "<div class=\"SRPage\">\n";
1505 t << "<div id=\"SRIndex\">\n";
1506 t << "<div id=\"SRResults\"></div>\n"; // here the results will be inserted
1507 t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>\n";
1508 t << "<div class=\"SRStatus\" id=\"Searching\">" << theTranslator->trSearching() << "</div>\n";
1509 t << "<div class=\"SRStatus\" id=\"NoMatches\">" << theTranslator->trNoMatches() << "</div>\n";
1510 t << "</div>\n"; // SRIndex
1511 t << "</div>\n"; // SRPage
1512 t << "</div>\n"; // MSearchResults
1513 t << "</div>\n"; // MSearchResultsWindow
1514 t << "\n";
1515 }
1516}
1517
1522
1523
1525{
1526 QCString result;
1527 switch (Config_getEnum(TIMESTAMP))
1528 {
1529 case TIMESTAMP_t::YES:
1530 case TIMESTAMP_t::DATETIME:
1531 result += theTranslator->trGeneratedAt(
1533 Config_getString(PROJECT_NAME)
1534 );
1535 break;
1536 case TIMESTAMP_t::DATE:
1537 result += theTranslator->trGeneratedAt(
1539 Config_getString(PROJECT_NAME)
1540 );
1541 break;
1542 case TIMESTAMP_t::NO:
1543 result += theTranslator->trGeneratedBy();
1544 break;
1545 }
1546 result += "&#160;\n<a href=\"https://www.doxygen.org/index.html\">\n"
1547 "<img class=\"footer\" src=\"";
1548 result += path;
1549 result += "doxygen.svg\" width=\"104\" height=\"31\" alt=\"doxygen\"/></a> ";
1550 result += getDoxygenVersion();
1551 result += " ";
1552 return result;
1553}
1554
1559
1561 const QCString &relPath,const QCString &navPath)
1562{
1563 t << substituteHtmlKeywords(g_footer_file,g_footer,convertToHtml(lastTitle),relPath,navPath);
1564}
1565
1567{
1569}
1570
1572{
1573 endPlainFile();
1574}
1575
1577{
1578 m_t << "<h3 class=\"version\">";
1579}
1580
1582{
1583 m_t << "</h3>";
1584}
1585
1587{
1588 //printf("writeStyleInfo(%d)\n",part);
1589 if (part==0)
1590 {
1591 if (Config_getString(HTML_STYLESHEET).isEmpty()) // write default style sheet
1592 {
1593 //printf("write doxygen.css\n");
1594 startPlainFile("doxygen.css");
1596 endPlainFile();
1597 Doxygen::indexList->addStyleSheetFile("doxygen.css");
1598 }
1599 else // write user defined style sheet
1600 {
1601 QCString cssName=Config_getString(HTML_STYLESHEET);
1602 if (!cssName.startsWith("http:") && !cssName.startsWith("https:"))
1603 {
1604 FileInfo cssfi(cssName.str());
1605 if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1606 {
1607 err("style sheet {} does not exist or is not readable!\n", Config_getString(HTML_STYLESHEET));
1608 }
1609 else
1610 {
1611 // convert style sheet to string
1612 QCString fileStr = fileToString(cssName);
1613 // write the string into the output dir
1614 startPlainFile(cssfi.fileName().c_str());
1615 m_t << fileStr;
1616 endPlainFile();
1617 }
1618 Doxygen::indexList->addStyleSheetFile(cssfi.fileName().c_str());
1619 }
1620 }
1621 const StringVector &extraCssFiles = Config_getList(HTML_EXTRA_STYLESHEET);
1622 for (const auto &fileName : extraCssFiles)
1623 {
1624 if (!fileName.empty())
1625 {
1626 FileInfo fi(fileName);
1627 if (fi.exists())
1628 {
1629 Doxygen::indexList->addStyleSheetFile(fi.fileName().c_str());
1630 }
1631 }
1632 }
1633
1634 Doxygen::indexList->addStyleSheetFile("jquery.js");
1635 Doxygen::indexList->addStyleSheetFile("resize.js");
1636 Doxygen::indexList->addStyleSheetFile("navtree.css");
1637
1638 Doxygen::indexList->addStyleSheetFile("dynsections.js");
1639
1640 if (Config_getEnum(HTML_COLORSTYLE)==HTML_COLORSTYLE_t::TOGGLE)
1641 {
1642 Doxygen::indexList->addStyleSheetFile("darkmode_toggle.js");
1643 }
1644
1645 if (Config_getBool(INTERACTIVE_SVG))
1646 {
1647 Doxygen::indexList->addStyleSheetFile("svg.min.js");
1648 }
1649
1650 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
1651 {
1652 Doxygen::indexList->addStyleSheetFile("menu.js");
1653 Doxygen::indexList->addStyleSheetFile("menudata.js");
1654 }
1655 }
1656}
1657
1659 const QCString &anchor, const QCString &,
1660 const QCString &)
1661{
1662 m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>";
1663}
1664
1666{
1667}
1668
1670{
1671}
1672
1674{
1675 if (!classDef.isEmpty())
1676 m_t << "\n<p class=\"" << classDef << "\">";
1677 else
1678 m_t << "\n<p>";
1679}
1680
1682{
1683 m_t << "</p>\n";
1684}
1685
1687{
1688 m_t << text;
1689}
1690
1692{
1693 m_t << "<li>";
1694}
1695
1697{
1698 m_t << "</li>\n";
1699}
1700
1702{
1703 //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1704 if (!ref.isEmpty() || !f.isEmpty())
1705 {
1706 if (!ref.isEmpty())
1707 {
1708 m_t << "<a class=\"elRef\" ";
1710 }
1711 else
1712 {
1713 m_t << "<a class=\"el\" ";
1714 }
1715 m_t << "href=\"";
1716 m_t << externalRef(m_relPath,ref,TRUE);
1717 if (!f.isEmpty())
1718 {
1719 QCString fn=f;
1721 m_t << fn;
1722 }
1723 m_t << "\">";
1724 }
1725 else
1726 {
1727 m_t << "<b>";
1728 }
1729}
1730
1732{
1733 //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1734 if (!ref.isEmpty() || !f.isEmpty())
1735 {
1736 m_t << "</a>";
1737 }
1738 else
1739 {
1740 m_t << "</b>";
1741 }
1742}
1743
1745 const QCString &path,const QCString &name)
1746{
1747 m_t << "<li>";
1748 if (!path.isEmpty()) docify(path);
1749 QCString fn = f;
1751 m_t << "<a class=\"el\" href=\"" << fn << "\">";
1752 docify(name);
1753 m_t << "</a> ";
1754}
1755
1757 const QCString &anchor, const QCString &name)
1758{
1759 if (!ref.isEmpty())
1760 {
1761 m_t << "<a class=\"elRef\" ";
1763 }
1764 else
1765 {
1766 m_t << "<a class=\"el\" ";
1767 }
1768 m_t << "href=\"";
1769 QCString fn = f;
1771 m_t << createHtmlUrl(m_relPath,ref,true,
1772 fileName() == Config_getString(HTML_OUTPUT)+"/"+fn,
1773 fn,
1774 anchor);
1775 m_t << "\">";
1776 docify(name);
1777 m_t << "</a>";
1778}
1779
1781{
1782 m_t << "<a href=\"";
1783 QCString fn = f;
1785 m_t << createHtmlUrl(m_relPath,"",true,
1786 fileName() == Config_getString(HTML_OUTPUT)+"/"+fn,
1787 fn,
1788 anchor);
1789 m_t << "\">";
1790}
1791
1793{
1794 m_t << "</a>";
1795}
1796
1797void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1798{
1799 if (extraIndentLevel==2)
1800 {
1801 m_t << "<h4 class=\"groupheader\">";
1802 }
1803 else if (extraIndentLevel==1)
1804 {
1805 m_t << "<h3 class=\"groupheader\">";
1806 }
1807 else // extraIndentLevel==0
1808 {
1809 m_t << "<h2 class=\"groupheader\">";
1810 }
1811}
1812
1813void HtmlGenerator::endGroupHeader(int extraIndentLevel)
1814{
1815 if (extraIndentLevel==2)
1816 {
1817 m_t << "</h4>\n";
1818 }
1819 else if (extraIndentLevel==1)
1820 {
1821 m_t << "</h3>\n";
1822 }
1823 else
1824 {
1825 m_t << "</h2>\n";
1826 }
1827}
1828
1830{
1831 switch(type.level())
1832 {
1833 case SectionType::Page: m_t << "\n\n<h1>"; break;
1834 case SectionType::Section: m_t << "\n\n<h2>"; break;
1835 case SectionType::Subsection: m_t << "\n\n<h3>"; break;
1836 case SectionType::Subsubsection: m_t << "\n\n<h4>"; break;
1837 case SectionType::Paragraph: m_t << "\n\n<h5>"; break;
1838 case SectionType::Subparagraph: m_t << "\n\n<h6>"; break;
1839 case SectionType::Subsubparagraph: m_t << "\n\n<h6>"; break;
1840 default: ASSERT(0); break;
1841 }
1842 m_t << "<a id=\"" << lab << "\" name=\"" << lab << "\"></a>";
1843}
1844
1846{
1847 switch(type.level())
1848 {
1849 case SectionType::Page: m_t << "</h1>"; break;
1850 case SectionType::Section: m_t << "</h2>"; break;
1851 case SectionType::Subsection: m_t << "</h3>"; break;
1852 case SectionType::Subsubsection: m_t << "</h4>"; break;
1853 case SectionType::Paragraph: m_t << "</h5>"; break;
1854 case SectionType::Subparagraph: m_t << "</h6>"; break;
1855 case SectionType::Subsubparagraph: m_t << "</h6>"; break;
1856 default: ASSERT(0); break;
1857 }
1858}
1859
1861{
1862 docify_(str,FALSE);
1863}
1864
1865void HtmlGenerator::docify_(const QCString &str,bool inHtmlComment)
1866{
1867 if (!str.isEmpty())
1868 {
1869 const char *p=str.data();
1870 while (*p)
1871 {
1872 char c=*p++;
1873 switch(c)
1874 {
1875 case '<': m_t << "&lt;"; break;
1876 case '>': m_t << "&gt;"; break;
1877 case '&': m_t << "&amp;"; break;
1878 case '"': m_t << "&quot;"; break;
1879 case '-': if (inHtmlComment) m_t << "&#45;"; else m_t << "-"; break;
1880 case '\\':
1881 if (*p=='<')
1882 { m_t << "&lt;"; p++; }
1883 else if (*p=='>')
1884 { m_t << "&gt;"; p++; }
1885 else if (*p=='(')
1886 { m_t << "\\&zwj;("; p++; }
1887 else if (*p==')')
1888 { m_t << "\\&zwj;)"; p++; }
1889 else
1890 m_t << "\\";
1891 break;
1892 default: m_t << c;
1893 }
1894 }
1895 }
1896}
1897
1899{
1900 char cs[2];
1901 cs[0]=c;
1902 cs[1]=0;
1903 docify(cs);
1904}
1905
1906//--- helper function for dynamic sections -------------------------
1907
1909 const QCString &relPath,int sectionCount)
1910{
1911 //t << "<!-- startSectionHeader -->";
1912 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1913 if (dynamicSections)
1914 {
1915 t << "<div id=\"dynsection-" << sectionCount << "\" "
1916 "onclick=\"return dynsection.toggleVisibility(this)\" "
1917 "class=\"dynheader closed\" "
1918 "style=\"cursor:pointer;\">"
1919 "<span class=\"dynarrow\"><span class=\"arrowhead closed\"></span></span>";
1920 }
1921 else
1922 {
1923 t << "<div class=\"dynheader\">\n";
1924 }
1925}
1926
1928{
1929 //t << "<!-- endSectionHeader -->";
1930 t << "</div>\n";
1931}
1932
1933static void startSectionSummary(TextStream &t,int sectionCount)
1934{
1935 //t << "<!-- startSectionSummary -->";
1936 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1937 if (dynamicSections)
1938 {
1939 t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
1940 "class=\"dynsummary\" "
1941 "style=\"display:block;\">\n";
1942 }
1943}
1944
1946{
1947 //t << "<!-- endSectionSummary -->";
1948 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1949 if (dynamicSections)
1950 {
1951 t << "</div>\n";
1952 }
1953}
1954
1955static void startSectionContent(TextStream &t,int sectionCount)
1956{
1957 //t << "<!-- startSectionContent -->";
1958 bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1959 if (dynamicSections)
1960 {
1961 t << "<div id=\"dynsection-" << sectionCount << "-content\" "
1962 "class=\"dyncontent\" "
1963 "style=\"display:none;\">\n";
1964 }
1965 else
1966 {
1967 t << "<div class=\"dyncontent\">\n";
1968 }
1969}
1970
1972{
1973 //t << "<!-- endSectionContent -->";
1974 t << "</div>\n";
1975}
1976
1977//----------------------------
1978
1983
1985 const QCString &fileName,const QCString &name)
1986{
1991 TextStream tt;
1993 if (!tt.empty())
1994 {
1995 m_t << " <div class=\"center\">\n";
1996 m_t << " <img src=\"";
1997 m_t << m_relPath << fileName << ".png\" usemap=\"#" << convertToId(name);
1998 m_t << "_map\" alt=\"\"/>\n";
1999 m_t << " <map id=\"" << convertToId(name);
2000 m_t << "_map\" name=\"" << convertToId(name);
2001 m_t << "_map\">\n";
2002 m_t << tt.str();
2003 m_t << " </map>\n";
2004 m_t << "</div>";
2005 }
2006 else
2007 {
2008 m_t << " <div class=\"center\">\n";
2009 m_t << " <img src=\"";
2010 m_t << m_relPath << fileName << ".png\" alt=\"\"/>\n";
2011 m_t << " </div>";
2012 }
2015}
2016
2017
2019{
2020 DBG_HTML(m_t << "<!-- startMemberList -->\n")
2021}
2022
2024{
2025 DBG_HTML(m_t << "<!-- endMemberList -->\n")
2026}
2027
2028// anonymous type:
2029// 0 = single column right aligned
2030// 1 = double column left aligned
2031// 2 = single column left aligned
2033{
2034 DBG_HTML(m_t << "<!-- startMemberItem() -->\n")
2035 if (m_emptySection)
2036 {
2037 m_t << "<table class=\"memberdecls\">\n";
2039 }
2040 m_t << "<tr class=\"memitem:" << anchor;
2041 if (!inheritId.isEmpty())
2042 {
2043 m_t << " inherit " << inheritId;
2044 }
2045 m_t << "\"";
2046 if (!anchor.isEmpty())
2047 {
2048 m_t << " id=\"r_" << anchor << "\"";
2049 }
2050 m_t << ">";
2052}
2053
2055{
2057 {
2058 insertMemberAlign(false);
2059 }
2060 m_t << "</td></tr>\n";
2061}
2062
2066
2068{
2069 m_t << "</td></tr>\n";
2070 m_t << "<tr class=\"memitem:" << anchor;
2071 if (!inheritId.isEmpty())
2072 {
2073 m_t << " inherit " << inheritId;
2074 }
2075 m_t << " template\"><td class=\"memItemLeft\" align=\"right\" valign=\"top\">";
2076}
2077
2079{
2080 m_t << "<div class=\"compoundTemplParams\">";
2081}
2082
2084{
2085 m_t << "</div>";
2086}
2087
2089{
2090 DBG_HTML(m_t << "<!-- insertMemberAlign -->\n")
2091 m_t << "&#160;</td><td class=\"memItemRight\" valign=\"bottom\">";
2092}
2093
2095{
2096 if (!initTag) m_t << "&#160;</td>";
2097 switch (type)
2098 {
2099 case MemberItemType::Normal: m_t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
2100 case MemberItemType::AnonymousStart: m_t << "<td class=\"memItemLeft anon\">"; break;
2101 case MemberItemType::AnonymousEnd: m_t << "<td class=\"memItemLeft anonEnd\" valign=\"top\">"; break;
2102 case MemberItemType::Templated: m_t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
2103 }
2104}
2105
2106void HtmlGenerator::startMemberDescription(const QCString &anchor,const QCString &inheritId, bool typ)
2107{
2108 DBG_HTML(m_t << "<!-- startMemberDescription -->\n")
2109 if (m_emptySection)
2110 {
2111 m_t << "<table class=\"memberdecls\">\n";
2113 }
2114 m_t << "<tr class=\"memdesc:" << anchor;
2115 if (!inheritId.isEmpty())
2116 {
2117 m_t << " inherit " << inheritId;
2118 }
2119 m_t << "\">";
2120 m_t << "<td class=\"mdescLeft\">&#160;</td>";
2121 if (typ) m_t << "<td class=\"mdescLeft\">&#160;</td>";
2122 m_t << "<td class=\"mdescRight\">";
2123}
2124
2126{
2127 DBG_HTML(m_t << "<!-- endMemberDescription -->\n")
2128 m_t << "<br /></td></tr>\n";
2129}
2130
2132{
2133 DBG_HTML(m_t << "<!-- startMemberSections -->\n")
2134 m_emptySection=TRUE; // we postpone writing <table> until we actually
2135 // write a row to prevent empty tables, which
2136 // are not valid XHTML!
2137}
2138
2140{
2141 DBG_HTML(m_t << "<!-- endMemberSections -->\n")
2142 if (!m_emptySection)
2143 {
2144 m_t << "</table>\n";
2145 }
2146}
2147
2148void HtmlGenerator::startMemberHeader(const QCString &anchor, int typ)
2149{
2150 DBG_HTML(m_t << "<!-- startMemberHeader -->\n")
2151 if (!m_emptySection)
2152 {
2153 m_t << "</table>";
2155 }
2156 if (m_emptySection)
2157 {
2158 m_t << "<table class=\"memberdecls\">\n";
2160 }
2161 m_t << "<tr class=\"heading\"><td colspan=\"" << typ << "\"><h2 class=\"groupheader\">";
2162 if (!anchor.isEmpty())
2163 {
2164 m_t << "<a id=\"" << anchor << "\" name=\"" << anchor << "\"></a>\n";
2165 }
2166}
2167
2169{
2170 DBG_HTML(m_t << "<!-- endMemberHeader -->\n")
2171 m_t << "</h2></td></tr>\n";
2172}
2173
2175{
2176 DBG_HTML(m_t << "<!-- startMemberSubtitle -->\n")
2177 m_t << "<tr><td class=\"ititle\" colspan=\"2\">";
2178}
2179
2181{
2182 DBG_HTML(m_t << "<!-- endMemberSubtitle -->\n")
2183 m_t << "</td></tr>\n";
2184}
2185
2187{
2188 m_t << "<table>\n";
2189}
2190
2192{
2193 m_t << "</table>\n";
2194}
2195
2197{
2198 //m_t << " <tr><td class=\"indexkey\">";
2199}
2200
2202{
2203 //m_t << "</td>";
2204}
2205
2207{
2208 //m_t << "<td class=\"indexvalue\">";
2209}
2210
2212{
2213 //m_t << "</td></tr>\n";
2214}
2215
2217{
2218 DBG_HTML(m_t << "<!-- startMemberDocList -->\n";)
2219}
2220
2222{
2223 DBG_HTML(m_t << "<!-- endMemberDocList -->\n";)
2224}
2225
2226void HtmlGenerator::startMemberDoc( const QCString &/* clName */, const QCString &/* memName */,
2227 const QCString &anchor, const QCString &title,
2228 int memCount, int memTotal, bool /* showInline */)
2229{
2230 DBG_HTML(m_t << "<!-- startMemberDoc -->\n";)
2231 m_t << "\n<h2 class=\"memtitle\">"
2232 << "<span class=\"permalink\"><a href=\"#" << anchor << "\">&#9670;&#160;</a></span>";
2233 docify(title);
2234 if (memTotal>1)
2235 {
2236 m_t << " <span class=\"overload\">[" << memCount << "/" << memTotal <<"]</span>";
2237 }
2238 m_t << "</h2>\n";
2239 m_t << "\n<div class=\"memitem\">\n";
2240 m_t << "<div class=\"memproto\">\n";
2241}
2242
2244{
2245 DBG_HTML(m_t << "<!-- startMemberDocPrefixItem -->\n";)
2246 m_t << "<div class=\"memtemplate\">\n";
2247}
2248
2250{
2251 DBG_HTML(m_t << "<!-- endMemberDocPrefixItem -->\n";)
2252 m_t << "</div>\n";
2253}
2254
2256{
2257 DBG_HTML(m_t << "<!-- startMemberDocName -->\n";)
2258
2259 m_t << " <table class=\"memname\">\n";
2260
2261 m_t << " <tr>\n";
2262 m_t << " <td class=\"memname\">";
2263}
2264
2266{
2267 DBG_HTML(m_t << "<!-- endMemberDocName -->\n";)
2268 m_t << "</td>\n";
2269}
2270
2272{
2273 DBG_HTML(m_t << "<!-- startParameterList -->\n";)
2274 m_t << " <td>";
2275 if (openBracket) m_t << "(";
2276 m_t << "</td>\n";
2277}
2278
2280{
2281 if (first)
2282 {
2283 DBG_HTML(m_t << "<!-- startFirstParameterType -->\n";)
2284 m_t << " <td class=\"paramtype\">";
2285 }
2286 else
2287 {
2288 DBG_HTML(m_t << "<!-- startParameterType -->\n";)
2289 m_t << " <tr>\n";
2290 m_t << " <td class=\"paramkey\">" << key << "</td>\n";
2291 m_t << " <td></td>\n";
2292 m_t << " <td class=\"paramtype\">";
2293 }
2294}
2295
2297{
2298 DBG_HTML(m_t << "<!-- endParameterType -->\n";)
2299 m_t << "</td>";
2300}
2301
2302void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
2303{
2304 DBG_HTML(m_t << "<!-- startParameterName -->\n";)
2305 m_t << " <td class=\"paramname\"><span class=\"paramname\"><em>";
2306}
2307
2309{
2310 DBG_HTML(m_t << "<!-- endParameterName -->\n";)
2311 m_t << "</em></span>";
2312}
2313
2315{
2316 DBG_HTML(m_t << "<!-- startParameterExtra -->\n";)
2317}
2318
2319void HtmlGenerator::endParameterExtra(bool last,bool emptyList, bool closeBracket)
2320{
2321 DBG_HTML(m_t << "<!-- endParameterExtra -->\n";)
2322 if (last)
2323 {
2324 if (emptyList)
2325 {
2326 if (closeBracket) m_t << "</td><td>)";
2327 m_t << "</td>\n";
2328 m_t << " <td>";
2329 }
2330 else
2331 {
2332 m_t << "&#160;";
2333 if (closeBracket) m_t << ")";
2334 }
2335 }
2336 else
2337 {
2338 m_t << "</td>\n";
2339 m_t << " </tr>\n";
2340 }
2341}
2342
2344{
2345 m_t << "<span class=\"paramdefsep\">";
2346 docify(s);
2347 m_t << "</span><span class=\"paramdefval\">";
2348}
2349
2351{
2352 m_t << "</span>";
2353}
2354
2356{
2357 DBG_HTML(m_t << "<!-- endParameterList -->\n";)
2358 m_t << "</td>\n";
2359 m_t << " </tr>\n";
2360}
2361
2362void HtmlGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2363{
2364 DBG_HTML(m_t << "<!-- exceptionEntry -->\n";)
2365 if (!closeBracket)
2366 {
2367 m_t << "</td>\n";
2368 m_t << " </tr>\n";
2369 m_t << " <tr>\n";
2370 m_t << " <td align=\"right\">";
2371 }
2372 // colspan 2 so it gets both parameter type and parameter name columns
2373 if (!prefix.isEmpty())
2374 m_t << prefix << "</td><td>(</td><td colspan=\"2\">";
2375 else if (closeBracket)
2376 m_t << "&#160;)</td><td></td><td></td><td>";
2377 else
2378 m_t << "</td><td></td><td colspan=\"2\">";
2379}
2380
2382{
2383 DBG_HTML(m_t << "<!-- endMemberDoc -->\n";)
2384 if (!hasArgs)
2385 {
2386 m_t << " </tr>\n";
2387 }
2388 m_t << " </table>\n";
2389 // m_t << "</div>\n";
2390}
2391
2396
2398{
2399 bool generateLegend = Config_getBool(GENERATE_LEGEND);
2400 bool umlLook = Config_getBool(UML_LOOK);
2405
2407 if (generateLegend && !umlLook)
2408 {
2409 QCString url = m_relPath+"graph_legend"+Doxygen::htmlFileExtension;
2410 m_t << "<center><span class=\"legend\">[";
2411 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2412 m_t << "<a ";
2413 if (generateTreeView) m_t << "target=\"top\" ";
2414 m_t << "href=\"";
2415 if (!url.isEmpty()) m_t << url;
2416 m_t << "\">";
2417 m_t << theTranslator->trLegend();
2418 m_t << "</a>";
2419 m_t << "]</span></center>";
2420 }
2421
2424}
2425
2430
2443
2448
2461
2466
2479
2484
2497
2502
2504{
2505 m_t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
2506}
2507
2509{
2510 m_t << "</div></td></tr>\n";
2511}
2512
2514{
2515 m_t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
2516}
2517
2519{
2520 m_t << "</div></td></tr>\n";
2521}
2522
2526
2528{
2529}
2530
2532{
2533 DBG_HTML(m_t << "<!-- startIndent -->\n";)
2534
2535 m_t << "<div class=\"memdoc\">\n";
2536}
2537
2539{
2540 DBG_HTML(m_t << "<!-- endIndent -->\n";)
2541 m_t << "\n</div>\n" << "</div>\n";
2542}
2543
2545{
2546}
2547
2549{
2550 for (int i=0; i<n; i++)
2551 {
2552 m_t << "&#160;";
2553 }
2554}
2555
2556void HtmlGenerator::startDescTable(const QCString &title,const bool hasInits)
2557{
2558 m_t << "<table class=\"fieldtable\">\n"
2559 << "<tr><th colspan=\"" << (hasInits?3:2) << "\">" << title << "</th></tr>";
2560}
2562{
2563 m_t << "</table>\n";
2564}
2565
2567{
2568 m_t << "<tr>";
2569}
2570
2572{
2573 m_t << "</tr>\n";
2574}
2575
2577{
2578 m_t << "<td class=\"fieldname\">";
2579}
2580
2582{
2583 m_t << "&#160;</td>";
2584}
2585
2587{
2588 m_t << "<td class=\"fieldinit\">";
2589}
2590
2592{
2593 m_t << "&#160;</td>";
2594}
2595
2597{
2598 m_t << "<td class=\"fielddoc\">";
2599}
2600
2602{
2603 m_t << "</td>";
2604}
2605
2607{
2608 m_t << "<dl class=\"section examples\"><dt>";
2609 docify(theTranslator->trExamples());
2610 m_t << "</dt>";
2611}
2612
2614{
2615 m_t << "</dl>\n";
2616}
2617
2618void HtmlGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int id)
2619{
2620 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2621 if (astImpl)
2622 {
2623 m_codeList->setId(id);
2624 HtmlDocVisitor visitor(m_t,*m_codeList,ctx,fileName());
2625 std::visit(visitor,astImpl->root);
2626 }
2627}
2628
2629//---------------- helpers for index generation -----------------------------
2630
2631static void startQuickIndexList(TextStream &t,bool topLevel=TRUE)
2632{
2633 if (!Config_getBool(DISABLE_INDEX))
2634 {
2635 if (topLevel)
2636 {
2637 t << " <div id=\"navrow1\" class=\"tabs\">\n";
2638 }
2639 else
2640 {
2641 t << " <div id=\"navrow2\" class=\"tabs2\">\n";
2642 }
2643 t << " <ul class=\"tablist\">\n";
2644 }
2645 else
2646 {
2647 t << "<ul>";
2648 }
2649}
2650
2652{
2653 if (!Config_getBool(DISABLE_INDEX))
2654 {
2655 t << " </ul>\n";
2656 t << " </div>\n";
2657 }
2658 else
2659 {
2660 t << "</ul>\n";
2661 }
2662}
2663
2665 bool hl,bool /*compact*/,
2666 const QCString &relPath)
2667{
2668 t << " <li";
2669 if (hl)
2670 {
2671 t << " class=\"current\"";
2672 }
2673 t << ">";
2674 if (!l.isEmpty()) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2675 t << "<span>";
2676}
2677
2678static void endQuickIndexItem(TextStream &t,const QCString &l)
2679{
2680 t << "</span>";
2681 if (!l.isEmpty()) t << "</a>";
2682 t << "</li>\n";
2683}
2684
2686{
2687 const auto &index = Index::instance();
2688 bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
2689 bool showFiles = Config_getBool(SHOW_FILES);
2690 switch (kind)
2691 {
2692 case LayoutNavEntry::MainPage: return TRUE;
2693 case LayoutNavEntry::User: return TRUE;
2694 case LayoutNavEntry::UserGroup: return TRUE;
2695 case LayoutNavEntry::Pages: return index.numIndexedPages()>0;
2696 case LayoutNavEntry::Topics: return index.numDocumentedGroups()>0;
2697 case LayoutNavEntry::Modules: return index.numDocumentedModules()>0;
2698 case LayoutNavEntry::ModuleList: return index.numDocumentedModules()>0;
2699 case LayoutNavEntry::ModuleMembers: return index.numDocumentedModuleMembers(ModuleMemberHighlight::All)>0;
2700 case LayoutNavEntry::Namespaces: return showNamespaces && index.numDocumentedNamespaces()>0;
2701 case LayoutNavEntry::NamespaceList: return showNamespaces && index.numDocumentedNamespaces()>0;
2702 case LayoutNavEntry::NamespaceMembers: return showNamespaces && index.numDocumentedNamespaceMembers(NamespaceMemberHighlight::All)>0;
2703 case LayoutNavEntry::Concepts: return index.numDocumentedConcepts()>0;
2704 case LayoutNavEntry::Classes: return index.numAnnotatedClasses()>0;
2705 case LayoutNavEntry::ClassList: return index.numAnnotatedClasses()>0;
2706 case LayoutNavEntry::ClassIndex: return index.numAnnotatedClasses()>0;
2707 case LayoutNavEntry::ClassHierarchy: return index.numHierarchyClasses()>0;
2708 case LayoutNavEntry::ClassMembers: return index.numDocumentedClassMembers(ClassMemberHighlight::All)>0;
2709 case LayoutNavEntry::Files: return showFiles && index.numDocumentedFiles()>0;
2710 case LayoutNavEntry::FileList: return showFiles && index.numDocumentedFiles()>0;
2711 case LayoutNavEntry::FileGlobals: return showFiles && index.numDocumentedFileMembers(FileMemberHighlight::All)>0;
2712 case LayoutNavEntry::Examples: return !Doxygen::exampleLinkedMap->empty();
2713 case LayoutNavEntry::Interfaces: return index.numAnnotatedInterfaces()>0;
2714 case LayoutNavEntry::InterfaceList: return index.numAnnotatedInterfaces()>0;
2715 case LayoutNavEntry::InterfaceIndex: return index.numAnnotatedInterfaces()>0;
2716 case LayoutNavEntry::InterfaceHierarchy: return index.numHierarchyInterfaces()>0;
2717 case LayoutNavEntry::Structs: return index.numAnnotatedStructs()>0;
2718 case LayoutNavEntry::StructList: return index.numAnnotatedStructs()>0;
2719 case LayoutNavEntry::StructIndex: return index.numAnnotatedStructs()>0;
2720 case LayoutNavEntry::Exceptions: return index.numAnnotatedExceptions()>0;
2721 case LayoutNavEntry::ExceptionList: return index.numAnnotatedExceptions()>0;
2722 case LayoutNavEntry::ExceptionIndex: return index.numAnnotatedExceptions()>0;
2723 case LayoutNavEntry::ExceptionHierarchy: return index.numHierarchyExceptions()>0;
2724 case LayoutNavEntry::None: // should never happen, means not properly initialized
2725 assert(kind != LayoutNavEntry::None);
2726 return FALSE;
2727 }
2728 return FALSE;
2729}
2730
2731static void renderQuickLinksAsTree(TextStream &t,const QCString &relPath,LayoutNavEntry *root)
2732
2733{
2734 int count=0;
2735 for (const auto &entry : root->children())
2736 {
2737 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2738 }
2739 if (count>0) // at least one item is visible
2740 {
2742 for (const auto &entry : root->children())
2743 {
2744 if (entry->visible() && quickLinkVisible(entry->kind()))
2745 {
2746 QCString url = entry->url();
2747 t << "<li><a href=\"" << relPath << url << "\"><span>";
2748 t << fixSpaces(entry->title());
2749 t << "</span></a>\n";
2750 // recursive into child list
2751 renderQuickLinksAsTree(t,relPath,entry.get());
2752 t << "</li>";
2753 }
2754 }
2756 }
2757}
2758
2759
2760static void renderQuickLinksAsTabs(TextStream &t,const QCString &relPath,
2762 bool highlightParent,bool highlightSearch)
2763{
2764 if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2765 {
2766 renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2767 }
2768 if (hlEntry->parent() && !hlEntry->parent()->children().empty()) // draw tabs for row containing hlEntry
2769 {
2770 bool topLevel = hlEntry->parent()->parent()==nullptr;
2771 int count=0;
2772 for (const auto &entry : hlEntry->parent()->children())
2773 {
2774 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2775 }
2776 if (count>0) // at least one item is visible
2777 {
2778 startQuickIndexList(t,topLevel);
2779 for (const auto &entry : hlEntry->parent()->children())
2780 {
2781 if (entry->visible() && quickLinkVisible(entry->kind()))
2782 {
2783 QCString url = entry->url();
2784 startQuickIndexItem(t,url,
2785 entry.get()==hlEntry &&
2786 (!entry->children().empty() ||
2787 (entry->kind()==kind && !highlightParent)
2788 ),
2789 TRUE,relPath);
2790 t << fixSpaces(entry->title());
2791 endQuickIndexItem(t,url);
2792 }
2793 }
2794 if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2795 {
2796 bool searchEngine = Config_getBool(SEARCHENGINE);
2797 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2798 bool disableIndex = Config_getBool(DISABLE_INDEX);
2799 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2800 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
2801 // case where DISABLE_INDEX=NO & GENERATE_TREEVIEW=YES & FULL_SIDEBAR=YES has search box in the side panel
2802 if (searchEngine)
2803 {
2804 t << " <li>\n";
2805 if (disableIndex || !generateTreeView || !fullSidebar)
2806 {
2807 if (!serverBasedSearch) // pure client side search
2808 {
2809 writeClientSearchBox(t,relPath);
2810 t << " </li>\n";
2811 }
2812 else // server based search
2813 {
2814 writeServerSearchBox(t,relPath,highlightSearch);
2815 if (!highlightSearch)
2816 {
2817 t << " </li>\n";
2818 }
2819 }
2820 }
2821 else
2822 {
2823 t << " </li>\n";
2824 }
2825 }
2826 if (!highlightSearch || Config_getBool(FULL_SIDEBAR))
2827 // on the search page the index will be ended by the page itself if the search box is part of the navigation bar
2828 {
2830 }
2831 }
2832 else // normal case for other rows than first one
2833 {
2835 }
2836 }
2837 }
2838}
2839
2841 HighlightedItem hli,
2842 const QCString &file,
2843 const QCString &relPath,
2844 bool extraTabs)
2845{
2846 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2847 bool searchEngine = Config_getBool(SEARCHENGINE);
2848 bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
2849 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2850 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
2851 bool disableIndex = Config_getBool(DISABLE_INDEX);
2852 bool dynamicMenus = Config_getBool(HTML_DYNAMIC_MENUS);
2854 LayoutNavEntry::Kind kind = LayoutNavEntry::None;
2855 LayoutNavEntry::Kind altKind = LayoutNavEntry::None; // fall back for the old layout file
2856 bool highlightParent=false;
2857 switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2858 {
2859 case HighlightedItem::Main: kind = LayoutNavEntry::MainPage; break;
2860 case HighlightedItem::Topics: kind = LayoutNavEntry::Topics; break;
2861 case HighlightedItem::Modules: kind = LayoutNavEntry::ModuleList; altKind = LayoutNavEntry::Modules; break;
2862 case HighlightedItem::Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break;
2863 case HighlightedItem::ClassHierarchy: kind = LayoutNavEntry::ClassHierarchy; break;
2864 case HighlightedItem::InterfaceHierarchy: kind = LayoutNavEntry::InterfaceHierarchy; break;
2865 case HighlightedItem::ExceptionHierarchy: kind = LayoutNavEntry::ExceptionHierarchy; break;
2866 case HighlightedItem::Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break;
2867 case HighlightedItem::Concepts: kind = LayoutNavEntry::Concepts; break;
2868 case HighlightedItem::Interfaces: kind = LayoutNavEntry::InterfaceIndex; altKind = LayoutNavEntry::Interfaces; break;
2869 case HighlightedItem::Structs: kind = LayoutNavEntry::StructIndex; altKind = LayoutNavEntry::Structs; break;
2870 case HighlightedItem::Exceptions: kind = LayoutNavEntry::ExceptionIndex; altKind = LayoutNavEntry::Exceptions; break;
2871 case HighlightedItem::AnnotatedClasses: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break;
2872 case HighlightedItem::AnnotatedInterfaces: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces; break;
2873 case HighlightedItem::AnnotatedStructs: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs; break;
2874 case HighlightedItem::AnnotatedExceptions: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions; break;
2875 case HighlightedItem::Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break;
2876 case HighlightedItem::NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2877 case HighlightedItem::ModuleMembers: kind = LayoutNavEntry::ModuleMembers; break;
2878 case HighlightedItem::Functions: kind = LayoutNavEntry::ClassMembers; break;
2879 case HighlightedItem::Globals: kind = LayoutNavEntry::FileGlobals; break;
2880 case HighlightedItem::Pages: kind = LayoutNavEntry::Pages; break;
2881 case HighlightedItem::Examples: kind = LayoutNavEntry::Examples; break;
2882 case HighlightedItem::UserGroup: kind = LayoutNavEntry::UserGroup; break;
2883 case HighlightedItem::ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes;
2884 highlightParent = true; break;
2885 case HighlightedItem::ConceptVisible: kind = LayoutNavEntry::Concepts;
2886 highlightParent = true; break;
2887 case HighlightedItem::ModuleVisible: kind = LayoutNavEntry::ModuleList; altKind = LayoutNavEntry::Modules;
2888 highlightParent = true; break;
2889 case HighlightedItem::InterfaceVisible: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces;
2890 highlightParent = true; break;
2891 case HighlightedItem::StructVisible: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs;
2892 highlightParent = true; break;
2893 case HighlightedItem::ExceptionVisible: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions;
2894 highlightParent = true; break;
2895 case HighlightedItem::NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces;
2896 highlightParent = true; break;
2897 case HighlightedItem::FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files;
2898 highlightParent = true; break;
2899 case HighlightedItem::None: break;
2900 case HighlightedItem::Search: break;
2901 }
2902
2903 if (!disableIndex && dynamicMenus)
2904 {
2905 QCString searchPage;
2906 if (externalSearch)
2907 {
2908 searchPage = "search" + Doxygen::htmlFileExtension;
2909 }
2910 else
2911 {
2912 searchPage = "search.php";
2913 }
2914 t << "<script type=\"text/javascript\" src=\"" << relPath << "menudata.js\"></script>\n";
2915 t << "<script type=\"text/javascript\" src=\"" << relPath << "menu.js\"></script>\n";
2916 t << "<script type=\"text/javascript\">\n";
2917 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
2918 t << "$(function() {\n";
2919 t << " initMenu('" << relPath << "',"
2920 << (searchEngine && !(generateTreeView && fullSidebar)?"true":"false") << ","
2921 << (serverBasedSearch?"true":"false") << ",'"
2922 << searchPage << "','"
2923 << theTranslator->trSearch() << "',"
2924 << (generateTreeView?"true":"false")
2925 << ");\n";
2926 if (searchEngine)
2927 {
2928 if (!serverBasedSearch)
2929 {
2930 if (!disableIndex && dynamicMenus && !fullSidebar)
2931 {
2932 t << " $(function() { init_search(); });\n";
2933 }
2934 }
2935 else
2936 {
2937 t << " $(function() {\n"
2938 << " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n";
2939 t << " });\n";
2940 }
2941 }
2942 t << "});\n";
2943 t << "/* @license-end */\n";
2944 t << "</script>\n";
2945 t << "<div id=\"main-nav\"></div>\n";
2946 }
2947 else if (!disableIndex) // && !Config_getBool(HTML_DYNAMIC_MENUS)
2948 {
2949 // find highlighted index item
2950 LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : QCString());
2951 if (!hlEntry && altKind!=LayoutNavEntry::None) { hlEntry=root->find(altKind); kind=altKind; }
2952 if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2953 {
2954 highlightParent=TRUE;
2955 hlEntry = root->children().front().get();
2956 if (hlEntry==nullptr)
2957 {
2958 return; // argl, empty index!
2959 }
2960 }
2961 if (kind==LayoutNavEntry::UserGroup)
2962 {
2963 LayoutNavEntry *e = hlEntry->children().front().get();
2964 if (e)
2965 {
2966 hlEntry = e;
2967 }
2968 }
2969 t << "<div id=\"main-nav\">\n";
2970 renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HighlightedItem::Search);
2971 if (!extraTabs)
2972 {
2973 t << "</div><!-- main-nav -->\n";
2974 }
2975 }
2976 else if (!generateTreeView)
2977 {
2978 renderQuickLinksAsTree(t,relPath,root);
2979 }
2980 if (generateTreeView && !disableIndex && fullSidebar && !extraTabs)
2981 {
2982 t << "<div id=\"doc-content\">\n";
2983 }
2984}
2985
2987{
2988 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2989 m_t << "</div><!-- top -->\n";
2990 if (!generateTreeView)
2991 {
2992 m_t << "<div id=\"doc-content\">\n";
2993 }
2994}
2995
2997{
2998 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2999 QCString result;
3000 // write split bar
3001 if (generateTreeView)
3002 {
3003 QCString fn = name;
3005 if (/*!Config_getBool(DISABLE_INDEX) ||*/ !Config_getBool(FULL_SIDEBAR))
3006 {
3007 result += QCString(
3008 "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n");
3009 }
3010 result+=
3011 " <div id=\"nav-tree\">\n"
3012 " <div id=\"nav-tree-contents\">\n"
3013 " <div id=\"nav-sync\" class=\"sync\"></div>\n"
3014 " </div>\n"
3015 " </div>\n"
3016 " <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
3017 " class=\"ui-resizable-handle\">\n"
3018 " </div>\n"
3019 "</div>\n"
3020 "<script type=\"text/javascript\">\n"
3021 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
3022 "$(function(){initNavTree('" + fn +
3023 "','" + relpath +
3024 "'); initResizable(true); });\n"
3025 "/* @license-end */\n"
3026 "</script>\n";
3027 if (Config_getBool(DISABLE_INDEX) || !Config_getBool(FULL_SIDEBAR))
3028 {
3029 result+="<div id=\"doc-content\">\n";
3030 }
3031 }
3032 else
3033 {
3034 result += "<script type=\"text/javascript\">\n"
3035 "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n"
3036 "$(function(){ initResizable(false); });\n"
3037 "/* @license-end */\n"
3038 "</script>\n";
3039 }
3040 return result;
3041}
3042
3044{
3046}
3047
3049{
3050 m_t << substitute(s,"$relpath^",m_relPath);
3051}
3052
3054{
3055 m_t << "<div class=\"contents\">\n";
3056}
3057
3059{
3060 m_t << "</div><!-- contents -->\n";
3061}
3062
3063void HtmlGenerator::startPageDoc(const QCString &/* pageTitle */)
3064{
3065 m_t << "<div>";
3066}
3067
3069{
3070 m_t << "</div><!-- PageDoc -->\n";
3071}
3072
3073void HtmlGenerator::writeQuickLinks(HighlightedItem hli,const QCString &file,bool extraTabs)
3074{
3075 writeDefaultQuickLinks(m_t,hli,file,m_relPath,extraTabs);
3076}
3077
3078// PHP based search script
3080{
3081 bool disableIndex = Config_getBool(DISABLE_INDEX);
3082 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3083 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
3084 bool quickLinksAfterSplitbar = !disableIndex && generateTreeView && fullSidebar;
3085 QCString projectName = Config_getString(PROJECT_NAME);
3086 QCString htmlOutput = Config_getString(HTML_OUTPUT);
3087
3088 // OPENSEARCH_PROVIDER {
3089 QCString configFileName = htmlOutput+"/search_config.php";
3090 std::ofstream f = Portable::openOutputStream(configFileName);
3091 if (f.is_open())
3092 {
3093 TextStream t(&f);
3094 t << "<?php\n\n";
3095 t << "$config = array(\n";
3096 t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
3097 t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
3098 t << " 'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
3099 t << " 'FULL_SIDEBAR' => " << (fullSidebar?"true":"false") << ",\n";
3100 t << ");\n\n";
3101 t << "$translator = array(\n";
3102 t << " 'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
3103 t << " 'search_results' => array(\n";
3104 t << " 0 => \"" << theTranslator->trSearchResults(0) << "\",\n";
3105 t << " 1 => \"" << theTranslator->trSearchResults(1) << "\",\n";
3106 t << " 2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";
3107 t << " ),\n";
3108 t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
3109 t << " 'search' => \"" << theTranslator->trSearch() << "\",\n";
3110 t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
3111 t << ");\n\n";
3112 t << "?>\n";
3113 }
3114 f.close();
3115
3116 ResourceMgr::instance().copyResource("search_functions.php",htmlOutput);
3117 ResourceMgr::instance().copyResource("search_opensearch.php",htmlOutput);
3118 // OPENSEARCH_PROVIDER }
3119
3120 QCString fileName = htmlOutput+"/search.php";
3122 if (f.is_open())
3123 {
3124 TextStream t(&f);
3126
3127 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
3128 << getDoxygenVersion() << " -->\n";
3129 t << "<script type=\"text/javascript\">\n";
3130 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
3131 t << "var searchBox = new SearchBox(\"searchBox\", \""
3132 << "search/\",'" << Doxygen::htmlFileExtension << "');\n";
3133 t << "/* @license-end */\n";
3134 t << "</script>\n";
3135
3136 if (!disableIndex && !quickLinksAfterSplitbar)
3137 {
3139 }
3140 if (generateTreeView)
3141 {
3142 t << "</div><!-- top -->\n";
3143 }
3144 t << writeSplitBarAsString("search.php",QCString());
3145 if (quickLinksAfterSplitbar)
3146 {
3148 }
3149 t << "<!-- generated -->\n";
3150
3151 t << "<?php\n";
3152 t << "require_once \"search_functions.php\";\n";
3153 t << "main();\n";
3154 t << "?>\n";
3155
3156 // Write empty navigation path, to make footer connect properly
3157 if (generateTreeView)
3158 {
3159 t << "</div><!-- doc-content -->\n";
3160 }
3161
3162 writePageFooter(t,"Search","","");
3163 }
3164 f.close();
3165
3166 QCString scriptName = htmlOutput+"/search/search.js";
3167 f = Portable::openOutputStream(scriptName);
3168 if (f.is_open())
3169 {
3170 TextStream t(&f);
3171 t << ResourceMgr::instance().getAsString("extsearch.js");
3172 }
3173 else
3174 {
3175 err("Failed to open file '{}' for writing...\n",scriptName);
3176 }
3177}
3178
3180{
3181 bool disableIndex = Config_getBool(DISABLE_INDEX);
3182 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3183 bool fullSidebar = Config_getBool(FULL_SIDEBAR);
3184 bool quickLinksAfterSplitbar = !disableIndex && generateTreeView && fullSidebar;
3185 QCString dname = Config_getString(HTML_OUTPUT);
3187 std::ofstream f = Portable::openOutputStream(fileName);
3188 if (f.is_open())
3189 {
3190 TextStream t(&f);
3192
3193 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
3194 << getDoxygenVersion() << " -->\n";
3195 t << "<script type=\"text/javascript\">\n";
3196 t << "/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */\n";
3197 t << "var searchBox = new SearchBox(\"searchBox\", \""
3198 << "search/\",'" << Doxygen::htmlFileExtension << "');\n";
3199 t << "/* @license-end */\n";
3200 t << "</script>\n";
3201
3202 if (!disableIndex && !quickLinksAfterSplitbar)
3203 {
3205 }
3206 if (generateTreeView)
3207 {
3208 t << "</div><!-- top -->\n";
3209 }
3210 t << writeSplitBarAsString("search.php",QCString());
3211 if (quickLinksAfterSplitbar)
3212 {
3214 }
3215
3216 t << "<div class=\"header\">\n";
3217 t << " <div class=\"headertitle\">\n";
3218 t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>\n";
3219 t << " </div>\n";
3220 t << "</div>\n";
3221 t << "<div class=\"contents\">\n";
3222
3223 t << "<div id=\"searchresults\"></div>\n";
3224 t << "</div>\n";
3225
3226 if (generateTreeView)
3227 {
3228 t << "</div><!-- doc-content -->\n";
3229 }
3230
3231 writePageFooter(t,"Search","","");
3232
3233 }
3234 f.close();
3235
3236 QCString scriptName = dname+"/search/search.js";
3237 f = Portable::openOutputStream(scriptName);
3238 if (f.is_open())
3239 {
3240 TextStream t(&f);
3241 t << "var searchResultsText=["
3242 << "\"" << theTranslator->trSearchResults(0) << "\","
3243 << "\"" << theTranslator->trSearchResults(1) << "\","
3244 << "\"" << theTranslator->trSearchResults(2) << "\"];\n";
3245 t << "var serverUrl=\"" << Config_getString(SEARCHENGINE_URL) << "\";\n";
3246 t << "var tagMap = {\n";
3247 bool first=TRUE;
3248 // add search mappings
3249 const StringVector &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
3250 for (const auto &ml : extraSearchMappings)
3251 {
3252 QCString mapLine = ml.c_str();
3253 int eqPos = mapLine.find('=');
3254 if (eqPos!=-1) // tag command contains a destination
3255 {
3256 QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
3257 QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
3258 if (!tagName.isEmpty())
3259 {
3260 if (!first) t << ",\n";
3261 t << " \"" << tagName << "\": \"" << destName << "\"";
3262 first=FALSE;
3263 }
3264 }
3265 }
3266 if (!first) t << "\n";
3267 t << "};\n\n";
3268 t << ResourceMgr::instance().getAsString("extsearch.js");
3269 t << "\n";
3270 t << "$(function() {\n";
3271 t << " var query = trim(getURLParameter('query'));\n";
3272 t << " if (query) {\n";
3273 t << " searchFor(query,0,20);\n";
3274 t << " } else {\n";
3275 t << " var results = $('#results');\n";
3276 t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');\n";
3277 t << " }\n";
3278 t << "});\n";
3279 }
3280 else
3281 {
3282 err("Failed to open file '{}' for writing...\n",scriptName);
3283 }
3284}
3285
3287{
3288 m_t << "<div class=\"typeconstraint\">\n";
3289 m_t << "<dl><dt><b>" << header << "</b></dt><dd>\n";
3290 m_t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">\n";
3291}
3292
3294{
3295 m_t << "<tr><td valign=\"top\"><em>";
3296}
3297
3299{
3300 m_t << "</em></td>";
3301}
3302
3304{
3305 m_t << "<td>&#160;:</td><td valign=\"top\"><em>";
3306}
3307
3309{
3310 m_t << "</em></td>";
3311}
3312
3314{
3315 m_t << "<td>&#160;";
3316}
3317
3319{
3320 m_t << "</td></tr>\n";
3321}
3322
3324{
3325 m_t << "</table>\n";
3326 m_t << "</dd>\n";
3327 m_t << "</dl>\n";
3328 m_t << "</div>\n";
3329}
3330
3332{
3333 if (!style.isEmpty())
3334 {
3335 m_t << "<br class=\"" << style << "\" />\n";
3336 }
3337 else
3338 {
3339 m_t << "<br />\n";
3340 }
3341}
3342
3344{
3345 m_t << "<div class=\"header\">\n";
3346}
3347
3349{
3350 m_t << " <div class=\"headertitle\">";
3351 startTitle();
3352}
3353
3355{
3356 endTitle();
3357 m_t << "</div>\n";
3358}
3359
3361{
3362 m_t << "</div><!--header-->\n";
3363}
3364
3366{
3367 if (m_emptySection)
3368 {
3369 m_t << "<table class=\"memberdecls\">\n";
3371 }
3372 m_t << "<tr><td colspan=\"2\"><h3>";
3373}
3374
3376{
3377 m_t << "</h3></td></tr>\n";
3378}
3379
3381{
3382 DBG_HTML(m_t << "<!-- startMemberDocSimple -->\n";)
3383 m_t << "<table class=\"fieldtable\">\n";
3384 m_t << "<tr><th colspan=\"" << (isEnum?"2":"3") << "\">";
3385 m_t << (isEnum? theTranslator->trEnumerationValues() :
3386 theTranslator->trCompoundMembers()) << "</th></tr>\n";
3387}
3388
3390{
3391 DBG_HTML(m_t << "<!-- endMemberDocSimple -->\n";)
3392 m_t << "</table>\n";
3393}
3394
3396{
3397 DBG_HTML(m_t << "<!-- startInlineMemberType -->\n";)
3398 m_t << "<tr><td class=\"fieldtype\">\n";
3399}
3400
3402{
3403 DBG_HTML(m_t << "<!-- endInlineMemberType -->\n";)
3404 m_t << "</td>\n";
3405}
3406
3408{
3409 DBG_HTML(m_t << "<!-- startInlineMemberName -->\n";)
3410 m_t << "<td class=\"fieldname\">\n";
3411}
3412
3414{
3415 DBG_HTML(m_t << "<!-- endInlineMemberName -->\n";)
3416 m_t << "</td>\n";
3417}
3418
3420{
3421 DBG_HTML(m_t << "<!-- startInlineMemberDoc -->\n";)
3422 m_t << "<td class=\"fielddoc\">\n";
3423}
3424
3426{
3427 DBG_HTML(m_t << "<!-- endInlineMemberDoc -->\n";)
3428 m_t << "</td></tr>\n";
3429}
3430
3432{
3433 DBG_HTML(m_t << "<!-- startLabels -->\n";)
3434 m_t << "<span class=\"mlabels\">";
3435}
3436
3437void HtmlGenerator::writeLabel(const QCString &label,bool /*isLast*/)
3438{
3439 DBG_HTML(m_t << "<!-- writeLabel(" << label << ") -->\n";)
3440
3441 auto convertLabelToClass = [](const std::string &lab) {
3442 QCString input = convertUTF8ToLower(lab);
3443 QCString result;
3444 size_t l=input.length();
3445 result.reserve(l);
3446
3447 // Create valid class selector, see 10.2 here https://www.w3.org/TR/selectors-3/#w3cselgrammar
3448 // ident [-]?{nmstart}{nmchar}*
3449 // nmstart [_a-z]|{nonascii}
3450 // nonascii [^\0-\177]
3451 // nmchar [_a-z0-9-]|{nonascii}
3452
3453 bool nmstart=false;
3454 for (size_t i=0; i<l; i++)
3455 {
3456 char c = input.at(i);
3457 if (c<0 || (c>='a' && c<='z') || c=='_') // nmstart pattern
3458 {
3459 nmstart=true;
3460 result+=c;
3461 }
3462 else if (nmstart && (c<0 || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_')) // nmchar pattern
3463 {
3464 result+=c;
3465 }
3466 else if (nmstart && (c==' ' || c=='-')) // show whitespace as -
3467 {
3468 result+='-';
3469 }
3470 }
3471 return result;
3472 };
3473
3474 m_t << "<span class=\"mlabel " << convertLabelToClass(label.stripWhiteSpace().str()) << "\">" << label << "</span>";
3475}
3476
3478{
3479 DBG_HTML(m_t << "<!-- endLabels -->\n";)
3480 m_t << "</span>";
3481}
3482
3484 const QCString &id, const QCString &ref,
3485 const QCString &file, const QCString &anchor,
3486 const QCString &title, const QCString &name)
3487{
3488 DBG_HTML(m_t << "<!-- writeInheritedSectionTitle -->\n";)
3489 QCString a = anchor;
3490 if (!a.isEmpty()) a.prepend("#");
3491 QCString classLink = QCString("<a class=\"el\" ");
3492 if (!ref.isEmpty())
3493 {
3494 classLink+= externalLinkTarget();
3495 classLink += " href=\"";
3496 classLink+= externalRef(m_relPath,ref,TRUE);
3497 }
3498 else
3499 {
3500 classLink += "href=\"";
3501 classLink+=m_relPath;
3502 }
3503 QCString fn = file;
3505 classLink=classLink+fn+a;
3506 classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
3507 m_t << "<tr class=\"inherit_header " << id << "\">"
3508 << "<td colspan=\"2\" onclick=\"javascript:dynsection.toggleInherit('" << id << "')\">"
3509 << "<span class=\"dynarrow\"><span class=\"arrowhead closed\"></span></span>"
3510 << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
3511 << "</td></tr>\n";
3512}
3513
3514void HtmlGenerator::writeSummaryLink(const QCString &file,const QCString &anchor,const QCString &title,bool first)
3515{
3516 if (first)
3517 {
3518 m_t << " <div class=\"summary\">\n";
3519 }
3520 else
3521 {
3522 m_t << " &#124;\n";
3523 }
3524 m_t << "<a href=\"";
3525 if (!file.isEmpty())
3526 {
3527 QCString fn = file;
3529 m_t << m_relPath << fn;
3530 }
3531 else if (!anchor.isEmpty())
3532 {
3533 m_t << "#";
3534 m_t << anchor;
3535 }
3536 m_t << "\">";
3537 m_t << title;
3538 m_t << "</a>";
3539}
3540
3541void HtmlGenerator::endMemberDeclaration(const QCString &anchor,const QCString &inheritId)
3542{
3543 m_t << "<tr class=\"separator:" << anchor;
3544 if (!inheritId.isEmpty())
3545 {
3546 m_t << " inherit " << inheritId;
3547 }
3548 m_t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
3549}
3550
3555
3557{
3559 return replaceVariables(mgr.getAsString("navtree.css"));
3560}
3561
3562void HtmlGenerator::writeLocalToc(const SectionRefs &sectionRefs,const LocalToc &localToc)
3563{
3564 if (localToc.isHtmlEnabled())
3565 {
3566 int level=0;
3567 int indent=0;
3568 auto writeIndent = [&]() { for (int i=0;i<indent*2;i++) m_t << " "; };
3569 auto incIndent = [&](const QCString &text) { writeIndent(); m_t << text << "\n"; indent++; };
3570 auto decIndent = [&](const QCString &text) { indent--; writeIndent(); m_t << text << "\n"; };
3571 m_t << "<div class=\"toc\">";
3572 m_t << "<h3>" << theTranslator->trRTFTableOfContents() << "</h3>\n";
3573 int maxLevel = localToc.htmlLevel();
3574 char cs[2];
3575 cs[1]='\0';
3576 BoolVector inLi(maxLevel+1,false);
3577 for (const SectionInfo *si : sectionRefs)
3578 {
3579 //printf("Section: label=%s type=%d isSection()=%d\n",qPrint(si->label()),si->type(),isSection(si->type()));
3580 SectionType type = si->type();
3581 if (type.isSection())
3582 {
3583 //printf(" level=%d title=%s maxLevel=%d\n",level,qPrint(si->title()),maxLevel);
3584 int nextLevel = type.level();
3585 if (nextLevel>level)
3586 {
3587 for (int l=level;l<nextLevel;l++)
3588 {
3589 if (l < maxLevel)
3590 {
3591 incIndent("<ul>");
3592 cs[0]=static_cast<char>('0'+l+1);
3593 const char *empty = (l!=nextLevel-1) ? " empty" : "";
3594 incIndent("<li class=\"level" + QCString(cs) + empty + "\">");
3595 }
3596 }
3597 }
3598 else if (nextLevel<level)
3599 {
3600 for (int l=level;l>nextLevel;l--)
3601 {
3602 if (l <= maxLevel) decIndent("</li>");
3603 inLi[l] = false;
3604 if (l <= maxLevel) decIndent("</ul>");
3605 }
3606 }
3607 if (nextLevel <= maxLevel)
3608 {
3609 if (inLi[nextLevel] || level>nextLevel)
3610 {
3611 decIndent("</li>");
3612 cs[0]=static_cast<char>('0'+nextLevel);
3613 incIndent("<li class=\"level" + QCString(cs) + "\">");
3614 }
3615 QCString titleDoc = si->title();
3616 QCString label = si->label();
3617 if (titleDoc.isEmpty()) titleDoc = label;
3618 writeIndent();
3619 m_t << "<a href=\"#"+label+"\">"
3620 << convertToHtml(filterTitle(titleDoc))
3621 << "</a>\n";
3622 inLi[nextLevel]=true;
3623 level = nextLevel;
3624 }
3625 }
3626 }
3627 if (level > maxLevel) level = maxLevel;
3628 while (level>0)
3629 {
3630 decIndent("</li>");
3631 decIndent("</ul>");
3632 level--;
3633 }
3634 m_t << "</div>\n";
3635 }
3636}
3637
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:730
bool m_stripCodeComments
Definition htmlgen.h:76
void startSpecialComment() override
Definition htmlgen.cpp:816
void endCodeLine() override
Definition htmlgen.cpp:999
void startFontClass(const QCString &s) override
Definition htmlgen.cpp:1014
void writeCodeAnchor(const QCString &anchor) override
Definition htmlgen.cpp:1026
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:864
void startFold(int, const QCString &, const QCString &) override
Definition htmlgen.cpp:1045
void writeLineNumber(const QCString &, const QCString &, const QCString &, int, bool) override
Definition htmlgen.cpp:833
void startCodeLine(int) override
Definition htmlgen.cpp:988
void endFold() override
Definition htmlgen.cpp:1079
void _writeCodeLink(const QCString &className, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip)
Definition htmlgen.cpp:880
void setRelativePath(const QCString &path)
Definition htmlgen.cpp:725
void setStripIndentAmount(size_t amount) override
Definition htmlgen.cpp:828
void endSpecialComment() override
Definition htmlgen.cpp:822
HtmlCodeGenerator(TextStream *t, const QCString &relPath)
Definition htmlgen.cpp:719
void writeTooltip(const QCString &id, const DocLinkInfo &docInfo, const QCString &decl, const QCString &desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo) override
Definition htmlgen.cpp:908
void endFontClass() override
Definition htmlgen.cpp:1020
void startCodeFragment(const QCString &style) override
Definition htmlgen.cpp:1032
TextStream * m_t
Definition htmlgen.h:71
LineInfo m_lastLineInfo
Definition htmlgen.h:89
void endCodeFragment(const QCString &) override
Definition htmlgen.cpp:1037
void stripCodeComments(bool b) override
Definition htmlgen.cpp:811
OutputType type() const override
Definition htmlgen.h:34
Concrete visitor implementation for HTML output.
void startClassDiagram() override
Definition htmlgen.cpp:1979
void writeLogo() override
Definition htmlgen.cpp:1555
void endFile() override
Definition htmlgen.cpp:1571
void endParameterExtra(bool last, bool emptyList, bool closeBracket) override
Definition htmlgen.cpp:2319
static void init()
Definition htmlgen.cpp:1140
void startInlineMemberName() override
Definition htmlgen.cpp:3407
void endDescTableInit() override
Definition htmlgen.cpp:2591
void startTitle()
Definition htmlgen.h:333
void startTextLink(const QCString &file, const QCString &anchor) override
Definition htmlgen.cpp:1780
void startInlineMemberType() override
Definition htmlgen.cpp:3395
void endDescTable() override
Definition htmlgen.cpp:2561
void startParameterDefVal(const char *sep) override
Definition htmlgen.cpp:2343
void endMemberGroupHeader() override
Definition htmlgen.cpp:2508
void startIndexKey() override
Definition htmlgen.cpp:2196
void lineBreak(const QCString &style) override
Definition htmlgen.cpp:3331
void startParameterName(bool) override
Definition htmlgen.cpp:2302
void startMemberItem(const QCString &anchor, MemberItemType, const QCString &inheritId) override
Definition htmlgen.cpp:2032
static void writeSearchPage()
Definition htmlgen.cpp:3079
void startInclDepGraph() override
Definition htmlgen.cpp:2426
void insertMemberAlignLeft(MemberItemType, bool) override
Definition htmlgen.cpp:2094
void writeQuickLinks(HighlightedItem hli, const QCString &file, bool extraTabs) override
Definition htmlgen.cpp:3073
void startMemberSubtitle() override
Definition htmlgen.cpp:2174
HtmlGenerator & operator=(const HtmlGenerator &)
Definition htmlgen.cpp:1115
void writeFooter(const QCString &navPath) override
Definition htmlgen.cpp:1566
int m_sectionCount
Definition htmlgen.h:341
void startMemberDocName(bool) override
Definition htmlgen.cpp:2255
void endParameterType() override
Definition htmlgen.cpp:2296
void startLabels() override
Definition htmlgen.cpp:3431
void startCallGraph() override
Definition htmlgen.cpp:2462
void endMemberList() override
Definition htmlgen.cpp:2023
static QCString getNavTreeCss()
Definition htmlgen.cpp:3556
void startParagraph(const QCString &classDef) override
Definition htmlgen.cpp:1673
void endIndexList() override
Definition htmlgen.cpp:2191
void writeSearchInfo() override
Definition htmlgen.cpp:1518
void startContents() override
Definition htmlgen.cpp:3053
void startMemberDoc(const QCString &clName, const QCString &memName, const QCString &anchor, const QCString &title, int memCount, int memTotal, bool showInline) override
Definition htmlgen.cpp:2226
void startDescTableRow() override
Definition htmlgen.cpp:2566
void startDoxyAnchor(const QCString &fName, const QCString &manName, const QCString &anchor, const QCString &name, const QCString &args) override
Definition htmlgen.cpp:1658
void startDirDepGraph() override
Definition htmlgen.cpp:2480
void startCompoundTemplateParams() override
Definition htmlgen.cpp:2078
void startConstraintParam() override
Definition htmlgen.cpp:3293
void endGroupHeader(int) override
Definition htmlgen.cpp:1813
QCString m_lastFile
Definition htmlgen.h:339
void writeNavigationPath(const QCString &s) override
Definition htmlgen.cpp:3048
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name) override
Definition htmlgen.cpp:1756
void startMemberDescription(const QCString &anchor, const QCString &inheritId, bool typ) override
Definition htmlgen.cpp:2106
void writeChar(char c) override
Definition htmlgen.cpp:1898
void endConstraintList() override
Definition htmlgen.cpp:3323
void endParameterList() override
Definition htmlgen.cpp:2355
void writeDoc(const IDocNodeAST *node, const Definition *, const MemberDef *, int id) override
Definition htmlgen.cpp:2618
void startDotGraph() override
Definition htmlgen.cpp:2392
void endIndent() override
Definition htmlgen.cpp:2538
void endParameterName() override
Definition htmlgen.cpp:2308
void endPageDoc() override
Definition htmlgen.cpp:3068
void startMemberDocList() override
Definition htmlgen.cpp:2216
static QCString writeLogoAsString(const QCString &path)
Definition htmlgen.cpp:1524
void endDescTableRow() override
Definition htmlgen.cpp:2571
void writeSplitBar(const QCString &name) override
Definition htmlgen.cpp:3043
void startParameterType(bool first, const QCString &key) override
Definition htmlgen.cpp:2279
void startDescTableInit() override
Definition htmlgen.cpp:2586
void startMemberList() override
Definition htmlgen.cpp:2018
void endQuickIndices() override
Definition htmlgen.cpp:2986
void startHeaderSection() override
Definition htmlgen.cpp:3343
void startDescTableTitle() override
Definition htmlgen.cpp:2576
void endDirDepGraph(DotDirDeps &g) override
Definition htmlgen.cpp:2485
void startIndexList() override
Definition htmlgen.cpp:2186
void endParameterDefVal() override
Definition htmlgen.cpp:2350
void endMemberGroup(bool) override
Definition htmlgen.cpp:2527
void endInlineHeader() override
Definition htmlgen.cpp:3375
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1437
void endMemberDescription() override
Definition htmlgen.cpp:2125
void startGroupCollaboration() override
Definition htmlgen.cpp:2444
void endClassDiagram(const ClassDiagram &, const QCString &, const QCString &) override
Definition htmlgen.cpp:1984
void startConstraintList(const QCString &) override
Definition htmlgen.cpp:3286
void startDescTable(const QCString &title, const bool hasInits) override
Definition htmlgen.cpp:2556
void endConstraintDocs() override
Definition htmlgen.cpp:3318
void writeNonBreakableSpace(int) override
Definition htmlgen.cpp:2548
void startInlineMemberDoc() override
Definition htmlgen.cpp:3419
void exceptionEntry(const QCString &, bool) override
Definition htmlgen.cpp:2362
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1300
void endExamples() override
Definition htmlgen.cpp:2613
void endIndexKey() override
Definition htmlgen.cpp:2201
void writeString(const QCString &text) override
Definition htmlgen.cpp:1686
void endMemberDocName() override
Definition htmlgen.cpp:2265
void endContents() override
Definition htmlgen.cpp:3058
void endInlineMemberType() override
Definition htmlgen.cpp:3401
void startMemberGroupDocs() override
Definition htmlgen.cpp:2513
void startMemberDocSimple(bool) override
Definition htmlgen.cpp:3380
void startIndexItem(const QCString &ref, const QCString &file) override
Definition htmlgen.cpp:1701
OutputType type() const override
Definition htmlgen.h:121
void endHeaderSection() override
Definition htmlgen.cpp:3360
void startIndent() override
Definition htmlgen.cpp:2531
void writeStyleInfo(int part) override
Definition htmlgen.cpp:1586
void addIndexItem(const QCString &, const QCString &) override
Definition htmlgen.cpp:2544
void docify_(const QCString &text, bool inHtmlComment)
Definition htmlgen.cpp:1865
void endMemberGroupDocs() override
Definition htmlgen.cpp:2518
void cleanup() override
Definition htmlgen.cpp:1292
void endDotGraph(DotClassGraph &g) override
Definition htmlgen.cpp:2397
void endMemberHeader() override
Definition htmlgen.cpp:2168
void endTextLink() override
Definition htmlgen.cpp:1792
void writeLabel(const QCString &l, bool isLast) override
Definition htmlgen.cpp:3437
void startMemberSections() override
Definition htmlgen.cpp:2131
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1312
static QCString writeSplitBarAsString(const QCString &name, const QCString &relpath)
Definition htmlgen.cpp:2996
void endMemberSections() override
Definition htmlgen.cpp:2139
void endMemberDocList() override
Definition htmlgen.cpp:2221
void endCompoundTemplateParams() override
Definition htmlgen.cpp:2083
static void writeExternalSearchPage()
Definition htmlgen.cpp:3179
void endDescTableData() override
Definition htmlgen.cpp:2601
void startDescTableData() override
Definition htmlgen.cpp:2596
void writeStartAnnoItem(const QCString &type, const QCString &file, const QCString &path, const QCString &name) override
Definition htmlgen.cpp:1744
static void writePageFooter(TextStream &t, const QCString &, const QCString &, const QCString &)
Definition htmlgen.cpp:1560
void endParagraph() override
Definition htmlgen.cpp:1681
void insertMemberAlign(bool) override
Definition htmlgen.cpp:2088
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1425
void endDoxyAnchor(const QCString &fName, const QCString &anchor) override
Definition htmlgen.cpp:1665
void startMemberTemplateParams() override
Definition htmlgen.cpp:2063
void endLabels() override
Definition htmlgen.cpp:3477
void startPageDoc(const QCString &pageTitle) override
Definition htmlgen.cpp:3063
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId) override
Definition htmlgen.cpp:3541
HtmlCodeGenerator * m_codeGen
Definition htmlgen.h:344
void startIndexValue(bool) override
Definition htmlgen.cpp:2206
void endGroupCollaboration(DotGroupCollaboration &g) override
Definition htmlgen.cpp:2449
QCString m_relPath
Definition htmlgen.h:340
static void writeSearchInfoStatic(TextStream &t, const QCString &relPath)
Definition htmlgen.cpp:1488
std::unique_ptr< OutputCodeList > m_codeList
Definition htmlgen.h:343
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1431
void startConstraintType() override
Definition htmlgen.cpp:3303
void endConstraintParam() override
Definition htmlgen.cpp:3298
void startTitleHead(const QCString &) override
Definition htmlgen.cpp:3348
void startFile(const QCString &name, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition htmlgen.cpp:1445
void endIndexValue(const QCString &, bool) override
Definition htmlgen.cpp:2211
void addCodeGen(OutputCodeList &list) override
Definition htmlgen.cpp:1135
void startConstraintDocs() override
Definition htmlgen.cpp:3313
void endMemberTemplateParams(const QCString &anchor, const QCString &inheritId) override
Definition htmlgen.cpp:2067
void endPlainFile() override
Definition htmlgen.h:330
void startIndexListItem() override
Definition htmlgen.cpp:1691
void endProjectNumber() override
Definition htmlgen.cpp:1581
void writeSummaryLink(const QCString &file, const QCString &anchor, const QCString &title, bool first) override
Definition htmlgen.cpp:3514
void endMemberDocPrefixItem() override
Definition htmlgen.cpp:2249
void endDescTableTitle() override
Definition htmlgen.cpp:2581
void addLabel(const QCString &, const QCString &) override
Definition htmlgen.cpp:1669
void endInclDepGraph(DotInclDepGraph &g) override
Definition htmlgen.cpp:2431
void startParameterExtra() override
Definition htmlgen.cpp:2314
void writeLocalToc(const SectionRefs &sr, const LocalToc &lt) override
Definition htmlgen.cpp:3562
void startProjectNumber() override
Definition htmlgen.cpp:1576
void writeGraphicalHierarchy(DotGfxHierarchyTable &g) override
Definition htmlgen.cpp:2498
void startExamples() override
Definition htmlgen.cpp:2606
void docify(const QCString &text) override
Definition htmlgen.cpp:1860
bool m_emptySection
Definition htmlgen.h:342
void endInlineMemberDoc() override
Definition htmlgen.cpp:3425
void endCallGraph(DotCallGraph &g) override
Definition htmlgen.cpp:2467
void endConstraintType() override
Definition htmlgen.cpp:3308
void endMemberSubtitle() override
Definition htmlgen.cpp:2180
void endTitle()
Definition htmlgen.h:334
void startGroupHeader(int) override
Definition htmlgen.cpp:1797
void startMemberDocPrefixItem() override
Definition htmlgen.cpp:2243
void startSection(const QCString &, const QCString &, SectionType) override
Definition htmlgen.cpp:1829
void endMemberItem(MemberItemType) override
Definition htmlgen.cpp:2054
void startMemberGroup() override
Definition htmlgen.cpp:2523
void endMemberDoc(bool) override
Definition htmlgen.cpp:2381
void endIndexItem(const QCString &ref, const QCString &file) override
Definition htmlgen.cpp:1731
void startMemberHeader(const QCString &, int) override
Definition htmlgen.cpp:2148
void endTitleHead(const QCString &, const QCString &) override
Definition htmlgen.cpp:3354
void endSection(const QCString &, SectionType) override
Definition htmlgen.cpp:1845
void startInlineHeader() override
Definition htmlgen.cpp:3365
void endInlineMemberName() override
Definition htmlgen.cpp:3413
void endMemberDocSimple(bool) override
Definition htmlgen.cpp:3389
void writeInheritedSectionTitle(const QCString &id, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &title, const QCString &name) override
Definition htmlgen.cpp:3483
void endIndexListItem() override
Definition htmlgen.cpp:1696
static QCString getMathJaxMacros()
Definition htmlgen.cpp:3551
void startParameterList(bool) override
Definition htmlgen.cpp:2271
QCString m_lastTitle
Definition htmlgen.h:338
void startMemberGroupHeader(bool) override
Definition htmlgen.cpp:2503
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:1955
static QCString g_header_file
Definition htmlgen.cpp:65
static void endQuickIndexList(TextStream &t)
Definition htmlgen.cpp:2651
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:2631
static void startSectionSummary(TextStream &t, int sectionCount)
Definition htmlgen.cpp:1933
static void startQuickIndexItem(TextStream &t, const QCString &l, bool hl, bool, const QCString &relPath)
Definition htmlgen.cpp:2664
static void renderQuickLinksAsTabs(TextStream &t, const QCString &relPath, LayoutNavEntry *hlEntry, LayoutNavEntry::Kind kind, bool highlightParent, bool highlightSearch)
Definition htmlgen.cpp:2760
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:2840
static QCString g_footer_file
Definition htmlgen.cpp:66
static void endSectionContent(TextStream &t)
Definition htmlgen.cpp:1971
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:2678
static StringUnorderedMap g_lightMap
Definition htmlgen.cpp:634
static void startSectionHeader(TextStream &t, const QCString &relPath, int sectionCount)
Definition htmlgen.cpp:1908
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:1357
static void renderQuickLinksAsTree(TextStream &t, const QCString &relPath, LayoutNavEntry *root)
Definition htmlgen.cpp:2731
static bool quickLinkVisible(LayoutNavEntry::Kind kind)
Definition htmlgen.cpp:2685
static std::mutex g_indexLock
Definition htmlgen.cpp:1443
static StringUnorderedMap g_darkMap
Definition htmlgen.cpp:635
static void endSectionHeader(TextStream &t)
Definition htmlgen.cpp:1927
static void writeClientSearchBox(TextStream &t, const QCString &relPath)
Definition htmlgen.cpp:76
static void endSectionSummary(TextStream &t)
Definition htmlgen.cpp:1945
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:6231
size_t updateColumnCount(const char *s, size_t col)
Definition util.cpp:7356
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:6998
QCString correctURL(const QCString &url, const QCString &relPath)
Corrects URL url according to the relative path relPath.
Definition util.cpp:6403
QCString stripPath(const QCString &s)
Definition util.cpp:5457
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:7062
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:6885
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:7287
QCString externalLinkTarget(const bool parent)
Definition util.cpp:6187
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:6284
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:6198
A bunch of utility functions.
QCString fixSpaces(const QCString &s)
Definition util.h:471