Doxygen
Loading...
Searching...
No Matches
layout.cpp File Reference
#include "layout.h"
#include <array>
#include "config.h"
#include "debug.h"
#include "docnode.h"
#include "docparser.h"
#include "language.h"
#include "message.h"
#include "regex.h"
#include "resourcemgr.h"
#include "textstream.h"
#include "types.h"
#include "util.h"
#include "version.h"
#include "xml.h"
Include dependency graph for layout.cpp:

Go to the source code of this file.

Classes

class  LayoutParser
struct  anonymous_namespace{layout.cpp}::ElementCallbacks
class  LayoutDocManager::Private

Namespaces

namespace  anonymous_namespace{layout.cpp}

Functions

DString compileOptions (const DString &def)
DString compileOptions (const DString &def, SrcLangExt langId1, const DString &value1)
DString compileOptions (const DString &def, SrcLangExt langId1, const DString &value1, SrcLangExt langId2, const DString &value2)
DString compileOptions (const DString &def, SrcLangExt langId1, const DString &value1, SrcLangExt langId2, const DString &value2, SrcLangExt langId3, const DString &value3)
DString compileOptions (const DString &def, SrcLangExt langId1, const DString &value1, SrcLangExt langId2, const DString &value2, SrcLangExt langId3, const DString &value3, SrcLangExt langId4, const DString &value4)
DString compileOptions (const DString &def, SrcLangExt langId1, const DString &value1, SrcLangExt langId2, const DString &value2, SrcLangExt langId3, const DString &value3, SrcLangExt langId4, const DString &value4, SrcLangExt langId5, const DString &value5)
static bool elemIsVisible (const XMLHandlers::Attributes &attrib, bool defVal=true)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...))
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), LayoutDocEntry::Kind kind)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), LayoutDocEntry::Kind kind, const std::function< DString()> &title)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), MemberListType type, const std::function< DString()> &title)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), MemberListType type, const std::function< DString()> &title, const std::function< DString()> &subtitle)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), LayoutDocManager::LayoutPart part, const DString &scope, LayoutNavEntry::Kind nav)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::endCb (void(LayoutParser::*fn)(Args...))
static LayoutNavEntry * findNavEntryRec (LayoutNavEntry *root, const std::string &id)
static void mergeNavTreeNodesRec (LayoutNavEntry *targetTree, LayoutNavEntry *sourceTree)
static void mergeDocEntryLists (const DString &fileName, LayoutDocEntryList &targetList, LayoutDocEntryList &sourceList)
void writeDefaultLayoutFile (const DString &fileName)
DString extractLanguageSpecificTitle (const DString &input, SrcLangExt lang)
static void printNavLayout (LayoutNavEntry *root, int indent)
void printLayout ()

Variables

static const std::map< std::string, ElementCallbacks > anonymous_namespace{layout.cpp}::g_elementHandlers

Function Documentation

◆ compileOptions() [1/6]

DString compileOptions ( const DString & def)
inline

Definition at line 37 of file layout.cpp.

38{
39 return def;
40}

Referenced by compileOptions(), compileOptions(), compileOptions(), compileOptions(), and compileOptions().

◆ compileOptions() [2/6]

DString compileOptions ( const DString & def,
SrcLangExt langId1,
const DString & value1 )
inline

Definition at line 42 of file layout.cpp.

43{
44 return compileOptions(def)+"|"+DString().setNum(static_cast<long>(langId1))+"="+value1;
45}
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
DString compileOptions(const DString &def)
Definition layout.cpp:37

References compileOptions(), and DString::setNum().

◆ compileOptions() [3/6]

DString compileOptions ( const DString & def,
SrcLangExt langId1,
const DString & value1,
SrcLangExt langId2,
const DString & value2 )
inline

Definition at line 47 of file layout.cpp.

49{
50 return compileOptions(def,langId1,value1)+
51 "|"+DString().setNum(static_cast<long>(langId2))+"="+value2;
52}

References compileOptions(), and DString::setNum().

◆ compileOptions() [4/6]

DString compileOptions ( const DString & def,
SrcLangExt langId1,
const DString & value1,
SrcLangExt langId2,
const DString & value2,
SrcLangExt langId3,
const DString & value3 )
inline

Definition at line 54 of file layout.cpp.

