1 /******************************************************************************
5 * Copyright (C) 1997-2015 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
31 #include "docparser.h"
32 #include "latexdocvisitor.h"
36 #include "classlist.h"
37 #include "namespacedef.h"
39 #include "resourcemgr.h"
41 static bool DoxyCodeOpen = FALSE;
42 static bool DoxyCodeLineOpen = FALSE;
43 //-------------------------------
45 LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName)
46 : m_relPath(relPath), m_sourceFileName(sourceFileName), m_col(0)
48 m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
52 LatexCodeGenerator::LatexCodeGenerator() : m_streamSet(FALSE), m_col(0)
54 m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
57 void LatexCodeGenerator::setTextStream(FTextStream &t)
59 m_streamSet = t.device()!=0;
60 m_t.setDevice(t.device());
63 void LatexCodeGenerator::setRelativePath(const QCString &path)
68 void LatexCodeGenerator::setSourceFileName(const QCString &name)
70 m_sourceFileName = name;
73 void LatexCodeGenerator::codify(const char *str)
80 int spacesToNextTabStop;
81 static int tabSize = Config_getInt(TAB_SIZE);
82 static char *result = NULL;
83 static int lresult = 0;
89 case 0x0c: p++; // remove ^L
95 case '^': m_t <<"\\string^";
99 case '\t': spacesToNextTabStop =
100 tabSize - (m_col%tabSize);
101 for (i = 0; i < spacesToNextTabStop; i++) m_t <<" ";
102 m_col+=spacesToNextTabStop;
105 case '\n': (usedTableLevels()>0 && !DoxyCodeOpen) ? m_t << "\\newline\n" : m_t << '\n'; m_col=0; p++;
111 // helper macro to copy a single utf8 character, dealing with multibyte chars.
112 #define COPYCHAR() do { \
113 if (lresult < (i + 5)) \
116 result = (char *)realloc(result, lresult); \
118 result[i++]=c; p++; \
119 if (c<0) /* multibyte utf-8 character */ \
121 /* 1xxx.xxxx: >=2 byte character */ \
123 if (((uchar)c&0xE0)==0xE0) \
125 /* 111x.xxxx: >=3 byte character */ \
128 if (((uchar)c&0xF0)==0xF0) \
130 /* 1111.xxxx: 4 byte character */ \
137 // gather characters until we find whitespace or another special character
140 c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^'
145 result[i]=0; // add terminator
148 filterLatexString(m_t,result,FALSE,TRUE);
161 void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f,
162 const char *anchor,const char *name,
165 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
166 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
167 int l = qstrlen(name);
168 if (!ref && usePDFLatex && pdfHyperlinks)
170 m_t << "\\mbox{\\hyperlink{";
171 if (f) m_t << stripPath(f);
172 if (f && anchor) m_t << "_";
173 if (anchor) m_t << anchor;
185 void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l)
187 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
188 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
189 if (!DoxyCodeLineOpen)
191 m_t << "\\DoxyCodeLine{";
192 DoxyCodeLineOpen = TRUE;
197 lineNumber.sprintf("%05d",l);
199 if (fileName && !m_sourceFileName.isEmpty())
202 lineAnchor.sprintf("_l%05d",l);
203 lineAnchor.prepend(stripExtensionGeneral(m_sourceFileName, ".tex"));
204 //if (!m_prettyCode) return;
205 if (usePDFLatex && pdfHyperlinks)
207 m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
209 writeCodeLink(ref,fileName,anchor,lineNumber,0);
224 void LatexCodeGenerator::startCodeLine(bool)
227 if (!DoxyCodeLineOpen)
229 m_t << "\\DoxyCodeLine{";
230 DoxyCodeLineOpen = TRUE;
234 void LatexCodeGenerator::endCodeLine()
236 if (DoxyCodeLineOpen)
239 DoxyCodeLineOpen = FALSE;
244 void LatexCodeGenerator::startFontClass(const char *name)
246 m_t << "\\textcolor{" << name << "}{";
249 void LatexCodeGenerator::endFontClass()
254 void LatexCodeGenerator::setDoxyCodeOpen(bool val)
259 //-------------------------------
261 LatexGenerator::LatexGenerator() : OutputGenerator()
263 dir=Config_getString(LATEX_OUTPUT);
264 //printf("LatexGenerator::LatexGenerator() insideTabbing=FALSE\n");
269 templateMemberItem = FALSE;
270 m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
273 LatexGenerator::~LatexGenerator()
277 static void writeLatexMakefile()
279 bool generateBib = !Doxygen::citeDict->isEmpty();
280 QCString dir=Config_getString(LATEX_OUTPUT);
281 QCString fileName=dir+"/Makefile";
282 QFile file(fileName);
283 if (!file.open(IO_WriteOnly))
285 err("Could not open file %s for writing\n",fileName.data());
288 // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
289 QCString latex_command = theTranslator->latexCommandName();
290 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME);
291 // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
292 FTextStream t(&file);
293 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
295 t << "LATEX_CMD=" << latex_command << endl
297 << "all: refman.dvi" << endl
299 << "ps: refman.ps" << endl
301 << "pdf: refman.pdf" << endl
303 << "ps_2on1: refman_2on1.ps" << endl
305 << "pdf_2on1: refman_2on1.pdf" << endl
307 << "refman.ps: refman.dvi" << endl
308 << "\tdvips -o refman.ps refman.dvi" << endl
310 t << "refman.pdf: refman.ps" << endl;
311 t << "\tps2pdf refman.ps refman.pdf" << endl << endl;
312 t << "refman.dvi: clean refman.tex doxygen.sty" << endl
313 << "\techo \"Running latex...\"" << endl
314 << "\t$(LATEX_CMD) refman.tex" << endl
315 << "\techo \"Running makeindex...\"" << endl
316 << "\t" << mkidx_command << " refman.idx" << endl;
319 t << "\techo \"Running bibtex...\"" << endl;
320 t << "\tbibtex refman" << endl;
321 t << "\techo \"Rerunning latex....\"" << endl;
322 t << "\t$(LATEX_CMD) refman.tex" << endl;
324 t << "\techo \"Rerunning latex....\"" << endl
325 << "\t$(LATEX_CMD) refman.tex" << endl
326 << "\tlatex_count=8 ; \\" << endl
327 << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
328 << "\t do \\" << endl
329 << "\t echo \"Rerunning latex....\" ;\\" << endl
330 << "\t $(LATEX_CMD) refman.tex ; \\" << endl
331 << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
333 << "\t" << mkidx_command << " refman.idx" << endl
334 << "\t$(LATEX_CMD) refman.tex" << endl << endl
335 << "refman_2on1.ps: refman.ps" << endl
336 << "\tpsnup -2 refman.ps >refman_2on1.ps" << endl
338 << "refman_2on1.pdf: refman_2on1.ps" << endl
339 << "\tps2pdf refman_2on1.ps refman_2on1.pdf" << endl;
341 else // use pdflatex for higher quality output
343 t << "LATEX_CMD=" << latex_command << endl
345 t << "all: refman.pdf" << endl << endl
346 << "pdf: refman.pdf" << endl << endl;
347 t << "refman.pdf: clean refman.tex" << endl;
348 t << "\t$(LATEX_CMD) refman" << endl;
349 t << "\t" << mkidx_command << " refman.idx" << endl;
352 t << "\tbibtex refman" << endl;
353 t << "\t$(LATEX_CMD) refman" << endl;
355 t << "\t$(LATEX_CMD) refman" << endl
356 << "\tlatex_count=8 ; \\" << endl
357 << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
358 << "\t do \\" << endl
359 << "\t echo \"Rerunning latex....\" ;\\" << endl
360 << "\t $(LATEX_CMD) refman ;\\" << endl
361 << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
363 << "\t" << mkidx_command << " refman.idx" << endl
364 << "\t$(LATEX_CMD) refman" << endl << endl;
370 << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl;
373 static void writeMakeBat()
375 #if defined(_MSC_VER)
376 QCString dir=Config_getString(LATEX_OUTPUT);
377 QCString fileName=dir+"/make.bat";
378 QCString latex_command = theTranslator->latexCommandName();
379 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME);
380 QFile file(fileName);
381 bool generateBib = !Doxygen::citeDict->isEmpty();
382 if (!file.open(IO_WriteOnly))
384 err("Could not open file %s for writing\n",fileName.data());
387 FTextStream t(&file);
388 t << "set Dir_Old=%cd%\n";
389 t << "cd /D %~dp0\n\n";
390 t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n";
391 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
393 t << "set LATEX_CMD=" << latex_command << "\n";
394 t << "%LATEX_CMD% refman.tex\n";
396 t << mkidx_command << " refman.idx\n";
399 t << "bibtex refman\n";
401 t << "\t%LATEX_CMD% refman.tex\n";
403 t << "setlocal enabledelayedexpansion\n";
404 t << "set count=8\n";
406 t << "set content=X\n";
407 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
408 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
409 t << "if !content! == X goto :skip\n";
410 t << "set /a count-=1\n";
411 t << "if !count! EQU 0 goto :skip\n\n";
413 t << "%LATEX_CMD% refman.tex\n";
414 t << "goto :repeat\n";
417 t << mkidx_command << " refman.idx\n";
418 t << "%LATEX_CMD% refman.tex\n";
419 t << "dvips -o refman.ps refman.dvi\n";
420 t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
421 "-sOutputFile=refman.pdf -c save pop -f refman.ps\n";
425 t << "set LATEX_CMD=" << latex_command << "\n";
426 t << "%LATEX_CMD% refman\n";
428 t << mkidx_command << " refman.idx\n";
431 t << "bibtex refman" << endl;
432 t << "%LATEX_CMD% refman" << endl;
435 t << "%LATEX_CMD% refman\n\n";
436 t << "setlocal enabledelayedexpansion\n";
437 t << "set count=8\n";
439 t << "set content=X\n";
440 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
441 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
442 t << "if !content! == X goto :skip\n";
443 t << "set /a count-=1\n";
444 t << "if !count! EQU 0 goto :skip\n\n";
446 t << "%LATEX_CMD% refman\n";
447 t << "goto :repeat\n";
450 t << mkidx_command << " refman.idx\n";
451 t << "%LATEX_CMD% refman\n";
452 t << "cd /D %Dir_Old%\n";
453 t << "set Dir_Old=\n";
458 void LatexGenerator::init()
461 QCString dir=Config_getString(LATEX_OUTPUT);
463 if (!d.exists() && !d.mkdir(dir))
465 err("Could not create output directory %s\n",dir.data());
469 writeLatexMakefile();
475 static void writeDefaultHeaderPart1(FTextStream &t)
480 if (Config_getBool(LATEX_BATCHMODE))
481 t << "\\batchmode\n";
483 // to overcome problems wit too many open files
484 t << "\\let\\mypdfximage\\pdfximage"
485 "\\def\\pdfximage{\\immediate\\mypdfximage}";
487 // Set document class depending on configuration
488 QCString documentClass;
489 if (Config_getBool(COMPACT_LATEX))
490 documentClass = "article";
492 documentClass = "book";
493 t << "\\documentclass[twoside]{" << documentClass << "}\n"
496 // Load required packages
497 t << "% Packages required by doxygen\n"
498 "\\usepackage{fixltx2e}\n" // for \textsubscript
499 "\\usepackage{calc}\n"
500 "\\usepackage{doxygen}\n";
501 QStrList extraLatexStyle = Config_getList(LATEX_EXTRA_STYLESHEET);
502 for (uint i=0; i<extraLatexStyle.count(); ++i)
504 QCString fileName(extraLatexStyle.at(i));
505 if (!fileName.isEmpty())
507 QFileInfo fi(fileName);
510 if (checkExtension(fi.fileName().data(), latexStyleExtension))
512 // strip the extension, it will be added by the usepackage in the tex conversion process
513 t << "\\usepackage{" << stripExtensionGeneral(fi.fileName().data(), latexStyleExtension) << "}\n";
517 t << "\\usepackage{" << fi.fileName().utf8() << "}\n";
522 t << "\\usepackage{graphicx}\n"
523 "\\usepackage[utf8]{inputenc}\n"
524 "\\usepackage{makeidx}\n"
525 "\\usepackage{multicol}\n"
526 "\\usepackage{multirow}\n"
527 "\\PassOptionsToPackage{warn}{textcomp}\n"
528 "\\usepackage{textcomp}\n"
529 "\\usepackage[nointegrals]{wasysym}\n"
530 "\\usepackage[table]{xcolor}\n"
531 "\\usepackage{ifpdf,ifxetex}\n"
535 QCString languageSupport = theTranslator->latexLanguageSupportCommand();
536 if (!languageSupport.isEmpty())
538 t << "% NLS support packages\n"
543 // Define default fonts
544 t << "% Font selection\n";
545 QCString fontenc = theTranslator->latexFontenc();
546 if (!fontenc.isEmpty())
548 t << "\\usepackage[" << fontenc << "]{fontenc}\n";
550 t << "\\usepackage[scaled=.90]{helvet}\n"
551 "\\usepackage{courier}\n"
552 "\\usepackage{amssymb}\n"
553 "\\usepackage{sectsty}\n"
554 "\\renewcommand{\\familydefault}{\\sfdefault}\n"
555 "\\allsectionsfont{%\n"
556 " \\fontseries{bc}\\selectfont%\n"
557 " \\color{darkgray}%\n"
559 "\\renewcommand{\\DoxyLabelFont}{%\n"
560 " \\fontseries{bc}\\selectfont%\n"
561 " \\color{darkgray}%\n"
563 "\\newcommand{\\+}{\\discretionary{\\mbox{\\scriptsize$\\hookleftarrow$}}{}{}}\n"
566 QCString emojiDir=Config_getString(LATEX_EMOJI_DIRECTORY);
567 if (emojiDir.isEmpty()) emojiDir = ".";
568 emojiDir = substitute(emojiDir,"\\","/");
569 t << "% Arguments of doxygenemoji:\n"
570 "% 1) ':<text>:' form of the emoji, already \"LaTeX\"-escaped\n"
571 "% 2) file with the name of the emoji without the .png extension\n"
572 "% in case image exist use this otherwise use the ':<text>:' form\n";
573 t << "\\newcommand{\\doxygenemoji}[2]{%\n"
574 " \\IfFileExists{" << emojiDir << "/#2.png}{\\raisebox{-0.1em}{\\includegraphics[height=0.9em]{" << emojiDir << "/#2.png}}}{#1}%\n"
577 // Define page & text layout
578 QCString paperName=Config_getEnum(PAPER_TYPE);
579 // "a4wide" package is obsolete (see bug 563698)
580 t << "% Page & text layout\n"
581 "\\usepackage{geometry}\n"
583 " " << paperName << "paper,%\n"
589 // \sloppy is obsolete (see bug 563698)
590 // Allow a bit of overflow to go unnoticed by other means
591 t << "\\tolerance=750\n"
594 "\\setlength{\\emergencystretch}{15pt}\n"
595 "\\setlength{\\parindent}{0cm}\n"
596 "\\newcommand{\\doxynormalparskip}{\\setlength{\\parskip}{3ex plus 2ex minus 2ex}}\n"
597 "\\newcommand{\\doxytocparskip}{\\setlength{\\parskip}{1ex plus 0ex minus 0ex}}\n"
598 "\\doxynormalparskip\n";
599 // Redefine paragraph/subparagraph environments, using sectsty fonts
600 t << "\\makeatletter\n"
601 "\\renewcommand{\\paragraph}{%\n"
602 " \\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%\n"
603 " \\normalfont\\normalsize\\bfseries\\SS@parafont%\n"
606 "\\renewcommand{\\subparagraph}{%\n"
607 " \\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%\n"
608 " \\normalfont\\normalsize\\bfseries\\SS@subparafont%\n"
616 QCString generatedBy;
617 static bool timeStamp = Config_getBool(LATEX_TIMESTAMP);
618 FTextStream tg(&genString);
621 generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), Config_getString(PROJECT_NAME));
625 generatedBy = theTranslator->trGeneratedBy();
627 filterLatexString(tg, generatedBy, FALSE,FALSE,FALSE);
628 t << "% Headers & footers\n"
629 "\\usepackage{fancyhdr}\n"
630 "\\pagestyle{fancyplain}\n"
631 "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n"
632 "\\fancyhead[CE]{\\fancyplain{}{}}\n"
633 "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n"
634 "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n"
635 "\\fancyhead[CO]{\\fancyplain{}{}}\n"
636 "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n"
637 "\\fancyfoot[LE]{\\fancyplain{}{}}\n"
638 "\\fancyfoot[CE]{\\fancyplain{}{}}\n"
639 "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
640 "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
641 "\\fancyfoot[CO]{\\fancyplain{}{}}\n"
642 "\\fancyfoot[RO]{\\fancyplain{}{}}\n"
643 "\\renewcommand{\\footrulewidth}{0.4pt}\n";
644 if (!Config_getBool(COMPACT_LATEX))
646 t << "\\renewcommand{\\chaptermark}[1]{%\n"
647 " \\markboth{#1}{}%\n"
650 t << "\\renewcommand{\\sectionmark}[1]{%\n"
651 " \\markright{\\thesection\\ #1}%\n"
655 // ToC, LoF, LoT, bibliography, and index
656 t << "% Indices & bibliography\n"
657 "\\usepackage{natbib}\n"
658 "\\usepackage[titles]{tocloft}\n"
659 "\\setcounter{tocdepth}{3}\n"
660 "\\setcounter{secnumdepth}{5}\n";
662 QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD);
663 if (!latex_mkidx_command.isEmpty())
665 if (latex_mkidx_command[0] == '\\')
666 t << latex_mkidx_command << "\n";
668 t << '\\' << latex_mkidx_command << "\n";
672 t << "\\makeindex\n";
676 writeExtraLatexPackages(t);
677 writeLatexSpecialFormulaChars(t);
680 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
683 t << "% Hyperlinks (required, but should be loaded last)\n"
685 " \\usepackage[pdftex,pagebackref=true]{hyperref}\n"
688 " \\usepackage[pagebackref=true]{hyperref}\n"
690 " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n"
695 " colorlinks=true,%\n"
696 " linkcolor=blue,%\n"
697 " citecolor=blue,%\n"
703 // Custom commands used by the header
704 t << "% Custom commands\n"
705 "\\newcommand{\\clearemptydoublepage}{%\n"
706 " \\newpage{\\pagestyle{empty}\\cleardoublepage}%\n"
710 // caption style definition
711 t << "\\usepackage{caption}\n"
712 << "\\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}\n\n";
715 // in page table of contents
716 t << "\\usepackage{etoc}\n"
717 "\\etocsettocstyle{\\doxytocparskip}{\\doxynormalparskip}\n";
719 // prevent numbers overlap the titles in toc
720 t << "\\renewcommand{\\numberline}[1]{#1~}\n";
722 // End of preamble, now comes the document contents
723 t << "%===== C O N T E N T S =====\n"
725 "\\begin{document}\n";
726 QCString documentPre = theTranslator->latexDocumentPre();
727 if (!documentPre.isEmpty())
734 t << "% Titlepage & ToC\n";
735 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
736 if (pdfHyperlinks && usePDFLatex)
738 // To avoid duplicate page anchors due to reuse of same numbers for
739 // the index (be it as roman numbers)
740 t << "\\hypersetup{pageanchor=false,\n"
741 // << " bookmarks=true,\n" // commented out to prevent warning
742 << " bookmarksnumbered=true,\n"
743 << " pdfencoding=unicode\n"
746 t << "\\pagenumbering{alph}\n"
747 "\\begin{titlepage}\n"
753 static void writeDefaultHeaderPart2(FTextStream &t)
756 // Finalize project name
762 static void writeDefaultHeaderPart3(FTextStream &t)
765 // Finalize project number
766 t << " Doxygen " << versionString << "}\\\\\n";
767 if (Config_getBool(LATEX_TIMESTAMP))
768 t << "\\vspace*{0.5cm}\n"
769 "{\\small " << dateToString(TRUE) << "}\\\\\n";
770 t << "\\end{center}\n"
771 "\\end{titlepage}\n";
772 bool compactLatex = Config_getBool(COMPACT_LATEX);
774 t << "\\clearemptydoublepage\n";
775 t << "\\pagenumbering{roman}\n";
778 t << "\\tableofcontents\n";
780 t << "\\clearemptydoublepage\n";
781 t << "\\pagenumbering{arabic}\n";
782 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
783 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
784 if (pdfHyperlinks && usePDFLatex)
786 // re-enable anchors again
787 t << "\\hypersetup{pageanchor=true}\n";
790 "%--- Begin generated contents ---\n";
793 static void writeDefaultStyleSheet(FTextStream &t)
795 t << ResourceMgr::instance().getAsString("doxygen.sty");
798 static void writeDefaultFooter(FTextStream &t)
800 t << "%--- End generated contents ---\n"
804 Doxygen::citeDict->writeLatexBibliography(t);
809 if (Config_getBool(COMPACT_LATEX))
816 t << "\\backmatter\n";
820 "\\clearemptydoublepage\n"
821 "\\addcontentsline{toc}{" << unit << "}{\\indexname}\n"
824 QCString documentPost = theTranslator->latexDocumentPost();
825 if (!documentPost.isEmpty())
829 t << "\\end{document}\n";
832 void LatexGenerator::writeHeaderFile(QFile &f)
835 t << "% Latex header for doxygen " << versionString << endl;
836 writeDefaultHeaderPart1(t);
837 t << "Your title here";
838 writeDefaultHeaderPart2(t);
840 writeDefaultHeaderPart3(t);
843 void LatexGenerator::writeFooterFile(QFile &f)
846 t << "% Latex footer for doxygen " << versionString << endl;
847 writeDefaultFooter(t);
850 void LatexGenerator::writeStyleSheetFile(QFile &f)
853 t << "% stylesheet for doxygen " << versionString << endl;
854 writeDefaultStyleSheet(t);
857 void LatexGenerator::startFile(const char *name,const char *,const char *)
860 setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
862 QCString fileName=name;
863 relPath = relativePathToRoot(fileName);
864 if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex";
865 startPlainFile(fileName);
866 m_codeGen.setTextStream(t);
867 m_codeGen.setRelativePath(relPath);
868 m_codeGen.setSourceFileName(stripPath(fileName));
871 void LatexGenerator::endFile()
874 m_codeGen.setSourceFileName("");
877 //void LatexGenerator::writeIndex()
879 // startFile("refman.tex");
882 void LatexGenerator::startProjectNumber()
884 t << "\\\\[1ex]\\large ";
887 void LatexGenerator::startIndexSection(IndexSections is)
889 bool &compactLatex = Config_getBool(COMPACT_LATEX);
890 QCString &latexHeader = Config_getString(LATEX_HEADER);
893 case isTitlePageStart:
895 if (latexHeader.isEmpty())
897 writeDefaultHeaderPart1(t);
901 QCString header = fileToString(latexHeader);
902 t << substituteKeywords(header,"",
903 convertToLaTeX(Config_getString(PROJECT_NAME)),
904 convertToLaTeX(Config_getString(PROJECT_NUMBER)),
905 convertToLaTeX(Config_getString(PROJECT_BRIEF)));
909 case isTitlePageAuthor:
910 if (latexHeader.isEmpty())
912 writeDefaultHeaderPart2(t);
916 if (compactLatex) t << "\\section"; else t << "\\chapter";
917 t << "{"; //Introduction}\n"
919 //case isPackageIndex:
920 // if (compactLatex) t << "\\section"; else t << "\\chapter";
921 // t << "{"; //Package Index}\n"
924 if (compactLatex) t << "\\section"; else t << "\\chapter";
925 t << "{"; //Module Index}\n"
928 if (compactLatex) t << "\\section"; else t << "\\chapter";
929 t << "{"; //Directory Index}\n"
931 case isNamespaceIndex:
932 if (compactLatex) t << "\\section"; else t << "\\chapter";
933 t << "{"; //Namespace Index}\"
935 case isClassHierarchyIndex:
936 if (compactLatex) t << "\\section"; else t << "\\chapter";
937 t << "{"; //Hierarchical Index}\n"
939 case isCompoundIndex:
940 if (compactLatex) t << "\\section"; else t << "\\chapter";
941 t << "{"; //Annotated Compound Index}\n"
944 if (compactLatex) t << "\\section"; else t << "\\chapter";
945 t << "{"; //Annotated File Index}\n"
948 if (compactLatex) t << "\\section"; else t << "\\chapter";
949 t << "{"; //Annotated Page Index}\n"
951 case isModuleDocumentation:
953 GroupSDict::Iterator gli(*Doxygen::groupSDict);
956 for (gli.toFirst();(gd=gli.current()) && !found;++gli)
958 if (!gd->isReference())
960 if (compactLatex) t << "\\section"; else t << "\\chapter";
961 t << "{"; //Module Documentation}\n";
967 case isDirDocumentation:
969 SDict<DirDef>::Iterator dli(*Doxygen::directories);
972 for (dli.toFirst();(dd=dli.current()) && !found;++dli)
974 if (dd->isLinkableInProject())
976 if (compactLatex) t << "\\section"; else t << "\\chapter";
977 t << "{"; //Module Documentation}\n";
983 case isNamespaceDocumentation:
985 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
988 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
990 if (nd->isLinkableInProject())
992 if (compactLatex) t << "\\section"; else t << "\\chapter";
993 t << "{"; // Namespace Documentation}\n":
999 case isClassDocumentation:
1001 ClassSDict::Iterator cli(*Doxygen::classSDict);
1004 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
1006 if (cd->isLinkableInProject() &&
1007 cd->templateMaster()==0 &&
1008 !cd->isEmbeddedInOuterScope()
1011 if (compactLatex) t << "\\section"; else t << "\\chapter";
1012 t << "{"; //Compound Documentation}\n";
1018 case isFileDocumentation:
1021 FileNameListIterator fnli(*Doxygen::inputNameList);
1023 for (fnli.toFirst();(fn=fnli.current());++fnli)
1025 FileNameIterator fni(*fn);
1027 for (;(fd=fni.current());++fni)
1029 if (fd->isLinkableInProject())
1033 if (compactLatex) t << "\\section"; else t << "\\chapter";
1034 t << "{"; //File Documentation}\n";
1043 case isExampleDocumentation:
1045 if (compactLatex) t << "\\section"; else t << "\\chapter";
1046 t << "{"; //Example Documentation}\n";
1049 case isPageDocumentation:
1051 if (compactLatex) t << "\\section"; else t << "\\chapter";
1052 t << "{"; //Page Documentation}\n";
1055 case isPageDocumentation2:
1062 void LatexGenerator::endIndexSection(IndexSections is)
1064 //static bool compactLatex = Config_getBool(COMPACT_LATEX);
1065 static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
1066 static QCString latexHeader = Config_getString(LATEX_HEADER);
1067 static QCString latexFooter = Config_getString(LATEX_FOOTER);
1070 case isTitlePageStart:
1072 case isTitlePageAuthor:
1073 if (latexHeader.isEmpty())
1075 writeDefaultHeaderPart3(t);
1080 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
1081 QCString indexName="index";
1082 t << "}\n\\label{index}";
1083 if (Config_getBool(PDF_HYPERLINKS)) t << "\\hypertarget{index}{}";
1084 t << "\\input{" << indexName << "}\n";
1088 t << "}\n\\input{modules}\n";
1091 t << "}\n\\input{dirs}\n";
1093 case isNamespaceIndex:
1094 t << "}\n\\input{namespaces}\n";
1096 case isClassHierarchyIndex:
1097 t << "}\n\\input{hierarchy}\n";
1099 case isCompoundIndex:
1100 t << "}\n\\input{annotated}\n";
1103 t << "}\n\\input{files}\n";
1106 t << "}\n\\input{pages}\n";
1108 case isModuleDocumentation:
1110 GroupSDict::Iterator gli(*Doxygen::groupSDict);
1113 for (gli.toFirst();(gd=gli.current()) && !found;++gli)
1115 if (!gd->isReference())
1117 t << "}\n\\input{" << gd->getOutputFileBase() << "}\n";
1121 for (;(gd=gli.current());++gli)
1123 if (!gd->isReference())
1125 //if (compactLatex) t << "\\input"; else t << "\\include";
1127 t << "{" << gd->getOutputFileBase() << "}\n";
1132 case isDirDocumentation:
1134 SDict<DirDef>::Iterator dli(*Doxygen::directories);
1137 for (dli.toFirst();(dd=dli.current()) && !found;++dli)
1139 if (dd->isLinkableInProject())
1141 t << "}\n\\input{" << dd->getOutputFileBase() << "}\n";
1145 for (;(dd=dli.current());++dli)
1147 if (dd->isLinkableInProject())
1149 //if (compactLatex) t << "\\input"; else t << "\\include";
1151 t << "{" << dd->getOutputFileBase() << "}\n";
1156 case isNamespaceDocumentation:
1158 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1161 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
1163 if (nd->isLinkableInProject())
1165 t << "}\n\\input{" << nd->getOutputFileBase() << "}\n";
1169 while ((nd=nli.current()))
1171 if (nd->isLinkableInProject())
1173 //if (compactLatex) t << "\\input"; else t << "\\include";
1175 t << "{" << nd->getOutputFileBase() << "}\n";
1181 case isClassDocumentation:
1183 ClassSDict::Iterator cli(*Doxygen::classSDict);
1186 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
1188 if (cd->isLinkableInProject() &&
1189 cd->templateMaster()==0 &&
1190 !cd->isEmbeddedInOuterScope()
1193 t << "}\n\\input{" << cd->getOutputFileBase() << "}\n";
1197 for (;(cd=cli.current());++cli)
1199 if (cd->isLinkableInProject() &&
1200 cd->templateMaster()==0 &&
1201 !cd->isEmbeddedInOuterScope()
1204 //if (compactLatex) t << "\\input"; else t << "\\include";
1206 t << "{" << cd->getOutputFileBase() << "}\n";
1211 case isFileDocumentation:
1214 FileNameListIterator fnli(*Doxygen::inputNameList);
1216 for (fnli.toFirst();(fn=fnli.current());++fnli)
1218 FileNameIterator fni(*fn);
1220 for (;(fd=fni.current());++fni)
1222 if (fd->isLinkableInProject())
1226 t << "}\n\\input{" << fd->getOutputFileBase() << "}\n";
1227 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1229 //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1230 t << "\\input{" << fd->getSourceFileBase() << "}\n";
1236 //if (compactLatex) t << "\\input" ; else t << "\\include";
1238 t << "{" << fd->getOutputFileBase() << "}\n";
1239 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1241 //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1242 t << "\\input{" << fd->getSourceFileBase() << "}\n";
1250 case isExampleDocumentation:
1253 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
1254 PageDef *pd=pdi.toFirst();
1257 t << "\\input{" << pd->getOutputFileBase() << "}\n";
1259 for (++pdi;(pd=pdi.current());++pdi)
1261 //if (compactLatex) t << "\\input" ; else t << "\\include";
1263 t << "{" << pd->getOutputFileBase() << "}\n";
1267 case isPageDocumentation:
1271 PageSDict::Iterator pdi(*Doxygen::pageSDict);
1272 PageDef *pd=pdi.toFirst();
1274 for (pdi.toFirst();(pd=pdi.current());++pdi)
1276 if (!pd->getGroupDef() && !pd->isReference())
1278 if (compactLatex) t << "\\section"; else t << "\\chapter";
1279 t << "{" << pd->title();
1282 if (compactLatex || first) t << "\\input" ; else t << "\\include";
1283 t << "{" << pd->getOutputFileBase() << "}\n";
1290 case isPageDocumentation2:
1293 if (latexFooter.isEmpty())
1295 writeDefaultFooter(t);
1299 QCString footer = fileToString(latexFooter);
1300 t << substituteKeywords(footer,"",
1301 convertToLaTeX(Config_getString(PROJECT_NAME)),
1302 convertToLaTeX(Config_getString(PROJECT_NUMBER)),
1303 convertToLaTeX(Config_getString(PROJECT_BRIEF)));
1309 void LatexGenerator::writePageLink(const char *name, bool /*first*/)
1311 //bool &compactLatex = Config_getBool(COMPACT_LATEX);
1312 // next is remove for bug615957
1313 //if (compactLatex || first) t << "\\input" ; else t << "\\include";
1315 t << "{" << name << "}\n";
1319 void LatexGenerator::writeStyleInfo(int part)
1324 startPlainFile("doxygen.sty");
1325 writeDefaultStyleSheet(t);
1329 void LatexGenerator::newParagraph()
1334 void LatexGenerator::startParagraph(const char *)
1339 void LatexGenerator::endParagraph()
1344 void LatexGenerator::writeString(const char *text)
1349 void LatexGenerator::startIndexItem(const char *ref,const char *fn)
1354 t << "\\contentsline{section}{";
1358 void LatexGenerator::endIndexItem(const char *ref,const char *fn)
1362 t << "}{\\pageref{" << stripPath(fn) << "}}{}" << endl;
1366 //void LatexGenerator::writeIndexFileItem(const char *,const char *text)
1368 // t << "\\item\\contentsline{section}{";
1370 // t << "}{\\pageref{" << stripPath(text) << "}}" << endl;
1374 void LatexGenerator::startHtmlLink(const char *url)
1376 if (Config_getBool(PDF_HYPERLINKS))
1385 void LatexGenerator::endHtmlLink()
1390 //void LatexGenerator::writeMailLink(const char *url)
1392 // if (Config_getBool(PDF_HYPERLINKS))
1394 // t << "\\href{mailto:";
1398 // t << "\\texttt{ ";
1403 void LatexGenerator::writeStartAnnoItem(const char *,const char *,
1404 const char *path,const char *name)
1406 t << "\\item\\contentsline{section}\\textbf{ ";
1407 if (path) docify(path);
1412 void LatexGenerator::writeEndAnnoItem(const char *name)
1414 t << "}{\\pageref{" << stripPath(name) << "}}{}" << endl;
1417 void LatexGenerator::startIndexKey()
1419 t << "\\item\\contentsline{section}{";
1422 void LatexGenerator::endIndexKey()
1426 void LatexGenerator::startIndexValue(bool hasBrief)
1429 if (hasBrief) t << "\\\\*";
1432 void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/)
1434 //if (hasBrief) t << ")";
1435 t << "}{\\pageref{" << stripPath(name) << "}}{}" << endl;
1438 //void LatexGenerator::writeClassLink(const char *,const char *,
1439 // const char *,const char *name)
1441 // t << "\\textbf{ ";
1446 void LatexGenerator::startTextLink(const char *f,const char *anchor)
1448 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1449 if (!disableLinks && pdfHyperlinks)
1451 t << "\\mbox{\\hyperlink{";
1452 if (f) t << stripPath(f);
1453 if (anchor) t << "_" << anchor;
1462 void LatexGenerator::endTextLink()
1464 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1465 if (!disableLinks && pdfHyperlinks)
1472 void LatexGenerator::writeObjectLink(const char *ref, const char *f,
1473 const char *anchor, const char *text)
1475 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1476 if (!disableLinks && !ref && pdfHyperlinks)
1478 t << "\\mbox{\\hyperlink{";
1479 if (f) t << stripPath(f);
1480 if (f && anchor) t << "_";
1481 if (anchor) t << anchor;
1494 void LatexGenerator::startPageRef()
1496 t << " \\doxyref{}{";
1499 void LatexGenerator::endPageRef(const char *clname, const char *anchor)
1502 if (clname) t << clname;
1503 if (anchor) t << "_" << anchor;
1508 void LatexGenerator::startTitleHead(const char *fileName)
1510 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1511 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1512 if (usePDFLatex && pdfHyperlinks && fileName)
1514 t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1516 if (Config_getBool(COMPACT_LATEX))
1518 t << "\\subsection{";
1526 void LatexGenerator::endTitleHead(const char *fileName,const char *name)
1531 t << "\\label{" << stripPath(fileName) << "}\\index{";
1532 t << latexEscapeLabelName(name);
1534 t << latexEscapeIndexChars(name);
1539 void LatexGenerator::startTitle()
1541 if (Config_getBool(COMPACT_LATEX))
1543 t << "\\subsection{";
1551 void LatexGenerator::startGroupHeader(int extraIndentLevel)
1553 if (Config_getBool(COMPACT_LATEX))
1558 if (extraIndentLevel==3)
1560 t << "\\subparagraph*{";
1562 else if (extraIndentLevel==2)
1564 t << "\\paragraph{";
1566 else if (extraIndentLevel==1)
1568 t << "\\subsubsection{";
1570 else // extraIndentLevel==0
1572 t << "\\subsection{";
1577 void LatexGenerator::endGroupHeader(int)
1583 void LatexGenerator::startMemberHeader(const char *,int)
1585 if (Config_getBool(COMPACT_LATEX))
1587 t << "\\subsubsection*{";
1591 t << "\\subsection*{";
1596 void LatexGenerator::endMemberHeader()
1602 void LatexGenerator::startMemberDoc(const char *clname,
1603 const char *memname,
1610 if (memname && memname[0]!='@')
1615 t << latexEscapeLabelName(clname);
1617 t << latexEscapeIndexChars(clname);
1620 t << latexEscapeLabelName(memname);
1622 t << latexEscapeIndexChars(memname);
1626 t << latexEscapeLabelName(memname);
1628 t << latexEscapeIndexChars(memname);
1633 t << latexEscapeLabelName(clname);
1635 t << latexEscapeIndexChars(clname);
1640 static const char *levelLab[] = { "subsubsection","paragraph","subparagraph", "subparagraph" };
1641 static bool compactLatex = Config_getBool(COMPACT_LATEX);
1642 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1644 if (showInline) level+=2;
1645 if (compactLatex) level++;
1646 t << "\\" << levelLab[level];
1651 t << "\\texorpdfstring{";
1653 t << latexEscapeIndexChars(title);
1656 t << "}{" << latexEscapePDFString(title) << "}";
1660 t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1663 t << "\n{\\footnotesize\\ttfamily ";
1664 //disableLinks=TRUE;
1667 void LatexGenerator::endMemberDoc(bool)
1671 //if (Config_getBool(COMPACT_LATEX)) t << "\\hfill";
1674 void LatexGenerator::startDoxyAnchor(const char *fName,const char *,
1675 const char *anchor, const char *,
1678 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1679 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1681 if (usePDFLatex && pdfHyperlinks)
1683 t << "\\Hypertarget{";
1684 if (fName) t << stripPath(fName);
1685 if (anchor) t << "_" << anchor;
1689 if (fName) t << stripPath(fName);
1690 if (anchor) t << "_" << anchor;
1694 void LatexGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1698 void LatexGenerator::writeAnchor(const char *fName,const char *name)
1700 //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1701 t << "\\label{" << stripPath(name) << "}" << endl;
1702 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1703 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1704 if (usePDFLatex && pdfHyperlinks)
1708 t << "\\Hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}" << endl;
1712 t << "\\Hypertarget{" << stripPath(name) << "}" << endl;
1718 //void LatexGenerator::writeLatexLabel(const char *clName,const char *anchor)
1720 // writeDoxyAnchor(0,clName,anchor,0);
1723 void LatexGenerator::addIndexItem(const char *s1,const char *s2)
1728 t << latexEscapeLabelName(s1);
1730 t << latexEscapeIndexChars(s1);
1735 t << latexEscapeLabelName(s2);
1737 t << latexEscapeIndexChars(s2);
1745 void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
1747 static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1748 static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1749 if (usePDFLatex && pdfHyperlinks)
1751 t << "\\hypertarget{" << stripPath(lab) << "}{}";
1754 if (Config_getBool(COMPACT_LATEX))
1758 case SectionInfo::Page: t << "subsection"; break;
1759 case SectionInfo::Section: t << "subsubsection"; break;
1760 case SectionInfo::Subsection: t << "paragraph"; break;
1761 case SectionInfo::Subsubsection: t << "subparagraph"; break;
1762 case SectionInfo::Paragraph: t << "subparagraph"; break;
1763 default: ASSERT(0); break;
1771 case SectionInfo::Page: t << "section"; break;
1772 case SectionInfo::Section: t << "subsection"; break;
1773 case SectionInfo::Subsection: t << "subsubsection"; break;
1774 case SectionInfo::Subsubsection: t << "paragraph"; break;
1775 case SectionInfo::Paragraph: t << "subparagraph"; break;
1776 default: ASSERT(0); break;
1782 void LatexGenerator::endSection(const char *lab,SectionInfo::SectionType)
1784 t << "}\\label{" << lab << "}" << endl;
1788 void LatexGenerator::docify(const char *str)
1790 filterLatexString(t,str,insideTabbing,FALSE,FALSE);
1793 void LatexGenerator::writeChar(char c)
1801 void LatexGenerator::startClassDiagram()
1803 //if (Config_getBool(COMPACT_LATEX)) t << "\\subsubsection"; else t << "\\subsection";
1807 void LatexGenerator::endClassDiagram(const ClassDiagram &d,
1808 const char *fileName,const char *)
1810 d.writeFigure(t,dir,fileName);
1814 void LatexGenerator::startAnonTypeScope(int indent)
1818 t << "\\begin{tabbing}" << endl;
1819 t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill" << endl;
1825 void LatexGenerator::endAnonTypeScope(int indent)
1829 t << endl << "\\end{tabbing}";
1830 insideTabbing=FALSE;
1835 void LatexGenerator::startMemberTemplateParams()
1837 if (templateMemberItem)
1839 t << "{\\footnotesize ";
1843 void LatexGenerator::endMemberTemplateParams(const char *,const char *)
1845 if (templateMemberItem)
1851 void LatexGenerator::startMemberItem(const char *,int annoType,const char *)
1853 //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1856 t << "\\item " << endl;
1857 templateMemberItem = (annoType == 3);
1861 void LatexGenerator::endMemberItem()
1867 templateMemberItem = FALSE;
1871 void LatexGenerator::startMemberDescription(const char *,const char *,bool)
1875 t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1879 for (int i=0;i<m_indent+2;i++) t << "\\>";
1884 void LatexGenerator::endMemberDescription()
1888 //t << "\\item\\end{DoxyCompactList}";
1889 t << "\\end{DoxyCompactList}";
1898 void LatexGenerator::writeNonBreakableSpace(int)
1900 //printf("writeNonBreakbleSpace()\n");
1911 // ----------------------------------------------
1912 // nesting of functions below:
1914 // - startDescTableRow()
1915 // - startDescTableTitle()
1916 // - endDescTabelTitle()
1917 // - startDescTableData()
1918 // - endDescTableData()
1919 // - endDescTableRow()
1920 // - startDescTableRow()
1922 // - endDescTableRow()
1925 void LatexGenerator::startDescTable(const char *title)
1927 incUsedTableLevels();
1928 t << "\\begin{DoxyEnumFields}{" << title << "}" << endl;
1931 void LatexGenerator::endDescTable()
1933 decUsedTableLevels();
1934 t << "\\end{DoxyEnumFields}" << endl;
1937 void LatexGenerator::startDescTableRow()
1939 // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1940 // the row height (based on http://tex.stackexchange.com/a/186102)
1941 t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1944 void LatexGenerator::endDescTableRow()
1948 void LatexGenerator::startDescTableTitle()
1953 void LatexGenerator::endDescTableTitle()
1957 void LatexGenerator::startDescTableData()
1962 void LatexGenerator::endDescTableData()
1964 t << "\\\\\n\\hline\n" << endl;
1967 void LatexGenerator::lastIndexPage()
1972 void LatexGenerator::startMemberList()
1976 t << "\\begin{DoxyCompactItemize}" << endl;
1980 void LatexGenerator::endMemberList()
1982 //printf("LatexGenerator::endMemberList(%d)\n",insideTabbing);
1985 t << "\\end{DoxyCompactItemize}" << endl;
1990 void LatexGenerator::startMemberGroupHeader(bool hasHeader)
1992 if (hasHeader) t << "\\begin{Indent}";
1994 // changed back to rev 756 due to bug 660501
1995 //if (Config_getBool(COMPACT_LATEX))
1997 // t << "\\subparagraph*{";
2001 // t << "\\paragraph*{";
2005 void LatexGenerator::endMemberGroupHeader()
2007 // changed back to rev 756 due to bug 660501
2008 t << "}\\par" << endl;
2012 void LatexGenerator::startMemberGroupDocs()
2017 void LatexGenerator::endMemberGroupDocs()
2022 void LatexGenerator::startMemberGroup()
2026 void LatexGenerator::endMemberGroup(bool hasHeader)
2028 if (hasHeader)t << "\\end{Indent}";
2032 void LatexGenerator::startDotGraph()
2037 void LatexGenerator::endDotGraph(const DotClassGraph &g)
2039 g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath);
2042 void LatexGenerator::startInclDepGraph()
2046 void LatexGenerator::endInclDepGraph(const DotInclDepGraph &g)
2048 g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath);
2051 void LatexGenerator::startGroupCollaboration()
2055 void LatexGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
2057 g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath);
2060 void LatexGenerator::startCallGraph()
2064 void LatexGenerator::endCallGraph(const DotCallGraph &g)
2066 g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath);
2069 void LatexGenerator::startDirDepGraph()
2073 void LatexGenerator::endDirDepGraph(const DotDirDeps &g)
2075 g.writeGraph(t,GOF_EPS,EOF_LaTeX,Config_getString(LATEX_OUTPUT),fileName,relPath);
2078 void LatexGenerator::startDescription()
2080 t << "\\begin{description}" << endl;
2083 void LatexGenerator::endDescription()
2085 t << "\\end{description}" << endl;
2089 void LatexGenerator::startDescItem()
2095 void LatexGenerator::endDescItem()
2100 firstDescItem=FALSE;
2108 void LatexGenerator::startExamples()
2110 t << "\\begin{Desc}\n\\item[";
2111 docify(theTranslator->trExamples());
2115 void LatexGenerator::endExamples()
2117 t << "\\end{Desc}" << endl;
2120 void LatexGenerator::startParamList(ParamListTypes,const char *title)
2122 t << "\\begin{Desc}\n\\item[";
2127 void LatexGenerator::endParamList()
2129 t << "\\end{Desc}" << endl;
2132 void LatexGenerator::startParameterList(bool openBracket)
2134 /* start of ParameterType ParameterName list */
2135 if (openBracket) t << "(";
2136 t << "\\begin{DoxyParamCaption}";
2139 void LatexGenerator::endParameterList()
2143 void LatexGenerator::startParameterType(bool first,const char *key)
2146 if (!first && key) docify(key);
2149 void LatexGenerator::endParameterType()
2154 void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2159 void LatexGenerator::endParameterName(bool last,bool /*emptyList*/,bool closeBracket)
2164 t << "\\end{DoxyParamCaption}";
2165 if (closeBracket) t << ")";
2169 void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2172 t << " " << prefix << "(";
2173 else if (closeBracket)
2178 void LatexGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2180 LatexDocVisitor *visitor =
2181 new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),insideTabbing);
2186 void LatexGenerator::startConstraintList(const char *header)
2188 t << "\\begin{Desc}\n\\item[";
2191 t << "\\begin{description}" << endl;
2194 void LatexGenerator::startConstraintParam()
2196 t << "\\item[{\\em ";
2199 void LatexGenerator::endConstraintParam()
2203 void LatexGenerator::startConstraintType()
2208 void LatexGenerator::endConstraintType()
2213 void LatexGenerator::startConstraintDocs()
2217 void LatexGenerator::endConstraintDocs()
2221 void LatexGenerator::endConstraintList()
2223 t << "\\end{description}" << endl;
2224 t << "\\end{Desc}" << endl;
2227 void LatexGenerator::startCodeFragment()
2229 t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n";
2230 DoxyCodeOpen = TRUE;
2233 void LatexGenerator::endCodeFragment()
2235 //endCodeLine checks is there is still an open code line, if so closes it.
2238 t << "\\end{DoxyCode}\n";
2239 DoxyCodeOpen = FALSE;
2242 void LatexGenerator::startInlineHeader()
2244 if (Config_getBool(COMPACT_LATEX))
2246 t << "\\paragraph*{";
2250 t << "\\subsubsection*{";
2254 void LatexGenerator::endInlineHeader()
2259 void LatexGenerator::lineBreak(const char *)
2271 void LatexGenerator::startMemberDocSimple(bool isEnum)
2273 incUsedTableLevels();
2276 t << "\\begin{DoxyEnumFields}{";
2277 docify(theTranslator->trEnumerationValues());
2281 t << "\\begin{DoxyFields}{";
2282 docify(theTranslator->trCompoundMembers());
2287 void LatexGenerator::endMemberDocSimple(bool isEnum)
2289 decUsedTableLevels();
2292 t << "\\end{DoxyEnumFields}" << endl;
2296 t << "\\end{DoxyFields}" << endl;
2300 void LatexGenerator::startInlineMemberType()
2302 insideTabbing = TRUE; // to prevent \+ from causing unwanted breaks
2305 void LatexGenerator::endInlineMemberType()
2308 insideTabbing = FALSE;
2311 void LatexGenerator::startInlineMemberName()
2313 insideTabbing = TRUE; // to prevent \+ from causing unwanted breaks
2316 void LatexGenerator::endInlineMemberName()
2319 insideTabbing = FALSE;
2322 void LatexGenerator::startInlineMemberDoc()
2326 void LatexGenerator::endInlineMemberDoc()
2328 t << "\\\\\n\\hline\n" << endl;
2331 void LatexGenerator::startLabels()
2333 t << "\\hspace{0.3cm}";
2336 void LatexGenerator::writeLabel(const char *l,bool isLast)
2338 t << "{\\ttfamily [" << l << "]}";
2339 if (!isLast) t << ", ";
2342 void LatexGenerator::endLabels()