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:444
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()

static 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:153
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
QCString lower() const
Definition qcstring.h:234
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
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 1756 of file layout.cpp.

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

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

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

◆ findNavEntryRec()

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

Definition at line 1540 of file layout.cpp.

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

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

Definition at line 1638 of file layout.cpp.

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

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

Definition at line 1555 of file layout.cpp.

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

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

static void printNavLayout ( LayoutNavEntry * root,
int indent )
static

Definition at line 1805 of file layout.cpp.

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

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

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

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