Skip to content

Commit 219610a

Browse files
committed
Support for basic hierarchical grouping in LaTeX output
Partial fix for #842
1 parent 2ac024c commit 219610a

22 files changed

+168
-68
lines changed

src/docbookgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ void DocbookGenerator::cleanup()
368368
}
369369

370370

371-
void DocbookGenerator::startFile(const QCString &name,const QCString &,const QCString &,int)
371+
void DocbookGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int)
372372
{
373373
DB_GEN_C
374374
QCString fileName=name;

src/docbookgen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class DocbookGenerator : public OutputGenerator
112112
// structural output interface
113113
///////////////////////////////////////////////////////////////
114114
void startFile(const QCString &name,const QCString &manName,
115-
const QCString &title,int id);
115+
const QCString &title,int id,int hierarchyLevel);
116116
void writeSearchInfo(){DB_GEN_EMPTY};
117117
void writeFooter(const QCString &){DB_GEN_NEW};
118118
void endFile();

src/groupdef.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
7575
virtual void removeMember(MemberDef *md);
7676
virtual bool findGroup(const GroupDef *def) const; // true if def is a subgroup of this group
7777
virtual void writeDocumentation(OutputList &ol);
78-
virtual void writeMemberPages(OutputList &ol);
78+
virtual void writeMemberPages(OutputList &ol, int hierarchyLevel);
7979
virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const;
8080
virtual void writeTagFile(TextStream &);
8181
virtual size_t numDocMembers() const;
@@ -1104,7 +1104,20 @@ void GroupDefImpl::writeDocumentation(OutputList &ol)
11041104
{
11051105
//bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
11061106
ol.pushGeneratorState();
1107-
startFile(ol,getOutputFileBase(),name(),m_title,HighlightedItem::Modules);
1107+
1108+
/* Find out how deep this group is nested. In case of multiple parents, use
1109+
* the first one.
1110+
*/
1111+
int hierarchyLevel = 0;
1112+
auto gd = static_cast<GroupDef*>(this);
1113+
while (!gd->partOfGroups().empty())
1114+
{
1115+
gd = gd->partOfGroups().front();
1116+
++hierarchyLevel;
1117+
}
1118+
1119+
startFile(ol,getOutputFileBase(),name(),m_title,HighlightedItem::Modules,
1120+
FALSE /* additionalIndices*/, QCString() /*altSidebarName*/, hierarchyLevel);
11081121

11091122
ol.startHeaderSection();
11101123
writeSummaryLinks(ol);
@@ -1253,12 +1266,11 @@ void GroupDefImpl::writeDocumentation(OutputList &ol)
12531266
if (Config_getBool(SEPARATE_MEMBER_PAGES))
12541267
{
12551268
m_allMemberList.sort();
1256-
writeMemberPages(ol);
1269+
writeMemberPages(ol, hierarchyLevel + 1);
12571270
}
1258-
12591271
}
12601272

