From c44fd3b5049ff3b16403c95ec51d1fa3f83412ce Mon Sep 17 00:00:00 2001 From: albert-github Date: Tue, 5 Jan 2021 14:56:23 +0100 Subject: bug 668003 Default LaTeX header misses $-placeholders Create, analogous to HTML, also for LaTeX default header and footer files. --- src/cite.cpp | 43 +--- src/cite.h | 5 +- src/config.xml | 201 +++++++++++++--- src/htmlgen.cpp | 113 +-------- src/index.cpp | 5 +- src/latexgen.cpp | 584 +++++++++++++-------------------------------- src/util.cpp | 114 +++++++++ src/util.h | 5 +- templates/latex/footer.tex | 50 ++++ templates/latex/header.tex | 249 +++++++++++++++++++ 10 files changed, 770 insertions(+), 599 deletions(-) create mode 100755 templates/latex/footer.tex create mode 100644 templates/latex/header.tex diff --git a/src/cite.cpp b/src/cite.cpp index e02641a..ab090e0 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -417,35 +417,9 @@ void CitationManager::generatePage() } } -void CitationManager::writeLatexBibliography(FTextStream &t) const +QCString CitationManager::latexBibFiles() { - if (p->entries.empty()) return; - - QCString style = Config_getString(LATEX_BIB_STYLE); - if (style.isEmpty()) - { - style="plain"; - } - QCString unit; - if (Config_getBool(COMPACT_LATEX)) - { - unit = "section"; - } - else - { - unit = "chapter"; - } - t << "% Bibliography\n" - "\\newpage\n" - "\\phantomsection\n"; - bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - if (!pdfHyperlinks) - { - t << "\\clearemptydoublepage\n"; - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; - } - t << "\\bibliographystyle{" << style << "}\n" - "\\bibliography{"; + QCString result; const StringVector &citeDataList = Config_getList(CITE_BIB_FILES); int i = 0; for (const auto &bibdata : citeDataList) @@ -458,17 +432,12 @@ void CitationManager::writeLatexBibliography(FTextStream &t) const { if (!bibFile.isEmpty()) { - if (i) t << ","; + if (i) result += ","; i++; - t << bibTmpFile << QCString().setNum(i); + result += bibTmpFile; + result += QCString().setNum(i); } } } - t << "}\n"; - if (pdfHyperlinks) - { - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; - } - t << "\n"; + return result; } - diff --git a/src/cite.h b/src/cite.h index 9fea954..adf0840 100644 --- a/src/cite.h +++ b/src/cite.h @@ -59,10 +59,9 @@ class CitationManager */ bool isEmpty() const; - /** writes the latex code for the standard bibliography - * section to text stream \a t + /** lists the bibtex cite files in a comma separated list */ - void writeLatexBibliography(FTextStream &t) const; + QCString latexBibFiles(); const char *fileName() const; const char *anchorPrefix() const; diff --git a/src/config.xml b/src/config.xml index c0b846a..9c0ccc8 100644 --- a/src/config.xml +++ b/src/config.xml @@ -1853,34 +1853,50 @@ doxygen -w html new_header.html new_footer.html new_stylesheet.css YourConfigFil -
\$title
will be replaced with the title of the page. -
\$datetime
will be replaced with current the date and time. -
\$date
will be replaced with the current date. -
\$year
will be replaces with the current year. -
\$doxygenversion
will be replaced with the version of doxygen -
\$projectname
will be replaced with the name of +
$title
will be replaced with the title of the page. +
$datetime
will be replaced with current the date and time. +
$date
will be replaced with the current date. +
$year
will be replaces with the current year. +
$doxygenversion
will be replaced with the version of doxygen +
$projectname
will be replaced with the name of the project (see \ref cfg_project_name "PROJECT_NAME") -
\$projectnumber
will be replaced with the project number +
$projectnumber
will be replaced with the project number (see \ref cfg_project_number "PROJECT_NUMBER") -
\$projectbrief
will be replaced with the project brief +
$projectbrief
will be replaced with the project brief description (see \ref cfg_project_brief "PROJECT_BRIEF") -
\$projectlogo
will be replaced with the project logo +
$projectlogo
will be replaced with the project logo (see \ref cfg_project_logo "PROJECT_LOGO") -
\$treeview
will be replaced with links to +
$generatedby
will be replaced with the output language dependent + version of the text "Generated by" or when the + \ref cfg_html_timestamp "HTML_TIMESTAMP" is set by the output language + dependent version of the text "Generated on `$datetime` for `$projectname` by". +
$stylesheet
will be replaced with the setting of + \ref cfg_html_stylesheet "HTML_STYLESHEET" unless it is empty or the file in which case + it is replaced by the default setting `doxygen.css`. +
$extrastylesheet
will be replaced with the setting of + \ref cfg_html_extra_stylesheet "HTML_EXTRA_STYLESHEET" including the required + HTML tags for each extra stylesheet. +
$treeview
will be replaced with links to the javascript and style sheets needed for the navigation tree (or an empty string when \ref cfg_generate_treeview "GENERATE_TREEVIEW" is disabled). -
\$search
will be replaced with a links to +
$search
will be replaced with a links to the javascript and style sheets needed for the search engine (or an empty string when \ref cfg_searchengine "SEARCHENGINE" is disabled). -
\$mathjax
will be replaced with a links to +
$searchbox
will be replaced with the HTML code needed for + the search box to be shown + (or an empty string when \ref cfg_searchengine "SEARCHENGINE" + is disabled). +
$mathjax
will be replaced with a links to the javascript and style sheets needed for the MathJax feature (or an empty string when \ref cfg_use_mathjax "USE_MATHJAX" is disabled). -
\$relpath^
- If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command \$relpath^ can be - used to produce a relative path to the root of the HTML output directory, - e.g. use \$relpath^doxygen.css, to refer to the standard style sheet. +
$relpath^
+ If \ref cfg_create_subdirs "CREATE_SUBDIRS" is enabled, the command $relpath^ can be + used to produce a relative path to the root of the HTML output directory, + e.g. use $relpath^doxygen.css, to refer to the standard style sheet. +
$navpath
will be replaced with a path as required by + \ref cfg_generate_treeview "GENERATE_TREEVIEW" To cope with differences in the layout of the header and footer that depend on @@ -2737,38 +2753,165 @@ or
$title
will be replaced with the project name. +
$datetime
will be replaced with current the date and time. +
$date
will be replaced with the current date. +
$year
will be replaces with the current year. +
$doxygenversion
will be replaced with the version of doxygen +
$projectname
will be replaced with the name of + the project (see \ref cfg_project_name "PROJECT_NAME") +
$projectnumber
will be replaced with the project number + (see \ref cfg_project_number "PROJECT_NUMBER") +
$projectbrief
will be replaced with the project brief + description (see \ref cfg_project_brief "PROJECT_BRIEF") +
$projectlogo
will be replaced with the project logo + (see \ref cfg_project_logo "PROJECT_LOGO") +
$latexdocumentpre
will be replaced by an output language dependent setting + e.g. embed the entire document in a special environment (for Chinese, Japanese etc.) + Commonly used together with `$latexdocumentpost` in the footer. +
$latexdocumentpost
will be replaced by an output language dependent setting + e.g. embed the entire document in a special environment (for Chinese, Japanese etc.) + Commonly used together with `$latexdocumentpre` in the header. +
$generatedby
will be replaced with the output language dependent + version of the text "Generated by" or when the + \ref cfg_latex_timestamp "LATEX_TIMESTAMP" is set by the output language + dependent version of the text "Generated on `$datetime` for `$projectname` by". +
$latexcitereference
will be replaced by the output language dependent$ + version of the word "Bibliography". + This setting is typically used in combination with the block name `CITATIONS_PRESENT`. +
$latexbibstyle
will be replaced with the latex bib style to be used as + as set by \ref cfg_latex_bib_style "LATEX_BIB_STYLE", in case nothing is set the bib style + `plain` is used. + This setting is typically used in combination with the block name `CITATIONS_PRESENT`. +
$latexbibfiles
will be replaced by the comma separeted list of `bib. files + as set by \ref cfg_cite_bib_files "CITE_BIB_FILES" (when necessary a missing `.bib` is + automatically added). + This setting is typically used in combination with the block name `CITATIONS_PRESENT`. +
$papertype
will be replaced by the paper type as set in + \ref cfg_paper_type "PAPER_TYPE" and the word "paper" is directly appended to it to have + a correct \f$\mbox{\LaTeX}\f$ paper type. +
$languagesupport
will be replaced by an output language dependent setting + of packages required for translating terms of the specified language. +
$latexfontenc
will be replaced by an output language dependent setting + of the fontencoding to be used. + This setting is typically used in combination with the block name `LATEX_FONTENC`. +
$latexfont
will be replaced by an output language dependent setting + of the fonts to be used. +
$latexemojidirectory
will be replaced by the directory as set in + \ref cfg_latex_emoji_directory "LATEX_EMOJI_DIRECTORY" with the backslashes replaced by + forward slashes (so usable by \f$\mbox{\LaTeX}\f$). In case the + \ref cfg_latex_emoji_directory "LATEX_EMOJI_DIRECTORY" is + empty, the current directory will be used. +
$makeindex
will be replaced by the command as set in + \ref cfg_latex_makeindex_cmd "LATEX_MAKEINDEX_CMD". Then the command doesn't start with + a backslash, a backslash is automatically prepended. In case the setting is empty the + command `\makeindex` is used. +
$extralatexpackages
will be replaced by commands for usinging the packages set + in \ref cfg_extra_packages "EXTRA_PACKAGES". +
$extralatexstylesheet
will be replaced by commands for usinging the packages set + in \ref cfg_latex_extra_stylesheet "LATEX_EXTRA_STYLESHEET" (when the extension is the default + extension, `.sty`, this extension is stripped for the package name). +
$latexspecialformulachars
will be replaced by the code for some special + unicode characters that are commonly used (i.e. superscript minus, superscript 2 and superscript 3) +
$formulamacrofile
will be replaced by the name of the file as set + in \ref cfg_formula_macrofile "FORMULA_MACROFILE". + This setting is typically used in combination with the block name `FORMULA_MACROFILE`. + + +To cope with differences in the layout of the header and footer that depend on + configuration settings, the header and footer can also contain special blocks that + will be copied to the output or skipped depending on the configuration. + Such blocks have the following form: +\verbatim + %%BEGIN BLOCKNAME + Some context copied when condition BLOCKNAME holds + %%END BLOCKNAME + %%BEGIN !BLOCKNAME + Some context copied when condition BLOCKNAME does not hold + %%END !BLOCKNAME +\endverbatim +The following block names are set based on the used settings in the + configuration file: +
+
COMPACT_LATEX
Content within this block is copied to the output + when the \ref cfg_compact_latex "COMPACT_LATEX" option is enabled. +
PDF_HYPERLINKS
Content within this block is copied to the output + when the \ref cfg_pdf_hyperlinks "PDF_HYPERLINKS" option is enabled. +
USE_PDFLATEX
Content within this block is copied to the output + when the \ref cfg_use_pdflatex "USE_PDFLATEX" option is enabled. +
LATEX_BATCHMODE
Content within this block is copied to the output + when the \ref cfg_latex_batchmode "LATEX_BATCHMODE" option is enabled. +
LATEX_TIMESTAMP
Content within this block is copied to the output + when the \ref cfg_latex_timestamp "LATEX_TIMESTAMP" option is enabled. +
+The following block names are set based on the fact whether or not the tag has a + value in the used configuration file: +
+
LATEX_FONTENC
Content within this block is copied to the output + when the doxygen latex translator function returns a value for the font encoding + to be used. It is to be used in combination with the above mentioned `$latexfontenc`. +
FORMULA_MACROFILE
Content within this block is copied to the output + when the \ref cfg_formula_macrofile "FORMULA_MACROFILE" option is not empty. It is + to be used in combination with the above mentioned `$formulamacrofile`. +
+The following block name is set based on whether or not a feature is used in the + documentation: +
+
CITATIONS_PRESENT
Content within this block is copied to the output + when in the documentation citations are present and the relevant .. are present. + It is to be used in combination with the above mentioned `$latexcitereference`, + `$latexbibstyle` and `$latexbibfiles`. +
+]]> + + + diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index e186c37..a9032b1 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -296,73 +296,6 @@ static QCString getConvertLatexMacro() out.addChar(0); return out.get(); } -//------------------------------------------------------------------------ - -/// Clear a text block \a s from \a begin to \a end markers -QCString clearBlock(const char *s,const char *begin,const char *end) -{ - if (s==0 || begin==0 || end==0) return s; - const char *p, *q; - int beginLen = qstrlen(begin); - int endLen = qstrlen(end); - int resLen = 0; - for (p=s; (q=strstr(p,begin))!=0; p=q+endLen) - { - resLen+=(int)(q-p); - p=q+beginLen; - if ((q=strstr(p,end))==0) - { - resLen+=beginLen; - break; - } - } - resLen+=qstrlen(p); - // resLen is the length of the string without the marked block - - QCString result(resLen+1); - char *r; - for (r=result.rawData(), p=s; (q=strstr(p,begin))!=0; p=q+endLen) - { - int l = (int)(q-p); - memcpy(r,p,l); - r+=l; - p=q+beginLen; - if ((q=strstr(p,end))==0) - { - memcpy(r,begin,beginLen); - r+=beginLen; - break; - } - } - qstrcpy(r,p); - return result; -} -//---------------------------------------------------------------------- - -QCString selectBlock(const QCString& s,const QCString &name,bool enable) -{ - // TODO: this is an expensive function that is called a lot -> optimize it - const QCString begin = ""; - const QCString end = ""; - const QCString nobegin = ""; - const QCString noend = ""; - - QCString result = s; - if (enable) - { - result = substitute(result, begin, ""); - result = substitute(result, end, ""); - result = clearBlock(result, nobegin, noend); - } - else - { - result = substitute(result, nobegin, ""); - result = substitute(result, noend, ""); - result = clearBlock(result, begin, end); - } - - return result; -} static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch) { @@ -379,36 +312,6 @@ static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSe return QCString(result); } -static QCString removeEmptyLines(const QCString &s) -{ - BufStr out(s.length()+1); - const char *p=s.data(); - if (p) - { - char c; - while ((c=*p++)) - { - if (c=='\n') - { - const char *e = p; - while (*e==' ' || *e=='\t') e++; - if (*e=='\n') - { - p=e; - } - else out.addChar(c); - } - else - { - out.addChar(c); - } - } - } - out.addChar('\0'); - //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data()); - return out.data(); -} - static QCString substituteHtmlKeywords(const QCString &str, const QCString &title, const QCString &relPath, @@ -592,14 +495,14 @@ static QCString substituteHtmlKeywords(const QCString &str, result = substitute(result,"$relpath^",relPath); //<-- must be last // additional HTML only conditional blocks - result = selectBlock(result,"DISABLE_INDEX",disableIndex); - result = selectBlock(result,"GENERATE_TREEVIEW",treeView); - result = selectBlock(result,"SEARCHENGINE",searchEngine); - result = selectBlock(result,"TITLEAREA",titleArea); - result = selectBlock(result,"PROJECT_NAME",hasProjectName); - result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber); - result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief); - result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo); + result = selectBlock(result,"DISABLE_INDEX",disableIndex,OutputGenerator::Html); + result = selectBlock(result,"GENERATE_TREEVIEW",treeView,OutputGenerator::Html); + result = selectBlock(result,"SEARCHENGINE",searchEngine,OutputGenerator::Html); + result = selectBlock(result,"TITLEAREA",titleArea,OutputGenerator::Html); + result = selectBlock(result,"PROJECT_NAME",hasProjectName,OutputGenerator::Html); + result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber,OutputGenerator::Html); + result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief,OutputGenerator::Html); + result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo,OutputGenerator::Html); result = removeEmptyLines(result); diff --git a/src/index.cpp b/src/index.cpp index e2e5ea1..c71e8fb 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -4233,10 +4233,7 @@ static void writeIndex(OutputList &ol) ol.startFile("refman",0,0); ol.startIndexSection(isTitlePageStart); - if (!Config_getString(LATEX_HEADER).isEmpty()) - { - ol.disable(OutputGenerator::Latex); - } + ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::Docbook); if (projPrefix.isEmpty()) diff --git a/src/latexgen.cpp b/src/latexgen.cpp index ece344f..e73f6b8 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -44,6 +44,9 @@ #include "resourcemgr.h" #include "portable.h" +static QCString g_header; +static QCString g_footer; + LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName) : m_relPath(relPath), m_sourceFileName(sourceFileName) { @@ -483,359 +486,29 @@ void LatexGenerator::init() term("Could not create output directory %s\n",dname.data()); } - writeLatexMakefile(); - writeMakeBat(); - - createSubDirs(d); -} - -static void writeDefaultHeaderPart1(FTextStream &t) -{ - // part 1 - - // Handle batch mode - if (Config_getBool(LATEX_BATCHMODE)) - t << "\\batchmode\n"; - - // to overcome problems with too many open files - t << "\\let\\mypdfximage\\pdfximage" - "\\def\\pdfximage{\\immediate\\mypdfximage}"; - - // Set document class depending on configuration - QCString documentClass; - if (Config_getBool(COMPACT_LATEX)) - documentClass = "article"; - else - documentClass = "book"; - t << "\\documentclass[twoside]{" << documentClass << "}\n" - "\n"; - t << "%% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package\n" - "\\usepackage{ifthen}\n" - "\\ifx\\requestedLaTeXdate\\undefined\n" - "\\usepackage{array}\n" - "\\else\n" - "\\usepackage{array}[=2016-10-06]\n" - "\\fi\n" - "%%\n"; - - // Load required packages - t << "% Packages required by doxygen\n" - "\\usepackage{fixltx2e}\n" // for \textsubscript - "\\usepackage{doxygen}\n"; - const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET); - for (const auto &extraStyle : extraLatexStyles) - { - QCString fileName = extraStyle.c_str(); - if (!fileName.isEmpty()) - { - QFileInfo fi(fileName); - if (fi.exists()) - { - if (checkExtension(fi.fileName().data(), LATEX_STYLE_EXTENSION)) - { - // strip the extension, it will be added by the usepackage in the tex conversion process - t << "\\usepackage{" << stripExtensionGeneral(fi.fileName().data(), LATEX_STYLE_EXTENSION) << "}\n"; - } - else - { - t << "\\usepackage{" << fi.fileName().utf8() << "}\n"; - } - } - } - } - t << "\\usepackage{graphicx}\n" - "\\usepackage[utf8]{inputenc}\n" - "\\usepackage{makeidx}\n" - "\\PassOptionsToPackage{warn}{textcomp}\n" - "\\usepackage{textcomp}\n" - "\\usepackage[nointegrals]{wasysym}\n" - "\\usepackage{ifxetex}\n" - "\n"; - - // Language support - QCString languageSupport = theTranslator->latexLanguageSupportCommand(); - if (!languageSupport.isEmpty()) - { - t << "% NLS support packages\n" - << languageSupport - << "\n"; - } - - // Define default fonts - t << "% Font selection\n"; - QCString fontenc = theTranslator->latexFontenc(); - if (!fontenc.isEmpty()) - { - t << "\\usepackage[" << fontenc << "]{fontenc}\n"; - } - QCString font = theTranslator->latexFont(); - if (!font.isEmpty()) - { - t << font; - } - t << "\\usepackage{sectsty}\n" - "\\allsectionsfont{%\n" - " \\fontseries{bc}\\selectfont%\n" - " \\color{darkgray}%\n" - "}\n" - "\\renewcommand{\\DoxyLabelFont}{%\n" - " \\fontseries{bc}\\selectfont%\n" - " \\color{darkgray}%\n" - "}\n" - "\\newcommand{\\+}{\\discretionary{\\mbox{\\scriptsize$\\hookleftarrow$}}{}{}}\n" - "\n"; - - QCString emojiDir=Config_getString(LATEX_EMOJI_DIRECTORY); - if (emojiDir.isEmpty()) emojiDir = "."; - emojiDir = substitute(emojiDir,"\\","/"); - t << "% Arguments of doxygenemoji:\n" - "% 1) '::' form of the emoji, already \"LaTeX\"-escaped\n" - "% 2) file with the name of the emoji without the .png extension\n" - "% in case image exist use this otherwise use the '::' form\n"; - t << "\\newcommand{\\doxygenemoji}[2]{%\n" - " \\IfFileExists{" << emojiDir << "/#2.png}{\\raisebox{-0.1em}{\\includegraphics[height=0.9em]{" << emojiDir << "/#2.png}}}{#1}%\n" - "}\n"; - - // Define page & text layout - QCString paperName=Config_getEnum(PAPER_TYPE); - // "a4wide" package is obsolete (see bug 563698) - t << "% Page & text layout\n" - "\\usepackage{geometry}\n" - "\\geometry{%\n" - " " << paperName << "paper,%\n" - " top=2.5cm,%\n" - " bottom=2.5cm,%\n" - " left=2.5cm,%\n" - " right=2.5cm%\n" - "}\n"; - // \sloppy is obsolete (see bug 563698) - // Allow a bit of overflow to go unnoticed by other means - t << "\\tolerance=750\n" - "\\hfuzz=15pt\n" - "\\hbadness=750\n" - "\\setlength{\\emergencystretch}{15pt}\n" - "\\setlength{\\parindent}{0cm}\n" - "\\newcommand{\\doxynormalparskip}{\\setlength{\\parskip}{3ex plus 2ex minus 2ex}}\n" - "\\newcommand{\\doxytocparskip}{\\setlength{\\parskip}{1ex plus 0ex minus 0ex}}\n" - "\\doxynormalparskip\n"; - // Redefine paragraph/subparagraph environments, using sectsty fonts - t << "\\makeatletter\n" - "\\renewcommand{\\paragraph}{%\n" - " \\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%\n" - " \\normalfont\\normalsize\\bfseries\\SS@parafont%\n" - " }%\n" - "}\n" - "\\renewcommand{\\subparagraph}{%\n" - " \\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%\n" - " \\normalfont\\normalsize\\bfseries\\SS@subparafont%\n" - " }%\n" - "}\n" - "\\makeatother\n" - "\n"; - // - t << "\\makeatletter\n" - "\\newcommand\\hrulefilll{\\leavevmode\\leaders\\hrule\\hskip 0pt plus 1filll\\kern\\z@}\n" - "\\makeatother\n" - "\n"; - - // Headers & footers - QGString genString; - QCString generatedBy; - bool timeStamp = Config_getBool(LATEX_TIMESTAMP); - FTextStream tg(&genString); - if (timeStamp) + if (!Config_getString(LATEX_HEADER).isEmpty()) { - generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), Config_getString(PROJECT_NAME)); + g_header=fileToString(Config_getString(LATEX_HEADER)); + //printf("g_header='%s'\n",g_header.data()); } else { - generatedBy = theTranslator->trGeneratedBy(); + g_header = ResourceMgr::instance().getAsString("header.tex"); } - filterLatexString(tg, generatedBy, - false, // insideTabbing - false, // insidePre - false, // insideItem - false, // insideTable - false // keepSpaces - ); - t << "% Headers & footers\n" - "\\usepackage{fancyhdr}\n" - "\\pagestyle{fancyplain}\n" - "\\renewcommand{\\footrulewidth}{0.4pt}\n" - "%\n" - "\\fancypagestyle{fancyplain}{\n" - "\\fancyhf{}\n" - "\\fancyhead[LE, RO]{\\bfseries\\thepage}\n" - "\\fancyhead[LO]{\\bfseries\\rightmark}\n" - "\\fancyhead[RE]{\\bfseries\\leftmark}\n" - "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n" - "}\n" - "%\n" - "\\fancypagestyle{plain}{\n" - "\\fancyhf{}\n" - "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n" - "\\renewcommand{\\headrulewidth}{0pt}}\n" - "%\n" - "\\pagestyle{fancyplain}\n" - "%\n"; - - if (!Config_getBool(COMPACT_LATEX)) - { - t << "\\renewcommand{\\chaptermark}[1]{%\n" - " \\markboth{#1}{}%\n" - "}\n"; - } - t << "\\renewcommand{\\sectionmark}[1]{%\n" - " \\markright{\\thesection\\ #1}%\n" - "}\n" - "\n"; - - // ToC, LoF, LoT, bibliography, and index - t << "% Indices & bibliography\n" - "\\usepackage{natbib}\n" - "\\usepackage[titles]{tocloft}\n" - "\\setcounter{tocdepth}{3}\n" - "\\setcounter{secnumdepth}{5}\n"; - - QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD); - if (!latex_mkidx_command.isEmpty()) + if (!Config_getString(LATEX_FOOTER).isEmpty()) { - if (latex_mkidx_command[0] == '\\') - t << latex_mkidx_command << "\n"; - else - t << '\\' << latex_mkidx_command << "\n"; + g_footer=fileToString(Config_getString(LATEX_FOOTER)); + //printf("g_footer='%s'\n",g_footer.data()); } else { - t << "\\makeindex\n"; + g_footer = ResourceMgr::instance().getAsString("footer.tex"); } - t << "\n"; - writeExtraLatexPackages(t); - writeLatexSpecialFormulaChars(t); - QCString macroFile = Config_getString(FORMULA_MACROFILE); - if (!macroFile.isEmpty()) - { - QFileInfo fi(macroFile); - macroFile=fi.absFilePath().utf8(); - QCString stripMacroFile = fi.fileName().data(); - copyFile(macroFile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile); - t << "\\input{" << stripMacroFile << "}" << endl; - } + writeLatexMakefile(); + writeMakeBat(); - // Hyperlinks - bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - if (pdfHyperlinks) - { - t << "% Hyperlinks (required, but should be loaded last)\n" - "\\ifpdf\n" - " \\usepackage[pdftex,pagebackref=true]{hyperref}\n" - "\\else\n" - " \\ifxetex\n" - " \\usepackage[pagebackref=true]{hyperref}\n" - " \\else\n" - " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n" - " \\fi\n" - "\\fi\n" - "\n" - "\\hypersetup{%\n" - " colorlinks=true,%\n" - " linkcolor=blue,%\n" - " citecolor=blue,%\n" - " unicode%\n" - "}\n" - "\n"; - } - - // Custom commands used by the header - t << "% Custom commands\n" - "\\newcommand{\\clearemptydoublepage}{%\n" - " \\newpage{\\pagestyle{empty}\\cleardoublepage}%\n" - "}\n" - "\n"; - - // caption style definition - t << "\\usepackage{caption}\n" - << "\\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}\n\n"; - - - // in page table of contents - t << "\\usepackage{etoc}\n" - "\\etocsettocstyle{\\doxytocparskip}{\\doxynormalparskip}\n"; - - // prevent numbers overlap the titles in toc - t << "\\renewcommand{\\numberline}[1]{#1~}\n"; - - // End of preamble, now comes the document contents - t << "%===== C O N T E N T S =====\n" - "\n" - "\\begin{document}\n" - "\\raggedbottom\n"; - QCString documentPre = theTranslator->latexDocumentPre(); - if (!documentPre.isEmpty()) - { - t << documentPre; - } - t << "\n"; - - // Front matter - t << "% Titlepage & ToC\n"; - bool usePDFLatex = Config_getBool(USE_PDFLATEX); - if (pdfHyperlinks && usePDFLatex) - { - // To avoid duplicate page anchors due to reuse of same numbers for - // the index (be it as roman numbers) - t << "\\hypersetup{pageanchor=false,\n" - // << " bookmarks=true,\n" // commented out to prevent warning - << " bookmarksnumbered=true,\n" - << " pdfencoding=unicode\n" - << " }\n"; - } - t << "\\pagenumbering{alph}\n" - "\\begin{titlepage}\n" - "\\vspace*{7cm}\n" - "\\begin{center}%\n" - "{\\Large "; -} - -static void writeDefaultHeaderPart2(FTextStream &t) -{ - // part 2 - // Finalize project name - t << "}\\\\\n" - "\\vspace*{1cm}\n" - "{\\large "; -} - -static void writeDefaultHeaderPart3(FTextStream &t) -{ - // part 3 - // Finalize project number - t << " Doxygen " << getDoxygenVersion() << "}\\\\\n"; - if (Config_getBool(LATEX_TIMESTAMP)) - t << "\\vspace*{0.5cm}\n" - "{\\small " << dateToString(TRUE) << "}\\\\\n"; - t << "\\end{center}\n" - "\\end{titlepage}\n"; - bool compactLatex = Config_getBool(COMPACT_LATEX); - if (!compactLatex) - t << "\\clearemptydoublepage\n"; - t << "\\pagenumbering{roman}\n"; - - // ToC - t << "\\tableofcontents\n"; - if (!compactLatex) - t << "\\clearemptydoublepage\n"; - t << "\\pagenumbering{arabic}\n"; - bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - bool usePDFLatex = Config_getBool(USE_PDFLATEX); - if (pdfHyperlinks && usePDFLatex) - { - // re-enable anchors again - t << "\\hypersetup{pageanchor=true}\n"; - } - t << "\n" - "%--- Begin generated contents ---\n"; + createSubDirs(d); } static void writeDefaultStyleSheet(FTextStream &t) @@ -843,56 +516,18 @@ static void writeDefaultStyleSheet(FTextStream &t) t << ResourceMgr::instance().getAsString("doxygen.sty"); } -static void writeDefaultFooter(FTextStream &t) -{ - t << "%--- End generated contents ---\n" - "\n"; - - // Bibliography - CitationManager::instance().writeLatexBibliography(t); - - // Index - t << "% Index\n"; - QCString unit; - if (Config_getBool(COMPACT_LATEX)) - { - unit = "section"; - } - else - { - unit = "chapter"; - t << "\\backmatter\n"; - } - t << "\\newpage\n" - "\\phantomsection\n" - "\\clearemptydoublepage\n" - "\\addcontentsline{toc}{" << unit << "}{\\indexname}\n" - "\\printindex\n" - "\n"; - QCString documentPost = theTranslator->latexDocumentPost(); - if (!documentPost.isEmpty()) - { - t << documentPost; - } - t << "\\end{document}\n"; -} - void LatexGenerator::writeHeaderFile(QFile &f) { FTextStream t(&f); t << "% Latex header for doxygen " << getDoxygenVersion() << endl; - writeDefaultHeaderPart1(t); - t << "Your title here"; - writeDefaultHeaderPart2(t); - t << "Generated by"; - writeDefaultHeaderPart3(t); + t << ResourceMgr::instance().getAsString("header.tex"); } void LatexGenerator::writeFooterFile(QFile &f) { FTextStream t(&f); t << "% Latex footer for doxygen " << getDoxygenVersion() << endl; - writeDefaultFooter(t); + t << ResourceMgr::instance().getAsString("footer.tex"); } void LatexGenerator::writeStyleSheetFile(QFile &f) @@ -932,33 +567,164 @@ void LatexGenerator::startProjectNumber() t << "\\\\[1ex]\\large "; } -void LatexGenerator::startIndexSection(IndexSections is) +static QCString extraLatexStyleSheet() { - bool compactLatex = Config_getBool(COMPACT_LATEX); - QCString latexHeader = Config_getString(LATEX_HEADER); - switch (is) + QCString result; + const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET); + for (const auto &extraStyle : extraLatexStyles) { - case isTitlePageStart: + QCString fileName = extraStyle.c_str(); + if (!fileName.isEmpty()) + { + QFileInfo fi(fileName); + if (fi.exists()) { - if (latexHeader.isEmpty()) + result += "\\usepackage{"; + if (checkExtension(fi.fileName().data(), LATEX_STYLE_EXTENSION)) { - writeDefaultHeaderPart1(t); + // strip the extension, it will be added by the usepackage in the tex conversion process + result += stripExtensionGeneral(fi.fileName().data(), LATEX_STYLE_EXTENSION); } else { - QCString header = fileToString(latexHeader); - t << substituteKeywords(header,"", - convertToLaTeX(Config_getString(PROJECT_NAME)), - convertToLaTeX(Config_getString(PROJECT_NUMBER)), - convertToLaTeX(Config_getString(PROJECT_BRIEF))); + result += fi.fileName().utf8(); } + result += "}\n"; } + } + } + return result; +} + +static QCString makeIndex() +{ + QCString result; + QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD); + if (!latex_mkidx_command.isEmpty()) + { + if (latex_mkidx_command[0] == '\\') + result += latex_mkidx_command; + else + result += '\\'+latex_mkidx_command; + } + else + { + result += "\\makeindex"; + } + return result; +} + +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_getString(PAPER_TYPE); + + QCString style = Config_getString(LATEX_BIB_STYLE); + if (style.isEmpty()) + { + style="plain"; + } + + QGString genString; + FTextStream tg(&genString); + QCString generatedBy; + bool timeStamp = Config_getBool(LATEX_TIMESTAMP); + if (timeStamp) + { + generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), Config_getString(PROJECT_NAME)); + } + else + { + generatedBy = theTranslator->trGeneratedBy(); + } + filterLatexString(tg, generatedBy, + false, // insideTabbing + false, // insidePre + false, // insideItem + false, // insideTable + false // keepSpaces + ); + generatedBy = genString; + + QCString latexFontenc = theTranslator->latexFontenc(); + + QCString latexEmojiDirectory = Config_getString(LATEX_EMOJI_DIRECTORY); + if (latexEmojiDirectory.isEmpty()) latexEmojiDirectory = "."; + latexEmojiDirectory = substitute(latexEmojiDirectory,"\\","/"); + + QGString genExtraLatexPackages; + FTextStream tg1(&genExtraLatexPackages); + writeExtraLatexPackages(tg1); + QCString extraLatexPackages; + extraLatexPackages = genExtraLatexPackages; + + QGString genLatexSpecialFormulaChars; + FTextStream tg2(&genLatexSpecialFormulaChars); + writeLatexSpecialFormulaChars(tg2); + QCString latexSpecialFormulaChars; + latexSpecialFormulaChars = genLatexSpecialFormulaChars; + + QCString formulaMacrofile = Config_getString(FORMULA_MACROFILE); + if (!formulaMacrofile.isEmpty()) + { + QFileInfo fi(formulaMacrofile); + formulaMacrofile=fi.absFilePath().utf8(); + QCString stripMacroFile = fi.fileName().data(); + copyFile(formulaMacrofile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile); + } + + // first substitute generic keywords + QCString result = substituteKeywords(str,title, + convertToLaTeX(Config_getString(PROJECT_NAME)), + convertToLaTeX(Config_getString(PROJECT_NUMBER)), + convertToLaTeX(Config_getString(PROJECT_BRIEF))); + + // 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",formulaMacrofile); + + // 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 = removeEmptyLines(result); + + return result; +} + +void LatexGenerator::startIndexSection(IndexSections is) +{ + bool compactLatex = Config_getBool(COMPACT_LATEX); + switch (is) + { + case isTitlePageStart: + t << substituteLatexKeywords(g_header,convertToLaTeX(Config_getString(PROJECT_NAME))); break; case isTitlePageAuthor: - if (latexHeader.isEmpty()) - { - writeDefaultHeaderPart2(t); - } break; case isMainPage: if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; @@ -978,7 +744,7 @@ void LatexGenerator::startIndexSection(IndexSections is) break; case isNamespaceIndex: if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; - t << "{"; //Namespace Index}\" + t << "{"; //Namespace Index}\n" break; case isClassHierarchyIndex: if (compactLatex) t << "\\doxysection"; else t << "\\chapter"; @@ -1094,19 +860,12 @@ void LatexGenerator::startIndexSection(IndexSections is) void LatexGenerator::endIndexSection(IndexSections is) { - //bool compactLatex = Config_getBool(COMPACT_LATEX); bool sourceBrowser = Config_getBool(SOURCE_BROWSER); - QCString latexHeader = Config_getString(LATEX_HEADER); - QCString latexFooter = Config_getString(LATEX_FOOTER); switch (is) { case isTitlePageStart: break; case isTitlePageAuthor: - if (latexHeader.isEmpty()) - { - writeDefaultHeaderPart3(t); - } break; case isMainPage: { @@ -1268,18 +1027,7 @@ void LatexGenerator::endIndexSection(IndexSections is) case isPageDocumentation2: break; case isEndIndex: - if (latexFooter.isEmpty()) - { - writeDefaultFooter(t); - } - else - { - QCString footer = fileToString(latexFooter); - t << substituteKeywords(footer,"", - convertToLaTeX(Config_getString(PROJECT_NAME)), - convertToLaTeX(Config_getString(PROJECT_NUMBER)), - convertToLaTeX(Config_getString(PROJECT_BRIEF))); - } + t << substituteLatexKeywords(g_footer,convertToLaTeX(Config_getString(PROJECT_NAME))); break; } } @@ -2320,5 +2068,3 @@ void LatexGenerator::writeLabel(const char *l,bool isLast) void LatexGenerator::endLabels() { } - - diff --git a/src/util.cpp b/src/util.cpp index 0c6d8fd..6f2ffc2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -7334,3 +7334,117 @@ FortranFormat convertFileNameFortranParserCode(QCString fn) return FortranFormat_Unknown; } +//------------------------------------------------------------------------ + +/// Clear a text block \a s from \a begin to \a end markers +QCString clearBlock(const char *s,const char *begin,const char *end) +{ + if (s==0 || begin==0 || end==0) return s; + const char *p, *q; + int beginLen = qstrlen(begin); + int endLen = qstrlen(end); + int resLen = 0; + for (p=s; (q=strstr(p,begin))!=0; p=q+endLen) + { + resLen+=(int)(q-p); + p=q+beginLen; + if ((q=strstr(p,end))==0) + { + resLen+=beginLen; + break; + } + } + resLen+=qstrlen(p); + // resLen is the length of the string without the marked block + + QCString result(resLen+1); + char *r; + for (r=result.rawData(), p=s; (q=strstr(p,begin))!=0; p=q+endLen) + { + int l = (int)(q-p); + memcpy(r,p,l); + r+=l; + p=q+beginLen; + if ((q=strstr(p,end))==0) + { + memcpy(r,begin,beginLen); + r+=beginLen; + break; + } + } + qstrcpy(r,p); + return result; +} +//---------------------------------------------------------------------- + +QCString selectBlock(const QCString& s,const QCString &name,bool enable, OutputGenerator::OutputType o) +{ + // TODO: this is an expensive function that is called a lot -> optimize it + QCString begin; + QCString end; + QCString nobegin; + QCString noend; + switch (o) + { + case OutputGenerator::Html: + begin = ""; + end = ""; + nobegin = ""; + noend = ""; + break; + case OutputGenerator::Latex: + begin = "%%BEGIN " + name; + end = "%%END " + name; + nobegin = "%%BEGIN !" + name; + noend = "%%END !" + name; + break; + default: + break; + } + + QCString result = s; + if (enable) + { + result = substitute(result, begin, ""); + result = substitute(result, end, ""); + result = clearBlock(result, nobegin, noend); + } + else + { + result = substitute(result, nobegin, ""); + result = substitute(result, noend, ""); + result = clearBlock(result, begin, end); + } + + return result; +} + +QCString removeEmptyLines(const QCString &s) +{ + BufStr out(s.length()+1); + const char *p=s.data(); + if (p) + { + char c; + while ((c=*p++)) + { + if (c=='\n') + { + const char *e = p; + while (*e==' ' || *e=='\t') e++; + if (*e=='\n') + { + p=e; + } + else out.addChar(c); + } + else + { + out.addChar(c); + } + } + } + out.addChar('\0'); + //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data()); + return out.data(); +} diff --git a/src/util.h b/src/util.h index b19e1c5..6d50d88 100644 --- a/src/util.h +++ b/src/util.h @@ -35,6 +35,7 @@ #include "arguments.h" #include "containers.h" #include "namespacedef.h" +#include "outputgen.h" //-------------------------------------------------------------------- @@ -168,8 +169,8 @@ QCString substituteClassNames(const QCString &s); QCString clearBlock(const char *s,const char *begin,const char *end); - -QCString selectBlock(const QCString& s,const QCString &name,bool which); +QCString selectBlock(const QCString& s,const QCString &name,bool enable, OutputGenerator::OutputType o); +QCString removeEmptyLines(const QCString &s); QCString resolveDefines(const char *n); diff --git a/templates/latex/footer.tex b/templates/latex/footer.tex new file mode 100755 index 0000000..0227221 --- /dev/null +++ b/templates/latex/footer.tex @@ -0,0 +1,50 @@ +%--- End generated contents --- + +%%BEGIN CITATIONS_PRESENT + % Bibliography + \newpage + \phantomsection + +%%BEGIN !PDF_HYPERLINKS + \clearemptydoublepage +%%BEGIN COMPACT_LATEX + \addcontentsline{toc}{section}{$latexcitereference} +%%END COMPACT_LATEX +%%BEGIN !COMPACT_LATEX + \addcontentsline{toc}{chapter}{$latexcitereference} +%%END !COMPACT_LATEX + \printindex +%%END !PDF_HYPERLINKS + + \bibliographystyle{$latexbibstyle} + \bibliography{$latexbibfiles} +%%BEGIN PDF_HYPERLINKS +%%BEGIN COMPACT_LATEX + \addcontentsline{toc}{section}{$latexcitereference} +%%END COMPACT_LATEX +%%BEGIN !COMPACT_LATEX + \addcontentsline{toc}{chapter}{$latexcitereference} +%%END !COMPACT_LATEX +%%END PDF_HYPERLINKS + +%%END CITATIONS_PRESENT + +% Index +%%BEGIN !COMPACT_LATEX + \backmatter +%%END !COMPACT_LATEX + \newpage + \phantomsection + \clearemptydoublepage +%%BEGIN COMPACT_LATEX + \addcontentsline{toc}{section}{\indexname} +%%END COMPACT_LATEX +%%BEGIN !COMPACT_LATEX + \addcontentsline{toc}{chapter}{\indexname} +%%END !COMPACT_LATEX + \printindex + +% Required for some languages (in combination with latexdocumentpre from the header) +$latexdocumentpost +\end{document} + diff --git a/templates/latex/header.tex b/templates/latex/header.tex new file mode 100644 index 0000000..a9446d7 --- /dev/null +++ b/templates/latex/header.tex @@ -0,0 +1,249 @@ + % Handle batch mode +%%BEGIN LATEX_BATCHMODE + \batchmode +%%END LATEX_BATCHMODE + + % to overcome problems with too many open files + \let\mypdfximage\pdfximage\def\pdfximage{\immediate\mypdfximage} + + % Set document class depending on configuration +%%BEGIN COMPACT_LATEX + \documentclass[twoside]{article} +%%END COMPACT_LATEX +%%BEGIN !COMPACT_LATEX + \documentclass[twoside]{book} +%%END !COMPACT_LATEX + + %% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package + \usepackage{ifthen} + \ifx\requestedLaTeXdate\undefined + \usepackage{array} + \else + \usepackage{array}[=2016-10-06] + \fi + %% + + % Packages required by doxygen + \usepackage{fixltx2e} % for \textsubscript + \usepackage{doxygen} + + $extralatexstylesheet + + \usepackage{graphicx} + \usepackage[utf8]{inputenc} + \usepackage{makeidx} + \PassOptionsToPackage{warn}{textcomp} + \usepackage{textcomp} + \usepackage[nointegrals]{wasysym} + \usepackage{ifxetex} + + % NLS support packages + $languagesupport + + % Define default fonts + % Font selection +%%BEGIN LATEX_FONTENC + \usepackage[$latexfontenc]{fontenc} +%%END LATEX_FONTENC + + % set main and monospaced font + $latexfont + + \usepackage{sectsty} + \allsectionsfont{% + \fontseries{bc}\selectfont% + \color{darkgray}% + } + \renewcommand{\DoxyLabelFont}{% + \fontseries{bc}\selectfont% + \color{darkgray}% + } + \newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}} + + % Arguments of doxygenemoji: + % 1) '::' form of the emoji, already LaTeX-escaped + % 2) file with the name of the emoji without the .png extension + % in case image exist use this otherwise use the '::' form + \newcommand{\doxygenemoji}[2]{% + \IfFileExists{$latexemojidirectory/#2.png}{\raisebox{-0.1em}{\includegraphics[height=0.9em]{$latexemojidirectory/#2.png}}}{#1}% + } + + % Page & text layout + \usepackage{geometry} + \geometry{% + $papertype,% + top=2.5cm,% + bottom=2.5cm,% + left=2.5cm,% + right=2.5cm% + } + + % Allow a bit of overflow to go unnoticed by other means + \tolerance=750 + \hfuzz=15pt + \hbadness=750 + \setlength{\emergencystretch}{15pt} + \setlength{\parindent}{0cm} + \newcommand{\doxynormalparskip}{\setlength{\parskip}{3ex plus 2ex minus 2ex}} + \newcommand{\doxytocparskip}{\setlength{\parskip}{1ex plus 0ex minus 0ex}} + \doxynormalparskip + % Redefine paragraph/subparagraph environments, using sectsty fonts + \makeatletter + \renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@parafont% + }% + } + \renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@subparafont% + }% + } + \makeatother + + \makeatletter + \newcommand\hrulefilll{\leavevmode\leaders\hrule\hskip 0pt plus 1filll\kern\z@} + \makeatother + + % Headers & footers + \usepackage{fancyhdr} + \pagestyle{fancyplain} + \renewcommand{\footrulewidth}{0.4pt} + + \fancypagestyle{fancyplain}{ + \fancyhf{} + \fancyhead[LE, RO]{\bfseries\thepage} + \fancyhead[LO]{\bfseries\rightmark} + \fancyhead[RE]{\bfseries\leftmark} + \fancyfoot[LO, RE]{\bfseries\scriptsize $generatedby Doxygen } + } + + \fancypagestyle{plain}{ + \fancyhf{} + \fancyfoot[LO, RE]{\bfseries\scriptsize $generatedby Doxygen } + \renewcommand{\headrulewidth}{0pt} + } + + \pagestyle{fancyplain} + + +%%BEGIN !COMPACT_LATEX + \renewcommand{\chaptermark}[1]{% + \markboth{#1}{}% + } +%%END !COMPACT_LATEX + \renewcommand{\sectionmark}[1]{% + \markright{\thesection\ #1}% + } + + % ToC, LoF, LoT, bibliography, and index + % Indices & bibliography + \usepackage{natbib} + \usepackage[titles]{tocloft} + \setcounter{tocdepth}{3} + \setcounter{secnumdepth}{5} + + % creating indexes + $makeindex + + $extralatexpackages + + $latexspecialformulachars + +%%BEGIN FORMULA_MACROFILE + \input{$formulamacrofile} +%%END FORMULA_MACROFILE + + % Hyperlinks +%%BEGIN PDF_HYPERLINKS + % Hyperlinks (required, but should be loaded last) + \ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} + \else + \ifxetex + \usepackage[pagebackref=true]{hyperref} + \else + \usepackage[ps2pdf,pagebackref=true]{hyperref} + \fi + \fi + + \hypersetup{% + colorlinks=true,% + linkcolor=blue,% + citecolor=blue,% + unicode% + } + +%%END PDF_HYPERLINKS + + % Custom commands used by the header + % Custom commands + \newcommand{\clearemptydoublepage}{% + \newpage{\pagestyle{empty}\cleardoublepage}% + } + + % caption style definition + \usepackage{caption} + \captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top} + + + % in page table of contents + \usepackage{etoc} + \etocsettocstyle{\doxytocparskip}{\doxynormalparskip} + + % prevent numbers overlap the titles in toc + \renewcommand{\numberline}[1]{#1~} + +% End of preamble, now comes the document contents +%===== C O N T E N T S ===== + +\begin{document} + \raggedbottom + + $latexdocumentpre + + % Titlepage & ToC +%%BEGIN PDF_HYPERLINKS +%%BEGIN USE_PDFLATEX + % To avoid duplicate page anchors due to reuse of same numbers for + % the index (be it as roman numbers) + \hypersetup{pageanchor=false, + bookmarksnumbered=true, + pdfencoding=unicode + } +%%END USE_PDFLATEX +%%END PDF_HYPERLINKS + \pagenumbering{alph} + \begin{titlepage} + \vspace*{7cm} + \begin{center}% + {\Large $title}\\ + \vspace*{1cm} + {\large $generatedby Doxygen $doxygenversion}\\ +%%BEGIN LATEX_TIMESTAMP + \vspace*{0.5cm} + {\small $datetime} +%%END LATEX_TIMESTAMP + \end{center} + \end{titlepage} + +%%BEGIN !COMPACT_LATEX + \clearemptydoublepage +%%END !COMPACT_LATEX + \pagenumbering{roman} + + \tableofcontents +%%BEGIN !COMPACT_LATEX + \clearemptydoublepage +%%END !COMPACT_LATEX + \pagenumbering{arabic} + +%%BEGIN PDF_HYPERLINKS +%%BEGIN USE_PDFLATEX + % re-enable anchors again + \hypersetup{pageanchor=true} +%%END USE_PDFLATEX +%%END PDF_HYPERLINKS + +%--- Begin generated contents --- + -- cgit v0.12