summaryrefslogtreecommitdiff
path: root/src/latexgen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/latexgen.cpp')
-rw-r--r--src/latexgen.cpp1110
1 files changed, 782 insertions, 328 deletions
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index c5f436c..f68c85a 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -14,7 +14,6 @@
*/
#include <cstdlib>
-#include <sstream>
#include "latexgen.h"
#include "config.h"
@@ -44,16 +43,23 @@
#include "portable.h"
#include "fileinfo.h"
#include "utf8.h"
+#include "datetime.h"
+#include "portable.h"
+#include "outputlist.h"
+#include "moduledef.h"
static QCString g_header;
static QCString g_footer;
+static const SelectionMarkerInfo latexMarkerInfo = { '%', "%%BEGIN ",8 ,"%%END ",6, "",0 };
+
+static QCString substituteLatexKeywords(const QCString &str, const QCString &title);
-LatexCodeGenerator::LatexCodeGenerator(TextStream &t,const QCString &relPath,const QCString &sourceFileName)
+LatexCodeGenerator::LatexCodeGenerator(TextStream *t,const QCString &relPath,const QCString &sourceFileName)
: m_t(t), m_relPath(relPath), m_sourceFileName(sourceFileName)
{
}
-LatexCodeGenerator::LatexCodeGenerator(TextStream &t) : m_t(t)
+LatexCodeGenerator::LatexCodeGenerator(TextStream *t) : m_t(t)
{
}
@@ -85,21 +91,25 @@ void LatexCodeGenerator::codify(const QCString &str)
{
case 0x0c: p++; // remove ^L
break;
- case ' ': m_t <<" ";
+ case ' ': *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
+ m_col++;
+ p++;
+ break;
+ case '^': *m_t <<"\\string^";
m_col++;
p++;
break;
- case '^': m_t <<"\\string^";
+ case '`': *m_t <<"\\`{}";
m_col++;
p++;
break;
case '\t': spacesToNextTabStop =
tabSize - (m_col%tabSize);
- for (i = 0; i < spacesToNextTabStop; i++) m_t <<" ";
+ for (i = 0; i < spacesToNextTabStop; i++) *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
m_col+=spacesToNextTabStop;
p++;
break;
- case '\n': m_t << '\n';
+ case '\n': *m_t << '\n';
m_col=0;
p++;
break;
@@ -131,8 +141,8 @@ void LatexCodeGenerator::codify(const QCString &str)
COPYCHAR();
}
result[i]=0; // add terminator
- filterLatexString(m_t,result,
- false, // insideTabbing
+ filterLatexString(*m_t,result,
+ m_insideTabbing, // insideTabbing
true, // insidePre
false, // insideItem
m_usedTableLevel>0, // insideTable
@@ -152,16 +162,16 @@ void LatexCodeGenerator::writeCodeLink(CodeSymbolType,
{
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
bool usePDFLatex = Config_getBool(USE_PDFLATEX);
- uint l = name.length();
+ uint32_t l = name.length();
if (ref.isEmpty() && usePDFLatex && pdfHyperlinks)
{
- m_t << "\\mbox{\\hyperlink{";
- if (!f.isEmpty()) m_t << stripPath(f);
- if (!f.isEmpty() && !anchor.isEmpty()) m_t << "_";
- if (!anchor.isEmpty()) m_t << anchor;
- m_t << "}{";
+ *m_t << "\\mbox{\\hyperlink{";
+ if (!f.isEmpty()) *m_t << stripPath(f);
+ if (!f.isEmpty() && !anchor.isEmpty()) *m_t << "_";
+ if (!anchor.isEmpty()) *m_t << anchor;
+ *m_t << "}{";
codify(name);
- m_t << "}}";
+ *m_t << "}}";
}
else
{
@@ -176,7 +186,7 @@ void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fil
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
if (!m_doxyCodeLineOpen)
{
- m_t << "\\DoxyCodeLine{";
+ *m_t << "\\DoxyCodeLine{";
m_doxyCodeLineOpen = TRUE;
}
if (Config_getBool(SOURCE_BROWSER))
@@ -193,7 +203,7 @@ void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fil
bool showTarget = usePDFLatex && pdfHyperlinks && !lineAnchor.isEmpty() && writeLineAnchor;
if (showTarget)
{
- m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
+ *m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
}
if (!fileName.isEmpty())
{
@@ -203,11 +213,14 @@ void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fil
{
codify(lineNumber);
}
- m_t << " ";
+ *m_t << "\\ ";
}
else
{
- m_t << l << " ";
+ QCString lineNumber;
+ lineNumber.sprintf("%05d",l);
+ codify(lineNumber);
+ *m_t << "\\ ";
}
m_col=0;
}
@@ -218,7 +231,7 @@ void LatexCodeGenerator::startCodeLine(bool)
m_col=0;
if (!m_doxyCodeLineOpen)
{
- m_t << "\\DoxyCodeLine{";
+ *m_t << "\\DoxyCodeLine{";
m_doxyCodeLineOpen = TRUE;
}
}
@@ -227,7 +240,7 @@ void LatexCodeGenerator::endCodeLine()
{
if (m_doxyCodeLineOpen)
{
- m_t << "}";
+ *m_t << "}";
m_doxyCodeLineOpen = FALSE;
}
codify("\n");
@@ -235,17 +248,17 @@ void LatexCodeGenerator::endCodeLine()
void LatexCodeGenerator::startFontClass(const QCString &name)
{
- m_t << "\\textcolor{" << name << "}{";
+ *m_t << "\\textcolor{" << name << "}{";
}
void LatexCodeGenerator::endFontClass()
{
- m_t << "}";
+ *m_t << "}";
}
void LatexCodeGenerator::startCodeFragment(const QCString &style)
{
- m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n";
+ *m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n";
}
void LatexCodeGenerator::endCodeFragment(const QCString &style)
@@ -253,41 +266,78 @@ void LatexCodeGenerator::endCodeFragment(const QCString &style)
//endCodeLine checks is there is still an open code line, if so closes it.
endCodeLine();
- m_t << "\\end{" << style << "}\n";
+ *m_t << "\\end{" << style << "}\n";
}
//-------------------------------
-LatexGenerator::LatexGenerator() : OutputGenerator(Config_getString(LATEX_OUTPUT)), m_codeGen(m_t)
+LatexGenerator::LatexGenerator()
+ : OutputGenerator(Config_getString(LATEX_OUTPUT))
+ , m_codeList(std::make_unique<OutputCodeList>())
{
- //printf("LatexGenerator::LatexGenerator() m_insideTabbing=FALSE\n");
+ m_codeGen = m_codeList->add<LatexCodeGenerator>(&m_t);
}
-LatexGenerator::LatexGenerator(const LatexGenerator &og) : OutputGenerator(og), m_codeGen(m_t)
+LatexGenerator::LatexGenerator(const LatexGenerator &og) : OutputGenerator(og.m_dir)
{
+ m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
+ m_codeGen = m_codeList->get<LatexCodeGenerator>();
+ m_codeGen->setTextStream(&m_t);
+ m_firstDescItem = og.m_firstDescItem;
+ m_disableLinks = og.m_disableLinks;
+ m_relPath = og.m_relPath;
+ m_indent = og.m_indent;
+ m_templateMemberItem = og.m_templateMemberItem;
+ m_hierarchyLevel = og.m_hierarchyLevel;
}
LatexGenerator &LatexGenerator::operator=(const LatexGenerator &og)
{
- OutputGenerator::operator=(og);
+ if (this!=&og)
+ {
+ m_dir = og.m_dir;
+ m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
+ m_codeGen = m_codeList->get<LatexCodeGenerator>();
+ m_codeGen->setTextStream(&m_t);
+ m_firstDescItem = og.m_firstDescItem;
+ m_disableLinks = og.m_disableLinks;
+ m_relPath = og.m_relPath;
+ m_indent = og.m_indent;
+ m_templateMemberItem = og.m_templateMemberItem;
+ m_hierarchyLevel = og.m_hierarchyLevel;
+ }
return *this;
}
-std::unique_ptr<OutputGenerator> LatexGenerator::clone() const
+LatexGenerator::LatexGenerator(LatexGenerator &&og)
+ : OutputGenerator(std::move(og))
{
- return std::make_unique<LatexGenerator>(*this);
+ m_codeList = std::exchange(og.m_codeList,std::unique_ptr<OutputCodeList>());
+ m_codeGen = m_codeList->get<LatexCodeGenerator>();
+ m_codeGen->setTextStream(&m_t);
+ m_firstDescItem = std::exchange(og.m_firstDescItem,true);
+ m_disableLinks = std::exchange(og.m_disableLinks,false);
+ m_relPath = std::exchange(og.m_relPath,QCString());
+ m_indent = std::exchange(og.m_indent,0);
+ m_templateMemberItem = std::exchange(og.m_templateMemberItem,false);
+ m_hierarchyLevel = og.m_hierarchyLevel;
}
LatexGenerator::~LatexGenerator()
{
}
+void LatexGenerator::addCodeGen(OutputCodeList &list)
+{
+ list.add(OutputCodeList::OutputCodeVariant(LatexCodeGeneratorDefer(m_codeGen)));
+}
+
static void writeLatexMakefile()
{
bool generateBib = !CitationManager::instance().isEmpty();
QCString fileName=Config_getString(LATEX_OUTPUT)+"/Makefile";
- std::ofstream f(fileName.str(),std::ofstream::out | std::ofstream::binary);
+ std::ofstream f = Portable::openOutputStream(fileName);
if (!f.is_open())
{
term("Could not open file %s for writing\n",qPrint(fileName));
@@ -338,7 +388,7 @@ static void writeLatexMakefile()
t << "\techo \"Rerunning latex....\"\n"
<< "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"
<< "\tlatex_count=$(LATEX_COUNT) ; \\\n"
- << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
+ << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
<< "\t do \\\n"
<< "\t echo \"Rerunning latex....\" ;\\\n"
<< "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n"
@@ -366,7 +416,7 @@ static void writeLatexMakefile()
}
t << "\t$(LATEX_CMD) $(MANUAL_FILE)\n"
<< "\tlatex_count=$(LATEX_COUNT) ; \\\n"
- << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
+ << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
<< "\t do \\\n"
<< "\t echo \"Rerunning latex....\" ;\\\n"
<< "\t $(LATEX_CMD) $(MANUAL_FILE) ;\\\n"
@@ -393,13 +443,13 @@ static void writeMakeBat()
QCString manual_file = "refman";
const int latex_count = 8;
bool generateBib = !CitationManager::instance().isEmpty();
- std::ofstream t(fileName.str(),std::ofstream::out | std::ofstream::binary);
+ std::ofstream t = Portable::openOutputStream(fileName);
if (!t.is_open())
{
term("Could not open file %s for writing\n",qPrint(fileName));
}
- t << "set Dir_Old=%cd%\r\n";
- t << "cd /D %~dp0\r\n\r\n";
+ t << "pushd %~dp0\r\n";
+ t << "if not %errorlevel% == 0 goto :end\r\n";
t << "\r\n";
t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n";
t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n";
@@ -479,8 +529,7 @@ static void writeMakeBat()
}
t<< "\r\n";
t<< "@REM reset environment\r\n";
- t<< "cd /D %Dir_Old%\r\n";
- t<< "set Dir_Old=\r\n";
+ t<< "popd\r\n";
t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n";
t<< "set ORG_LATEX_CMD=\r\n";
t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n";
@@ -491,6 +540,8 @@ static void writeMakeBat()
t<< "set ORG_MANUAL_FILE=\r\n";
t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n";
t<< "set ORG_LATEX_COUNT=\r\n";
+ t<< "\r\n";
+ t<< ":end\r\n";
#endif
}
@@ -507,19 +558,27 @@ void LatexGenerator::init()
{
g_header=fileToString(Config_getString(LATEX_HEADER));
//printf("g_header='%s'\n",qPrint(g_header));
+ QCString result = substituteLatexKeywords(g_header,QCString());
+ checkBlocks(result,Config_getString(LATEX_HEADER),latexMarkerInfo);
}
else
{
g_header = ResourceMgr::instance().getAsString("header.tex");
+ QCString result = substituteLatexKeywords(g_header,QCString());
+ checkBlocks(result,"<default header.tex>",latexMarkerInfo);
}
if (!Config_getString(LATEX_FOOTER).isEmpty())
{
g_footer=fileToString(Config_getString(LATEX_FOOTER));
//printf("g_footer='%s'\n",qPrint(g_footer));
+ QCString result = substituteLatexKeywords(g_footer,QCString());
+ checkBlocks(result,Config_getString(LATEX_FOOTER),latexMarkerInfo);
}
else
{
g_footer = ResourceMgr::instance().getAsString("footer.tex");
+ QCString result = substituteLatexKeywords(g_footer,QCString());
+ checkBlocks(result,"<default footer.tex>",latexMarkerInfo);
}
writeLatexMakefile();
@@ -558,23 +617,24 @@ void LatexGenerator::writeStyleSheetFile(TextStream &t)
writeDefaultStyleSheet(t);
}
-void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int)
+void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
{
#if 0
setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
#endif
QCString fileName=name;
+ m_hierarchyLevel = hierarchyLevel;
m_relPath = relativePathToRoot(fileName);
if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
startPlainFile(fileName);
- m_codeGen.setRelativePath(m_relPath);
- m_codeGen.setSourceFileName(stripPath(fileName));
+ m_codeGen->setRelativePath(m_relPath);
+ m_codeGen->setSourceFileName(stripPath(fileName));
}
void LatexGenerator::endFile()
{
endPlainFile();
- m_codeGen.setSourceFileName("");
+ m_codeGen->setSourceFileName("");
}
//void LatexGenerator::writeIndex()
@@ -633,13 +693,26 @@ static QCString makeIndex()
return result;
}
+static QCString latex_batchmode()
+{
+ switch (Config_getEnum(LATEX_BATCHMODE))
+ {
+ case LATEX_BATCHMODE_t::NO: return "";
+ case LATEX_BATCHMODE_t::YES: return "\\batchmode";
+ case LATEX_BATCHMODE_t::BATCH: return "\\batchmode";
+ case LATEX_BATCHMODE_t::NON_STOP: return "\\nonstopmode";
+ case LATEX_BATCHMODE_t::SCROLL: return "\\scrollmode";
+ case LATEX_BATCHMODE_t::ERROR_STOP: return "\\errorstopmode";
+ }
+ return "";
+}
+
static QCString substituteLatexKeywords(const QCString &str,
const QCString &title)
{
bool compactLatex = Config_getBool(COMPACT_LATEX);
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
bool usePdfLatex = Config_getBool(USE_PDFLATEX);
- bool latexBatchmode = Config_getBool(LATEX_BATCHMODE);
QCString paperType = Config_getEnumAsString(PAPER_TYPE);
QCString style = Config_getString(LATEX_BIB_STYLE);
@@ -649,16 +722,22 @@ static QCString substituteLatexKeywords(const QCString &str,
}
TextStream tg;
- bool timeStamp = Config_getBool(LATEX_TIMESTAMP);
QCString generatedBy;
- if (timeStamp)
- {
- generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE).data(),
- Config_getString(PROJECT_NAME).data());
- }
- else
+ auto timeStamp = Config_getEnum(TIMESTAMP);
+ switch (timeStamp)
{
- generatedBy = theTranslator->trGeneratedBy();
+ case TIMESTAMP_t::YES:
+ case TIMESTAMP_t::DATETIME:
+ generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::DateTime),
+ Config_getString(PROJECT_NAME));
+ break;
+ case TIMESTAMP_t::DATE:
+ generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::Date),
+ Config_getString(PROJECT_NAME));
+ break;
+ case TIMESTAMP_t::NO:
+ generatedBy = theTranslator->trGeneratedBy();
+ break;
}
filterLatexString(tg, generatedBy,
false, // insideTabbing
@@ -697,117 +776,140 @@ static QCString substituteLatexKeywords(const QCString &str,
// first substitute generic keywords
QCString result = substituteKeywords(str,title,
- convertToLaTeX(Config_getString(PROJECT_NAME)),
- convertToLaTeX(projectNumber),
- convertToLaTeX(Config_getString(PROJECT_BRIEF)));
+ convertToLaTeX(Config_getString(PROJECT_NAME),false),
+ convertToLaTeX(projectNumber,false),
+ convertToLaTeX(Config_getString(PROJECT_BRIEF),false));
// additional LaTeX only keywords
- result = substitute(result,"$latexdocumentpre",theTranslator->latexDocumentPre());
- result = substitute(result,"$latexdocumentpost",theTranslator->latexDocumentPost());
- result = substitute(result,"$generatedby",generatedBy);
- result = substitute(result,"$latexbibstyle",style);
- result = substitute(result,"$latexcitereference",theTranslator->trCiteReferences());
- result = substitute(result,"$latexbibfiles",CitationManager::instance().latexBibFiles());
- result = substitute(result,"$papertype",paperType+"paper");
- result = substitute(result,"$extralatexstylesheet",extraLatexStyleSheet());
- result = substitute(result,"$languagesupport",theTranslator->latexLanguageSupportCommand());
- result = substitute(result,"$latexfontenc",latexFontenc);
- result = substitute(result,"$latexfont",theTranslator->latexFont());
- result = substitute(result,"$latexemojidirectory",latexEmojiDirectory);
- result = substitute(result,"$makeindex",makeIndex());
- result = substitute(result,"$extralatexpackages",extraLatexPackages);
- result = substitute(result,"$latexspecialformulachars",latexSpecialFormulaChars);
- result = substitute(result,"$formulamacrofile",stripMacroFile);
-
- // additional LaTeX only conditional blocks
- result = selectBlock(result,"CITATIONS_PRESENT", !CitationManager::instance().isEmpty(),OutputGenerator::Latex);
- result = selectBlock(result,"COMPACT_LATEX",compactLatex,OutputGenerator::Latex);
- result = selectBlock(result,"PDF_HYPERLINKS",pdfHyperlinks,OutputGenerator::Latex);
- result = selectBlock(result,"USE_PDFLATEX",usePdfLatex,OutputGenerator::Latex);
- result = selectBlock(result,"LATEX_TIMESTAMP",timeStamp,OutputGenerator::Latex);
- result = selectBlock(result,"LATEX_BATCHMODE",latexBatchmode,OutputGenerator::Latex);
- result = selectBlock(result,"LATEX_FONTENC",!latexFontenc.isEmpty(),OutputGenerator::Latex);
- result = selectBlock(result,"FORMULA_MACROFILE",!formulaMacrofile.isEmpty(),OutputGenerator::Latex);
- result = selectBlock(result,"PROJECT_NUMBER",!projectNumber.isEmpty(),OutputGenerator::Latex);
+ result = substituteKeywords(result,
+ {
+ // keyword value getter
+ { "$latexdocumentpre", [&]() { return theTranslator->latexDocumentPre(); } },
+ { "$latexdocumentpost", [&]() { return theTranslator->latexDocumentPost(); } },
+ { "$generatedby", [&]() { return generatedBy; } },
+ { "$latexbibstyle", [&]() { return style; } },
+ { "$latexcitereference", [&]() { return theTranslator->trCiteReferences(); } },
+ { "$latexbibfiles", [&]() { return CitationManager::instance().latexBibFiles(); } },
+ { "$papertype", [&]() { return paperType+"paper"; } },
+ { "$extralatexstylesheet", [&]() { return extraLatexStyleSheet(); } },
+ { "$languagesupport", [&]() { return theTranslator->latexLanguageSupportCommand(); } },
+ { "$latexfontenc", [&]() { return latexFontenc; } },
+ { "$latexfont", [&]() { return theTranslator->latexFont(); } },
+ { "$latexemojidirectory", [&]() { return latexEmojiDirectory; } },
+ { "$makeindex", [&]() { return makeIndex(); } },
+ { "$extralatexpackages", [&]() { return extraLatexPackages; } },
+ { "$latexspecialformulachars", [&]() { return latexSpecialFormulaChars; } },
+ { "$formulamacrofile", [&]() { return stripMacroFile; } },
+ { "$latex_batchmode", [&]() { return latex_batchmode(); } }
+ });
+
+ // remove conditional blocks
+ result = selectBlocks(result,
+ {
+ // marker is enabled
+ { "CITATIONS_PRESENT", !CitationManager::instance().isEmpty() },
+ { "COMPACT_LATEX", compactLatex },
+ { "PDF_HYPERLINKS", pdfHyperlinks },
+ { "USE_PDFLATEX", usePdfLatex },
+ { "TIMESTAMP", timeStamp!=TIMESTAMP_t::NO },
+ { "LATEX_FONTENC", !latexFontenc.isEmpty() },
+ { "FORMULA_MACROFILE", !formulaMacrofile.isEmpty() },
+ { "PROJECT_NUMBER", !projectNumber.isEmpty() }
+ },latexMarkerInfo);
result = removeEmptyLines(result);
return result;
}
-void LatexGenerator::startIndexSection(IndexSections is)
+void LatexGenerator::startIndexSection(IndexSection is)
{
bool compactLatex = Config_getBool(COMPACT_LATEX);
switch (is)
{
- case isTitlePageStart:
- m_t << substituteLatexKeywords(g_header,convertToLaTeX(Config_getString(PROJECT_NAME)));
+ case IndexSection::isTitlePageStart:
+ m_t << substituteLatexKeywords(g_header,convertToLaTeX(Config_getString(PROJECT_NAME),m_codeGen->insideTabbing()));
break;
- case isTitlePageAuthor:
+ case IndexSection::isTitlePageAuthor:
break;
- case isMainPage:
- if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
- m_t << "{"; //Introduction}\n"
+ case IndexSection::isMainPage:
break;
- case isModuleIndex:
+ case IndexSection::isModuleIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Module Index}\n"
break;
- case isDirIndex:
+ case IndexSection::isTopicIndex:
+ if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
+ m_t << "{"; //Topic Index}\n"
+ break;
+ case IndexSection::isDirIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Directory Index}\n"
break;
- case isNamespaceIndex:
+ case IndexSection::isNamespaceIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Namespace Index}\n"
break;
- case isConceptIndex:
+ case IndexSection::isConceptIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Concept Index}\n"
break;
- case isClassHierarchyIndex:
+ case IndexSection::isClassHierarchyIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Hierarchical Index}\n"
break;
- case isCompoundIndex:
+ case IndexSection::isCompoundIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Annotated Compound Index}\n"
break;
- case isFileIndex:
+ case IndexSection::isFileIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Annotated File Index}\n"
break;
- case isPageIndex:
+ case IndexSection::isPageIndex:
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Annotated Page Index}\n"
break;
- case isModuleDocumentation:
+ case IndexSection::isTopicDocumentation:
{
for (const auto &gd : *Doxygen::groupLinkedMap)
{
if (!gd->isReference())
{
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
- m_t << "{"; //Module Documentation}\n";
+ m_t << "{"; //Topic Documentation}\n";
break;
}
}
}
break;
- case isDirDocumentation:
+ case IndexSection::isModuleDocumentation:
+ {
+ for (const auto &mod : ModuleManager::instance().modules())
+ {
+ if (!mod->isReference() && mod->isPrimaryInterface())
+ {
+ if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
+ m_t << "{"; //Topic Documentation}\n";
+ break;
+ }
+ }
+ }
+ break;
+ case IndexSection::isDirDocumentation:
{
for (const auto &dd : *Doxygen::dirLinkedMap)
{
if (dd->isLinkableInProject())
{
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
- m_t << "{"; //Module Documentation}\n";
+ m_t << "{"; //Dir Documentation}\n";
break;
}
}
}
break;
- case isNamespaceDocumentation:
+ case IndexSection::isNamespaceDocumentation:
{
for (const auto &nd : *Doxygen::namespaceLinkedMap)
{
@@ -820,7 +922,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
}
}
break;
- case isConceptDocumentation:
+ case IndexSection::isConceptDocumentation:
{
for (const auto &cd : *Doxygen::conceptLinkedMap)
{
@@ -833,7 +935,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
}
}
break;
- case isClassDocumentation:
+ case IndexSection::isClassDocumentation:
{
for (const auto &cd : *Doxygen::classLinkedMap)
{
@@ -850,7 +952,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
}
}
break;
- case isFileDocumentation:
+ case IndexSection::isFileDocumentation:
{
bool isFirst=TRUE;
for (const auto &fn : *Doxygen::inputNameLinkedMap)
@@ -871,84 +973,89 @@ void LatexGenerator::startIndexSection(IndexSections is)
}
}
break;
- case isExampleDocumentation:
+ case IndexSection::isExampleDocumentation:
{
if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
m_t << "{"; //Example Documentation}\n";
}
break;
- case isPageDocumentation:
- {
- if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
- m_t << "{"; //Page Documentation}\n";
- }
+ case IndexSection::isPageDocumentation:
break;
- case isPageDocumentation2:
+ case IndexSection::isPageDocumentation2:
break;
- case isEndIndex:
+ case IndexSection::isEndIndex:
break;
}
}
-void LatexGenerator::endIndexSection(IndexSections is)
+void LatexGenerator::endIndexSection(IndexSection is)
{
switch (is)
{
- case isTitlePageStart:
+ case IndexSection::isTitlePageStart:
break;
- case isTitlePageAuthor:
+ case IndexSection::isTitlePageAuthor:
break;
- case isMainPage:
+ case IndexSection::isMainPage:
{
- //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
- QCString indexName="index";
- m_t << "}\n\\label{index}";
- if (Config_getBool(PDF_HYPERLINKS)) m_t << "\\hypertarget{index}{}";
- m_t << "\\input{" << indexName << "}\n";
+ if (Doxygen::mainPage)
+ {
+ writePageLink(Doxygen::mainPage->getOutputFileBase(), FALSE);
+ }
}
break;
- case isModuleIndex:
+ case IndexSection::isModuleIndex:
m_t << "}\n\\input{modules}\n";
break;
- case isDirIndex:
+ case IndexSection::isTopicIndex:
+ m_t << "}\n\\input{topics}\n";
+ break;
+ case IndexSection::isDirIndex:
m_t << "}\n\\input{dirs}\n";
break;
- case isNamespaceIndex:
+ case IndexSection::isNamespaceIndex:
m_t << "}\n\\input{namespaces}\n";
break;
- case isConceptIndex:
+ case IndexSection::isConceptIndex:
m_t << "}\n\\input{concepts}\n";
break;
- case isClassHierarchyIndex:
+ case IndexSection::isClassHierarchyIndex:
m_t << "}\n\\input{hierarchy}\n";
break;
- case isCompoundIndex:
+ case IndexSection::isCompoundIndex:
m_t << "}\n\\input{annotated}\n";
break;
- case isFileIndex:
+ case IndexSection::isFileIndex:
m_t << "}\n\\input{files}\n";
break;
- case isPageIndex:
+ case IndexSection::isPageIndex:
m_t << "}\n\\input{pages}\n";
break;
- case isModuleDocumentation:
+ case IndexSection::isTopicDocumentation:
{
- bool found=FALSE;
+ m_t << "}\n";
for (const auto &gd : *Doxygen::groupLinkedMap)
{
- if (!gd->isReference())
+ if (!gd->isReference() && !gd->isASubGroup())
{
- if (!found)
- {
- m_t << "}\n";
- found=TRUE;
- }
- m_t << "\\input{" << gd->getOutputFileBase() << "}\n";
+ writePageLink(gd->getOutputFileBase(), FALSE);
}
}
}
break;
- case isDirDocumentation:
+ case IndexSection::isModuleDocumentation:
+ {
+ m_t << "}\n";
+ for (const auto &mod : ModuleManager::instance().modules())
+ {
+ if (!mod->isReference() && mod->isPrimaryInterface())
+ {
+ writePageLink(mod->getOutputFileBase(), FALSE);
+ }
+ }
+ }
+ break;
+ case IndexSection::isDirDocumentation:
{
bool found=FALSE;
for (const auto &dd : *Doxygen::dirLinkedMap)
@@ -965,7 +1072,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isNamespaceDocumentation:
+ case IndexSection::isNamespaceDocumentation:
{
bool found=FALSE;
for (const auto &nd : *Doxygen::namespaceLinkedMap)
@@ -982,7 +1089,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isConceptDocumentation:
+ case IndexSection::isConceptDocumentation:
{
bool found=FALSE;
for (const auto &cd : *Doxygen::conceptLinkedMap)
@@ -999,7 +1106,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isClassDocumentation:
+ case IndexSection::isClassDocumentation:
{
bool found=FALSE;
for (const auto &cd : *Doxygen::classLinkedMap)
@@ -1020,7 +1127,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isFileDocumentation:
+ case IndexSection::isFileDocumentation:
{
bool isFirst=TRUE;
for (const auto &fn : *Doxygen::inputNameLinkedMap)
@@ -1049,7 +1156,7 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isExampleDocumentation:
+ case IndexSection::isExampleDocumentation:
{
m_t << "}\n";
for (const auto &pd : *Doxygen::exampleLinkedMap)
@@ -1058,31 +1165,22 @@ void LatexGenerator::endIndexSection(IndexSections is)
}
}
break;
- case isPageDocumentation:
+ case IndexSection::isPageDocumentation:
{
- m_t << "}\n";
-#if 0
- bool first=TRUE;
- for (const auto *pd : Doxygen::pageLinkedMap)
+ for (const auto &pd : *Doxygen::pageLinkedMap)
{
- if (!pd->getGroupDef() && !pd->isReference())
+ if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
+ && pd->name() != "citelist" && Doxygen::mainPage.get() != pd.get())
{
- if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
- m_t << "{" << pd->title();
- m_t << "}\n";
-
- if (compactLatex || first) m_t << "\\input" ; else m_t << "\\include";
- m_t << "{" << pd->getOutputFileBase() << "}\n";
- first=FALSE;
+ writePageLink(pd->getOutputFileBase(), FALSE);
}
}
-#endif
}
break;
- case isPageDocumentation2:
+ case IndexSection::isPageDocumentation2:
break;
- case isEndIndex:
- m_t << substituteLatexKeywords(g_footer,convertToLaTeX(Config_getString(PROJECT_NAME)));
+ case IndexSection::isEndIndex:
+ m_t << substituteLatexKeywords(g_footer,convertToLaTeX(Config_getString(PROJECT_NAME),m_codeGen->insideTabbing()));
break;
}
}
@@ -1096,7 +1194,6 @@ void LatexGenerator::writePageLink(const QCString &name, bool /*first*/)
m_t << "{" << name << "}\n";
}
-
void LatexGenerator::writeStyleInfo(int part)
{
if (part > 0)
@@ -1114,11 +1211,12 @@ void LatexGenerator::writeStyleInfo(int part)
startPlainFile("longtable_doxygen.sty");
m_t << ResourceMgr::instance().getAsString("longtable_doxygen.sty");
endPlainFile();
-}
-
-void LatexGenerator::newParagraph()
-{
- m_t << "\n" << "\n";
+ /// an extension of the etoc package is required that is only available in the
+ /// newer version. Providing the updated version to be used with older versions
+ /// of LaTeX
+ startPlainFile("etoc_doxygen.sty");
+ m_t << ResourceMgr::instance().getAsString("etoc_doxygen.sty");
+ endPlainFile();
}
void LatexGenerator::startParagraph(const QCString &)
@@ -1153,43 +1251,6 @@ void LatexGenerator::endIndexItem(const QCString &ref,const QCString &fn)
}
}
-//void LatexGenerator::writeIndexFileItem(const QCString &,const QCString &text)
-//{
-// m_t << "\\item\\contentsline{section}{";
-// docify(text);
-// m_t << "}{\\pageref{" << stripPath(text) << "}}\n";
-//}
-
-
-void LatexGenerator::startHtmlLink(const QCString &url)
-{
- if (Config_getBool(PDF_HYPERLINKS))
- {
- m_t << "\\href{";
- m_t << latexFilterURL(url);
- m_t << "}";
- }
- m_t << "{\\texttt{ ";
-}
-
-void LatexGenerator::endHtmlLink()
-{
- m_t << "}}";
-}
-
-//void LatexGenerator::writeMailLink(const QCString &url)
-//{
-// if (Config_getBool(PDF_HYPERLINKS))
-// {
-// m_t << "\\href{mailto:";
-// m_t << url;
-// m_t << "}";
-// }
-// m_t << "\\texttt{ ";
-// docify(url);
-// m_t << "}";
-//}
-
void LatexGenerator::writeStartAnnoItem(const QCString &,const QCString &,
const QCString &path,const QCString &name)
{
@@ -1199,11 +1260,6 @@ void LatexGenerator::writeStartAnnoItem(const QCString &,const QCString &,
m_t << "} ";
}
-void LatexGenerator::writeEndAnnoItem(const QCString &name)
-{
- m_t << "}{\\pageref{" << stripPath(name) << "}}{}\n";
-}
-
void LatexGenerator::startIndexKey()
{
m_t << "\\item\\contentsline{section}{";
@@ -1259,28 +1315,50 @@ void LatexGenerator::endTextLink()
m_t << "}";
}
-void LatexGenerator::writeObjectLink(const QCString &ref, const QCString &f,
- const QCString &anchor, const QCString &text)
+static QCString objectLinkToString(const QCString &ref, const QCString &f,
+ const QCString &anchor, const QCString &text,
+ bool insideTabbing,bool disableLinks)
{
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
- if (!m_disableLinks && ref.isEmpty() && pdfHyperlinks)
+ QCString result;
+ if (!disableLinks && ref.isEmpty() && pdfHyperlinks)
{
- m_t << "\\mbox{\\hyperlink{";
- if (!f.isEmpty()) m_t << stripPath(f);
- if (!f.isEmpty() && !anchor.isEmpty()) m_t << "_";
- if (!anchor.isEmpty()) m_t << anchor;
- m_t << "}{";
- docify(text);
- m_t << "}}";
+ result += "\\mbox{\\hyperlink{";
+ if (!f.isEmpty()) result += stripPath(f);
+ if (!f.isEmpty() && !anchor.isEmpty()) result += "_";
+ if (!anchor.isEmpty()) result += anchor;
+ result += "}{";
+ result += convertToLaTeX(text,insideTabbing);
+ result += "}}";
}
else
{
- m_t << "\\textbf{ ";
- docify(text);
- m_t << "}";
+ result += "\\textbf{ ";
+ result += convertToLaTeX(text,insideTabbing);
+ result += "}";
+ }
+ return result;
+}
+
+static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
+{
+ if (pdfHyperlinks)
+ {
+ t << "\\texorpdfstring{";
+ }
+ t << strForm;
+ if (pdfHyperlinks)
+ {
+ t << "}{" << strRepl << "}";
}
}
+void LatexGenerator::writeObjectLink(const QCString &ref, const QCString &f,
+ const QCString &anchor, const QCString &text)
+{
+ m_t << objectLinkToString(ref,f,anchor,text,m_codeGen->insideTabbing(),m_disableLinks);
+}
+
void LatexGenerator::startPageRef()
{
m_t << " \\doxyref{}{";
@@ -1297,28 +1375,37 @@ void LatexGenerator::endPageRef(const QCString &clname, const QCString &anchor)
void LatexGenerator::startTitleHead(const QCString &fileName)
{
- bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
- bool usePDFLatex = Config_getBool(USE_PDFLATEX);
- if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
- {
- m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
- }
+ int hierarchyLevel = m_hierarchyLevel;
if (Config_getBool(COMPACT_LATEX))
{
- m_t << "\\doxysubsection{";
+ ++hierarchyLevel;
}
+
+ if (hierarchyLevel < 0)
+ m_t << "\\chapter{";
else
- {
- m_t << "\\doxysection{";
- }
+ m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
}
void LatexGenerator::endTitleHead(const QCString &fileName,const QCString &name)
{
m_t << "}\n";
+
+ bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
+ bool usePDFLatex = Config_getBool(USE_PDFLATEX);
+ if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
+ {
+ m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
+ }
+
+ QCString fn = stripPath(fileName);
+ if (!fn.isEmpty())
+ {
+ m_t << "\\label{" << fn << "}";
+ }
if (!name.isEmpty())
{
- m_t << "\\label{" << stripPath(fileName) << "}\\index{";
+ m_t << "\\index{";
m_t << latexEscapeLabelName(name);
m_t << "@{";
m_t << latexEscapeIndexChars(name);
@@ -1345,7 +1432,7 @@ void LatexGenerator::startGroupHeader(int extraIndentLevel)
extraIndentLevel++;
}
- if (extraIndentLevel==3)
+ if (extraIndentLevel>=3)
{
m_t << "\\doxysubparagraph*{";
}
@@ -1353,13 +1440,10 @@ void LatexGenerator::startGroupHeader(int extraIndentLevel)
{
m_t << "\\doxyparagraph{";
}
- else if (extraIndentLevel==1)
- {
- m_t << "\\doxysubsubsection{";
- }
- else // extraIndentLevel==0
+ else
{
- m_t << "\\doxysubsection{";
+ extraIndentLevel += m_hierarchyLevel + 1;
+ m_t << "\\doxy" << QCString("sub").repeat(extraIndentLevel) << "section{";
}
m_disableLinks=TRUE;
}
@@ -1372,14 +1456,13 @@ void LatexGenerator::endGroupHeader(int)
void LatexGenerator::startMemberHeader(const QCString &,int)
{
+ int l = m_hierarchyLevel + 1;
if (Config_getBool(COMPACT_LATEX))
{
- m_t << "\\doxysubsubsection*{";
- }
- else
- {
- m_t << "\\doxysubsection*{";
+ ++l;
}
+
+ m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
m_disableLinks=TRUE;
}
@@ -1427,13 +1510,20 @@ void LatexGenerator::startMemberDoc(const QCString &clname,
}
m_t << "}\n";
}
- static const char *levelLab[] = { "doxysubsubsection","doxyparagraph","doxysubparagraph", "doxysubparagraph" };
bool compactLatex = Config_getBool(COMPACT_LATEX);
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
- int level=0;
- if (showInline) level+=2;
- if (compactLatex) level++;
- m_t << "\\" << levelLab[level];
+ if (showInline)
+ {
+ m_t << "\\doxysubparagraph";
+ }
+ else if (compactLatex)
+ {
+ m_t << "\\doxyparagraph";
+ }
+ else
+ {
+ m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 2) << "section";
+ }
m_t << "{";
if (pdfHyperlinks)
@@ -1467,7 +1557,7 @@ void LatexGenerator::startDoxyAnchor(const QCString &fName,const QCString &,
{
bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
bool usePDFLatex = Config_getBool(USE_PDFLATEX);
- m_t << "\\mbox{";
+ if (m_insideTableEnv) m_t << "\\mbox{"; // see issue #6093
if (usePDFLatex && pdfHyperlinks)
{
m_t << "\\Hypertarget{";
@@ -1478,10 +1568,11 @@ void LatexGenerator::startDoxyAnchor(const QCString &fName,const QCString &,
m_t << "\\label{";
if (!fName.isEmpty()) m_t << stripPath(fName);
if (!anchor.isEmpty()) m_t << "_" << anchor;
- m_t << "}} \n";
+ if (m_insideTableEnv) m_t << "}";
+ m_t << "} \n";
}
-void LatexGenerator::endDoxyAnchor(const QCString &fName,const QCString &anchor)
+void LatexGenerator::endDoxyAnchor(const QCString &/* fName */,const QCString &/* anchor */)
{
}
@@ -1578,10 +1669,10 @@ void LatexGenerator::endSection(const QCString &lab,SectionType)
void LatexGenerator::docify(const QCString &str)
{
filterLatexString(m_t,str,
- m_insideTabbing, // insideTabbing
+ m_codeGen->insideTabbing(), // insideTabbing
false, // insidePre
false, // insideItem
- m_codeGen.usedTableLevel()>0, // insideTable
+ m_codeGen->usedTableLevel()>0, // insideTable
false // keepSpaces
);
}
@@ -1613,7 +1704,7 @@ void LatexGenerator::startAnonTypeScope(int indent)
{
m_t << "\\begin{tabbing}\n";
m_t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill\n";
- m_insideTabbing=TRUE;
+ m_codeGen->setInsideTabbing(true);
}
m_indent=indent;
}
@@ -1623,14 +1714,14 @@ void LatexGenerator::endAnonTypeScope(int indent)
if (indent==0)
{
m_t << "\n" << "\\end{tabbing}";
- m_insideTabbing=FALSE;
+ m_codeGen->setInsideTabbing(false);
}
m_indent=indent;
}
void LatexGenerator::startMemberTemplateParams()
{
- if (templateMemberItem)
+ if (m_templateMemberItem)
{
m_t << "{\\footnotesize ";
}
@@ -1638,35 +1729,35 @@ void LatexGenerator::startMemberTemplateParams()
void LatexGenerator::endMemberTemplateParams(const QCString &,const QCString &)
{
- if (templateMemberItem)
+ if (m_templateMemberItem)
{
m_t << "}\\\\";
}
}
-void LatexGenerator::startMemberItem(const QCString &,int annoType,const QCString &)
+void LatexGenerator::startMemberItem(const QCString &,MemberItemType type,const QCString &)
{
//printf("LatexGenerator::startMemberItem(%d)\n",annType);
- if (!m_insideTabbing)
+ if (!m_codeGen->insideTabbing())
{
m_t << "\\item \n";
- templateMemberItem = (annoType == 3);
+ m_templateMemberItem = (type == MemberItemType::Templated);
}
}
-void LatexGenerator::endMemberItem()
+void LatexGenerator::endMemberItem(MemberItemType)
{
- if (m_insideTabbing)
+ if (m_codeGen->insideTabbing())
{
m_t << "\\\\";
}
- templateMemberItem = FALSE;
+ m_templateMemberItem = FALSE;
m_t << "\n";
}
void LatexGenerator::startMemberDescription(const QCString &,const QCString &,bool)
{
- if (!m_insideTabbing)
+ if (!m_codeGen->insideTabbing())
{
m_t << "\\begin{DoxyCompactList}\\small\\item\\em ";
}
@@ -1679,7 +1770,7 @@ void LatexGenerator::startMemberDescription(const QCString &,const QCString &,bo
void LatexGenerator::endMemberDescription()
{
- if (!m_insideTabbing)
+ if (!m_codeGen->insideTabbing())
{
//m_t << "\\item\\end{DoxyCompactList}";
m_t << "\\end{DoxyCompactList}";
@@ -1694,7 +1785,7 @@ void LatexGenerator::endMemberDescription()
void LatexGenerator::writeNonBreakableSpace(int)
{
//printf("writeNonBreakableSpace()\n");
- if (m_insideTabbing)
+ if (m_codeGen->insideTabbing())
{
m_t << "\\>";
}
@@ -1720,13 +1811,13 @@ void LatexGenerator::writeNonBreakableSpace(int)
void LatexGenerator::startDescTable(const QCString &title)
{
- m_codeGen.incUsedTableLevel();
+ m_codeGen->incUsedTableLevel();
m_t << "\\begin{DoxyEnumFields}{" << title << "}\n";
}
void LatexGenerator::endDescTable()
{
- m_codeGen.decUsedTableLevel();
+ m_codeGen->decUsedTableLevel();
m_t << "\\end{DoxyEnumFields}\n";
}
@@ -1767,7 +1858,7 @@ void LatexGenerator::lastIndexPage()
void LatexGenerator::startMemberList()
{
- if (!m_insideTabbing)
+ if (!m_codeGen->insideTabbing())
{
m_t << "\\begin{DoxyCompactItemize}\n";
}
@@ -1775,8 +1866,8 @@ void LatexGenerator::startMemberList()
void LatexGenerator::endMemberList()
{
- //printf("LatexGenerator::endMemberList(%d)\n",m_insideTabbing);
- if (!m_insideTabbing)
+ //printf("LatexGenerator::endMemberList(%d)\n",m_codeGen->InsideTabbing());
+ if (!m_codeGen->insideTabbing())
{
m_t << "\\end{DoxyCompactItemize}\n";
}
@@ -1827,7 +1918,7 @@ void LatexGenerator::endMemberGroup(bool hasHeader)
void LatexGenerator::startDotGraph()
{
- newParagraph();
+ m_t << "\n" << "\n";
}
void LatexGenerator::endDotGraph(DotClassGraph &g)
@@ -1871,36 +1962,6 @@ void LatexGenerator::endDirDepGraph(DotDirDeps &g)
g.writeGraph(m_t,GOF_EPS,EOF_LaTeX,dir(),fileName(),m_relPath);
}
-void LatexGenerator::startDescription()
-{
- m_t << "\\begin{description}\n";
-}
-
-void LatexGenerator::endDescription()
-{
- m_t << "\\end{description}\n";
- m_firstDescItem=TRUE;
-}
-
-void LatexGenerator::startDescItem()
-{
- m_firstDescItem=TRUE;
- m_t << "\\item[";
-}
-
-void LatexGenerator::endDescItem()
-{
- if (m_firstDescItem)
- {
- m_t << "]\n";
- m_firstDescItem=FALSE;
- }
- else
- {
- lineBreak();
- }
-}
-
void LatexGenerator::startExamples()
{
m_t << "\\begin{Desc}\n\\item[";
@@ -1913,18 +1974,6 @@ void LatexGenerator::endExamples()
m_t << "\\end{Desc}\n";
}
-void LatexGenerator::startParamList(ParamListTypes,const QCString &title)
-{
- m_t << "\\begin{Desc}\n\\item[";
- docify(title);
- m_t << "]";
-}
-
-void LatexGenerator::endParamList()
-{
- m_t << "\\end{Desc}\n";
-}
-
void LatexGenerator::startParameterList(bool openBracket)
{
/* start of ParameterType ParameterName list */
@@ -1980,9 +2029,9 @@ void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const
const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
if (astImpl)
{
- LatexDocVisitor visitor(m_t,m_codeGen,
+ LatexDocVisitor visitor(m_t,*m_codeList,*m_codeGen,
ctx?ctx->getDefFileExtension():QCString(""),
- m_insideTabbing);
+ m_hierarchyLevel);
std::visit(visitor,astImpl->root);
}
}
@@ -2036,7 +2085,7 @@ void LatexGenerator::startInlineHeader()
}
else
{
- m_t << "\\doxysubsubsection*{";
+ m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
}
}
@@ -2047,7 +2096,7 @@ void LatexGenerator::endInlineHeader()
void LatexGenerator::lineBreak(const QCString &)
{
- if (m_insideTabbing)
+ if (m_codeGen->insideTabbing())
{
m_t << "\\\\\n";
}
@@ -2059,7 +2108,7 @@ void LatexGenerator::lineBreak(const QCString &)
void LatexGenerator::startMemberDocSimple(bool isEnum)
{
- m_codeGen.incUsedTableLevel();
+ m_codeGen->incUsedTableLevel();
if (isEnum)
{
m_t << "\\begin{DoxyEnumFields}{";
@@ -2071,11 +2120,13 @@ void LatexGenerator::startMemberDocSimple(bool isEnum)
docify(theTranslator->trCompoundMembers());
}
m_t << "}\n";
+ m_insideTableEnv=true;
}
void LatexGenerator::endMemberDocSimple(bool isEnum)
{
- m_codeGen.decUsedTableLevel();
+ m_insideTableEnv=false;
+ m_codeGen->decUsedTableLevel();
if (isEnum)
{
m_t << "\\end{DoxyEnumFields}\n";
@@ -2088,24 +2139,24 @@ void LatexGenerator::endMemberDocSimple(bool isEnum)
void LatexGenerator::startInlineMemberType()
{
- m_insideTabbing = TRUE; // to prevent \+ from causing unwanted breaks
+ m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
}
void LatexGenerator::endInlineMemberType()
{
m_t << "&\n";
- m_insideTabbing = FALSE;
+ m_codeGen->setInsideTabbing(false);
}
void LatexGenerator::startInlineMemberName()
{
- m_insideTabbing = TRUE; // to prevent \+ from causing unwanted breaks
+ m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
}
void LatexGenerator::endInlineMemberName()
{
m_t << "&\n";
- m_insideTabbing = FALSE;
+ m_codeGen->setInsideTabbing(false);
}
void LatexGenerator::startInlineMemberDoc()
@@ -2131,3 +2182,406 @@ void LatexGenerator::writeLabel(const QCString &l,bool isLast)
void LatexGenerator::endLabels()
{
}
+
+void LatexGenerator::writeInheritedSectionTitle(
+ const QCString &/*id*/,const QCString &ref,
+ const QCString &file, const QCString &anchor,
+ const QCString &title, const QCString &name)
+{
+ if (Config_getBool(COMPACT_LATEX))
+ {
+ m_t << "\\doxyparagraph*{";
+ }
+ else
+ {
+ m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
+ }
+ m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
+ objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));
+ m_t << "}\n";
+}
+
+void LatexGenerator::writeLocalToc(const SectionRefs &,const LocalToc &localToc)
+{
+ if (localToc.isLatexEnabled())
+ {
+ int maxLevel = localToc.latexLevel() + m_hierarchyLevel;
+ m_t << "\\etocsetnexttocdepth{" << maxLevel << "}\n";
+ m_t << "\\localtableofcontents\n";
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+
+void writeExtraLatexPackages(TextStream &t)
+{
+ // User-specified packages
+ const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
+ if (!extraPackages.empty())
+ {
+ t << "% Packages requested by user\n";
+ for (const auto &pkgName : extraPackages)
+ {
+ if ((pkgName[0] == '[') || (pkgName[0] == '{'))
+ t << "\\usepackage" << pkgName.c_str() << "\n";
+ else
+ t << "\\usepackage{" << pkgName.c_str() << "}\n";
+ }
+ t << "\n";
+ }
+}
+
+void writeLatexSpecialFormulaChars(TextStream &t)
+{
+ unsigned char minus[4]; // Superscript minus
+ unsigned char sup2[3]; // Superscript two
+ unsigned char sup3[3];
+ minus[0]= 0xE2;
+ minus[1]= 0x81;
+ minus[2]= 0xBB;
+ minus[3]= 0;
+ sup2[0]= 0xC2;
+ sup2[1]= 0xB2;
+ sup2[2]= 0;
+ sup3[0]= 0xC2;
+ sup3[1]= 0xB3;
+ sup3[2]= 0;
+
+ t << "\\usepackage{newunicodechar}\n";
+ // taken from the newunicodechar package and removed the warning message
+ // actually forcing to redefine the unicode character
+ t << " \\makeatletter\n"
+ " \\def\\doxynewunicodechar#1#2{%\n"
+ " \\@tempswafalse\n"
+ " \\edef\\nuc@tempa{\\detokenize{#1}}%\n"
+ " \\if\\relax\\nuc@tempa\\relax\n"
+ " \\nuc@emptyargerr\n"
+ " \\else\n"
+ " \\edef\\@tempb{\\expandafter\\@car\\nuc@tempa\\@nil}%\n"
+ " \\nuc@check\n"
+ " \\if@tempswa\n"
+ " \\@namedef{u8:\\nuc@tempa}{#2}%\n"
+ " \\fi\n"
+ " \\fi\n"
+ " }\n"
+ " \\makeatother\n";
+
+ t << " \\doxynewunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n"
+ " \\doxynewunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n"
+ " \\doxynewunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n"
+ "\n";
+}
+
+void filterLatexString(TextStream &t,const QCString &str,
+ bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces, const bool retainNewline)
+{
+ if (str.isEmpty()) return;
+ bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
+ //printf("filterLatexString(%s) insideTabbing=%d\n",qPrint(str),insideTabbing);
+ const char *p=str.data();
+ const char *q;
+ int cnt;
+ unsigned char c;
+ unsigned char pc='\0';
+
+ while (*p)
+ {
+ c=static_cast<unsigned char>(*p++);
+
+ if (insidePre)
+ {
+ switch(c)
+ {
+ case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
+ // the LaTeX command \ucr has been defined in doxygen.sty
+ if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
+ {
+ t << "{\\ucr}";
+ p += 2;
+ }
+ else
+ t << static_cast<char>(c);
+ break;
+ case '\\': t << "\\(\\backslash\\)"; break;
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '_': t << "\\_"; break;
+ case '&': t << "\\&"; break;
+ case '%': t << "\\%"; break;
+ case '#': t << "\\#"; break;
+ case '$': t << "\\$"; break;
+ case '"': t << "\"{}"; break;
+ case '-': t << "-\\/"; break;
+ case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break;
+ case '~': t << "\\string~"; break;
+ case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
+ break;
+ case ' ': if (keepSpaces) t << "~"; else t << ' ';
+ break;
+ default:
+ if (c<32) t << ' '; // non printable control character
+ else t << static_cast<char>(c);
+ break;
+ }
+ }
+ else
+ {
+ switch(c)
+ {
+ case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
+ // the LaTeX command \ucr has been defined in doxygen.sty
+ if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
+ {
+ t << "{\\ucr}";
+ p += 2;
+ }
+ else
+ t << static_cast<char>(c);
+ break;
+ case '#': t << "\\#"; break;
+ case '$': t << "\\$"; break;
+ case '%': t << "\\%"; break;
+ case '^': processEntity(t,pdfHyperlinks,"$^\\wedge$","\\string^"); break;
+ case '&': // possibility to have a special symbol
+ q = p;
+ cnt = 2; // we have to count & and ; as well
+ while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
+ {
+ cnt++;
+ q++;
+ }
+ if (*q == ';')
+ {
+ --p; // we need & as well
+ HtmlEntityMapper::SymType res = HtmlEntityMapper::instance().name2sym(QCString(p).left(cnt));
+ if (res == HtmlEntityMapper::Sym_Unknown)
+ {
+ p++;
+ t << "\\&";
+ }
+ else
+ {
+ t << HtmlEntityMapper::instance().latex(res);
+ q++;
+ p = q;
+ }
+ }
+ else
+ {
+ t << "\\&";
+ }
+ break;
+ case '*': processEntity(t,pdfHyperlinks,"$\\ast$","*"); break;
+ case '_': if (!insideTabbing) t << "\\+";
+ t << "\\_";
+ if (!insideTabbing) t << "\\+";
+ break;
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '<': t << "$<$"; break;
+ case '>': t << "$>$"; break;
+ case '|': processEntity(t,pdfHyperlinks,"$\\vert$","|"); break;
+ case '~': processEntity(t,pdfHyperlinks,"$\\sim$","\\string~"); break;
+ case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
+ t << "\\mbox{[}";
+ else
+ t << "[";
+ break;
+ case ']': if (pc=='[') t << "$\\,$";
+ if (Config_getBool(PDF_HYPERLINKS) || insideItem)
+ t << "\\mbox{]}";
+ else
+ t << "]";
+ break;
+ case '-': t << "-\\/";
+ break;
+ case '\\': t << "\\textbackslash{}";
+ break;
+ case '"': t << "\"{}";
+ break;
+ case '`': t << "\\`{}";
+ break;
+ case '\'': t << "\\textquotesingle{}";
+ break;
+ case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
+ break;
+ case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
+ break;
+
+ default:
+ //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
+ if (!insideTabbing &&
+ ((c>='A' && c<='Z' && pc!=' ' && !(pc>='A' && pc <= 'Z') && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c)))
+ )
+ {
+ t << "\\+";
+ }
+ if (c<32)
+ {
+ t << ' '; // non-printable control character
+ }
+ else
+ {
+ t << static_cast<char>(c);
+ }
+ }
+ }
+ pc = c;
+ }
+}
+
+QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces)
+{
+ TextStream t;
+ filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces);
+ return t.str();
+}
+
+QCString latexEscapeLabelName(const QCString &s)
+{
+ //printf("latexEscapeLabelName(%s)\n",qPrint(s));
+ if (s.isEmpty()) return s;
+ QCString tmp(s.length()+1);
+ TextStream t;
+ const char *p=s.data();
+ char c;
+ int i;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '|': t << "\\texttt{\"|}"; break;
+ case '!': t << "\"!"; break;
+ case '@': t << "\"@"; break;
+ case '%': t << "\\%"; break;
+ case '{': t << "\\lcurly{}"; break;
+ case '}': t << "\\rcurly{}"; break;
+ case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
+ // NOTE: adding a case here, means adding it to while below as well!
+ default:
+ i=0;
+ // collect as long string as possible, before handing it to docify
+ tmp[i++]=c;
+ while ((c=*p) && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
+ {
+ tmp[i++]=c;
+ p++;
+ }
+ tmp[i]=0;
+ filterLatexString(t,tmp,
+ true, // insideTabbing
+ false, // insidePre
+ false, // insideItem
+ false, // insideTable
+ false // keepSpaces
+ );
+ break;
+ }
+ }
+ return t.str();
+}
+
+QCString latexEscapeIndexChars(const QCString &s)
+{
+ //printf("latexEscapeIndexChars(%s)\n",qPrint(s));
+ if (s.isEmpty()) return s;
+ QCString tmp(s.length()+1);
+ TextStream t;
+ const char *p=s.data();
+ char c;
+ int i;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '!': t << "\"!"; break;
+ case '"': t << "\"\""; break;
+ case '@': t << "\"@"; break;
+ case '|': t << "\\texttt{\"|}"; break;
+ case '[': t << "["; break;
+ case ']': t << "]"; break;
+ case '{': t << "\\lcurly{}"; break;
+ case '}': t << "\\rcurly{}"; break;
+ // NOTE: adding a case here, means adding it to while below as well!
+ default:
+ i=0;
+ // collect as long string as possible, before handing it to docify
+ tmp[i++]=c;
+ while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
+ {
+ tmp[i++]=c;
+ p++;
+ }
+ tmp[i]=0;
+ filterLatexString(t,tmp,
+ true, // insideTabbing
+ false, // insidePre
+ false, // insideItem
+ false, // insideTable
+ false // keepSpaces
+ );
+ break;
+ }
+ }
+ return t.str();
+}
+
+QCString latexEscapePDFString(const QCString &s)
+{
+ if (s.isEmpty()) return s;
+ TextStream t;
+ const char *p=s.data();
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '\\': t << "\\textbackslash{}"; break;
+ case '{': t << "\\{"; break;
+ case '}': t << "\\}"; break;
+ case '_': t << "\\_"; break;
+ case '%': t << "\\%"; break;
+ case '&': t << "\\&"; break;
+ case '#': t << "\\#"; break;
+ case '$': t << "\\$"; break;
+ case '^': t << "\\string^"; break;
+ case '~': t << "\\string~"; break;
+ default:
+ t << c;
+ break;
+ }
+ }
+ return t.str();
+}
+
+QCString latexFilterURL(const QCString &s)
+{
+ constexpr auto hex = "0123456789ABCDEF";
+ if (s.isEmpty()) return s;
+ TextStream t;
+ const char *p=s.data();
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '#': t << "\\#"; break;
+ case '%': t << "\\%"; break;
+ case '\\': t << "\\\\"; break;
+ default:
+ if (c<0)
+ {
+ unsigned char id = static_cast<unsigned char>(c);
+ t << "\\%" << hex[id>>4] << hex[id&0xF];
+ }
+ else
+ {
+ t << c;
+ }
+ break;
+ }
+ }
+ return t.str();
+}
+
+