1261-
void GroupDefImpl::writeMemberPages(OutputList &ol)
1273+
void GroupDefImpl::writeMemberPages(OutputList &ol, int hierarchyLevel)
12621274
{
12631275
ol.pushGeneratorState();
12641276
ol.disableAllBut(OutputType::Html);
@@ -1267,7 +1279,7 @@ void GroupDefImpl::writeMemberPages(OutputList &ol)
12671279
{
12681280
if (ml->listType()&MemberListType_documentationLists)
12691281
{
1270-
ml->writeDocumentationPage(ol,name(),this);
1282+
ml->writeDocumentationPage(ol,name(),this,hierarchyLevel);
12711283
}
12721284
}
12731285

src/groupdef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class GroupDef : public DefinitionMutable, public Definition
6868
virtual void removeMember(MemberDef *md) = 0;
6969
virtual bool findGroup(const GroupDef *def) const = 0;
7070
virtual void writeDocumentation(OutputList &ol) = 0;
71-
virtual void writeMemberPages(OutputList &ol) = 0;
71+
virtual void writeMemberPages(OutputList &ol, int hierarchyLevel) = 0;
7272
virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0;
7373
virtual void writeTagFile(TextStream &) = 0;
7474
virtual size_t numDocMembers() const = 0;

src/htmlgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ void HtmlGenerator::writeFooterFile(TextStream &t)
13881388
static std::mutex g_indexLock;
13891389

13901390
void HtmlGenerator::startFile(const QCString &name,const QCString &,
1391-
const QCString &title,int /*id*/)
1391+
const QCString &title,int /*id*/, int /*hierarchyLevel*/)
13921392
{
13931393
//printf("HtmlGenerator::startFile(%s)\n",qPrint(name));
13941394
m_relPath = relativePathToRoot(name);

src/htmlgen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class HtmlGenerator : public OutputGenerator
9595

9696
void writeDoc(const IDocNodeAST *node,const Definition *,const MemberDef *,int id);
9797

98-
void startFile(const QCString &name,const QCString &manName,const QCString &title,int id);
98+
void startFile(const QCString &name,const QCString &manName,const QCString &title,int id, int hierarchyLevel);
9999
void writeFooter(const QCString &navPath);
100100
void endFile();
101101
void clearBuffer();

src/index.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,10 @@ void endTitle(OutputList &ol,const QCString &fileName,const QCString &name)
356356

357357
void startFile(OutputList &ol,const QCString &name,const QCString &manName,
358358
const QCString &title,HighlightedItem hli,bool additionalIndices,
359-
const QCString &altSidebarName)
359+
const QCString &altSidebarName, int hierarchyLevel)
360360
{
361361
bool disableIndex = Config_getBool(DISABLE_INDEX);
362-
ol.startFile(name,manName,title);
362+
ol.startFile(name,manName,title,hierarchyLevel);
363363
ol.startQuickIndices();
364364
if (!disableIndex)
365365
{

src/index.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void startTitle(OutputList &ol,const QCString &fileName,const DefinitionMutable
200200
void endTitle(OutputList &ol,const QCString &fileName,const QCString &name);
201201
void startFile(OutputList &ol,const QCString &name,const QCString &manName,
202202
const QCString &title,HighlightedItem hli=HighlightedItem::None,
203-
bool additionalIndices=FALSE,const QCString &altSidebarName=QCString());
203+
bool additionalIndices=FALSE,const QCString &altSidebarName=QCString(), int hierarchyLevel=0);
204204
void endFile(OutputList &ol,bool skipNavIndex=FALSE,bool skipEndContents=FALSE,
205205
const QCString &navPath=QCString());
206206
void endFileWithNavPath(OutputList &ol,const Definition *d);

src/latexdocvisitor.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,38 @@
3939
#include "regex.h"
4040
#include "portable.h"
4141

42-
const int maxLevels=5;
42+
const int maxLevels=7;
4343
static const char *secLabels[maxLevels] =
44-
{ "doxysection","doxysubsection","doxysubsubsection","doxyparagraph","doxysubparagraph" };
44+
{ "doxysection","doxysubsection","doxysubsubsection",
45+
"doxysubsubsubsection", "doxysubsubsubsubsection",
46+
"doxysubsubsubsubsubsection", "doxysubsubsubsubsubsubsection" };
47+
static const char *paragraphLabel = "doxyparagraph";
48+
static const char *subparagraphLabel = "doxysubparagraph";
4549

46-
static const char *getSectionName(int level)
50+
const char *LatexDocVisitor::getSectionName(int level) const
4751
{
4852
bool compactLatex = Config_getBool(COMPACT_LATEX);
4953
int l = level;
5054
if (compactLatex) l++;
5155
if (Doxygen::insideMainPage) l--;
52-
return secLabels[std::min(maxLevels-1,l)];
56+
57+
if (l <= 2)
58+
{
59+
// Sections get special treatment because they inherit the parent's level
60+
l += m_hierarchyLevel;
61+
if (l > maxLevels - 1)
62+
l = maxLevels - 1;
63+
64+
return secLabels[l];
65+
}
66+
else if (l == 3)
67+
{
68+
return paragraphLabel;
69+
}
70+
else
71+
{
72+
return subparagraphLabel;
73+
}
5374
}
5475

5576
static void insertDimension(TextStream &t, QCString dimension, const char *orientationString)
@@ -201,10 +222,10 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
201222

202223

203224
LatexDocVisitor::LatexDocVisitor(TextStream &t,OutputCodeList &ci,LatexCodeGenerator &lcg,
204-
const QCString &langExt)
225+
const QCString &langExt, int hierarchyLevel)
205226
: m_t(t), m_ci(ci), m_lcg(lcg), m_insidePre(FALSE),
206227
m_insideItem(FALSE), m_hide(FALSE),
207-
m_langExt(langExt)
228+
m_langExt(langExt), m_hierarchyLevel(hierarchyLevel)
208229
{
209230
}
210231

src/latexdocvisitor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class LatexDocVisitor : public DocVisitor
3232
{
3333
public:
3434
LatexDocVisitor(TextStream &t,OutputCodeList &ci,LatexCodeGenerator &lcg,
35-
const QCString &langExt);
35+
const QCString &langExt, int hierarchyLevel = 0);
3636

3737
//--------------------------------------
3838
// visitor functions for leaf nodes
@@ -155,6 +155,7 @@ class LatexDocVisitor : public DocVisitor
155155
void incIndentLevel();
156156
void decIndentLevel();
157157
int indentLevel() const;
158+
const char *getSectionName(int level) const;
158159

159160
//--------------------------------------
160161
// state variables
@@ -167,6 +168,7 @@ class LatexDocVisitor : public DocVisitor
167168
bool m_insideItem;
168169
bool m_hide;
169170
QCString m_langExt;
171+
int m_hierarchyLevel;
170172

171173
struct TableState
172174
{

src/latexgen.cpp

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ LatexGenerator::LatexGenerator(const LatexGenerator &og) : OutputGenerator(og.m_
281281
m_relPath = og.m_relPath;
282282
m_indent = og.m_indent;
283283
m_templateMemberItem = og.m_templateMemberItem;
284+
m_hierarchyLevel = og.m_hierarchyLevel;
284285
}
285286

286287
LatexGenerator &LatexGenerator::operator=(const LatexGenerator &og)
@@ -296,6 +297,7 @@ LatexGenerator &LatexGenerator::operator=(const LatexGenerator &og)
296297
m_relPath = og.m_relPath;
297298
m_indent = og.m_indent;
298299
m_templateMemberItem = og.m_templateMemberItem;
300+
m_hierarchyLevel = og.m_hierarchyLevel;
299301
}
300302
return *this;
301303
}
@@ -311,6 +313,7 @@ LatexGenerator::LatexGenerator(LatexGenerator &&og)
311313
m_relPath = std::exchange(og.m_relPath,QCString());
312314
m_indent = std::exchange(og.m_indent,0);
313315
m_templateMemberItem = std::exchange(og.m_templateMemberItem,false);
316+
m_hierarchyLevel = og.m_hierarchyLevel;
314317
}
315318

