summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/commands.doc16
-rw-r--r--src/commentscan.l42
-rw-r--r--src/definition.cpp30
-rw-r--r--src/definition.h13
-rw-r--r--src/doxygen.cpp4
-rw-r--r--src/entry.cpp8
-rw-r--r--src/entry.h1
-rw-r--r--src/index.cpp2
-rw-r--r--src/marshal.cpp8
-rw-r--r--src/pagedef.cpp15
-rw-r--r--src/pagedef.h5
-rw-r--r--src/xmlgen.cpp59
-rw-r--r--templates/xml/compound.xsd16
13 files changed, 183 insertions, 36 deletions
diff --git a/doc/commands.doc b/doc/commands.doc
index 67d8fe4..601de3e 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -2016,15 +2016,19 @@ Make sure you have first read \ref intro "the introduction".
\endverbatim
<hr>
-\section cmdtableofcontents \\tableofcontents['{'[option][,option]*'}']
+\section cmdtableofcontents \\tableofcontents['{'[option[:level]][,option[:level]]*'}']
\addindex \\tableofcontents
Creates a table of contents at the top of a page, listing all
- sections and subsections in the page. The option can be `HTML` or `LaTeX`.
- In case no option is specified \c \\tableofcontents acts as if just the
- option `HTML` was specified. In case of multiple \c \\tableofcontents
- commands in a page the option(s) will be used additional to the already
- specified option(s).
+ sections and subsections in the page. The `option` can be `HTML` or `LaTeX`
+ or `XML`. When a `level` is specified this means the maximum nesting level
+ that is shown. The value of `level` should be in the range 1..5, values outside
+ this range are considered to be 5. In case no `level` is specified `level` is
+ set to 5 (show all)
+ In case no `option. is specified \c \\tableofcontents acts as if just the
+ `option` `HTML` was specified. In case of multiple \c \\tableofcontents
+ commands in a page the `option`(s) will be used additional to the already
+ specified `option`(s), but only the last `level` of an `option` is valid.
\warning This command only works inside related page documentation and
\e not in other documentation blocks and only has effect in the
diff --git a/src/commentscan.l b/src/commentscan.l
index 0db1bf8..2e4750c 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -1094,7 +1094,7 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
);
inInternalDocs = FALSE;
}
-<Comment>{B}*{CMD}[a-z_A-Z]+"{"[a-zA-Z_,\. ]*"}"{B}* |
+<Comment>{B}*{CMD}[a-z_A-Z]+"{"[a-zA-Z_,:0-9\. ]*"}"{B}* |
<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
// the {B}* in the front was added for bug620924
QCString fullMatch = QCString(yytext);
@@ -2858,14 +2858,48 @@ static bool handleToc(const QCString &, const QCString &opt)
for ( it = optList.begin(); it != optList.end(); ++it )
{
QString opt = (*it).stripWhiteSpace().lower();
+ char dum;
+ int level = 5;
+ int i = opt.find(':');
+ if (i>0) // found ':' but not on position 0 what would mean just a level
+ {
+ if (sscanf(opt.right(opt.length() - i - 1).data(),"%d%c",&level,&dum) != 1)
+ {
+ warn(yyFileName,yyLineNr,"Unknown option:level specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data());
+ opt = "";
+ }
+ else
+ {
+ level = (level > 5 ? 5 : level);
+ level = (level <= 0 ? 5 : level);
+ opt = opt.left(i).stripWhiteSpace();
+ }
+ }
if (!opt.isEmpty())
{
- if (opt == "html") current->localToc |= Definition::Html;
- else if (opt == "latex") current->localToc |= Definition::Latex;
+ if (opt == "html")
+ {
+ current->localToc |= (1 << Definition::Html);
+ current->localTocLevel[Definition::Html] = level;
+ }
+ else if (opt == "latex")
+ {
+ current->localToc |= (1 << Definition::Latex);
+ current->localTocLevel[Definition::Latex] = level;
+ }
+ else if (opt == "xml")
+ {
+ current->localToc |= (1 << Definition::Xml);
+ current->localTocLevel[Definition::Xml] = level;
+ }
else warn(yyFileName,yyLineNr,"Unknown option specified with \\tableofcontents: `%s'", (*it).stripWhiteSpace().data());
}
}
- if (current->localToc == Definition::None) current->localToc |= Definition::Html;
+ if (current->localToc == Definition::None)
+ {
+ current->localToc |= (1 << Definition::Html);
+ current->localTocLevel[Definition::Html] = 5;
+ }
}
return FALSE;
}
diff --git a/src/definition.cpp b/src/definition.cpp
index 2f40e56..f44c403 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -41,6 +41,7 @@
#include "namespacedef.h"
#include "filedef.h"
#include "dirdef.h"
+#include "pagedef.h"
#define START_MARKER 0x4445465B // DEF[
#define END_MARKER 0x4445465D // DEF]
@@ -1613,12 +1614,13 @@ void Definition::writeNavigationPath(OutputList &ol) const
}
// TODO: move to htmlgen
-void Definition::writeToc(OutputList &ol, int localToc)
+void Definition::writeToc(OutputList &ol, int localToc, int *localTocLevel)
{
SectionDict *sectionDict = m_impl->sectionDict;
if (sectionDict==0) return;
- if (localToc & Definition::Html)
+ if (PageDef::isLocalToc(localToc, Definition::Html))
{
+ int maxLevel = localTocLevel[Definition::Html];
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
ol.writeString("<div class=\"toc\">");
@@ -1645,44 +1647,48 @@ void Definition::writeToc(OutputList &ol, int localToc)
{
for (l=level;l<nextLevel;l++)
{
- ol.writeString("<ul>");
+ if (l < maxLevel) ol.writeString("<ul>");
}
}
else if (nextLevel<level)
{
for (l=level;l>nextLevel;l--)
{
- if (inLi[l]) ol.writeString("</li>\n");
+ if (l <= maxLevel && inLi[l]) ol.writeString("</li>\n");
inLi[l]=FALSE;
- ol.writeString("</ul>\n");
+ if (l <= maxLevel) ol.writeString("</ul>\n");
}
}
cs[0]='0'+nextLevel;
- if (inLi[nextLevel]) ol.writeString("</li>\n");
+ if (nextLevel <= maxLevel && inLi[nextLevel]) ol.writeString("</li>\n");
QCString titleDoc = convertToHtml(si->title);
- ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>");
+ if (nextLevel <= maxLevel) ol.writeString("<li class=\"level"+QCString(cs)+"\"><a href=\"#"+si->label+"\">"+(si->title.isEmpty()?si->label:titleDoc)+"</a>");
inLi[nextLevel]=TRUE;
level = nextLevel;
}
}
- while (level>1)
+ while (level>1 && level <= maxLevel)
{
if (inLi[level]) ol.writeString("</li>\n");
inLi[level]=FALSE;
ol.writeString("</ul>\n");
level--;
}
- if (inLi[level]) ol.writeString("</li>\n");
+ if (level <= maxLevel && inLi[level]) ol.writeString("</li>\n");
inLi[level]=FALSE;
ol.writeString("</ul>\n");
ol.writeString("</div>\n");
ol.popGeneratorState();
}
- if (localToc & Definition::Latex)
+ if (PageDef::isLocalToc(localToc, Definition::Latex))
{
+ char tmp[100];
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Latex);
+ sprintf(tmp,"\\etocsetnexttocdepth{%d}\n",localTocLevel[Definition::Latex]);
+ ol.writeString(tmp);
+
ol.writeString("\\localtableofcontents\n");
ol.popGeneratorState();
}
@@ -1690,6 +1696,10 @@ void Definition::writeToc(OutputList &ol, int localToc)
//----------------------------------------------------------------------------------------
+SectionDict * Definition::getSectionDict(void)
+{
+ return m_impl->sectionDict;
+}
QCString Definition::symbolName() const
{
diff --git a/src/definition.h b/src/definition.h
index a2b2983..c77474c 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -98,9 +98,11 @@ class Definition : public DefinitionIntf
};
enum outputLocalTocType {
- None = 0,
- Html = 0x01,
- Latex = 0x02
+ None = 0, // absolute value
+ Html = 0, // index / also to be used as (1 << Definition::Html)
+ Latex = 1, // ...
+ Xml = 2, // ...
+ numOutputLocalTocType = 3 // number of outputLocalTocType
};
/*! Create a new definition */
Definition(
@@ -280,6 +282,9 @@ class Definition : public DefinitionIntf
QCString id() const;
+ /** returns the section dictionary, only of importance for pagedef */
+ SectionDict * Definition::getSectionDict(void);
+
//-----------------------------------------------------------------------------------
// ---- setters -----
//-----------------------------------------------------------------------------------
@@ -351,7 +356,7 @@ class Definition : public DefinitionIntf
void setLocalName(const QCString name);
void addSectionsToIndex();
- void writeToc(OutputList &ol, int localToc);
+ void writeToc(OutputList &ol, int localToc, int *localTocLevel);
void setCookie(Cookie *cookie) { delete m_cookie; m_cookie = cookie; }
Cookie *cookie() const { return m_cookie; }
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index f0140e0..ecdcd43 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -605,7 +605,7 @@ static void addRelatedPage(EntryNav *rootNav)
{
pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
pd->addSectionsToDefinition(root->anchors);
- pd->setShowToc(root->localToc);
+ pd->setShowToc(root->localToc, root->localTocLevel);
addPageToContext(pd,rootNav);
}
}
@@ -8712,7 +8712,7 @@ static void findMainPage(EntryNav *rootNav)
//setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
Doxygen::mainPage->setFileName(indexName);
- Doxygen::mainPage->setShowToc(root->localToc);
+ Doxygen::mainPage->setShowToc(root->localToc, root->localTocLevel);
addPageToContext(Doxygen::mainPage,rootNav);
SectionInfo *si = Doxygen::sectionDict->find(Doxygen::mainPage->name());
diff --git a/src/entry.cpp b/src/entry.cpp
index 9ecaf70..e4fb0a5 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -74,6 +74,10 @@ Entry::Entry(const Entry &e)
initLines = e.initLines;
stat = e.stat;
localToc = e.localToc;
+ for (int i = 0; i < sizeof(localTocLevel) / sizeof(*localTocLevel) ; i++)
+ {
+ localTocLevel[i] = e.localTocLevel[i];
+ }
explicitExternal = e.explicitExternal;
proto = e.proto;
subGrouping = e.subGrouping;
@@ -255,6 +259,10 @@ void Entry::reset()
virt = Normal;
stat = FALSE;
localToc = Definition::None;
+ for (int i = 0; i < sizeof(localTocLevel) / sizeof(*localTocLevel) ; i++)
+ {
+ localTocLevel[i] = 0;
+ }
proto = FALSE;
explicitExternal = FALSE;
spec = 0;
diff --git a/src/entry.h b/src/entry.h
index c1f8f19..8513fb9 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -289,6 +289,7 @@ class Entry
GroupDocType groupDocType;
QCString id; //!< libclang id
int localToc; //!< types of local TOC, command \tableofcontents
+ int localTocLevel[3];//!< depth of local TOC, command \tableofcontents
static int num; //!< counts the total number of entries
diff --git a/src/index.cpp b/src/index.cpp
index e9f5437..d9ef4e9 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -3885,7 +3885,7 @@ static void writeIndex(OutputList &ol)
Doxygen::insideMainPage=TRUE;
if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
{
- Doxygen::mainPage->writeToc(ol,Doxygen::mainPage->showToc());
+ Doxygen::mainPage->writeToc(ol,Doxygen::mainPage->showToc(),Doxygen::mainPage->showTocLevel());
}
ol.startTextBlock();
diff --git a/src/marshal.cpp b/src/marshal.cpp
index 282cb2a..43c5511 100644
--- a/src/marshal.cpp
+++ b/src/marshal.cpp
@@ -356,6 +356,10 @@ void marshalEntry(StorageIntf *s,Entry *e)
marshalInt(s,e->initLines);
marshalBool(s,e->stat);
marshalInt(s,e->localToc);
+ for (int i = 0; i < sizeof(e->localTocLevel) / sizeof(*(e->localTocLevel)) ; i++)
+ {
+ marshalInt(s,e->localTocLevel[i]);
+ }
marshalBool(s,e->explicitExternal);
marshalBool(s,e->proto);
marshalBool(s,e->subGrouping);
@@ -739,6 +743,10 @@ Entry * unmarshalEntry(StorageIntf *s)
e->initLines = unmarshalInt(s);
e->stat = unmarshalBool(s);
e->localToc = unmarshalInt(s);
+ for (int i = 0; i < sizeof(e->localTocLevel) / sizeof(*(e->localTocLevel)) ; i++)
+ {
+ e->localTocLevel[i] = unmarshalInt(s);
+ }
e->explicitExternal = unmarshalBool(s);
e->proto = unmarshalBool(s);
e->subGrouping = unmarshalBool(s);
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index c351a3f..df5cf0d 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -36,6 +36,10 @@ PageDef::PageDef(const char *f,int l,const char *n,
m_nestingLevel = 0;
m_fileName = ::convertNameToFile(n,FALSE,TRUE);
m_showToc = Definition::None;
+ for (int i = 0; i < sizeof(m_localTocLevel) / sizeof(*m_localTocLevel) ; i++)
+ {
+ m_localTocLevel[i] = 0;
+ }
}
PageDef::~PageDef()
@@ -209,7 +213,7 @@ void PageDef::writeDocumentation(OutputList &ol)
if (m_showToc && hasSections())
{
- writeToc(ol, m_showToc);
+ writeToc(ol, m_showToc, m_localTocLevel);
}
writePageDocumentation(ol);
@@ -326,8 +330,11 @@ void PageDef::setNestingLevel(int l)
m_nestingLevel = l;
}
-void PageDef::setShowToc(int b)
+void PageDef::setShowToc(int localToc, int *localTocLevel)
{
- m_showToc |= b;
+ m_showToc |= localToc;
+ for (int i = 0; i < sizeof(m_localTocLevel) / sizeof(*m_localTocLevel) ; i++)
+ {
+ m_localTocLevel[i] += localTocLevel[i];
+ }
}
-
diff --git a/src/pagedef.h b/src/pagedef.h
index 2f34c5f..7016049 100644
--- a/src/pagedef.h
+++ b/src/pagedef.h
@@ -34,7 +34,7 @@ class PageDef : public Definition
// setters
void setFileName(const char *name);
- void setShowToc(int b);
+ void setShowToc(int localToc, int *localTocLevel);
// getters
DefType definitionType() const { return TypePage; }
@@ -60,6 +60,8 @@ class PageDef : public Definition
bool hasSubPages() const;
bool hasParentPage() const;
int showToc() const { return m_showToc; }
+ int *showTocLevel() { return m_localTocLevel; }
+ static bool isLocalToc(int localToc, int tocType) { return(localToc & (1 << tocType)); }
void setPageScope(Definition *d){ m_pageScope = d; }
Definition *getPageScope() const { return m_pageScope; }
QCString displayName(bool=TRUE) const { return !m_title.isEmpty() ? m_title : Definition::name(); }
@@ -76,6 +78,7 @@ class PageDef : public Definition
Definition *m_pageScope;
int m_nestingLevel;
int m_showToc;
+ int m_localTocLevel[numOutputLocalTocType];
};
class PageSDict : public SDict<PageDef>
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 63fc8ad..02756d3 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -1838,9 +1838,62 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
}
}
writeInnerPages(pd->getSubPages(),t);
- if(pd->showToc())
- {
- t << " <tableofcontents/>" << endl;
+ if (PageDef::isLocalToc(pd->showToc(), Definition::Xml))
+ {
+ t << " <tableofcontents>" << endl;
+ SectionDict *sectionDict = pd->getSectionDict();
+ SDict<SectionInfo>::Iterator li(*sectionDict);
+ SectionInfo *si;
+ int level=1,l;
+ bool inLi[5]={ FALSE, FALSE, FALSE, FALSE };
+ int maxLevel = (pd -> showTocLevel())[Definition::Xml];
+ for (li.toFirst();(si=li.current());++li)
+ {
+ if (si->type==SectionInfo::Section ||
+ si->type==SectionInfo::Subsection ||
+ si->type==SectionInfo::Subsubsection ||
+ si->type==SectionInfo::Paragraph)
+ {
+ //printf(" level=%d title=%s\n",level,si->title.data());
+ int nextLevel = (int)si->type;
+ if (nextLevel>level)
+ {
+ for (l=level;l<nextLevel;l++)
+ {
+ if (l < maxLevel) t << " <tableofcontents>" << endl;
+ }
+ }
+ else if (nextLevel<level)
+ {
+ for (l=level;l>nextLevel;l--)
+ {
+ if (l <= maxLevel && inLi[l]) t << " </tocsect>" << endl;
+ inLi[l]=FALSE;
+ if (l <= maxLevel) t << " </tableofcontents>" << endl;
+ }
+ }
+ if (l <= maxLevel && inLi[nextLevel]) t << " </tocsect>" << endl;
+ if (nextLevel <= maxLevel)
+ {
+ QCString titleDoc = convertToXML(si->title);
+ t << " <tocsect>" << endl;
+ t << " <name>" << (si->title.isEmpty()?si->label:titleDoc) << "</name>" << endl;
+ t << " <reference>" << convertToXML(pageName) << "_1" << convertToXML(si -> label) << "</reference>" << endl;
+ }
+ inLi[nextLevel]=TRUE;
+ level = nextLevel;
+ }
+ }
+ while (level>1 && level <= maxLevel)
+ {
+ if (inLi[level]) t << " </tocsect>" << endl;
+ inLi[level]=FALSE;
+ t << " </tableofcontents>" << endl;
+ level--;
+ }
+ if (level <= maxLevel && inLi[level]) t << " </tocsect>" << endl;
+ inLi[level]=FALSE;
+ t << " </tableofcontents>" << endl;
}
t << " <briefdescription>" << endl;
writeXMLDocBlock(t,pd->briefFile(),pd->briefLine(),pd,0,pd->briefDescription());
diff --git a/templates/xml/compound.xsd b/templates/xml/compound.xsd
index b4356ac..72d9097 100644
--- a/templates/xml/compound.xsd
+++ b/templates/xml/compound.xsd
@@ -29,7 +29,7 @@
<xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
<xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
- <xsd:element name="tableofcontents" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="tableofcontents" type="tableofcontentsType" minOccurs="0" maxOccurs="1" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
<xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
@@ -879,5 +879,19 @@
</xsd:restriction>
</xsd:simpleType>
+ <xsd:complexType name="tableofcontentsType">
+ <xsd:sequence>
+ <xsd:element name="tocsect" type="tableofcontentsKindType" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="tableofcontentsKindType">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+ <xsd:element name="reference" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+ <xsd:element name="tableofcontents" type="tableofcontentsType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
</xsd:schema>