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