57{
58 return compileOptions(def,langId1,value1,langId2,value2)+
59 "|"+DString().setNum(static_cast<long>(langId3))+"="+value3;
60}

References compileOptions(), and DString::setNum().

◆ compileOptions() [5/6]

DString compileOptions ( const DString & def,
SrcLangExt langId1,
const DString & value1,
SrcLangExt langId2,
const DString & value2,
SrcLangExt langId3,
const DString & value3,
SrcLangExt langId4,
const DString & value4 )
inline

Definition at line 62 of file layout.cpp.

66{
67 return compileOptions(def,langId1,value1,langId2,value2,langId3,value3)+
68 "|"+DString().setNum(static_cast<long>(langId4))+"="+value4;
69}

References compileOptions(), and DString::setNum().

◆ compileOptions() [6/6]

DString compileOptions ( const DString & def,
SrcLangExt langId1,
const DString & value1,
SrcLangExt langId2,
const DString & value2,
SrcLangExt langId3,
const DString & value3,
SrcLangExt langId4,
const DString & value4,
SrcLangExt langId5,
const DString & value5 )
inline

Definition at line 71 of file layout.cpp.

76{
77 return compileOptions(def,langId1,value1,langId2,value2,langId3,value3,langId4,value4)+
78 "|"+DString().setNum(static_cast<long>(langId5))+"="+value5;
79}

References compileOptions(), and DString::setNum().

◆ elemIsVisible()

bool elemIsVisible ( const XMLHandlers::Attributes & attrib,
bool defVal = true )
static

Definition at line 81 of file layout.cpp.

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}
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
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
static std::string value(const Attributes &attrib, const std::string &key)
Definition xml.h:44
#define err(fmt,...)
Definition message.h:127

References DString::at(), DString::empty(), err, DString::length(), DString::lower(), DString::mid(), and XMLHandlers::value().

Referenced by LayoutParser::startMemberDecl(), LayoutParser::startMemberDeclEntry(), LayoutParser::startMemberDef(), LayoutParser::startMemberDefEntry(), LayoutParser::startNavEntry(), LayoutParser::startSectionEntry(), LayoutParser::startSimpleEntry(), and LayoutParser::startTop().

◆ extractLanguageSpecificTitle()

DString extractLanguageSpecificTitle ( const DString & input,
SrcLangExt lang )

Definition at line 1760 of file layout.cpp.

1761{
1762 size_t s=0,e=input.find('|');
1763 if (e==DString::npos) return input; // simple title case
1764 size_t e1=e;
1765 while (e!=DString::npos) // look for 'number=title' pattern separated by '|'
1766 {
1767 s=e+1;
1768 e=input.find('|',s);
1769 size_t i=input.find('=',s);
1770 ASSERT(i!=DString::npos && i>s);
1771 SrcLangExt key= static_cast<SrcLangExt>(input.mid(s,i-s).toUInt());
1772 if (key==lang) // found matching key
1773 {
1774 if (e==DString::npos) e=input.length();
1775 return input.mid(i+1,e-i-1);
1776 }
1777 }
1778 return input.left(e1); // fallback, no explicit language key found
1779}
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
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
DString left(size_t len) const
Definition dstring.h:306
#define ASSERT(x)
Definition message.h:142
SrcLangExt
Definition types.h:207

References ASSERT, DString::find(), DString::left(), DString::length(), DString::mid(), and DString::npos.

Referenced by LayoutDocEntryMemberDecl::subtitle(), LayoutDocEntryMemberDecl::title(), LayoutDocEntryMemberDef::title(), and LayoutDocEntrySection::title().

◆ findNavEntryRec()

LayoutNavEntry * findNavEntryRec ( LayoutNavEntry * root,
const std::string & id )
static

Definition at line 1544 of file layout.cpp.

1545{
1546 if (root)
1547 {
1548 if (root->id()==id) return root;
1549 for (auto &child : root->children())
1550 {
1551 LayoutNavEntry *childNavEntry = findNavEntryRec(child.get(),id);
1552 if (childNavEntry) return childNavEntry;
1553 }
1554 }
1555 return nullptr;
1556}
static LayoutNavEntry * findNavEntryRec(LayoutNavEntry *root, const std::string &id)
Definition layout.cpp:1544
Base class for the layout of a navigation item at the top of the HTML pages.
Definition layout.h:155
const LayoutNavEntryList & children() const
Definition layout.h:218
std::string id() const
Definition layout.h:214

