Doxygen
Loading...
Searching...
No Matches
layout.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2024 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// own header
17#include "layout.h"
18
19// standard includes
20#include <array>
21
22// other includes
23#include "config.h"
24#include "debug.h"
25#include "docnode.h"
26#include "docparser.h"
27#include "language.h"
28#include "message.h"
29#include "regex.h"
30#include "resourcemgr.h"
31#include "textstream.h"
32#include "types.h"
33#include "util.h"
34#include "version.h"
35#include "xml.h"
36
37inline DString compileOptions(const DString &def)
38{
39 return def;
40}
41
42inline DString compileOptions(const DString &def,SrcLangExt langId1,const DString &value1)
43{
44 return compileOptions(def)+"|"+DString().setNum(static_cast<long>(langId1))+"="+value1;
45}
46
47inline DString compileOptions(const DString &def,SrcLangExt langId1,const DString &value1,
48 SrcLangExt langId2,const DString &value2)
49{
50 return compileOptions(def,langId1,value1)+
51 "|"+DString().setNum(static_cast<long>(langId2))+"="+value2;
52}
53
54inline DString compileOptions(const DString &def,SrcLangExt langId1,const DString &value1,
55 SrcLangExt langId2,const DString &value2,
56 SrcLangExt langId3,const DString &value3)
57{
58 return compileOptions(def,langId1,value1,langId2,value2)+
59 "|"+DString().setNum(static_cast<long>(langId3))+"="+value3;
60}
61
62inline DString compileOptions(const DString &def,SrcLangExt langId1,const DString &value1,
63 SrcLangExt langId2,const DString &value2,
64 SrcLangExt langId3,const DString &value3,
65 SrcLangExt langId4,const DString &value4)
66{
67 return compileOptions(def,langId1,value1,langId2,value2,langId3,value3)+
68 "|"+DString().setNum(static_cast<long>(langId4))+"="+value4;
69}
70
71inline DString compileOptions(const DString &def,SrcLangExt langId1,const DString &value1,
72 SrcLangExt langId2,const DString &value2,
73 SrcLangExt langId3,const DString &value3,
74 SrcLangExt langId4,const DString &value4,
75 SrcLangExt langId5,const DString &value5)
76{
77 return compileOptions(def,langId1,value1,langId2,value2,langId3,value3,langId4,value4)+
78 "|"+DString().setNum(static_cast<long>(langId5))+"="+value5;
79}
80
81static bool elemIsVisible(const XMLHandlers::Attributes &attrib,bool defVal=true)
82{
83 DString visible = XMLHandlers::value(attrib,"visible");
84 //printf("visible_attribute=%s\n",qPrint(visible));
85 if (visible.empty()) return defVal;
86 if (visible.at(0)=='$' && visible.length()>1)
87 {
88 DString id = visible.mid(1);
89 const ConfigValues::Info *opt = ConfigValues::instance().get(id);
90 if (opt && opt->type==ConfigValues::Info::Bool)
91 {
92 return ConfigValues::instance().*(opt->value.b);
93 }
94 else if (opt && opt->type==ConfigValues::Info::String)
95 {
96 return opt->getBooleanRepresentation();
97 }
98 else if (!opt)
99 {
100 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
101 visible,(defVal?"yes":"no"));
102 return defVal;
103 }
104 }
105 DString visibleLow = visible.lower();
106 if (visibleLow=="no" || visibleLow=="false" || visibleLow=="0") return false;
107 else if (visibleLow=="yes" || visibleLow=="true" || visibleLow=="1") return true;
108 else
109 {
110 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
111 visible,(defVal?"yes":"no"));
112 return defVal;
113 }
114}
115
116//---------------------------------------------------------------------------------
117
119{
120 m_visible = m_visible && (parent==nullptr || parent->visible());
121}
122
123void LayoutNavEntry::appendChild(std::unique_ptr<LayoutNavEntry> &&e)
124{
125 e->updateVisibility(this);
126 m_children.push_back(std::move(e));
127}
128
129void LayoutNavEntry::insertChild(size_t pos,std::unique_ptr<LayoutNavEntry> &&e)
130{
131 e->updateVisibility(this);
132 m_children.insert(m_children.begin()+pos,std::move(e));
133}
134
136 const DString &file) const
137{
138 LayoutNavEntry *result=nullptr;
139 for (const auto &entry : m_children)
140 {
141 // depth first search, needed to find the entry furthest from the
142 // root in case an entry is in the tree twice
143 result = entry->find(kind,file);
144 if (result) return result;
145 if (entry->kind()==kind && (file==DString() || entry->baseFile()==file))
146 {
147 return entry.get();
148 }
149 }
150 return result;
151}
152
154{
156 if ((kind()!=LayoutNavEntry::User && kind()!=LayoutNavEntry::UserGroup) ||
157 (kind()==LayoutNavEntry::UserGroup && url.startsWith("usergroup")))
158 {
160 }
161 else if (url.startsWith("@ref ") || url.startsWith("\\ref "))
162 {
163 bool found=false;
164 DString relPath = "";
165 DString context = DString();
166 auto parser { createDocParser() };
167 auto dfAst { createRef( *parser.get(), url.mid(5).stripWhiteSpace(), context ) };
168 auto dfAstImpl = dynamic_cast<const DocNodeAST*>(dfAst.get());
169 const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root);
170 if (!df->file().empty() || !df->anchor().empty())
171 {
172 found = true;
173 url=externalRef(relPath,df->ref());
174 if (!df->file().empty())
175 {
176 DString fn = df->file();
178 url += fn;
179 }
180 if (!df->anchor().empty())
181 {
182 url += "#" + df->anchor();
183 }
184 }
185 if (!found)
186 {
187 msg("explicit link request to '{}' in layout file '{}' could not be resolved\n",url.mid(5),Config_getString(LAYOUT_FILE));
188 }
189 }
190 //printf("LayoutNavEntry::url()=%s\n",qPrint(url));
191 return url;
192}
193
195{
196 return parseCommentAsText(nullptr,nullptr,m_title,"DoxygenLayout",1);
197}
198
200{
201 return parseCommentAsHtml(nullptr,nullptr,m_title,"DoxygenLayout",1);
202}
203
204//---------------------------------------------------------------------------------
205
207{
208 public:
210
211 // =========== XMLHandler events
212 void setDocumentLocator(const XMLLocator *locator)
213 {
214 m_locator = locator;
215 }
216 void error( const std::string &fileName,int lineNr,const std::string &msg)
217 {
218 warn_layout(fileName,lineNr,"{}",msg);
219 }
220 void startElement( const std::string &name, const XMLHandlers::Attributes& attrib );
221 void endElement( const std::string &name );
222
223 void startSimpleEntry(LayoutDocEntry::Kind k,const std::string &id,const XMLHandlers::Attributes &attrib)
224 {
225 bool isVisible = m_visible && elemIsVisible(attrib);
226 if (m_part!=LayoutDocManager::Undefined)
227 {
228 auto elem = std::make_unique<LayoutDocEntrySimple>(k,id,isVisible);
229 //printf("startSimpleEntry(%s) isVisible=%d visible=%d\n",qPrint(elem->entryToString()),isVisible,elem->visible());
230 m_layoutDocManager.addEntry(m_part,std::move(elem));
231 }
232 }
233
234 // ============ Specific callbacks
235
236 void startSectionEntry(LayoutDocEntry::Kind k,const std::string &id,const XMLHandlers::Attributes &attrib,
237 const DString &title)
238 {
239 bool isVisible = m_visible && elemIsVisible(attrib);
240 DString userTitle = XMLHandlers::value(attrib,"title");
241 //printf("startSectionEntry: title='%s' userTitle='%s'\n",
242 // qPrint(title),qPrint(userTitle));
243 if (userTitle.empty()) userTitle = title;
244 if (m_part!=LayoutDocManager::Undefined)
245 {
246 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntrySection>(k,id,userTitle,isVisible));
247 }
248 }
249
250
251 void startMemberDeclEntry(const std::string &id,const XMLHandlers::Attributes &attrib,MemberListType type,
252 const DString &title,const DString &subscript)
253 {
254 DString userTitle = XMLHandlers::value(attrib,"title");
255 DString userSubscript = XMLHandlers::value(attrib,"subtitle");
256 if (userTitle.empty()) userTitle = title;
257 if (userSubscript.empty()) userSubscript = subscript;
258 bool isVisible = m_visible && elemIsVisible(attrib);
259 if (m_part!=LayoutDocManager::Undefined)
260 {
261 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntryMemberDecl>(type,id,userTitle,userSubscript,isVisible));
262 }
263 }
264
265 void startMemberDefEntry(const std::string &id,const XMLHandlers::Attributes &attrib,MemberListType type,
266 const DString &title,const DString &)
267 {
268 DString userTitle = XMLHandlers::value(attrib,"title");
269 if (userTitle.empty()) userTitle = title;
270 //printf("memberdef: %s\n",qPrint(userTitle));
271 bool isVisible = m_visible && elemIsVisible(attrib);
272 if (m_part!=LayoutDocManager::Undefined)
273 {
274 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntryMemberDef>(type,id,userTitle,isVisible));
275 }
276 }
277
278 void startLayout(const std::string &,const XMLHandlers::Attributes &attrib)
279 {
280 // extract and store version number
281 DString version = XMLHandlers::value(attrib,"version");
282 static const reg::Ex re(R"((\d+)\.(\d+))");
283 reg::Match match;
284 if (reg::match(version.view(),match,re))
285 {
286 m_majorVersion = atoi(match[1].str().c_str());
287 m_minorVersion = atoi(match[2].str().c_str());
288 //printf("layout version %d.%d\n",m_versionMajor,m_versionMinor);
289 }
290 }
291
292 void startNavIndex(const std::string &,const XMLHandlers::Attributes &)
293 {
294 m_scope="navindex/";
296 }
297
298 void endNavIndex(const std::string &)
299 {
300 m_scope="";
301 if (m_rootNav && !m_rootNav->find(LayoutNavEntry::MainPage))
302 {
303 // no MainPage node... add one as the first item of the root node...
304 m_rootNav->insertChild(0,std::make_unique<LayoutNavEntry>(m_rootNav,LayoutNavEntry::MainPage, true,
305 "index",theTranslator->trMainPage(),""));
306 }
307 }
308
309 void startNavEntry(const std::string &,const XMLHandlers::Attributes &attrib)
310 {
311 bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
312 bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
313 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
314 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
315 bool hasGraphicalHierarchy = Config_getBool(HAVE_DOT) &&
316 Config_getBool(GRAPHICAL_HIERARCHY);
317 bool extractAll = Config_getBool(EXTRACT_ALL);
318 static struct NavEntryMap
319 {
320 const char *typeStr; // type attribute name in the XML file
321 LayoutNavEntry::Kind kind; // corresponding enum name
322 DString mainName; // default title for an item if it has children
323 DString subName; // optional name for an item if it is rendered as a child
324 DString intro; // introduction text to be put on the index page
325 DString baseFile; // base name of the file containing the index page
326 } mapping[] =
327 {
328 { "mainpage",
329 LayoutNavEntry::MainPage,
331 DString(),
332 DString(),
333 "index"
334 },
335 { "pages",
336 LayoutNavEntry::Pages,
338 DString(),
340 "pages"
341 },
342 { "topics",
343 LayoutNavEntry::Topics,
345 DString(),
347 "topics"
348 },
349 { "modules",
350 LayoutNavEntry::Modules,
354 "modules"
355 },
356 { "modulelist",
357 LayoutNavEntry::ModuleList,
359 DString(),
361 "modules"
362 },
363 { "modulemembers",
364 LayoutNavEntry::ModuleMembers,
366 DString(),
368 "modulemembers"
369 },
370 { "namespaces",
371 LayoutNavEntry::Namespaces,
372 javaOpt || vhdlOpt ? theTranslator->trPackages() : fortranOpt || sliceOpt ? theTranslator->trModules() : theTranslator->trNamespaces(),
373 javaOpt || vhdlOpt ? theTranslator->trPackageList() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
374 javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt || sliceOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
375 "namespaces"
376 },
377 { "namespacelist",
378 LayoutNavEntry::NamespaceList,
379 javaOpt || vhdlOpt ? theTranslator->trPackageList() : fortranOpt || sliceOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
380 DString(),
381 javaOpt || vhdlOpt ? theTranslator->trPackageListDescription() : fortranOpt || sliceOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
382 "namespaces"
383 },
384 { "namespacemembers",
385 LayoutNavEntry::NamespaceMembers,
386 javaOpt || vhdlOpt ? theTranslator->trPackageMembers() : fortranOpt || sliceOpt ? theTranslator->trModulesMembers() : theTranslator->trNamespaceMembers(),
387 DString(),
388 fortranOpt || sliceOpt ? theTranslator->trModulesMemberDescription(extractAll) : theTranslator->trNamespaceMemberDescription(extractAll),
389 "namespacemembers"
390 },
391 { "concepts",
392 LayoutNavEntry::Concepts,
393 theTranslator->trConcept(true,false),
396 "concepts"
397 },
398 { "classindex",
399 LayoutNavEntry::ClassIndex,
401 DString(),
402 DString(),
403 "classes"
404 },
405 { "classes",
406 LayoutNavEntry::Classes,
410 "annotated"
411 },
412 { "classlist",
413 LayoutNavEntry::ClassList,
415 DString(),
417 "annotated"
418 },
419 { "hierarchy",
420 LayoutNavEntry::ClassHierarchy,
422 DString(),
424 hasGraphicalHierarchy ? "inherits" : "hierarchy"
425 },
426 { "classmembers",
427 LayoutNavEntry::ClassMembers,
429 DString(),
431 "functions"
432 },
433 { "interfaceindex",
434 LayoutNavEntry::InterfaceIndex,
436 DString(),
437 DString(),
438 "interfaces"
439 },
440 { "interfaces",
441 LayoutNavEntry::Interfaces,
445 "annotatedinterfaces"
446 },
447 { "interfacelist",
448 LayoutNavEntry::InterfaceList,
450 DString(),
452 "annotatedinterfaces"
453 },
454 { "interfacehierarchy",
455 LayoutNavEntry::InterfaceHierarchy,
457 DString(),
459 hasGraphicalHierarchy ? "interfaceinherits" : "interfacehierarchy"
460 },
461 { "structindex",
462 LayoutNavEntry::StructIndex,
464 DString(),
465 DString(),
466 "structs"
467 },
468 { "structs",
469 LayoutNavEntry::Structs,
473 "annotatedstructs"
474 },
475 { "structlist",
476 LayoutNavEntry::StructList,
478 DString(),
480 "annotatedstructs"
481 },
482 { "exceptionindex",
483 LayoutNavEntry::ExceptionIndex,
485 DString(),
486 DString(),
487 "exceptions"
488 },
489 { "exceptions",
490 LayoutNavEntry::Exceptions,
494 "annotatedexceptions"
495 },
496 { "exceptionlist",
497 LayoutNavEntry::ExceptionList,
499 DString(),
501 "annotatedexceptions"
502 },
503 { "exceptionhierarchy",
504 LayoutNavEntry::ExceptionHierarchy,
506 DString(),
508 hasGraphicalHierarchy ? "exceptioninherits" : "exceptionhierarchy"
509 },
510 { "files",
511 LayoutNavEntry::Files,
512 theTranslator->trFile(true,false),
515 "files"
516 },
517 { "filelist",
518 LayoutNavEntry::FileList,
520 DString(),
522 "files"
523 },
524 { "globals",
525 LayoutNavEntry::FileGlobals,
527 DString(),
529 "globals"
530 },
531 { "examples",
532 LayoutNavEntry::Examples,
534 DString(),
536 "examples"
537 },
538 { "user",
539 LayoutNavEntry::User,
540 DString(),
541 DString(),
542 DString(),
543 "user"
544 },
545 { "usergroup",
546 LayoutNavEntry::UserGroup,
547 DString(),
548 DString(),
549 DString(),
550 "usergroup"
551 },
552 { nullptr, // end of list
553 static_cast<LayoutNavEntry::Kind>(0),
554 DString(),
555 DString(),
556 DString(),
557 DString()
558 }
559 };
560 // find type in the table
561 int i=0;
562 DString type = XMLHandlers::value(attrib,"type");
563 while (mapping[i].typeStr)
564 {
565 if (mapping[i].typeStr==type)
566 break;
567 i++;
568 }
569 if (mapping[i].typeStr==nullptr)
570 {
571 DString fileName = m_locator->fileName();
572 if (type.empty())
573 {
574 warn_layout(fileName,m_locator->lineNr(),"an entry tag within a navindex has no type attribute! Check your layout file!");
575 }
576 else
577 {
578 warn_layout(fileName,m_locator->lineNr(),"the type '{}' is not supported for the entry tag within a navindex! Check your layout file!",type);
579 }
580 m_invalidEntry=true;
581 return;
582 }
583 LayoutNavEntry::Kind kind = mapping[i].kind;
584 DString baseFile = mapping[i].baseFile;
585 DString title = XMLHandlers::value(attrib,"title");
586 bool isVisible = m_visible && elemIsVisible(attrib);
587 if (title.empty()) // use default title
588 {
589 title = mapping[i].mainName; // use title for main row
590 if (m_rootNav!=m_layoutDocManager.rootNavEntry() && !mapping[i].subName.empty())
591 {
592 title = mapping[i].subName; // if this is a child of another row, use the subName if available
593 // this is mainly done to get compatible naming with older versions.
594 }
595 }
596 DString intro = XMLHandlers::value(attrib,"intro");
597 if (intro.empty()) // use default intro text
598 {
599 intro = mapping[i].intro;
600 }
601 DString url = XMLHandlers::value(attrib,"url");
602 if (mapping[i].kind==LayoutNavEntry::User && !url.empty())
603 {
604 baseFile=url;
605 }
606 else if (kind==LayoutNavEntry::UserGroup)
607 {
608 if (!url.empty())
609 {
610 if (url == "[none]")
611 {
612 baseFile = DString();
613 }
614 else
615 {
616 baseFile=url;
617 }
618 }
619 else
620 {
621 baseFile+=DString().sprintf("%d",m_userGroupCount++);
622 }
623 }
624 // create new item and make it the new root
625 m_rootNav = m_layoutDocManager.createChildNavEntry(m_rootNav,kind,isVisible,baseFile,title,intro);
626 }
627
628 void endNavEntry(const std::string &)
629 {
630 // set the root back to the parent
632 m_invalidEntry=false;
633 }
634
635 void startTop(const std::string &,const XMLHandlers::Attributes &attrib,LayoutDocManager::LayoutPart part,
636 const DString &scope, LayoutNavEntry::Kind nav)
637 {
638 //printf("startTop(scope=%s)\n",qPrint(scope));
639 m_scope = scope;
640 m_part = part;
641 m_visible = elemIsVisible(attrib);
642 }
643
644 void endTop(const std::string &)
645 {
646 m_scope="";
647 m_part = LayoutDocManager::Undefined;
648 }
649
650 void startMemberDef(const std::string &id,const XMLHandlers::Attributes &attrib)
651 {
652 m_scope+="memberdef/";
653 bool isVisible = m_visible && elemIsVisible(attrib);
654 if (m_part!=LayoutDocManager::Undefined)
655 {
656 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntrySimple>(LayoutDocEntry::MemberDefStart,id,isVisible));
657 }
658 }
659
660 void endMemberDef(const std::string &id)
661 {
662 DString scopeOrg = m_scope;
663 if (size_t i=m_scope.rfind("memberdef/"); i!=DString::npos)
664 {
666 bool isVisible = true;
667 for (const auto &lde : m_layoutDocManager.docEntries(m_part))
668 {
669 if (lde->kind() == LayoutDocEntry::MemberDefStart)
670 {
671 isVisible = static_cast<const LayoutDocEntrySimple*>(lde.get())->visible();
672 break;
673 }
674 }
675 if (m_part!=LayoutDocManager::Undefined)
676 {
677 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntrySimple>(LayoutDocEntry::MemberDefEnd,id,isVisible));
678 }
679 }
680 }
681
682 void startMemberDecl(const std::string &id,const XMLHandlers::Attributes &attrib)
683 {
684 m_scope+="memberdecl/";
685 bool isVisible = m_visible && elemIsVisible(attrib);
686 if (m_part!=LayoutDocManager::Undefined)
687 {
688 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntrySimple>(LayoutDocEntry::MemberDeclStart,id,isVisible));
689 }
690 }
691
692 void endMemberDecl(const std::string &id)
693 {
694 if (size_t i=m_scope.rfind("memberdecl/"); i!=DString::npos)
695 {
697 bool isVisible = true;
698 for (const auto &lde : m_layoutDocManager.docEntries(m_part))
699 {
700 if (lde->kind() == LayoutDocEntry::MemberDeclStart)
701 {
702 isVisible = static_cast<const LayoutDocEntrySimple*>(lde.get())->visible();
703 break;
704 }
705 }
706 if (m_part!=LayoutDocManager::Undefined)
707 {
708 m_layoutDocManager.addEntry(m_part,std::make_unique<LayoutDocEntrySimple>(LayoutDocEntry::MemberDeclEnd,id,isVisible));
709 }
710 }
711 }
712
713 int majorVersion() const { return m_majorVersion; }
714 int minorVersion() const { return m_minorVersion; }
715
716 private:
719 LayoutDocManager::LayoutPart m_part = LayoutDocManager::Undefined;
721 bool m_invalidEntry = false;
722 bool m_visible = true;
724 const XMLLocator *m_locator = nullptr;
727};
728
729//---------------------------------------------------------------------------------
730
731namespace {
732
734{
735 using StartCallback = std::function<void(LayoutParser&,const std::string &,const XMLHandlers::Attributes&)>;
736 using EndCallback = std::function<void(LayoutParser&,const std::string &)>;
737
739 EndCallback endCb = [](LayoutParser &,const std::string &){};
740};
741
742template<class...Args>
743static auto startCb(void (LayoutParser::*fn)(Args...))
744{
745 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(id,attr); };
746}
747
748template<class...Args>
749static auto startCb(void (LayoutParser::*fn)(Args...),
751 )
752{
753 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(kind,id,attr); };
754}
755
756template<class...Args>
757static auto startCb(void (LayoutParser::*fn)(Args...),
759 const std::function<DString()> &title
760 )
761{
762 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(kind,id,attr,title()); };
763}
764
765template<class...Args>
766static auto startCb(void (LayoutParser::*fn)(Args...),
767 MemberListType type,
768 const std::function<DString()> &title
769 )
770{
771 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(id,attr,type,title(),DString()); };
772}
773
774template<class...Args>
775static auto startCb(void (LayoutParser::*fn)(Args...),
776 MemberListType type,
777 const std::function<DString()> &title,
778 const std::function<DString()> &subtitle
779 )
780{
781 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(id,attr,type,title(),subtitle()); };
782}
783
784template<class...Args>
785static auto startCb(void (LayoutParser::*fn)(Args...),
787 const DString &scope,
789 )
790{
791 return [=](LayoutParser &parser,const std::string &id,const XMLHandlers::Attributes &attr) { (parser.*fn)(id,attr,part,scope,nav); };
792}
793
794template<class...Args>
795static auto endCb(void (LayoutParser::*fn)(Args...))
796{
797 return [=](LayoutParser &parser,const std::string &id) { (parser.*fn)(id); };
798}
799
800// clang-format off
801static const std::map< std::string, ElementCallbacks > g_elementHandlers =
802{
803 // path/name
804 { "doxygenlayout", { startCb(&LayoutParser::startLayout) } },
806 { "navindex/tab", { startCb(&LayoutParser::startNavEntry),
808 } },
809
810 // class layout handlers
811 { "class", { startCb(&LayoutParser::startTop,LayoutDocManager::Class,"class/",LayoutNavEntry::Classes),
813 } },
814 { "class/briefdescription", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::BriefDesc) } },
815 { "class/detaileddescription", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::DetailedDesc,
817 } },
818 { "class/authorsection", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::AuthorSection) } },
819 { "class/includes", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::Includes) } },
820 { "class/inheritancegraph", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassInheritanceGraph) } },
821 { "class/collaborationgraph", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassCollaborationGraph) } },
822 { "class/allmemberslink", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassAllMembersLink) } },
823 { "class/usedfiles", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::ClassUsedFiles) } },
825 { "class/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::MemberGroups) } },
826 { "class/memberdecl/nestedclasses", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::ClassNestedClasses,
827 []() { return compileOptions(/*default*/ theTranslator->trCompounds(),
828 SrcLangExt::VHDL, theTranslator->trVhdlType(VhdlSpecifier::ENTITY,false),
829 SrcLangExt::Fortran,theTranslator->trDataTypes()); })
830 } },
831 { "class/memberdecl/services", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType::Services(),
832 []() { return compileOptions(theTranslator->trServices()); })
833 } },
834 { "class/memberdecl/interfaces", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType::Interfaces(),
835 []() { return compileOptions(theTranslator->trInterfaces()); })
836 } },
837 { "class/memberdecl/publictypes", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType::PubTypes(),
838 []() { return compileOptions(theTranslator->trPublicTypes()); })
839 } },
840 { "class/memberdecl/publicslots", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType::PubSlots(),
841 []() { return compileOptions(theTranslator->trPublicSlots()); })
842 } },
843 { "class/memberdecl/signals", { startCb(&LayoutParser::startMemberDeclEntry,MemberListType::Signals(),
844 []() { return compileOptions(theTranslator->trSignals()); })
845 } },
846 { "class/memberdecl/publicmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PubMethods(),
847 []() { return compileOptions(/* default */ theTranslator->trPublicMembers(),
848 SrcLangExt::ObjC, theTranslator->trInstanceMethods(),
849 SrcLangExt::Slice,theTranslator->trOperations()); })
850 } },
851 { "class/memberdecl/publicstaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PubStaticMethods(),
852 []() { return compileOptions(/* default */ theTranslator->trStaticPublicMembers(),
853 SrcLangExt::ObjC, theTranslator->trClassMethods()); })
854 } },
855 { "class/memberdecl/publicattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PubAttribs(),
856 []() { return compileOptions(/* default */ theTranslator->trPublicAttribs(),
857 SrcLangExt::Slice,theTranslator->trDataMembers()); })
858 } },
859 { "class/memberdecl/publicstaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PubStaticAttribs(),
861 } },
862 { "class/memberdecl/protectedtypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProTypes(),
863 []() { return compileOptions(theTranslator->trProtectedTypes()); })
864 } },
865 { "class/memberdecl/protectedslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProSlots(),
866 []() { return compileOptions(theTranslator->trProtectedSlots()); })
867 } },
868 { "class/memberdecl/protectedmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProMethods(),
870 } },
871 { "class/memberdecl/protectedstaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProStaticMethods(),
873 } },
874 { "class/memberdecl/protectedattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProAttribs(),
876 } },
877 { "class/memberdecl/protectedstaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::ProStaticAttribs(),
879 } },
880 { "class/memberdecl/packagetypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PacTypes(),
881 []() { return compileOptions(theTranslator->trPackageTypes()); })
882 } },
883 { "class/memberdecl/packagemethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PacMethods(),
885 } },
886 { "class/memberdecl/packagestaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PacStaticMethods(),
888 } },
889 { "class/memberdecl/packageattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PacAttribs(),
890 []() { return compileOptions(theTranslator->trPackageAttribs()); })
891 } },
892 { "class/memberdecl/packagestaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PacStaticAttribs(),
894 } },
895 { "class/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Properties(),
896 []() { return compileOptions(theTranslator->trProperties()); })
897 } },
898 { "class/memberdecl/events", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Events(),
899 []() { return compileOptions(theTranslator->trEvents()); })
900 } },
901 { "class/memberdecl/privatetypes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriTypes(),
902 []() { return compileOptions(theTranslator->trPrivateTypes()); })
903 } },
904 { "class/memberdecl/privateslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriSlots(),
905 []() { return compileOptions(theTranslator->trPrivateSlots()); })
906 } },
907 { "class/memberdecl/privatemethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriMethods(),
908 []() { return compileOptions(theTranslator->trPrivateMembers()); })
909 } },
910 { "class/memberdecl/privatestaticmethods", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriStaticMethods(),
912 } },
913 { "class/memberdecl/privateattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriAttribs(),
914 []() { return compileOptions(theTranslator->trPrivateAttribs()); })
915 } },
916 { "class/memberdecl/privatestaticattributes", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::PriStaticAttribs(),
918 } },
919 { "class/memberdecl/friends", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Friends(),
920 []() { return compileOptions(theTranslator->trFriends()); })
921 } },
922 { "class/memberdecl/related", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Related(),
923 []() { return compileOptions(theTranslator->trRelatedSymbols()); },
925 } },
927 { "class/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ClassInlineClasses,
928 []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(),
929 SrcLangExt::Fortran,theTranslator->trTypeDocumentation()); })
930 } },
931 { "class/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::TypedefMembers(),
933 } },
934 { "class/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::EnumMembers(),
936 } },
937 { "class/memberdef/services", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::ServiceMembers(),
938 []() { return compileOptions(theTranslator->trInterfaces()); })
939 } },
940 { "class/memberdef/interfaces", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::InterfaceMembers(),
941 []() { return compileOptions(theTranslator->trInterfaces()); })
942 } },
943 { "class/memberdef/constructors", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::Constructors(),
945 } },
946 { "class/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::FunctionMembers(),
947 []() { return compileOptions(/* default */ theTranslator->trMemberFunctionDocumentation(), SrcLangExt::ObjC, theTranslator->trMethodDocumentation(),
949 SrcLangExt::Slice, theTranslator->trOperationDocumentation()); })
950 } },
951 { "class/memberdef/related", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::RelatedMembers(),
953 } },
954 { "class/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::VariableMembers(),
955 []() { return compileOptions(/* default */ theTranslator->trMemberDataDocumentation(),
956 SrcLangExt::Slice, theTranslator->trDataMemberDocumentation()); })
957 } },
958 { "class/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::PropertyMembers(),
960 } },
961 { "class/memberdef/events", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::EventMembers(),
963 } },
964
965 // concept layout handlers
966 { "concept", { startCb(&LayoutParser::startTop,LayoutDocManager::Concept,"concept/",LayoutNavEntry::Concepts),
968 } },
969 { "concept/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
970 { "concept/definition", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ConceptDefinition,
972 } },
973 { "concept/includes", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::Includes) } },
974 { "concept/sourcelink", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileSourceLink) } },
975 { "concept/detaileddescription", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::DetailedDesc,
977 } },
978 { "concept/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection) } },
979 // namespace layout handlers
980 { "namespace", { startCb(&LayoutParser::startTop,LayoutDocManager::Namespace,"namespace/",LayoutNavEntry::Namespaces),
982 } },
983 { "namespace/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
984 { "namespace/detaileddescription", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::DetailedDesc,
986 } },
987 { "namespace/includes", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::Includes) } },
988 { "namespace/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection) } },
989 { "namespace/memberdecl", { startCb(&LayoutParser::startMemberDecl),
991 } },
992 { "namespace/memberdecl/nestednamespaces", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceNestedNamespaces,
993 []() { return compileOptions(/* default */ theTranslator->trNamespaces(),
994 SrcLangExt::Java, theTranslator->trPackages(),
995 SrcLangExt::VHDL, theTranslator->trPackages(),
996 SrcLangExt::IDL, theTranslator->trModules(),
997 SrcLangExt::Fortran,theTranslator->trModules(),
998 SrcLangExt::Slice,(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
1001 } },
1002 { "namespace/memberdecl/constantgroups", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceNestedConstantGroups,
1003 []() { return compileOptions(theTranslator->trConstantGroups()); })
1004 } },
1005 { "namespace/memberdecl/interfaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceInterfaces,
1006 []() { return compileOptions(theTranslator->trSliceInterfaces()); })
1007 } },
1008 { "namespace/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceClasses,
1009 []() { return compileOptions(/* default */ theTranslator->trCompounds(),
1010 SrcLangExt::VHDL, theTranslator->trVhdlType(VhdlSpecifier::ENTITY,false),
1011 SrcLangExt::Fortran,theTranslator->trDataTypes()); })
1012 } },
1013 { "namespace/memberdecl/concepts", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceConcepts,
1014 []() { return compileOptions(theTranslator->trConcept(true,false)); })
1015 } },
1016 { "namespace/memberdecl/structs", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceStructs,
1017 []() { return compileOptions(theTranslator->trStructs()); })
1018 } },
1019 { "namespace/memberdecl/exceptions", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::NamespaceExceptions,
1020 []() { return compileOptions(theTranslator->trExceptions()); })
1021 } },
1022 { "namespace/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry,LayoutDocEntry::MemberGroups) } },
1023 { "namespace/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecTypedefMembers(),
1024 []() { return compileOptions(theTranslator->trTypedefs()); })
1025 } },
1026 { "namespace/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecSequenceMembers(),
1027 []() { return compileOptions(theTranslator->trSequences()); })
1028 } },
1029 { "namespace/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecDictionaryMembers(),
1030 []() { return compileOptions(theTranslator->trDictionaries()); })
1031 } },
1032 { "namespace/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEnumMembers(),
1033 []() { return compileOptions(theTranslator->trEnumerations()); })
1034 } },
1035 { "namespace/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecFuncMembers(),
1036 []() { return compileOptions(/* default */ theTranslator->trFunctions(),
1037 SrcLangExt::Fortran,theTranslator->trSubprograms(),
1038 SrcLangExt::VHDL, theTranslator->trFunctionAndProc()); })
1039 } },
1040 { "namespace/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecVarMembers(),
1041 []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
1044 } },
1045 { "namespace/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Properties(),
1046 []() { return compileOptions(theTranslator->trProperties()); })
1047 } },
1048 { "namespace/memberdef", { startCb(&LayoutParser::startMemberDef), endCb(&LayoutParser::endMemberDef) } },
1049 { "namespace/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::NamespaceInlineClasses,
1050 []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(),
1051 SrcLangExt::Fortran,theTranslator->trTypeDocumentation()); })
1052 } },
1053 { "namespace/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocTypedefMembers(),
1055 } },
1056 { "namespace/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocSequenceMembers(),
1058 } },
1059 { "namespace/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocDictionaryMembers(),
1061 } },
1062 { "namespace/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocEnumMembers(),
1064 } },
1065 { "namespace/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocFuncMembers(),
1066 []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(),
1067 SrcLangExt::Fortran,theTranslator->trSubprogramDocumentation()); })
1068 } },
1069 { "namespace/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocVarMembers(),
1070 []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
1073 } },
1074 { "namespace/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::PropertyMembers(),
1076 } },
1077
1078 // file layout handlers
1079 { "file", { startCb(&LayoutParser::startTop,LayoutDocManager::File,"file/",LayoutNavEntry::Files),
1081 } },
1082 { "file/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
1083 { "file/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc,
1085 } },
1086 { "file/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection) } },
1087 { "file/includes", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::Includes) } },
1088 { "file/includegraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileIncludeGraph) } },
1089 { "file/includedbygraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileIncludedByGraph) } },
1090 { "file/sourcelink", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::FileSourceLink) } },
1091 { "file/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::MemberGroups) } },
1093 { "file/memberdecl/interfaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileInterfaces,
1094 []() { return compileOptions(theTranslator->trSliceInterfaces()); })
1095 } },
1096 { "file/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileClasses,
1097 []() { return compileOptions(/* default */ theTranslator->trCompounds(),
1098 SrcLangExt::VHDL, theTranslator->trVhdlType(VhdlSpecifier::ENTITY,false),
1099 SrcLangExt::Fortran,theTranslator->trDataTypes()); })
1100 } },
1101 { "file/memberdecl/concepts", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::FileConcepts,
1102 []() { return compileOptions(theTranslator->trConcept(true,false)); })
1103 } },
1104 { "file/memberdecl/structs", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileStructs,
1105 []() { return compileOptions(theTranslator->trStructs()); })
1106 } },
1107 { "file/memberdecl/exceptions", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileExceptions,
1108 []() { return compileOptions(theTranslator->trExceptions()); })
1109 } },
1110 { "file/memberdecl/namespaces", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileNamespaces,
1111 []() { return compileOptions(/* default */ theTranslator->trNamespaces(),
1112 SrcLangExt::Java, theTranslator->trPackages(),
1113 SrcLangExt::IDL, theTranslator->trModules(),
1114 SrcLangExt::Fortran,theTranslator->trModules(),
1115 SrcLangExt::Slice, theTranslator->trModules()); })
1116 } },
1117 { "file/memberdecl/constantgroups", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileConstantGroups,
1118 []() { return compileOptions(theTranslator->trConstantGroups()); })
1119 } },
1120 { "file/memberdecl/defines", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecDefineMembers(),
1121 []() { return compileOptions(theTranslator->trDefines()); })
1122 } },
1123 { "file/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecTypedefMembers(),
1124 []() { return compileOptions(theTranslator->trTypedefs()); })
1125 } },
1126 { "file/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecSequenceMembers(),
1127 []() { return compileOptions(theTranslator->trSequences()); })
1128 } },
1129 { "file/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecDictionaryMembers(),
1130 []() { return compileOptions(theTranslator->trDictionaries()); })
1131 } },
1132 { "file/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEnumMembers(),
1133 []() { return compileOptions(theTranslator->trEnumerations()); })
1134 } },
1135 { "file/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecFuncMembers(),
1136 []() { return compileOptions(/* default */ theTranslator->trFunctions(),
1137 SrcLangExt::Fortran,theTranslator->trSubprograms(),
1138 SrcLangExt::VHDL, theTranslator->trFunctionAndProc()); })
1139 } },
1140 { "file/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecVarMembers(),
1141 []() { return compileOptions(Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
1144 } },
1145 { "file/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::Properties(),
1146 []() { return compileOptions(theTranslator->trProperties()); })
1147 } },
1149
1150 { "file/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry,LayoutDocEntry::FileInlineClasses,
1151 []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(),
1152 SrcLangExt::Fortran, theTranslator->trTypeDocumentation()); })
1153 } },
1154 { "file/memberdef/defines", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocDefineMembers(),
1156 } },
1157 { "file/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocTypedefMembers(),
1159 } },
1160 { "file/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocSequenceMembers(),
1162 } },
1163 { "file/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocDictionaryMembers(),
1165 } },
1166 { "file/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocEnumMembers(),
1168 } },
1169 { "file/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocFuncMembers(),
1170 []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(),
1171 SrcLangExt::Fortran, theTranslator->trSubprogramDocumentation()); })
1172 } },
1173 { "file/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocVarMembers(),
1175 } },
1176
1177 { "file/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::PropertyMembers(),
1179 } },
1180 // group layout handlers
1181 { "group", { startCb(&LayoutParser::startTop,LayoutDocManager::Group,"group/",LayoutNavEntry::None),
1183 } },
1184 { "group/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
1185 { "group/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc,
1187 } },
1188 { "group/includes", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::Includes) } },
1189 { "group/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection) } },
1190 { "group/groupgraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::GroupGraph) } },
1192 { "group/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::MemberGroups) } },
1193 { "group/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupClasses,
1194 []() { return compileOptions(/* default */ theTranslator->trCompounds(),
1195 SrcLangExt::VHDL, theTranslator->trVhdlType(VhdlSpecifier::ENTITY,false),
1196 SrcLangExt::Fortran, theTranslator->trDataTypes()); })
1197 } },
1198 { "group/memberdecl/concepts", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupConcepts,
1199 []() { return compileOptions(theTranslator->trConcept(true,false)); })
1200 } },
1201 { "group/memberdecl/modules", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupModules,
1202 []() { return compileOptions(theTranslator->trModule(true,false)); })
1203 } },
1204 { "group/memberdecl/namespaces", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupNamespaces,
1205 []() { return compileOptions(/* default */ theTranslator->trNamespaces(),
1206 SrcLangExt::Java, theTranslator->trPackages(),
1207 SrcLangExt::Fortran, theTranslator->trModules()); })
1208 } },
1209 { "group/memberdecl/dirs", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupDirs,
1210 []() { return compileOptions(theTranslator->trDirectories()); })
1211 } },
1212 { "group/memberdecl/nestedgroups", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupNestedGroups,
1213 []() { return compileOptions(theTranslator->trTopics()); })
1214 } },
1215 { "group/memberdecl/files", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupFiles,
1216 []() { return compileOptions(theTranslator->trFile(true,false)); })
1217 } },
1218 { "group/memberdecl/defines", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecDefineMembers(),
1219 []() { return compileOptions(theTranslator->trDefines()); })
1220 } },
1221 { "group/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecTypedefMembers(),
1222 []() { return compileOptions(theTranslator->trTypedefs()); })
1223 } },
1224 { "group/memberdecl/sequences", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecSequenceMembers(),
1225 []() { return compileOptions(theTranslator->trSequences()); })
1226 } },
1227 { "group/memberdecl/dictionaries", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecDictionaryMembers(),
1228 []() { return compileOptions(theTranslator->trDictionaries()); })
1229 } },
1230 { "group/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEnumMembers(),
1231 []() { return compileOptions(theTranslator->trEnumerations()); })
1232 } },
1233 { "group/memberdecl/enumvalues", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEnumValMembers(),
1235 } },
1236 { "group/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecFuncMembers(),
1237 []() { return compileOptions(/* default */ theTranslator->trFunctions(),
1238 SrcLangExt::Fortran,theTranslator->trSubprograms(),
1239 SrcLangExt::VHDL, theTranslator->trFunctionAndProc()); })
1240 } },
1241 { "group/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecVarMembers(),
1242 []() { return compileOptions(theTranslator->trVariables()); })
1243 } },
1244 { "group/memberdecl/signals", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecSignalMembers(),
1245 []() { return compileOptions(theTranslator->trSignals()); })
1246 } },
1247 { "group/memberdecl/publicslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecPubSlotMembers(),
1248 []() { return compileOptions(theTranslator->trPublicSlots()); })
1249 } },
1250 { "group/memberdecl/protectedslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecProSlotMembers(),
1251 []() { return compileOptions(theTranslator->trProtectedSlots()); })
1252 } },
1253 { "group/memberdecl/privateslots", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecPriSlotMembers(),
1254 []() { return compileOptions(theTranslator->trPrivateSlots()); })
1255 } },
1256 { "group/memberdecl/events", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEventMembers(),
1257 []() { return compileOptions(theTranslator->trEvents()); })
1258 } },
1259 { "group/memberdecl/properties", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecPropMembers(),
1260 []() { return compileOptions(theTranslator->trProperties()); })
1261 } },
1262 { "group/memberdecl/friends", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecFriendMembers(),
1263 []() { return compileOptions(theTranslator->trFriends()); })
1264 } },
1266 { "group/memberdef/pagedocs", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::GroupPageDocs) } },
1267 { "group/memberdef/inlineclasses", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::GroupInlineClasses,
1268 []() { return compileOptions(/* default */ theTranslator->trClassDocumentation(),
1269 SrcLangExt::Fortran,theTranslator->trTypeDocumentation()); })
1270 } },
1271 { "group/memberdef/defines", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocDefineMembers(),
1273 } },
1274 { "group/memberdef/typedefs", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocTypedefMembers(),
1276 } },
1277 { "group/memberdef/sequences", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocSequenceMembers(),
1279 } },
1280 { "group/memberdef/dictionaries", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocDictionaryMembers(),
1282 } },
1283 { "group/memberdef/enums", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocEnumMembers(),
1285 } },
1286 { "group/memberdef/enumvalues", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocEnumValMembers(),
1288 } },
1289 { "group/memberdef/functions", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocFuncMembers(),
1290 []() { return compileOptions(/* default */ theTranslator->trFunctionDocumentation(),
1291 SrcLangExt::Fortran,theTranslator->trSubprogramDocumentation()); })
1292 } },
1293 { "group/memberdef/variables", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocVarMembers(),
1295 } },
1296 { "group/memberdef/signals", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocSignalMembers(),
1297 []() { return compileOptions(theTranslator->trSignals()); })
1298 } },
1299 { "group/memberdef/publicslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocPubSlotMembers(),
1300 []() { return compileOptions(theTranslator->trPublicSlots()); })
1301 } },
1302 { "group/memberdef/protectedslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocProSlotMembers(),
1303 []() { return compileOptions(theTranslator->trProtectedSlots()); })
1304 } },
1305 { "group/memberdef/privateslots", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocPriSlotMembers(),
1306 []() { return compileOptions(theTranslator->trPrivateSlots()); })
1307 } },
1308 { "group/memberdef/events", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocEventMembers(),
1309 []() { return compileOptions(theTranslator->trEvents()); })
1310 } },
1311 { "group/memberdef/properties", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocPropMembers(),
1312 []() { return compileOptions(theTranslator->trProperties()); })
1313 } },
1314 { "group/memberdef/friends", { startCb(&LayoutParser::startMemberDefEntry, MemberListType::DocFriendMembers(),
1315 []() { return compileOptions(theTranslator->trFriends()); })
1316 } },
1317
1318 // module layout handlers
1319 { "module", { startCb(&LayoutParser::startTop,LayoutDocManager::Module,"module/",LayoutNavEntry::Modules),
1321 } },
1322 { "module/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
1323 { "module/exportedmodules", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ModuleExports,
1324 []() { return compileOptions(theTranslator->trExportedModules()); })
1325 } },
1326 { "module/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc,
1328 } },
1329 { "module/authorsection", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::AuthorSection) } },
1331 { "module/memberdecl/concepts", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ModuleConcepts,
1332 []() { return compileOptions(theTranslator->trConcept(true,false)); })
1333 } },
1334 { "module/memberdecl/classes", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ModuleClasses,
1335 []() { return compileOptions(theTranslator->trCompounds()); })
1336 } },
1337 { "module/memberdecl/enums", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecEnumMembers(),
1338 []() { return compileOptions(theTranslator->trEnumerations()); })
1339 } },
1340 { "module/memberdecl/typedefs", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecTypedefMembers(),
1341 []() { return compileOptions(theTranslator->trTypedefs()); })
1342 } },
1343 { "module/memberdecl/functions", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecFuncMembers(),
1344 []() { return compileOptions(theTranslator->trFunctions()); })
1345 } },
1346 { "module/memberdecl/variables", { startCb(&LayoutParser::startMemberDeclEntry, MemberListType::DecVarMembers(),
1347 []() { return compileOptions(theTranslator->trVariables()); })
1348 } },
1349 { "module/memberdecl/membergroups", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::MemberGroups) } },
1350 { "module/memberdecl/files", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::ModuleUsedFiles,
1351 []() { return compileOptions(theTranslator->trFile(true,false)); })
1352 } },
1353
1354 // directory layout handlers
1355 { "directory", { startCb(&LayoutParser::startTop,LayoutDocManager::Directory,"directory/",LayoutNavEntry::None),
1357 } },
1358 { "directory/briefdescription", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::BriefDesc) } },
1359 { "directory/detaileddescription", { startCb(&LayoutParser::startSectionEntry, LayoutDocEntry::DetailedDesc,
1361 } },
1362 { "directory/directorygraph", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirGraph) } },
1363 { "directory/memberdecl", { startCb(&LayoutParser::startMemberDecl), endCb(&LayoutParser::endMemberDecl) } },
1364 { "directory/memberdecl/dirs", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirSubDirs) } },
1365 { "directory/memberdecl/files", { startCb(&LayoutParser::startSimpleEntry, LayoutDocEntry::DirFiles) } },
1366};
1367// clang-format on
1368
1369} // namespace
1370
1371void LayoutParser::startElement( const std::string &name, const XMLHandlers::Attributes& attrib )
1372{
1373 //printf("startElement [%s]::[%s]\n",qPrint(m_scope),qPrint(name));
1374 auto it = g_elementHandlers.find(m_scope.str()+name);
1375 if (it!=g_elementHandlers.end())
1376 {
1377 it->second.startCb(*this,it->first,attrib);
1378 }
1379 else
1380 {
1381 DString fileName = m_locator->fileName();
1382 warn_layout(fileName,m_locator->lineNr(),"Unexpected start tag '{}' found in scope='{}'!",
1383 name,m_scope);
1384 }
1385}
1386
1387void LayoutParser::endElement( const std::string &name )
1388{
1389 //printf("endElement [%s]::[%s]\n",qPrint(m_scope),qPrint(name));
1390 auto it=g_elementHandlers.end();
1391
1392 if (!m_scope.empty() && m_scope.right(name.length()+1)==name+"/")
1393 { // element ends current scope
1394 it = g_elementHandlers.find(m_scope.left(m_scope.length()-1).str());
1395 }
1396 else // continue with current scope
1397 {
1398 it = g_elementHandlers.find(m_scope.str()+name);
1399 }
1400 if (it!=g_elementHandlers.end())
1401 {
1402 it->second.endCb(*this,it->first+" end"); // added end to id to make it unique
1403 }
1404}
1405
1406//---------------------------------------------------------------------------------
1407
1409
1410//---------------------------------------------------------------------------------
1411
1413{
1414 public:
1415 std::array<LayoutDocEntryList,LayoutDocManager::NrParts> docEntries;
1419};
1420
1422{
1423}
1424
1428
1430{
1432 XMLHandlers handlers;
1433 handlers.startElement = [&layoutParser](const std::string &name,const XMLHandlers::Attributes &attrs) { layoutParser.startElement(name,attrs); };
1434 handlers.endElement = [&layoutParser](const std::string &name) { layoutParser.endElement(name); };
1435 handlers.error = [&layoutParser](const std::string &fileName,int lineNr,const std::string &msg) { layoutParser.error(fileName,lineNr,msg); };
1436 XMLParser parser(handlers);
1437 layoutParser.setDocumentLocator(&parser);
1438 constexpr auto layoutFile = "layout_default.xml";
1439 DString layout_default = ResourceMgr::instance().getAsString(layoutFile);
1440 parser.parse(layoutFile,layout_default.data(),Debug::isFlagSet(Debug::Lex_xml),
1441 [&]() { DebugLex::print(Debug::Lex_xml,"Entering","libxml/xml.l",layoutFile); },
1442 [&]() { DebugLex::print(Debug::Lex_xml,"Finished", "libxml/xml.l",layoutFile); }
1443 );
1445 d->majorVersion = layoutParser.majorVersion();
1446 d->minorVersion = layoutParser.minorVersion();
1447}
1448
1450{
1451 static LayoutDocManager theInstance;
1452 return theInstance;
1453}
1454
1456{
1457 return d->docEntries[static_cast<int>(part)];
1458}
1459
1461{
1462 return &d->rootNav;
1463}
1464
1466 LayoutNavEntry::Kind k,bool vs,const DString &bf,
1467 const DString &tl,const DString &intro)
1468{
1469 if (parent==nullptr) parent = &d->rootNav;
1470 auto ptr = std::make_unique<LayoutNavEntry>(parent,k,vs,bf,tl,intro);
1471 auto child = ptr.get();
1472 parent->appendChild(std::move(ptr));
1473 return child;
1474}
1475
1477{
1478 auto &docEntry = d->docEntries[static_cast<int>(p)];
1479 docEntry.push_back(std::move(e)); // add
1480}
1481
1482void LayoutDocManager::parse(const DString &fileName, const char *data)
1483{
1484 //printf("============ LayoutDocManager::parse(%s)\n",qPrint(fileName));
1485 LayoutDocManager layoutDocManager;
1486 LayoutParser layoutParser(layoutDocManager);
1487 XMLHandlers handlers;
1488 handlers.startElement = [&layoutParser](const std::string &name,const XMLHandlers::Attributes &attrs) { layoutParser.startElement(name,attrs); };
1489 handlers.endElement = [&layoutParser](const std::string &name) { layoutParser.endElement(name); };
1490 handlers.error = [&layoutParser](const std::string &fn,int lineNr,const std::string &msg) { layoutParser.error(fn,lineNr,msg); };
1491 XMLParser parser(handlers);
1492 layoutParser.setDocumentLocator(&parser);
1493 parser.parse(fileName.data(),
1494 data ? data : fileToString(fileName).data(),
1496 [&]() { DebugLex::print(Debug::Lex_xml,"Entering","libxml/xml.l",qPrint(fileName)); },
1497 [&]() { DebugLex::print(Debug::Lex_xml,"Finished", "libxml/xml.l",qPrint(fileName)); },
1499 );
1500
1501 // version in the user defined layout overrides default one
1502 d->majorVersion = layoutParser.majorVersion();
1503 d->minorVersion = layoutParser.minorVersion();
1504
1505 // merge missing parts of the default layout into the user defined layout
1506 // For now merging in defaults has been disabled for navigation entries
1507 // to avoid "extra entries" for projects that work with partial layout files.
1508 //mergeNavEntries(layoutDocManager);
1509
1510 // for compatibility reasons we only merge defaults when the user defined layout has at least version 2.0 or higher
1511 if (d->majorVersion>=2)
1512 {
1513 mergeDocEntries(fileName,layoutDocManager);
1514 }
1515
1516 layoutDocManager.removeInvisibleDocEntries();
1517
1518 // replace default layout with merged layout
1519 d->docEntries.swap(layoutDocManager.d->docEntries);
1520 d->rootNav.swap(layoutDocManager.d->rootNav);
1521}
1522
1524{
1525 // remove invisible entries
1526 for (auto &list : d->docEntries)
1527 {
1528 auto it = list.begin();
1529 while (it!=list.end())
1530 {
1531 if (*it==nullptr || !(*it)->visible())
1532 {
1533 it = list.erase(it);
1534 }
1535 else
1536 {
1537 ++it;
1538 }
1539 }
1540 }
1541}
1542
1544{
1545 return d->majorVersion;
1546}
1547
1549{
1550 return d->minorVersion;
1551}
1552
1553// search for candidate node in tree with root target. Returns the match target node if found, or nullptr otherwise.
1554static LayoutNavEntry *findNavEntryRec(LayoutNavEntry *root, const std::string &id)
1555{
1556 if (root)
1557 {
1558 if (root->id()==id) return root;
1559 for (auto &child : root->children())
1560 {
1561 LayoutNavEntry *childNavEntry = findNavEntryRec(child.get(),id);
1562 if (childNavEntry) return childNavEntry;
1563 }
1564 }
1565 return nullptr;
1566}
1567
1568// merge the missing nodes
1569static void mergeNavTreeNodesRec(LayoutNavEntry *targetTree,LayoutNavEntry *sourceTree)
1570{
1571 using IdSet = std::unordered_set<std::string>;
1572 using IdMap = std::unordered_map<std::string,size_t>;
1573
1574 auto prepareSet = [](const LayoutNavEntry *tree, IdSet &set) {
1575 for (const auto &e : tree->children())
1576 {
1577 set.insert(e->id());
1578 }
1579 };
1580
1581 auto prepareMap = [](const LayoutNavEntry *tree, const IdSet &set, IdMap &map) {
1582 for (size_t i=0; i<tree->children().size(); i++)
1583 {
1584 std::string id = tree->children()[i]->id();
1585 auto it = set.find(id);
1586 if (it != set.end())
1587 {
1588 map[id]=i;
1589 }
1590 }
1591 };
1592
1593 IdSet sourceSet, targetSet;
1594 prepareSet(sourceTree,sourceSet);
1595 prepareSet(targetTree,targetSet);
1596
1597 IdMap sourceMap, targetMap;
1598 prepareMap(targetTree,sourceSet,targetMap);
1599 prepareMap(sourceTree,targetSet,sourceMap);
1600
1601 // calculate list of insertion positions in the target list for each id in the source list
1602 std::vector<size_t> insertionList;
1603 for (size_t i=0; i<sourceTree->children().size(); i++)
1604 {
1605 std::string id = sourceTree->children()[i]->id();
1606 // If an id in the source list appears before a set of shared ids we want it also to
1607 // appear before these id in the target list. To do this find the lowest target index of all shared
1608 // ids that come after position i in the source list
1609 size_t minIdx = targetTree->children().size();
1610 for (const auto &kv : sourceMap) // iterator over shared ids
1611 {
1612 if (i < kv.second) // i appears before this shared id
1613 {
1614 size_t idx = targetMap[kv.first]; // get the corresponding index in the target list
1615 if (idx<minIdx) // update minimum
1616 {
1617 minIdx=idx;
1618 }
1619 }
1620 }
1621 insertionList.push_back(minIdx);
1622 }
1623
1624 // Insert the missing elements of the source list into the target list.
1625 // Work backwards so the calculated insertion points don't change due to insertions.
1626 size_t idx = sourceTree->children().size()-1;
1627 for (auto it=insertionList.rbegin(); it!=insertionList.rend(); ++it, idx--)
1628 {
1629 std::string id = sourceTree->children()[idx]->id();
1630 if (targetSet.find(id)==targetSet.end()) // need to add id
1631 {
1632 // for efficiency we move the elements from the source list to the target list, thus modifying the source list!
1633 targetTree->insertChild(*it, std::move(sourceTree->children()[idx]));
1634 }
1635 }
1636
1637 for (auto &targetChild : targetTree->children())
1638 {
1639 auto *node = findNavEntryRec(sourceTree,targetChild->id());
1640 if (node)
1641 {
1642 mergeNavTreeNodesRec(targetChild.get(),node);
1643 }
1644 }
1645}
1646
1651
1652static void mergeDocEntryLists(const DString &fileName,LayoutDocEntryList &targetList,LayoutDocEntryList &sourceList)
1653{
1654 using IdSet = std::unordered_set<std::string>;
1655 using IdMap = std::unordered_map<std::string,size_t>;
1656
1657 auto prepareSet = [](const LayoutDocEntryList &list, IdSet &set) {
1658 //size_t idx=0;
1659 for (const auto &e : list)
1660 {
1661 //printf("idx=%zu set(%s)\n",idx,qPrint(e->id()));
1662 set.insert(e->id());
1663 //idx++;
1664 }
1665 };
1666
1667 auto prepareMap = [](const LayoutDocEntryList &list, const IdSet &set, IdMap &map) {
1668 for (size_t i=0; i<list.size(); i++)
1669 {
1670 std::string id = list[i]->id();
1671 auto it = set.find(id);
1672 if (it != set.end())
1673 {
1674 //printf("map %s->%zu\n",qPrint(id),i);
1675 map[id]=i;
1676 }
1677 }
1678 };
1679
1680 IdSet sourceSet, targetSet;
1681 //printf("---- sourceSet\n");
1682 prepareSet(sourceList,sourceSet);
1683 //printf("---- targetSet\n");
1684 prepareSet(targetList,targetSet);
1685
1686 IdMap sourceMap, targetMap;
1687 //printf("---- targetMap\n");
1688 prepareMap(targetList,sourceSet,targetMap);
1689 //printf("---- sourceMap\n");
1690 prepareMap(sourceList,targetSet,sourceMap);
1691
1692 // calculate list of insertion positions in the target list for each id in the source list
1693 std::vector<size_t> insertionList;
1694 for (size_t i=0; i<sourceList.size(); i++)
1695 {
1696 std::string id = sourceList[i]->id();
1697 // If an id in the source list appears before a set of shared ids we want it also to
1698 // appear before these id in the target list. To do this find the lowest target index of all shared
1699 // ids that come after position i in the source list
1700 size_t minIdx = targetList.size();
1701 for (const auto &kv : sourceMap) // iterator over shared ids
1702 {
1703 if (i < kv.second) // i appears before this shared id
1704 {
1705 size_t idx = targetMap[kv.first]; // get the corresponding index in the target list
1706 //printf(" evaluating %s->%zu min=%zu\n",qPrint(kv.first),idx,minIdx);
1707 if (idx<minIdx) // update minimum
1708 {
1709 minIdx=idx;
1710 }
1711 }
1712 }
1713 //printf("insertion %s->%zu\n",qPrint(id),minIdx);
1714 insertionList.push_back(minIdx);
1715 }
1716
1717 // Insert the missing elements of the source list into the target list.
1718 // Work backwards so the calculated insertion points don't change due to insertions.
1719 size_t idx = sourceList.size()-1;
1720 for (auto it=insertionList.rbegin(); it!=insertionList.rend(); ++it, idx--)
1721 {
1722 std::string id = sourceList[idx]->id();
1723 //printf("idx=%zu entry %s\n",idx,qPrint(id));
1724 if (targetSet.find(id)==targetSet.end()) // need to add id
1725 {
1726 // for efficiency we move the elements from the source list to the target list, thus modifying the source list!
1727 //printf("--> insert at %zu before %s\n",*it,qPrint(*it<targetList.size()?targetList[*it]->id():"none"));
1728 warn_layout(fileName,1,"User defined layout misses entry '{}'. Using default value.",id);
1729 targetList.insert(targetList.begin()+*it, std::move(sourceList[idx]));
1730 }
1731 }
1732
1733}
1734
1736{
1737 for (size_t i=0; i<d->docEntries.size(); i++)
1738 {
1739 //printf("========= part %zu\n",i);
1740 mergeDocEntryLists(fileName,other.d->docEntries[i],d->docEntries[i]);
1741 }
1742}
1743
1744//---------------------------------------------------------------------------------
1745
1746void writeDefaultLayoutFile(const DString &fileName)
1747{
1748 std::ofstream f;
1749 if (openOutputFile(fileName,f))
1750 {
1751 TextStream t(&f);
1752 DString layout_default = ResourceMgr::instance().getAsString("layout_default.xml");
1753 t << substitute(layout_default,"$doxygenversion",getDoxygenVersion());
1754 }
1755 else
1756 {
1757 err("Failed to open file {} for writing!\n",fileName);
1758 return;
1759 }
1760 f.close();
1761}
1762
1763//----------------------------------------------------------------------------------
1764
1765// Convert input to a title.
1766// The format of input can be a simple title "A title" or in case there are different
1767// titles for some programming languages they can take the following form:
1768// "A title|16=Another title|8=Yet Another title"
1769// where the number is a value of SrcLangExt in decimal notation (i.e. 16=Java, 8=IDL).
1771{
1772 size_t s=0,e=input.find('|');
1773 if (e==DString::npos) return input; // simple title case
1774 size_t e1=e;
1775 while (e!=DString::npos) // look for 'number=title' pattern separated by '|'
1776 {
1777 s=e+1;
1778 e=input.find('|',s);
1779 size_t i=input.find('=',s);
1780 ASSERT(i!=DString::npos && i>s);
1781 SrcLangExt key= static_cast<SrcLangExt>(input.mid(s,i-s).toUInt());
1782 if (key==lang) // found matching key
1783 {
1784 if (e==DString::npos) e=input.length();
1785 return input.mid(i+1,e-i-1);
1786 }
1787 }
1788 return input.left(e1); // fallback, no explicit language key found
1789}
1790
1791//----------------------------------------------------------------------------------
1792
1797
1798//----------------------------------------------------------------------------------
1799
1804
1809
1810//----------------------------------------------------------------------------------
1811
1816
1817//----------------------------------------------------------------------------------
1818
1819static void printNavLayout(LayoutNavEntry *root,int indent)
1820{
1822 {
1823 DString indentStr;
1824 indentStr.fill(' ',indent);
1825 Debug::print(Debug::Layout,0,"{}kind={} visible={} title='{}'\n",
1826 indentStr, root->navToString(), root->visible(), root->title());
1827 for (const auto &e : root->children())
1828 {
1829 printNavLayout(e.get(),indent+2);
1830 }
1831 }
1832}
1833
1835{
1836 bool extraIndent = false;
1837
1838 auto &mgr = LayoutDocManager::instance();
1839 Debug::print(Debug::Layout,0,"Layout version {}.{}\n",mgr.majorVersion(),mgr.minorVersion());
1840
1841 Debug::print(Debug::Layout,0,"Part: Navigation index\n");
1842 for (const auto &e : mgr.rootNavEntry()->children())
1843 {
1844 printNavLayout(e.get(),2);
1845 }
1846
1847 for (int i = 0; i < LayoutDocManager::NrParts; i++)
1848 {
1850 for (const auto &lde : mgr.docEntries(static_cast<LayoutDocManager::LayoutPart>(i)))
1851 {
1852 if (const LayoutDocEntrySimple *ldes = dynamic_cast<const LayoutDocEntrySimple*>(lde.get()))
1853 {
1854 if (lde->kind() == LayoutDocEntry::MemberDeclEnd || lde->kind() == LayoutDocEntry::MemberDefEnd) extraIndent = false;
1855 Debug::print(Debug::Layout,0," {}kind: {}, visible={}\n",
1856 extraIndent? " " : "",lde->entryToString(), ldes->visible());
1857 if (lde->kind() == LayoutDocEntry::MemberDeclStart || lde->kind() == LayoutDocEntry::MemberDefStart) extraIndent = true;
1858 }
1859 else if (const LayoutDocEntryMemberDecl *lmdecl = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()))
1860 {
1861 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1862 extraIndent? " " : "",lde->entryToString(),lmdecl->visible(),lmdecl->type.to_string());
1863 }
1864 else if (const LayoutDocEntryMemberDef *lmdef = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()))
1865 {
1866 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1867 extraIndent? " " : "",lde->entryToString(),lmdef->visible(),lmdef->type.to_string());
1868 }
1869 else
1870 {
1871 // should not happen
1872 Debug::print(Debug::Layout,0," {}not handled kind: {}\n",extraIndent? " " : "",lde->entryToString());
1873 }
1874 }
1875 }
1876}
1877
1878
1879
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
DString & setNum(short n)
Definition dstring.h:552
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:244
DString fill(char c, size_t len)
Fills a string with a predefined character.
Definition dstring.h:278
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
DString lower() const
Definition dstring.h:326
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
std::string_view view() const
Definition dstring.h:162
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
DString right(size_t len) const
Definition dstring.h:311
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
DString & sprintf(const char *format,...)
Definition dstring.cpp:34
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
DString left(size_t len) const
Definition dstring.h:306
const std::string & str() const
Definition dstring.h:645
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:157
bool startsWith(const char *s) const
Definition dstring.h:600
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
@ Layout
Definition debug.h:51
@ Lex_xml
Definition debug.h:72
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:78
static void print(Debug::DebugMask mask, const char *state, const char *lexName, const char *fileName)
Definition debug.cpp:156
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1471
Node representing a reference to some item.
Definition docnode.h:787
DString ref() const
Definition docnode.h:793
DString file() const
Definition docnode.h:791
DString anchor() const
Definition docnode.h:794
std::array< LayoutDocEntryList, LayoutDocManager::NrParts > docEntries
Definition layout.cpp:1415
LayoutNavEntry rootNav
Definition layout.cpp:1416
Singleton providing access to the (user configurable) layout of the documentation.
Definition layout.h:261
void mergeNavEntries(LayoutDocManager &manager)
Definition layout.cpp:1647
static std::string partToString(int k)
Definition layout.h:272
void parse(const DString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1482
std::unique_ptr< Private > d
Definition layout.h:304
LayoutNavEntry * createChildNavEntry(LayoutNavEntry *root, LayoutNavEntry::Kind k, bool vs, const DString &bf, const DString &tl, const DString &intro)
append a new node as a child to root.
Definition layout.cpp:1465
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1449
int majorVersion() const
Definition layout.cpp:1543
int minorVersion() const
Definition layout.cpp:1548
friend class LayoutParser
Definition layout.h:305
void mergeDocEntries(const DString &fileName, LayoutDocManager &manager)
Definition layout.cpp:1735
void addEntry(LayoutPart p, LayoutDocEntryPtr &&e)
Definition layout.cpp:1476
LayoutNavEntry * rootNavEntry() const
returns the (invisible) root of the navigation tree.
Definition layout.cpp:1460
void removeInvisibleDocEntries()
Definition layout.cpp:1523
const LayoutDocEntryList & docEntries(LayoutPart part) const
Returns the list of LayoutDocEntry's in representation order for a given page identified by part.
Definition layout.cpp:1455
void endTop(const std::string &)
Definition layout.cpp:644
void endNavIndex(const std::string &)
Definition layout.cpp:298
void setDocumentLocator(const XMLLocator *locator)
Definition layout.cpp:212
static int m_userGroupCount
Definition layout.cpp:723
void startMemberDefEntry(const std::string &id, const XMLHandlers::Attributes &attrib, MemberListType type, const DString &title, const DString &)
Definition layout.cpp:265
void startSimpleEntry(LayoutDocEntry::Kind k, const std::string &id, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:223
void startNavIndex(const std::string &, const XMLHandlers::Attributes &)
Definition layout.cpp:292
LayoutParser(LayoutDocManager &manager)
Definition layout.cpp:209
void startTop(const std::string &, const XMLHandlers::Attributes &attrib, LayoutDocManager::LayoutPart part, const DString &scope, LayoutNavEntry::Kind nav)
Definition layout.cpp:635
void error(const std::string &fileName, int lineNr, const std::string &msg)
Definition layout.cpp:216
const XMLLocator * m_locator
Definition layout.cpp:724
int m_minorVersion
Definition layout.cpp:726
int majorVersion() const
Definition layout.cpp:713
void startMemberDecl(const std::string &id, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:682
void endMemberDecl(const std::string &id)
Definition layout.cpp:692
void endMemberDef(const std::string &id)
Definition layout.cpp:660
int minorVersion() const
Definition layout.cpp:714
bool m_invalidEntry
Definition layout.cpp:721
void endNavEntry(const std::string &)
Definition layout.cpp:628
void startSectionEntry(LayoutDocEntry::Kind k, const std::string &id, const XMLHandlers::Attributes &attrib, const DString &title)
Definition layout.cpp:236
LayoutDocManager & m_layoutDocManager
Definition layout.cpp:718
void startMemberDeclEntry(const std::string &id, const XMLHandlers::Attributes &attrib, MemberListType type, const DString &title, const DString &subscript)
Definition layout.cpp:251
void startNavEntry(const std::string &, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:309
void startMemberDef(const std::string &id, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:650
bool m_visible
Definition layout.cpp:722
void endElement(const std::string &name)
Definition layout.cpp:1387
DString m_scope
Definition layout.cpp:717
LayoutNavEntry * m_rootNav
Definition layout.cpp:720
void startLayout(const std::string &, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:278
void startElement(const std::string &name, const XMLHandlers::Attributes &attrib)
Definition layout.cpp:1371
LayoutDocManager::LayoutPart m_part
Definition layout.cpp:719
int m_majorVersion
Definition layout.cpp:725
Wrapper class for the MemberListType type.
Definition types.h:346
static ResourceMgr & instance()
Returns the one and only instance of this class.
DString getAsString(const DString &name) const
Gets the resource data as a C string.
Text streaming class that buffers data.
Definition textstream.h:36
virtual DString trCompoundMembers()=0
virtual DString trFunctionAndProc()=0
virtual DString trStaticProtectedAttribs()=0
virtual DString trProtectedTypes()=0
virtual DString trTypedefs()=0
virtual DString trConceptList()=0
virtual DString trTopics()=0
virtual DString trModulesMembers()=0
virtual DString trCompoundMembersFortran()=0
virtual DString trStaticProtectedMembers()=0
virtual DString trPublicAttribs()=0
virtual DString trExceptions()=0
virtual DString trModulesList()=0
virtual DString trEnumerations()=0
virtual DString trRelatedSymbolDocumentation()=0
virtual DString trClasses()=0
virtual DString trDetailedDescription()=0
virtual DString trDataMemberDocumentation()=0
virtual DString trInterfaceIndex()=0
virtual DString trNamespaceMembers()=0
virtual DString trVariableDocumentation()=0
virtual DString trNamespaceMemberDescription(bool extractAll)=0
virtual DString trFileMembersDescription(bool extractAll)=0
virtual DString trPackageMembers()=0
virtual DString trNamespaceList()=0
virtual DString trPrivateAttribs()=0
virtual DString trExceptionList()=0
virtual DString trSequenceDocumentation()=0
virtual DString trTypedefDocumentation()=0
virtual DString trPrivateSlots()=0
virtual DString trStructs()=0
virtual DString trPrivateTypes()=0
virtual DString trClassDocumentation()=0
virtual DString trExceptionHierarchyDescription()=0
virtual DString trOperationDocumentation()=0
virtual DString trInterfaceList()=0
virtual DString trSequences()=0
virtual DString trClassMethods()=0
virtual DString trFunctions()=0
virtual DString trMemberEnumerationDocumentation()=0
virtual DString trProtectedSlots()=0
virtual DString trInterfaceListDescription()=0
virtual DString trFriends()=0
virtual DString trPropertyDocumentation()=0
virtual DString trInstanceMethods()=0
virtual DString trExceptionHierarchy()=0
virtual DString trCompoundList()=0
virtual DString trPackageAttribs()=0
virtual DString trEnumerationTypeDocumentation()=0
virtual DString trInterfaceHierarchy()=0
virtual DString trTypeDocumentation()=0
virtual DString trPackageList()=0
virtual DString trMemberTypedefDocumentation()=0
virtual DString trEnumerationValueDocumentation()=0
virtual DString trModulesDescription()=0
virtual DString trStaticPackageAttribs()=0
virtual DString trStructListDescription()=0
virtual DString trOperations()=0
virtual DString trConceptDefinition()=0
virtual DString trDefineDocumentation()=0
virtual DString trDesignUnitListDescription()=0
virtual DString trExamplesDescription()=0
virtual DString trCompounds()=0
virtual DString trFileList()=0
virtual DString trModules()=0
virtual DString trDefines()=0
virtual DString trRelatedPages()=0
virtual DString trPublicMembers()=0
virtual DString trSubprogramDocumentation()=0
virtual DString trCompoundListDescriptionFortran()=0
virtual DString trVhdlType(VhdlSpecifier type, bool single)=0
virtual DString trInterfaces()=0
virtual DString trRelatedSymbols()=0
virtual DString trFileMembers()=0
virtual DString trDesignUnitHierarchy()=0
virtual DString trDesignUnits()=0
virtual DString trProtectedMembers()=0
virtual DString trDirectories()=0
virtual DString trInterfaceHierarchyDescription()=0
virtual DString trStaticPrivateAttribs()=0
virtual DString trStructIndex()=0
virtual DString trExceptionIndex()=0
virtual DString trConstructorDocumentation()=0
virtual DString trPackageTypes()=0
virtual DString trExportedModules()=0
virtual DString trModule(bool first_capital, bool singular)=0
virtual DString trDictionaryDocumentation()=0
virtual DString trProtectedAttribs()=0
virtual DString trDesignUnitMembers()=0
virtual DString trConstantGroups()=0
virtual DString trExceptionListDescription()=0
virtual DString trProperties()=0
virtual DString trRelatedPagesDescription()=0
virtual DString trDesignUnitList()=0
virtual DString trModulesMemberDescription(bool extractAll)=0
virtual DString trCompoundIndexFortran()=0
virtual DString trDataTypes()=0
virtual DString trCompoundListDescription()=0
virtual DString trConcept(bool first_capital, bool singular)=0
virtual DString trTopicListDescription()=0
virtual DString trDataMembers()=0
virtual DString trFileListDescription(bool extractAll)=0
virtual DString trClassHierarchyDescription()=0
virtual DString trSliceInterfaces()=0
virtual DString trConceptListDescription(bool extractAll)=0
virtual DString trFunctionDocumentation()=0
virtual DString trSubprograms()=0
virtual DString trMemberFunctionDocumentationFortran()=0
virtual DString trMemberFunctionDocumentation()=0
virtual DString trCompoundListFortran()=0
virtual DString trPackageFunctions()=0
virtual DString trPackages()=0
virtual DString trPrivateMembers()=0
virtual DString trPackageListDescription()=0
virtual DString trConstantDocumentation()=0
virtual DString trPublicTypes()=0
virtual DString trVariables()=0
virtual DString trStaticPublicMembers()=0
virtual DString trMethodDocumentation()=0
virtual DString trEnumerationValues()=0
virtual DString trRelatedSymbolsSubscript()=0
virtual DString trStaticPublicAttribs()=0
virtual DString trModulesListDescription(bool extractAll)=0
virtual DString trServices()=0
virtual DString trStructList()=0
virtual DString trNamespaceListDescription(bool extractAll)=0
virtual DString trSignals()=0
virtual DString trClassHierarchy()=0
virtual DString trPublicSlots()=0
virtual DString trCompoundIndex()=0
virtual DString trFile(bool first_capital, bool singular)=0
virtual DString trDesignUnitIndex()=0
virtual DString trConstants()=0
virtual DString trCompoundMembersDescription(bool extractAll)=0
virtual DString trEventDocumentation()=0
virtual DString trMainPage()=0
virtual DString trNamespaces()=0
virtual DString trCompoundMembersDescriptionFortran(bool extractAll)=0
virtual DString trMemberDataDocumentation()=0
virtual DString trEvents()=0
virtual DString trDictionaries()=0
virtual DString trStaticPackageFunctions()=0
virtual DString trExamples()=0
virtual DString trStaticPrivateMembers()=0
Event handlers that can installed by the client and called while parsing a XML document.
Definition xml.h:27
std::unordered_map< std::string, std::string > Attributes
Definition xml.h:29
std::function< EndElementType > endElement
handler invoked when a closing tag has been found
Definition xml.h:40
std::function< StartElementType > startElement
handler invoked when an opening tag has been found
Definition xml.h:39
static std::string value(const Attributes &attrib, const std::string &key)
Definition xml.h:44
std::function< ErrorType > error
handler invoked when the parser encounters an error
Definition xml.h:42
virtual int lineNr() const =0
virtual std::string fileName() const =0
void parse(const char *fileName, const char *inputString, bool debugEnabled, std::function< void()> debugStart, std::function< void()> debugEnd, std::function< Transcode > transcoder=[](std::string &s, const char *){ return true;})
Definition xml.l:447
Class representing a regular expression.
Definition regex.h:39
Object representing the matching results.
Definition regex.h:154
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1335
DString parseCommentAsText(const Definition *scope, const MemberDef *md, const DString &doc, const DString &fileName, int lineNr)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:59
DString parseCommentAsHtml(const Definition *scope, const MemberDef *member, const DString &doc, const DString &fileName, int lineNr)
IDocNodeASTPtr createRef(IDocParser &parserIntf, const DString &target, const DString &context, const DString &srcFile, int srcLine)
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485
const char * qPrint(const char *s)
Definition dstring.h:783
Translator * theTranslator
Definition language.cpp:76
static void mergeNavTreeNodesRec(LayoutNavEntry *targetTree, LayoutNavEntry *sourceTree)
Definition layout.cpp:1569
static void mergeDocEntryLists(const DString &fileName, LayoutDocEntryList &targetList, LayoutDocEntryList &sourceList)
Definition layout.cpp:1652
static bool elemIsVisible(const XMLHandlers::Attributes &attrib, bool defVal=true)
Definition layout.cpp:81
DString extractLanguageSpecificTitle(const DString &input, SrcLangExt lang)
Definition layout.cpp:1770
static LayoutNavEntry * findNavEntryRec(LayoutNavEntry *root, const std::string &id)
Definition layout.cpp:1554
DString compileOptions(const DString &def)
Definition layout.cpp:37
void writeDefaultLayoutFile(const DString &fileName)
Definition layout.cpp:1746
void printLayout()
Definition layout.cpp:1834
static void printNavLayout(LayoutNavEntry *root, int indent)
Definition layout.cpp:1819
std::unique_ptr< LayoutDocEntry > LayoutDocEntryPtr
Definition layout.h:146
std::vector< LayoutDocEntryPtr > LayoutDocEntryList
Definition layout.h:147
#define msg(fmt,...)
Definition message.h:94
#define err(fmt,...)
Definition message.h:127
#define ASSERT(x)
Definition message.h:142
#define warn_layout(file, line, fmt,...)
Definition message.h:117
static auto startCb(void(LayoutParser::*fn)(Args...))
Definition layout.cpp:743
static const std::map< std::string, ElementCallbacks > g_elementHandlers
Definition layout.cpp:801
static auto endCb(void(LayoutParser::*fn)(Args...))
Definition layout.cpp:795
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:861
Definition dstring.h:913
Kind
Definition layout.h:66
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:111
DString m_title
Definition layout.h:124
DString subtitle(SrcLangExt lang) const
Definition layout.cpp:1805
DString m_subscript
Definition layout.h:125
DString title(SrcLangExt lang) const
Definition layout.cpp:1800
Represents of a member definition list with configurable title.
Definition layout.h:131
DString m_title
Definition layout.h:142
DString title(SrcLangExt lang) const
Definition layout.cpp:1812
DString title(SrcLangExt lang) const
Definition layout.cpp:1793
DString m_title
Definition layout.h:106
Represents of a piece of a documentation page without configurable parts.
Definition layout.h:88
bool visible() const override
Definition layout.h:92
Base class for the layout of a navigation item at the top of the HTML pages.
Definition layout.h:155
bool m_visible
Definition layout.h:247
LayoutNavEntryList m_children
Definition layout.h:251
const LayoutNavEntryList & children() const
Definition layout.h:219
LayoutNavEntry * find(LayoutNavEntry::Kind k, const DString &file=DString()) const
Definition layout.cpp:135
DString titleAsHtml() const
Definition layout.cpp:199
DString m_title
Definition layout.h:249
std::string id() const
Definition layout.h:214
void updateVisibility(LayoutNavEntry *parent)
Definition layout.cpp:118
void appendChild(std::unique_ptr< LayoutNavEntry > &&e)
Definition layout.cpp:123
void insertChild(size_t pos, std::unique_ptr< LayoutNavEntry > &&e)
Definition layout.cpp:129
LayoutNavEntry * parent() const
Definition layout.h:211
DString title() const
Definition layout.cpp:194
DString url() const
Definition layout.cpp:153
DString baseFile() const
Definition layout.h:213
Kind kind() const
Definition layout.h:212
bool visible() const
Definition layout.h:222
LayoutNavEntry(LayoutNavEntry *parent, Kind k, bool vs, const DString &bf, const DString &tl, const DString &intro)
Definition layout.h:208
Kind
Definition layout.h:192
std::string navToString() const
Definition layout.h:197
std::function< void(LayoutParser &, const std::string &)> EndCallback
Definition layout.cpp:736
std::function< void(LayoutParser &, const std::string &, const XMLHandlers::Attributes &)> StartCallback
Definition layout.cpp:735
This file contains a number of basic enums and types.
SrcLangExt
Definition types.h:207
bool transcodeCharacterStringToUTF8(std::string &input, const char *inputEncoding)
Recodes the input string from the given input encoding to UTF8.
Definition utf8.cpp:244
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3932
DString fileToString(const DString &name, bool filter, bool isSourceCode)
Definition util.cpp:1053
DString externalRef(const DString &relPath, const DString &ref)
Definition util.cpp:4539
bool openOutputFile(const DString &outFile, std::ofstream &f)
Definition util.cpp:4987
A bunch of utility functions.