316319
LatexGenerator::~LatexGenerator()
@@ -598,12 +601,13 @@ void LatexGenerator::writeStyleSheetFile(TextStream &t)
598601
writeDefaultStyleSheet(t);
599602
}
600603

601-
void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int)
604+
void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
602605
{
603606
#if 0
604607
setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
605608
#endif
606609
QCString fileName=name;
610+
m_hierarchyLevel = hierarchyLevel;
607611
m_relPath = relativePathToRoot(fileName);
608612
if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
609613
startPlainFile(fileName);
@@ -940,6 +944,18 @@ void LatexGenerator::startIndexSection(IndexSection is)
940944
}
941945
}
942946

947+
static void includeSubGroupsRecursive(TextStream &t, const GroupDef *gd)
948+
{
949+
t << "\\input{" << gd->getOutputFileBase() << "}\n";
950+
for (const auto &subgd : gd->getSubGroups())
951+
{
952+
if (!subgd->isReference() && subgd->partOfGroups().front() == gd)
953+
{
954+
includeSubGroupsRecursive(t, subgd);
955+
}
956+
}
957+
}
958+
943959
void LatexGenerator::endIndexSection(IndexSection is)
944960
{
945961
switch (is)
@@ -983,17 +999,12 @@ void LatexGenerator::endIndexSection(IndexSection is)
983999
break;
9841000
case IndexSection::isModuleDocumentation:
9851001
{
986-
bool found=FALSE;
1002+
m_t << "}\n";
9871003
for (const auto &gd : *Doxygen::groupLinkedMap)
9881004
{
989-
if (!gd->isReference())
1005+
if (!gd->isReference() && !gd->isASubGroup())
9901006
{
991-
if (!found)
992-
{
993-
m_t << "}\n";
994-
found=TRUE;
995-
}
996-
m_t << "\\input{" << gd->getOutputFileBase() << "}\n";
1007+
includeSubGroupsRecursive(m_t, gd.get());
9971008
}
9981009
}
9991010
}
@@ -1362,14 +1373,12 @@ void LatexGenerator::startTitleHead(const QCString &fileName)
13621373
{
13631374
m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
13641375
}
1376+
int hierarchyLevel = m_hierarchyLevel;
13651377
if (Config_getBool(COMPACT_LATEX))
13661378
{
1367-
m_t << "\\doxysubsection{";
1368-
}
1369-
else
1370-
{
1371-
m_t << "\\doxysection{";
1379+
++hierarchyLevel;
13721380
}
1381+
m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
13731382
}
13741383