References LayoutNavEntry::children(), findNavEntryRec(), and LayoutNavEntry::id().

Referenced by findNavEntryRec(), and mergeNavTreeNodesRec().

◆ mergeDocEntryLists()

void mergeDocEntryLists ( const DString & fileName,
LayoutDocEntryList & targetList,
LayoutDocEntryList & sourceList )
static

Definition at line 1642 of file layout.cpp.

1643{
1644 using IdSet = std::unordered_set<std::string>;
1645 using IdMap = std::unordered_map<std::string,size_t>;
1646
1647 auto prepareSet = [](const LayoutDocEntryList &list, IdSet &set) {
1648 //size_t idx=0;
1649 for (const auto &e : list)
1650 {
1651 //printf("idx=%zu set(%s)\n",idx,qPrint(e->id()));
1652 set.insert(e->id());
1653 //idx++;
1654 }
1655 };
1656
1657 auto prepareMap = [](const LayoutDocEntryList &list, const IdSet &set, IdMap &map) {
1658 for (size_t i=0; i<list.size(); i++)
1659 {
1660 std::string id = list[i]->id();
1661 auto it = set.find(id);
1662 if (it != set.end())
1663 {
1664 //printf("map %s->%zu\n",qPrint(id),i);
1665 map[id]=i;
1666 }
1667 }
1668 };
1669
1670 IdSet sourceSet, targetSet;
1671 //printf("---- sourceSet\n");
1672 prepareSet(sourceList,sourceSet);
1673 //printf("---- targetSet\n");
1674 prepareSet(targetList,targetSet);
1675
1676 IdMap sourceMap, targetMap;
1677 //printf("---- targetMap\n");
1678 prepareMap(targetList,sourceSet,targetMap);
1679 //printf("---- sourceMap\n");
1680 prepareMap(sourceList,targetSet,sourceMap);
1681
1682 // calculate list of insertion positions in the target list for each id in the source list
1683 std::vector<size_t> insertionList;
1684 for (size_t i=0; i<sourceList.size(); i++)
1685 {
1686 std::string id = sourceList[i]->id();
1687 // If an id in the source list appears before a set of shared ids we want it also to
1688 // appear before these id in the target list. To do this find the lowest target index of all shared
1689 // ids that come after position i in the source list
1690 size_t minIdx = targetList.size();
1691 for (const auto &kv : sourceMap) // iterator over shared ids
1692 {
1693 if (i < kv.second) // i appears before this shared id
1694 {
1695 size_t idx = targetMap[kv.first]; // get the corresponding index in the target list
1696 //printf(" evaluating %s->%zu min=%zu\n",qPrint(kv.first),idx,minIdx);
1697 if (idx<minIdx) // update minimum
1698 {
1699 minIdx=idx;
1700 }
1701 }
1702 }
1703 //printf("insertion %s->%zu\n",qPrint(id),minIdx);
1704 insertionList.push_back(minIdx);
1705 }
1706
1707 // Insert the missing elements of the source list into the target list.
1708 // Work backwards so the calculated insertion points don't change due to insertions.
1709 size_t idx = sourceList.size()-1;
1710 for (auto it=insertionList.rbegin(); it!=insertionList.rend(); ++it, idx--)
1711 {
1712 std::string id = sourceList[idx]->id();
1713 //printf("idx=%zu entry %s\n",idx,qPrint(id));
1714 if (targetSet.find(id)==targetSet.end()) // need to add id
1715 {
1716 // for efficiency we move the elements from the source list to the target list, thus modifying the source list!
1717 //printf("--> insert at %zu before %s\n",*it,qPrint(*it<targetList.size()?targetList[*it]->id():"none"));
1718 warn_layout(fileName,1,"User defined layout misses entry '{}'. Using default value.",id);
1719 targetList.insert(targetList.begin()+*it, std::move(sourceList[idx]));
1720 }
1721 }
1722
1723}
std::vector< LayoutDocEntryPtr > LayoutDocEntryList
Definition layout.h:147
#define warn_layout(file, line, fmt,...)
Definition message.h:117

