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 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

QCString compileOptions (const QCString &def)
QCString compileOptions (const QCString &def, SrcLangExt langId1, const QCString &value1)
QCString compileOptions (const QCString &def, SrcLangExt langId1, const QCString &value1, SrcLangExt langId2, const QCString &value2)
QCString compileOptions (const QCString &def, SrcLangExt langId1, const QCString &value1, SrcLangExt langId2, const QCString &value2, SrcLangExt langId3, const QCString &value3)
QCString compileOptions (const QCString &def, SrcLangExt langId1, const QCString &value1, SrcLangExt langId2, const QCString &value2, SrcLangExt langId3, const QCString &value3, SrcLangExt langId4, const QCString &value4)
QCString compileOptions (const QCString &def, SrcLangExt langId1, const QCString &value1, SrcLangExt langId2, const QCString &value2, SrcLangExt langId3, const QCString &value3, SrcLangExt langId4, const QCString &value4, SrcLangExt langId5, const QCString &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< QCString()> &title)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), MemberListType type, const std::function< QCString()> &title)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), MemberListType type, const std::function< QCString()> &title, const std::function< QCString()> &subtitle)
template<class... Args>
static auto anonymous_namespace{layout.cpp}::startCb (void(LayoutParser::*fn)(Args...), LayoutDocManager::LayoutPart part, const QCString &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 QCString &fileName, LayoutDocEntryList &targetList, LayoutDocEntryList &sourceList)
void writeDefaultLayoutFile (const QCString &fileName)
QCString extractLanguageSpecificTitle (const QCString &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]

QCString compileOptions ( const QCString & def)
inline

Definition at line 35 of file layout.cpp.

36{
37 return def;
38}

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

◆ compileOptions() [2/6]

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

Definition at line 40 of file layout.cpp.

41{
42 return compileOptions(def)+"|"+QCString().setNum(static_cast<long>(langId1))+"="+value1;
43}
This is an alternative implementation of QCString.
Definition qcstring.h:101
QCString & setNum(short n)
Definition qcstring.h:459
QCString compileOptions(const QCString &def)
Definition layout.cpp:35

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

◆ compileOptions() [3/6]

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

Definition at line 45 of file layout.cpp.

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

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

◆ compileOptions() [4/6]

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

Definition at line 52 of file layout.cpp.

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

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

◆ compileOptions() [5/6]

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

Definition at line 60 of file layout.cpp.

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

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

◆ compileOptions() [6/6]

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

Definition at line 69 of file layout.cpp.

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

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

◆ elemIsVisible()

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

Definition at line 79 of file layout.cpp.

80{
81 QCString visible = XMLHandlers::value(attrib,"visible");
82 //printf("visible_attribute=%s\n",qPrint(visible));
83 if (visible.isEmpty()) return defVal;
84 if (visible.at(0)=='$' && visible.length()>1)
85 {
86 QCString id = visible.mid(1);
87 const ConfigValues::Info *opt = ConfigValues::instance().get(id);
88 if (opt && opt->type==ConfigValues::Info::Bool)
89 {
90 return ConfigValues::instance().*(opt->value.b);
91 }
92 else if (opt && opt->type==ConfigValues::Info::String)
93 {
94 return opt->getBooleanRepresentation();
95 }
96 else if (!opt)
97 {
98 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
99 visible,(defVal?"yes":"no"));
100 return defVal;
101 }
102 }
103 QCString visibleLow = visible.lower();
104 if (visibleLow=="no" || visibleLow=="false" || visibleLow=="0") return FALSE;
105 else if (visibleLow=="yes" || visibleLow=="true" || visibleLow=="1") return TRUE;
106 else
107 {
108 err("found unsupported value '{}' for visible attribute in layout file, reverting to '{}'\n",
109 visible,(defVal?"yes":"no"));
110 return defVal;
111 }
112}
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
QCString lower() const
Definition qcstring.h:249
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
static std::string value(const Attributes &attrib, const std::string &key)
Definition xml.h:44
#define err(fmt,...)
Definition message.h:127
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34

References QCString::at(), err, FALSE, QCString::isEmpty(), QCString::length(), QCString::lower(), QCString::mid(), TRUE, and XMLHandlers::value().

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

◆ extractLanguageSpecificTitle()

QCString extractLanguageSpecificTitle ( const QCString & input,
SrcLangExt lang )

Definition at line 1758 of file layout.cpp.

1759{
1760 int s=0,e=input.find('|');
1761 if (e==-1) return input; // simple title case
1762 int e1=e;
1763 while (e!=-1) // look for 'number=title' pattern separated by '|'
1764 {
1765 s=e+1;
1766 e=input.find('|',s);
1767 int i=input.find('=',s);
1768 assert(i>s);
1769 SrcLangExt key= static_cast<SrcLangExt>(input.mid(s,i-s).toUInt());
1770 if (key==lang) // found matching key
1771 {
1772 if (e==-1) e=static_cast<int>(input.length());
1773 return input.mid(i+1,e-i-1);
1774 }
1775 }
1776 return input.left(e1); // fallback, no explicit language key found
1777}
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString left(size_t len) const
Definition qcstring.h:229
SrcLangExt
Definition types.h:207

References QCString::find(), QCString::left(), QCString::length(), and QCString::mid().

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

◆ findNavEntryRec()

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

Definition at line 1542 of file layout.cpp.

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

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

Referenced by findNavEntryRec(), and mergeNavTreeNodesRec().

◆ mergeDocEntryLists()

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

Definition at line 1640 of file layout.cpp.

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

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

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

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

◆ printLayout()

void printLayout ( )

Definition at line 1822 of file layout.cpp.

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

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 1807 of file layout.cpp.

1808{
1810 {
1811 QCString indentStr;
1812 indentStr.fill(' ',indent);
1813 Debug::print(Debug::Layout,0,"{}kind={} visible={} title='{}'\n",
1814 indentStr, root->navToString(), root->visible(), root->title());
1815 for (const auto &e : root->children())
1816 {
1817 printNavLayout(e.get(),indent+2);
1818 }
1819 }
1820}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:193
QCString title() const
Definition layout.h:216
bool visible() const
Definition layout.h:222
std::string navToString() const
Definition layout.h:198

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

Referenced by printLayout(), and printNavLayout().

◆ writeDefaultLayoutFile()

void writeDefaultLayoutFile ( const QCString & fileName)

Definition at line 1734 of file layout.cpp.

1735{
1736 std::ofstream f;
1737 if (openOutputFile(fileName,f))
1738 {
1739 TextStream t(&f);
1740 QCString layout_default = ResourceMgr::instance().getAsString("layout_default.xml");
1741 t << substitute(layout_default,"$doxygenversion",getDoxygenVersion());
1742 }
1743 else
1744 {
1745 err("Failed to open file {} for writing!\n",fileName);
1746 return;
1747 }
1748 f.close();
1749}
static ResourceMgr & instance()
Returns the one and only instance of this class.
QCString getAsString(const QCString &name) const
Gets the resource data as a C string.
Text streaming class that buffers data.
Definition textstream.h:36
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:482
bool openOutputFile(const QCString &outFile, std::ofstream &f)
Definition util.cpp:6226

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

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