13751384
void LatexGenerator::endTitleHead(const QCString &fileName,const QCString &name)
@@ -1404,21 +1413,18 @@ void LatexGenerator::startGroupHeader(int extraIndentLevel)
14041413
extraIndentLevel++;
14051414
}
14061415

1407-
if (extraIndentLevel==3)
1416+
if (extraIndentLevel>=3)
14081417
{
14091418
m_t << "\\doxysubparagraph*{";
14101419
}
14111420
else if (extraIndentLevel==2)
14121421
{
14131422
m_t << "\\doxyparagraph{";
14141423
}
1415-
else if (extraIndentLevel==1)
1424+
else
14161425
{
1417-
m_t << "\\doxysubsubsection{";
1418-
}
1419-
else // extraIndentLevel==0
1420-
{
1421-
m_t << "\\doxysubsection{";
1426+
extraIndentLevel += m_hierarchyLevel;
1427+
m_t << "\\doxysub" << QCString("sub").repeat(extraIndentLevel) << "section{";
14221428
}
14231429
m_disableLinks=TRUE;
14241430
}
@@ -1431,14 +1437,13 @@ void LatexGenerator::endGroupHeader(int)
14311437

14321438
void LatexGenerator::startMemberHeader(const QCString &,int)
14331439
{
1440+
int l = m_hierarchyLevel + 1;
14341441
if (Config_getBool(COMPACT_LATEX))
14351442
{
1436-
m_t << "\\doxysubsubsection*{";
1437-
}
1438-
else
1439-
{
1440-
m_t << "\\doxysubsection*{";
1443+
++l;
14411444
}
1445+
1446+
m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
14421447
m_disableLinks=TRUE;
14431448
}
14441449

@@ -1486,13 +1491,20 @@ void LatexGenerator::startMemberDoc(const QCString &clname,
14861491
}
14871492
m_t << "}\n";
14881493
}
1489-
static const char *levelLab[] = { "doxysubsubsection","doxyparagraph","doxysubparagraph", "doxysubparagraph" };
14901494
bool compactLatex = Config_getBool(COMPACT_LATEX);
14911495
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1492-
int level=0;
1493-
if (showInline) level+=2;
1494-
if (compactLatex) level++;
1495-
m_t << "\\" << levelLab[level];
1496+
if (showInline)
1497+
{
1498+
m_t << "\\doxysubparagraph";
1499+
}
1500+
else if (compactLatex)
1501+
{
1502+
m_t << "\\doxyparagraph";
1503+
}
1504+
else
1505+
{
1506+
m_t << "\\doxysubsub" << QCString("sub").repeat(m_hierarchyLevel) << "section";
1507+
}
14961508

14971509
m_t << "{";
14981510
if (pdfHyperlinks)
@@ -2041,7 +2053,8 @@ void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const
20412053
if (astImpl)
20422054
{
20432055
LatexDocVisitor visitor(m_t,*m_codeList,*m_codeGen,
2044-
ctx?ctx->getDefFileExtension():QCString(""));
2056+
ctx?ctx->getDefFileExtension():QCString(""),
2057+
m_hierarchyLevel);
20452058
std::visit(visitor,astImpl->root);
20462059
}
20472060
}
@@ -2095,7 +2108,7 @@ void LatexGenerator::startInlineHeader()
20952108
}
20962109
else
20972110
{
2098-
m_t << "\\doxysubsubsection*{";
2111+
m_t << "\\doxysub" << QCString("sub").repeat(m_hierarchyLevel) << "section*{";
20992112
}
21002113
}
21012114

@@ -2204,7 +2217,7 @@ void LatexGenerator::writeInheritedSectionTitle(
22042217
}
22052218
else
22062219
{
2207-
m_t << "\\doxysubsubsection*{";
2220+
m_t << "\\doxysub" << QCString("sub").repeat(m_hierarchyLevel) << "section*{";
22082221
}
22092222
m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
22102223
objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));

0 commit comments

Comments
 (0)