References warn_layout.

Referenced by LayoutDocManager::mergeDocEntries().

◆ mergeNavTreeNodesRec()

void mergeNavTreeNodesRec ( LayoutNavEntry * targetTree,
LayoutNavEntry * sourceTree )
static

Definition at line 1559 of file layout.cpp.

1560{
1561 using IdSet = std::unordered_set<std::string>;
1562 using IdMap = std::unordered_map<std::string,size_t>;
1563
1564 auto prepareSet = [](const LayoutNavEntry *tree, IdSet &set) {
1565 for (const auto &e : tree->children())
1566 {
1567 set.insert(e->id());
1568 }
1569 };
1570
1571 auto prepareMap = [](const LayoutNavEntry *tree, const IdSet &set, IdMap &map) {
1572 for (size_t i=0; i<tree->children().size(); i++)
1573 {
1574 std::string id = tree->children()[i]->id();
1575 auto it = set.find(id);
1576 if (it != set.end())
1577 {
1578 map[id]=i;
1579 }
1580 }
1581 };
1582
1583 IdSet sourceSet, targetSet;
1584 prepareSet(sourceTree,sourceSet);
1585 prepareSet(targetTree,targetSet);
1586
1587 IdMap sourceMap, targetMap;
1588 prepareMap(targetTree,sourceSet,targetMap);
1589 prepareMap(sourceTree,targetSet,sourceMap);
1590
1591 // calculate list of insertion positions in the target list for each id in the source list
1592 std::vector<size_t> insertionList;
1593 for (size_t i=0; i<sourceTree->children().size(); i++)
1594 {
1595 std::string id = sourceTree->children()[i]->id();
1596 // If an id in the source list appears before a set of shared ids we want it also to
1597 // appear before these id in the target list. To do this find the lowest target index of all shared
1598 // ids that come after position i in the source list
1599 size_t minIdx = targetTree->children().size();
1600 for (const auto &kv : sourceMap) // iterator over shared ids
1601 {
1602 if (i < kv.second) // i appears before this shared id
1603 {
1604 size_t idx = targetMap[kv.first]; // get the corresponding index in the target list
1605 if (idx<minIdx) // update minimum
1606 {
1607 minIdx=idx;
1608 }
1609 }
1610 }
1611 insertionList.push_back(minIdx);
1612 }
1613
1614 // Insert the missing elements of the source list into the target list.
1615 // Work backwards so the calculated insertion points don't change due to insertions.
1616 size_t idx = sourceTree->children().size()-1;
1617 for (auto it=insertionList.rbegin(); it!=insertionList.rend(); ++it, idx--)
1618 {
1619 std::string id = sourceTree->children()[idx]->id();
1620 if (targetSet.find(id)==targetSet.end()) // need to add id
1621 {
1622 // for efficiency we move the elements from the source list to the target list, thus modifying the source list!
1623 targetTree->insertChild(*it, std::move(sourceTree->children()[idx]));
1624 }
1625 }
1626
1627 for (auto &targetChild : targetTree->children())
1628 {
1629 auto *node = findNavEntryRec(sourceTree,targetChild->id());
1630 if (node)
1631 {
1632 mergeNavTreeNodesRec(targetChild.get(),node);
1633 }
1634 }
1635}
static void mergeNavTreeNodesRec(LayoutNavEntry *targetTree, LayoutNavEntry *sourceTree)
Definition layout.cpp:1559
void insertChild(size_t pos, std::unique_ptr< LayoutNavEntry > &&e)
Definition layout.cpp:129

References LayoutNavEntry::children(), findNavEntryRec(), LayoutNavEntry::id(), LayoutNavEntry::insertChild(), and mergeNavTreeNodesRec().

Referenced by LayoutDocManager::mergeNavEntries(), and mergeNavTreeNodesRec().

◆ printLayout()

void printLayout ( )

Definition at line 1824 of file layout.cpp.

