Doxygen
Loading...
Searching...
No Matches
layout.cpp File Reference
#include <array>
#include <assert.h>
#include "types.h"
#include "layout.h"
#include "message.h"
#include "language.h"
#include "util.h"
#include "doxygen.h"
#include "version.h"
#include "config.h"
#include "xml.h"
#include "resourcemgr.h"
#include "docparser.h"
#include "docnode.h"
#include "debug.h"
#include "regex.h"
#include "textstream.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 LayoutNavEntryfindNavEntryRec (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, ElementCallbacksanonymous_namespace{layout.cpp}::g_elementHandlers

Function Documentation

◆ compileOptions() [1/6]

DString compileOptions ( const DString & def)
inline

Definition at line 36 of file layout.cpp.

37{
38 return def;
39}

References compileOptions().

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

◆ compileOptions() [2/6]

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

Definition at line 41 of file layout.cpp.

42{
43 return compileOptions(def)+"|"+DString().setNum(static_cast<long>(langId1))+"="+value1;
44}
DString & setNum(short n)
Definition dstring.h:556
DString()=default
DString compileOptions(const DString &def)
Definition layout.cpp:36

References compileOptions(), DString::DString(), 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 46 of file layout.cpp.

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

References compileOptions(), DString::DString(), 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 53 of file layout.cpp.

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

References compileOptions(), DString::DString(), 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 61 of file layout.cpp.

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

References compileOptions(), DString::DString(), 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 70 of file layout.cpp.

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

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

◆ elemIsVisible()

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

Definition at line 80 of file layout.cpp.

81{
82 DString visible = XMLHandlers::value(attrib,"visible");
83 //printf("visible_attribute=%s\n",qPrint(visible));
84 if (visible.empty()) return defVal;
85 if (visible.at(0)=='$' && visible.length()>1)
86 {
87 DString id = visible.mid(1);
88 const ConfigValues::Info *opt = ConfigValues::instance().get(id);
89 if (opt && opt->type==ConfigValues::Info::Bool)
90 {
91 return ConfigValues::instance().*(opt->value.b);
92 }
93 else if (opt && opt->type==ConfigValues::Info::String)
94 {
95 return opt->getBooleanRepresentation();
96 }
97 else if (!opt)
98 {
99 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
100 visible,(defVal?"yes":"no"));
101 return defVal;
102 }
103 }
104 DString visibleLow = visible.lower();
105 if (visibleLow=="no" || visibleLow=="false" || visibleLow=="0") return false;
106 else if (visibleLow=="yes" || visibleLow=="true" || visibleLow=="1") return true;
107 else
108 {
109 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
110 visible,(defVal?"yes":"no"));
111 return defVal;
112 }
113}
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:88
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:322
DString lower() const
Definition dstring.h:330
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:152
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:690
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:155
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(), elemIsVisible(), DString::empty(), err, DString::length(), DString::lower(), DString::mid(), and XMLHandlers::value().

Referenced by elemIsVisible(), 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 1757 of file layout.cpp.

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

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

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

◆ findNavEntryRec()

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

Definition at line 1541 of file layout.cpp.

1542{
1543 if (root)
1544 {
1545 if (root->id()==id) return root;
1546 for (auto &child : root->children())
1547 {
1548 LayoutNavEntry *childNavEntry = findNavEntryRec(child.get(),id);
1549 if (childNavEntry) return childNavEntry;
1550 }
1551 }
1552 return nullptr;
1553}
static LayoutNavEntry * findNavEntryRec(LayoutNavEntry *root, const std::string &id)
Definition layout.cpp:1541
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 1639 of file layout.cpp.

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

References mergeDocEntryLists(), and warn_layout.

Referenced by LayoutDocManager::mergeDocEntries(), and mergeDocEntryLists().

◆ mergeNavTreeNodesRec()

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

Definition at line 1556 of file layout.cpp.

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

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

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

◆ printLayout()

void printLayout ( )

Definition at line 1821 of file layout.cpp.

1822{
1823 bool extraIndent = false;
1824
1825 auto &mgr = LayoutDocManager::instance();
1826 Debug::print(Debug::Layout,0,"Layout version {}.{}\n",mgr.majorVersion(),mgr.minorVersion());
1827
1828 Debug::print(Debug::Layout,0,"Part: Navigation index\n");
1829 for (const auto &e : mgr.rootNavEntry()->children())
1830 {
1831 printNavLayout(e.get(),2);
1832 }
1833
1834 for (int i = 0; i < LayoutDocManager::NrParts; i++)
1835 {
1837 for (const auto &lde : mgr.docEntries(static_cast<LayoutDocManager::LayoutPart>(i)))
1838 {
1839 if (const LayoutDocEntrySimple *ldes = dynamic_cast<const LayoutDocEntrySimple*>(lde.get()))
1840 {
1841 if (lde->kind() == LayoutDocEntry::MemberDeclEnd || lde->kind() == LayoutDocEntry::MemberDefEnd) extraIndent = false;
1842 Debug::print(Debug::Layout,0," {}kind: {}, visible={}\n",
1843 extraIndent? " " : "",lde->entryToString(), ldes->visible());
1844 if (lde->kind() == LayoutDocEntry::MemberDeclStart || lde->kind() == LayoutDocEntry::MemberDefStart) extraIndent = true;
1845 }
1846 else if (const LayoutDocEntryMemberDecl *lmdecl = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()))
1847 {
1848 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1849 extraIndent? " " : "",lde->entryToString(),lmdecl->visible(),lmdecl->type.to_string());
1850 }
1851 else if (const LayoutDocEntryMemberDef *lmdef = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()))
1852 {
1853 Debug::print(Debug::Layout,0," {}complex kind: {}, visible={}, type: {}\n",
1854 extraIndent? " " : "",lde->entryToString(),lmdef->visible(),lmdef->type.to_string());
1855 }
1856 else
1857 {
1858 // should not happen
1859 Debug::print(Debug::Layout,0," {}not handled kind: {}\n",extraIndent? " " : "",lde->entryToString());
1860 }
1861 }
1862 }
1863}
@ 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:1436
static void printNavLayout(LayoutNavEntry *root, int indent)
Definition layout.cpp:1806
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(), printLayout(), and printNavLayout().

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

◆ printNavLayout()

void printNavLayout ( LayoutNavEntry * root,
int indent )
static

Definition at line 1806 of file layout.cpp.

1807{
1809 {
1810 DString indentStr;
1811 indentStr.fill(' ',indent);
1812 Debug::print(Debug::Layout,0,"{}kind={} visible={} title='{}'\n",
1813 indentStr, root->navToString(), root->visible(), root->title());
1814 for (const auto &e : root->children())
1815 {
1816 printNavLayout(e.get(),indent+2);
1817 }
1818 }
1819}
DString fill(char c, size_t len)
Fills a string with a predefined character.
Definition dstring.h:282
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:133
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 1733 of file layout.cpp.

1734{
1735 std::ofstream f;
1736 if (openOutputFile(fileName,f))
1737 {
1738 TextStream t(&f);
1739 DString layout_default = ResourceMgr::instance().getAsString("layout_default.xml");
1740 t << substitute(layout_default,"$doxygenversion",getDoxygenVersion());
1741 }
1742 else
1743 {
1744 err("Failed to open file {} for writing!\n",fileName);
1745 return;
1746 }
1747 f.close();
1748}
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:481
bool openOutputFile(const DString &outFile, std::ofstream &f)
Definition util.cpp:4973

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

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