1825{
1826 bool extraIndent = false;
1827
1828 auto &mgr = LayoutDocManager::instance();
1829 Debug::print(Debug::Layout,0,"Layout version {}.{}\n",mgr.majorVersion(),mgr.minorVersion());
1830
1831 Debug::print(Debug::Layout,0,"Part: Navigation index\n");
1832 for (const auto &e : mgr.rootNavEntry()->children())
1833 {
1834 printNavLayout(e.get(),2);
1835 }
1836
1837 for (int i = 0; i < LayoutDocManager::NrParts; i++)
1838 {
1840 for (const auto &lde : mgr.docEntries(static_cast<LayoutDocManager::LayoutPart>(i)))
1841 {
1842 if (const LayoutDocEntrySimple *ldes = dynamic_cast<const LayoutDocEntrySimple*>(lde.get()))
1843 {
1844 if (lde->kind() == LayoutDocEntry::MemberDeclEnd || lde->kind() == LayoutDocEntry::MemberDefEnd) extraIndent = false;
1845 Debug::print(Debug::Layout,0," {}kind: {}, visible={}\n",
1846 extraIndent? " " : "",lde->entryToString(), ldes->visible());
1847 if (lde->kind() == LayoutDocEntry::MemberDeclStart || lde->kind() == LayoutDocEntry::MemberDefStart) extraIndent = true;
1848 }
1849 else if (const LayoutDocEntryMemberDecl *lmdecl = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()))
1850 {
1851 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1852 extraIndent? " " : "",lde->entryToString(),lmdecl->visible(),lmdecl->type.to_string());
1853 }
1854 else if (const LayoutDocEntryMemberDef *lmdef = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()))
1855 {
1856 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1857 extraIndent? " " : "",lde->entryToString(),lmdef->visible(),lmdef->type.to_string());
1858 }
1859 else
1860 {
1861 // should not happen
1862 Debug::print(Debug::Layout,0," {}not handled kind: {}\n",extraIndent? " " : "",lde->entryToString());
1863 }
1864 }
1865 }
1866}
@ Layout
Definition debug.h:51
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:78
static std::string partToString(int k)
Definition layout.h:271
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1439
static void printNavLayout(LayoutNavEntry *root, int indent)
Definition layout.cpp:1809
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:111
Represents of a member definition list with configurable title.
Definition layout.h:131
Represents of a piece of a documentation page without configurable parts.
Definition layout.h:88

References LayoutDocManager::instance(), Debug::Layout, LayoutDocManager::partToString(), Debug::print(), and printNavLayout().

Referenced by LayoutDocManager::LayoutParser, and parseInput().

◆ printNavLayout()

void printNavLayout ( LayoutNavEntry * root,
int indent )
static

Definition at line 1809 of file layout.cpp.

1810{
1812 {
1813 DString indentStr;
1814 indentStr.fill(' ',indent);
1815 Debug::print(Debug::Layout,0,"{}kind={} visible={} title='{}'\n",
1816 indentStr, root->navToString(), root->visible(), root->title());
1817 for (const auto &e : root->children())
1818 {
1819 printNavLayout(e.get(),indent+2);
1820 }
1821 }
1822}
DString fill(char c, size_t len)
Fills a string with a predefined character.
Definition dstring.h:278
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
DString title() const
Definition layout.h:215
bool visible() const
Definition layout.h:221
std::string navToString() const
Definition layout.h:197

References LayoutNavEntry::children(), DString::fill(), Debug::isFlagSet(), Debug::Layout, LayoutNavEntry::navToString(), Debug::print(), printNavLayout(), LayoutNavEntry::title(), and LayoutNavEntry::visible().

Referenced by printLayout(), and printNavLayout().

◆ writeDefaultLayoutFile()

void writeDefaultLayoutFile ( const DString & fileName)

Definition at line 1736 of file layout.cpp.

1737{
1738 std::ofstream f;
1739 if (openOutputFile(fileName,f))
1740 {
1741 TextStream t(&f);
1742 DString layout_default = ResourceMgr::instance().getAsString("layout_default.xml");
1743 t << substitute(layout_default,"$doxygenversion",getDoxygenVersion());
1744 }
1745 else
1746 {
1747 err("Failed to open file {} for writing!\n",fileName);
1748 return;
1749 }
1750 f.close();
1751}
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
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485
bool openOutputFile(const DString &outFile, std::ofstream &f)
Definition util.cpp:4987

References err, ResourceMgr::getAsString(), ResourceMgr::instance(), openOutputFile(), and substitute().

Referenced by LayoutDocManager::LayoutParser, and readConfiguration().