Fix for UBSan build
[platform/upstream/doxygen.git] / src / latexgen.cpp
1 /******************************************************************************
2  *
3  * $Id: latexgen.cpp,v 1.58 2001/03/19 19:27:40 root Exp $
4  *
5  * Copyright (C) 1997-2012 by Dimitri van Heesch.
6  *
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.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include <stdlib.h>
19
20 #include "qtbc.h"
21 #include <qdir.h>
22 #include "latexgen.h"
23 #include "config.h"
24 #include "message.h"
25 #include "doxygen.h"
26 #include "util.h"
27 #include "diagram.h"
28 #include "language.h"
29 #include "version.h"
30 #include "dot.h"
31 #include "pagedef.h"
32 #include "docparser.h"
33 #include "latexdocvisitor.h"
34 #include "dirdef.h"
35 #include "cite.h"
36
37 //static QCString filterTitle(const char *s)
38 //{
39 //  QCString tmp=s,result;
40 //  uint i;for (i=0;i<tmp.length();i++)
41 //  {
42 //    char c=tmp.at(i);
43 //    switch(c)
44 //    {
45 //      case '#': result+="\\#";  break;
46 //      case '"': result+="\\\""; break;
47 //      case '%': result+="\\%";  break;
48 //      case '[': result+="{";    break;
49 //      case ']': result+="}";    break;
50 //      default:  result+=c;      break;
51 //    }
52 //  }
53 //  return result;  
54 //}
55
56
57
58 LatexGenerator::LatexGenerator() : OutputGenerator()
59 {
60   dir=Config_getString("LATEX_OUTPUT");
61   col=0;
62   //printf("LatexGenerator::LatexGenerator() insideTabbing=FALSE\n");
63   insideTabbing=FALSE;
64   firstDescItem=TRUE;
65   disableLinks=FALSE;
66   m_indent=0;
67   templateMemberItem = FALSE;
68   m_prettyCode=Config_getBool("LATEX_SOURCE_CODE");
69 }
70
71 LatexGenerator::~LatexGenerator()
72 {
73 }
74
75 static void writeLatexMakefile()
76 {
77   bool generateBib = !Doxygen::citeDict->isEmpty();
78   QCString dir=Config_getString("LATEX_OUTPUT");
79   QCString fileName=dir+"/Makefile";
80   QFile file(fileName);
81   if (!file.open(IO_WriteOnly))
82   {
83     err("Could not open file %s for writing\n",fileName.data());
84     exit(1);
85   }
86   // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
87   QCString latex_command = Config_getString("LATEX_CMD_NAME");
88   QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME");
89   // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
90   FTextStream t(&file);
91   if (!Config_getBool("USE_PDFLATEX")) // use plain old latex
92   {
93     t << "all: refman.dvi" << endl
94       << endl
95       << "ps: refman.ps" << endl
96       << endl
97       << "pdf: refman.pdf" << endl
98       << endl
99       << "ps_2on1: refman_2on1.ps" << endl
100       << endl
101       << "pdf_2on1: refman_2on1.pdf" << endl
102       << endl
103       << "refman.ps: refman.dvi" << endl
104       << "\tdvips -o refman.ps refman.dvi" << endl
105       << endl;
106     t << "refman.pdf: refman.ps" << endl;
107     t << "\tps2pdf refman.ps refman.pdf" << endl << endl;
108     t << "refman.dvi: clean refman.tex doxygen.sty" << endl
109       << "\techo \"Running latex...\"" << endl
110       << "\t" << latex_command << " refman.tex" << endl
111       << "\techo \"Running makeindex...\"" << endl
112       << "\t" << mkidx_command << " refman.idx" << endl;
113     if (generateBib)
114     {
115       t << "\techo \"Running bibtex...\"" << endl;
116       t << "\tbibtex refman" << endl;
117       t << "\techo \"Rerunning latex....\"" << endl;
118       t << "\t" << latex_command << " refman.tex" << endl;
119     }
120     t << "\techo \"Rerunning latex....\"" << endl
121       << "\t" << latex_command << " refman.tex" << endl
122       << "\tlatex_count=5 ; \\" << endl
123       << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
124       << "\t    do \\" << endl
125       << "\t      echo \"Rerunning latex....\" ;\\" << endl
126       << "\t      " << latex_command << " refman.tex ;\\" << endl
127       << "\t      latex_count=`expr $$latex_count - 1` ;\\" << endl
128       << "\t    done" << endl << endl
129       << "refman_2on1.ps: refman.ps" << endl
130       << "\tpsnup -2 refman.ps >refman_2on1.ps" << endl
131       << endl
132       << "refman_2on1.pdf: refman_2on1.ps" << endl
133       << "\tps2pdf refman_2on1.ps refman_2on1.pdf" << endl;
134   }
135   else // use pdflatex for higher quality output
136   {
137     t << "all: refman.pdf" << endl << endl
138       << "pdf: refman.pdf" << endl << endl;
139     t << "refman.pdf: clean refman.tex" << endl;
140     t << "\tpdflatex refman" << endl;
141     t << "\t" << mkidx_command << " refman.idx" << endl;
142     if (generateBib)
143     {
144       t << "\tbibtex refman" << endl;
145       t << "\tpdflatex refman" << endl;
146     }
147     t << "\tpdflatex refman" << endl
148       << "\tlatex_count=5 ; \\" << endl
149       << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
150       << "\t    do \\" << endl
151       << "\t      echo \"Rerunning latex....\" ;\\" << endl
152       << "\t      pdflatex refman ;\\" << endl
153       << "\t      latex_count=`expr $$latex_count - 1` ;\\" << endl
154       << "\t    done" << endl << endl;
155   }
156
157   t << endl
158     << "clean:" << endl
159     << "\trm -f " 
160     << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl;
161 }
162
163 static void writeMakeBat()
164 {
165 #if defined(_MSC_VER)
166   QCString dir=Config_getString("LATEX_OUTPUT");
167   QCString fileName=dir+"/make.bat";
168   QCString latex_command = Config_getString("LATEX_CMD_NAME");
169   QCString mkidx_command = Config_getString("MAKEINDEX_CMD_NAME");
170   QFile file(fileName);
171   bool generateBib = !Doxygen::citeDict->isEmpty();
172   if (!file.open(IO_WriteOnly))
173   {
174     err("Could not open file %s for writing\n",fileName.data());
175     exit(1);
176   }
177   FTextStream t(&file);
178   t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n";
179   if (!Config_getBool("USE_PDFLATEX")) // use plain old latex
180   {
181     t << latex_command << " refman.tex\n";
182     t << "echo ----\n";
183     t << mkidx_command << " refman.idx\n";
184     if (generateBib)
185     {
186       t << "bibtex refman\n";
187       t << "echo ----\n";
188       t << latex_command << " refman.tex\n";
189     }
190     t << "setlocal enabledelayedexpansion\n";
191     t << "set count=5\n";
192     t << ":repeat\n";
193     t << "set content=X\n";
194     t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
195     t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
196     t << "if !content! == X goto :skip\n";
197     t << "set /a count-=1\n";
198     t << "if !count! EQU 0 goto :skip\n\n";
199     t << "echo ----\n";
200     t << latex_command << " refman.tex\n";
201     t << "goto :repeat\n";
202     t << ":skip\n";
203     t << "endlocal\n";
204     t << "dvips -o refman.ps refman.dvi\n";
205     t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
206          "-sOutputFile=refman.pdf -c save pop -f refman.ps\n";
207   }
208   else // use pdflatex
209   {
210     t << "pdflatex refman\n";
211     t << "echo ----\n";
212     t << mkidx_command << " refman.idx\n";
213     if (generateBib)
214     {
215       t << "bibtex refman" << endl;
216       t << "pdflatex refman" << endl;
217     }
218     t << "echo ----\n";
219     t << "pdflatex refman\n\n";
220     t << "setlocal enabledelayedexpansion\n";
221     t << "set count=5\n";
222     t << ":repeat\n";
223     t << "set content=X\n";
224     t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
225     t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
226     t << "if !content! == X goto :skip\n";
227     t << "set /a count-=1\n";
228     t << "if !count! EQU 0 goto :skip\n\n";
229     t << "echo ----\n";
230     t << "pdflatex refman\n";
231     t << "goto :repeat\n";
232     t << ":skip\n";
233     t << "endlocal\n";
234   }
235 #endif
236 }
237
238 void LatexGenerator::init()
239 {
240
241   QCString dir=Config_getString("LATEX_OUTPUT");
242   QDir d(dir);
243   if (!d.exists() && !d.mkdir(dir))
244   {
245     err("Could not create output directory %s\n",dir.data());
246     exit(1);
247   }
248
249   writeLatexMakefile();
250   writeMakeBat();
251
252   createSubDirs(d);
253 }
254
255 static void writeDefaultHeaderPart1(FTextStream &t)
256 {
257   // part 1
258
259   QCString paperName;
260   if (Config_getBool("LATEX_BATCHMODE")) t << "\\batchmode" << endl;
261   QCString &paperType=Config_getEnum("PAPER_TYPE");
262   if (paperType=="a4wide") 
263     paperName="a4"; 
264   else 
265     paperName=paperType;
266   t << "\\documentclass";
267   //"[" << paperName << "paper";
268   //t << "]";
269   t << "{";
270   if (Config_getBool("COMPACT_LATEX")) t << "article"; else t << "book";
271   t << "}\n";
272   // the next package is obsolete (see bug 563698)
273   //if (paperType=="a4wide") t << "\\usepackage{a4wide}\n";
274   t << 
275     "\\usepackage["<<paperName<<"paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry}\n"
276     "\\usepackage{makeidx}\n"
277     "\\usepackage{natbib}\n"
278     "\\usepackage{graphicx}\n"
279     "\\usepackage{multicol}\n"
280     "\\usepackage{float}\n"
281     "\\usepackage{listings}\n"
282     "\\usepackage{color}\n"
283     "\\usepackage{ifthen}\n"
284     "\\usepackage[table]{xcolor}\n"
285     "\\usepackage{textcomp}\n"
286     "\\usepackage{alltt}\n"
287     //"\\usepackage{ae,aecompl,aeguill}\n"
288     ;
289   //if (Config_getBool("USE_PDFLATEX"))
290   //{
291   //  t << "\\usepackage{times}" << endl;
292   //}
293   if (Config_getBool("PDF_HYPERLINKS")) 
294   {
295     t << "\\usepackage{ifpdf}" << endl
296       << "\\ifpdf" << endl
297       << "\\usepackage[pdftex," << endl
298       << "            pagebackref=true," << endl
299       << "            colorlinks=true," << endl
300       << "            linkcolor=blue," << endl
301       << "            unicode" << endl
302       << "           ]{hyperref}" << endl
303       << "\\else" << endl
304       << "\\usepackage[ps2pdf," << endl
305       << "            pagebackref=true," << endl
306       << "            colorlinks=true," << endl
307       << "            linkcolor=blue," << endl
308       << "            unicode" << endl
309       << "           ]{hyperref}" << endl
310       << "\\usepackage{pspicture}" << endl
311       << "\\fi" << endl;
312   }
313   // Try to get the command for switching on the language
314   // support
315   t << "\\usepackage[utf8]{inputenc}" << endl;
316   QCString sLanguageSupportCommand(
317       theTranslator->latexLanguageSupportCommand());
318
319   if (!sLanguageSupportCommand.isEmpty())
320   {
321     // The command is not empty.  Put it to the output.
322     // if the command is empty, no output is needed.
323     t << sLanguageSupportCommand << endl;
324   }
325   t << "\\usepackage{mathptmx}\n";
326   t << "\\usepackage[scaled=.90]{helvet}\n";
327   t << "\\usepackage{courier}\n";
328   t << "\\usepackage{sectsty}\n";
329   t << "\\usepackage{amssymb}\n";
330   t << "\\usepackage[titles]{tocloft}\n";
331   t << "\\usepackage{doxygen}\n";
332
333   // define option for listings
334   t << "\\lstset{language=C++,"
335                 "inputencoding=utf8,"
336                 "basicstyle=\\footnotesize,"
337                 "breaklines=true,"
338                 "breakatwhitespace=true,"
339                 "tabsize=" << Config_getInt("TAB_SIZE") <<","
340                 "numbers=left }" << endl;
341
342   QStrList &extraPackages = Config_getList("EXTRA_PACKAGES");
343   const char *s=extraPackages.first();
344   while (s)
345   {
346     t << "\\usepackage{" << s << "}\n";
347     s=extraPackages.next();
348   }
349   t << "\\makeindex\n"
350     "\\setcounter{tocdepth}{3}\n"
351     "\\renewcommand{\\footrulewidth}{0.4pt}\n"
352     "\\renewcommand{\\familydefault}{\\sfdefault}\n"
353     "\\hfuzz=15pt\n"  // allow a bit of overflow to go unnoticed
354     "\\setlength{\\emergencystretch}{15pt}\n"
355     "\\hbadness=750\n"
356     "\\tolerance=750\n"
357     "\\begin{document}\n";
358   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
359   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
360   if (pdfHyperlinks && usePDFLatex)
361   {
362     // to avoid duplicate page anchors due to reuse of same numbers for
363     // the index (be it as roman numbers)
364     t << "\\hypersetup{pageanchor=false,citecolor=blue}" << endl;
365   }
366   if (theTranslator->idLanguage()=="greek") t << "\\selectlanguage{greek}\n";
367   t << "\\begin{titlepage}\n"
368     "\\vspace*{7cm}\n"
369     "\\begin{center}\n"
370     "{\\Large ";
371
372 }
373
374 static void writeDefaultHeaderPart2(FTextStream &t)
375 {
376   // part 2
377   t << "}\\\\" << endl
378     << "\\vspace*{1cm}" << endl
379     << "{\\large ";
380 }
381
382 static void writeDefaultHeaderPart3(FTextStream &t)
383 {
384   // part 3
385   t << " Doxygen " << versionString << "}\\\\" << endl
386     << "\\vspace*{0.5cm}" << endl
387     << "{\\small " << dateToString(TRUE) << "}\\\\" << endl
388     << "\\end{center}" << endl
389     << "\\end{titlepage}" << endl;
390   if (!Config_getBool("COMPACT_LATEX")) t << "\\clearemptydoublepage\n";
391   t << "\\pagenumbering{roman}\n";
392   t << "\\tableofcontents\n";
393   if (!Config_getBool("COMPACT_LATEX")) t << "\\clearemptydoublepage\n";
394   t << "\\pagenumbering{arabic}\n";
395   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
396   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
397   if (pdfHyperlinks && usePDFLatex)
398   {
399     t << "\\hypersetup{pageanchor=true,citecolor=blue}" << endl;
400   }
401 }
402
403 static void writeDefaultStyleSheetPart1(FTextStream &t)
404 {
405   // part 1
406   t << "\\NeedsTeXFormat{LaTeX2e}\n"
407        "\\ProvidesPackage{doxygen}\n\n";
408   t << "% Packages used by this style file\n"
409        "\\RequirePackage{alltt}\n"
410        "\\RequirePackage{array}\n"
411        "\\RequirePackage{calc}\n"
412        "\\RequirePackage{color}\n"
413        "\\RequirePackage{fancyhdr}\n"
414        "\\RequirePackage{longtable}\n"
415        "\\RequirePackage{verbatim}\n"
416        "\\RequirePackage{ifthen}\n"
417        "\\RequirePackage{xtab}\n"
418        "\\RequirePackage{multirow}\n"
419        "\\RequirePackage[table]{xcolor}\n\n";
420
421   t << "% Use helvetica font instead of times roman\n"
422        "\\RequirePackage{helvet}\n"
423        "\\RequirePackage{sectsty}\n"
424        "\\RequirePackage{tocloft}\n"
425 //       "\\allsectionsfont{\\usefont{OT1}{phv}{bc}{n}\\selectfont}\n"
426 //       "\\providecommand{\\cftchapfont}{%\n"
427 //       "  \\fontsize{11}{13}\\usefont{OT1}{phv}{bc}{n}\\selectfont\n"
428 //       "}\n"
429 //       "\\providecommand{\\cftchappagefont}{%\n"
430 //       "  \\fontsize{11}{13}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
431 //       "}\n"
432 //       "\\providecommand{\\cftsecfont}{%\n"
433 //       "  \\fontsize{10}{12}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
434 //       "}\n"
435 //       "\\providecommand{\\cftsecpagefont}{%\n"
436 //       "  \\fontsize{10}{12}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
437 //       "}\n"
438 //       "\\providecommand{\\cftsubsecfont}{%\n"
439 //       "  \\fontsize{10}{12}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
440 //       "}\n"
441 //       "\\providecommand{\\cftsubsecpagefont}{%\n"
442 //       "  \\fontsize{10}{12}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
443 //       "}\n"
444 //       "\\providecommand{\\cftsubsubsecfont}{%\n"
445 //       "  \\fontsize{9}{11}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
446 //       "}\n"
447 //       "\\providecommand{\\cftsubsubsecpagefont}{%\n"
448 //       "  \\fontsize{9}{11}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
449 //       "}\n"
450 //       "\\providecommand{\\cftparafont}{%\n"
451 //       "  \\fontsize{9}{11}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
452 //       "}\n"
453 //       "\\providecommand{\\cftparapagefont}{%\n"
454 //       "  \\fontsize{9}{11}\\usefont{OT1}{phv}{c}{n}\\selectfont\n"
455 //       "}\n"
456 //       "\\providecommand{\\cfttoctitlefont}{%\n"
457 //       "  \\fontsize{20}{22}\\usefont{OT1}{phv}{b}{n}\\selectfont\n"
458 //       "}\n"
459        "\\providecommand{\\rmdefault}{phv}\n"
460        "\\providecommand{\\bfdefault}{bc}\n"
461        "\n\n";
462
463   t << "% Setup fancy headings\n"
464        "\\pagestyle{fancyplain}\n"
465        "\\newcommand{\\clearemptydoublepage}{%\n"
466        "  \\newpage{\\pagestyle{empty}\\cleardoublepage}%\n"
467        "}\n";
468   if (!Config_getBool("COMPACT_LATEX")) 
469     t << "\\renewcommand{\\chaptermark}[1]{%\n"
470          "  \\markboth{#1}{}%\n"
471          "}\n";
472   t << "\\renewcommand{\\sectionmark}[1]{%\n"
473        "  \\markright{\\thesection\\ #1}%\n"
474        "}\n";
475
476   //t << "\\lhead[\\fancyplain{}{\\bfseries\\thepage}]{%\n"
477   //     "  \\fancyplain{}{\\bfseries\\rightmark}%\n"
478   //     "}\n";
479   //t << "\\rhead[\\fancyplain{}{\\bfseries\\leftmark}]{%\n"
480   //     "  \\fancyplain{}{\\bfseries\\thepage}%\n"
481   //     "}\n";
482   //t << "\\rfoot[\\fancyplain{}{\\bfseries\\scriptsize%\n  ";
483   t << "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n";
484   t << "\\fancyhead[CE]{\\fancyplain{}{}}\n";
485   t << "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n";
486   t << "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n";
487   t << "\\fancyhead[CO]{\\fancyplain{}{}}\n";
488   t << "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n";
489
490   t << "\\fancyfoot[LE]{\\fancyplain{}{}}\n";
491   t << "\\fancyfoot[CE]{\\fancyplain{}{}}\n";
492   t << "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize ";
493 }
494
495 static void writeDefaultStyleSheetPart2(FTextStream &t)
496 {
497   t << "}}\n";
498   t << "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize ";
499   //t << "\\lfoot[]{\\fancyplain{}{\\bfseries\\scriptsize%\n  ";
500
501 }
502
503 static void writeDefaultStyleSheetPart3(FTextStream &t)
504 {
505   //static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
506   t << "}}\n";
507   //t << "\\cfoot{}\n\n";
508   t << "\\fancyfoot[CO]{\\fancyplain{}{}}\n";
509   t << "\\fancyfoot[RO]{\\fancyplain{}{}}\n";
510
511   t << "%---------- Internal commands used in this style file ----------------\n\n";
512
513   t << "\\newcommand\\tabfill[1]{%\n";
514   t << "  \\dimen@\\linewidth%\n";
515   t << "  \\advance\\dimen@\\@totalleftmargin%\n";
516   t << "  \\advance\\dimen@-\\dimen\\@curtab%\n";
517   t << "  \\parbox[t]\\dimen@{\\raggedright #1\\ifhmode\\strut\\fi}%\n";
518   t << "}\n\n";
519
520   t << "\\newcommand{\\ensurespace}[1]{%\n";
521   t << "  \\begingroup\n";
522   t << "    \\setlength{\\dimen@}{#1}%\n";
523   t << "    \\vskip\\z@\\@plus\\dimen@\n";
524   t << "    \\penalty -100\\vskip\\z@\\@plus -\\dimen@\n";
525   t << "    \\vskip\\dimen@\n";
526   t << "    \\penalty 9999%\n";
527   t << "    \\vskip -\\dimen@\n";
528   t << "    \\vskip\\z@skip % hide the previous |\\vskip| from |\\addvspace|\n";
529   t << "  \\endgroup\n";
530   t << "}\n\n";
531
532   t << "% Generic environment used by all paragraph-based environments defined\n"
533        "% below. Note that the command \\title{...} needs to be defined inside\n"
534        "% those environments!\n"
535        "\\newenvironment{DoxyDesc}[1]{%\n"
536        //"  \\filbreak%\n"
537        "  \\ensurespace{4\\baselineskip}%\n"
538        "  \\begin{list}{}%\n"
539        "  {%\n"
540        "    \\settowidth{\\labelwidth}{40pt}%\n"
541        "    \\setlength{\\leftmargin}{\\labelwidth}%\n"
542        "    \\setlength{\\parsep}{0pt}%\n"
543        "    \\setlength{\\itemsep}{-4pt}%\n"
544        "    \\renewcommand{\\makelabel}{\\entrylabel}%\n"
545        "  }%\n"
546        "  \\item[#1]%\n"
547        "}{%\n"
548        "  \\end{list}%\n"
549        "}\n\n";
550   t << "%---------- Commands used by doxygen LaTeX output generator ----------\n\n";
551   t << "% Used by <pre> ... </pre>\n"
552        "\\newenvironment{DoxyPre}{%\n"
553        "  \\small%\n"
554        "  \\begin{alltt}%\n"
555        "}{%\n"
556        "  \\end{alltt}%\n"
557        "  \\normalsize%\n"
558        "}\n\n";
559   t << "% Used by @code ... @endcode\n"
560        "\\newenvironment{DoxyCode}{%\n";
561   //if (latexSourceCode)
562   //{
563     t << "\n\n\\begin{scriptsize}\\begin{alltt}%" << endl;
564   //}
565   //else
566   //{
567   //  t << "  \\footnotesize%\n"
568   //       "  \\verbatim%\n";
569   //}
570   t << "}{%\n";
571   //if (latexSourceCode)
572   //{
573     t << "\\end{alltt}\\end{scriptsize}%" << endl; 
574   //}
575   //else
576   //{
577   //  t << "  \\endverbatim%\n"
578   //       "  \\normalsize%\n";
579   //}
580   t << "}\n\n";
581   t << "% Used by @example, @include, @includelineno and @dontinclude\n"
582        "\\newenvironment{DoxyCodeInclude}{%\n"
583        "  \\DoxyCode%\n"
584        "}{%\n"
585        "  \\endDoxyCode%\n"
586        "}\n\n";
587   t << "% Used by @verbatim ... @endverbatim\n"
588        "\\newenvironment{DoxyVerb}{%\n"
589        "  \\footnotesize%\n"
590        "  \\verbatim%\n"
591        "}{%\n"
592        "  \\endverbatim%\n"
593        "  \\normalsize%\n"
594        "}\n\n";
595   t << "% Used by @verbinclude\n"
596        "\\newenvironment{DoxyVerbInclude}{%\n"
597        "  \\DoxyVerb%\n"
598        "}{%\n"
599        "  \\endDoxyVerb%\n"
600        "}\n\n";
601   t << "% Used by numbered lists (using '-#' or <ol> ... </ol>)\n"
602        "\\newenvironment{DoxyEnumerate}{%\n"
603        "  \\enumerate%\n"
604        "}{%\n"
605        "  \\endenumerate%\n"
606        "}\n\n";
607   t << "% Used by bullet lists (using '-', @li, @arg, or <ul> ... </ul>)\n"
608        "\\newenvironment{DoxyItemize}{%\n"
609        "  \\itemize%\n"
610        "}{%\n"
611        "  \\enditemize%\n"
612        "}\n\n";
613   t << "% Used by description lists (using <dl> ... </dl>)\n"
614        "\\newenvironment{DoxyDescription}{%\n"
615        "  \\description%\n"
616        "}{%\n"
617        "  \\enddescription%\n"
618        "}\n\n";
619   t << "% Used by @image, @dotfile, and @dot ... @enddot\n"
620        "% (only if caption is specified)\n"
621        "\\newenvironment{DoxyImage}{%\n"
622        "  \\begin{figure}[H]%\n"
623        "  \\begin{center}%\n"
624        "}{%\n"
625        "  \\end{center}%\n"
626        "  \\end{figure}%\n"
627        "}\n\n";
628   t << "% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc\n"
629        "% (only if no caption is specified)\n"
630        "\\newenvironment{DoxyImageNoCaption}{%\n"
631        "}{%\n"
632        "}\n\n";
633   t << "% Used by @attention\n"
634        "\\newenvironment{DoxyAttention}[1]{%\n"
635        "  \\begin{DoxyDesc}{#1}%\n"
636        "}{%\n"
637        "  \\end{DoxyDesc}%\n"
638        "}\n\n";
639   t << "% Used by @author and @authors\n"
640        "\\newenvironment{DoxyAuthor}[1]{%\n"
641        "  \\begin{DoxyDesc}{#1}%\n"
642        "}{%\n"
643        "  \\end{DoxyDesc}%\n"
644        "}\n\n";
645   t << "% Used by @date\n"
646        "\\newenvironment{DoxyDate}[1]{%\n"
647        "  \\begin{DoxyDesc}{#1}%\n"
648        "}{%\n"
649        "  \\end{DoxyDesc}%\n"
650        "}\n\n";
651   t << "% Used by @invariant\n"
652        "\\newenvironment{DoxyInvariant}[1]{%\n"
653        "  \\begin{DoxyDesc}{#1}%\n"
654        "}{%\n"
655        "  \\end{DoxyDesc}%\n"
656        "}\n\n";
657   t << "% Used by @note\n"
658        "\\newenvironment{DoxyNote}[1]{%\n"
659        "  \\begin{DoxyDesc}{#1}%\n"
660        "}{%\n"
661        "  \\end{DoxyDesc}%\n"
662        "}\n\n";
663   t << "% Used by @post\n"
664        "\\newenvironment{DoxyPostcond}[1]{%\n"
665        "  \\begin{DoxyDesc}{#1}%\n"
666        "}{%\n"
667        "  \\end{DoxyDesc}%\n"
668        "}\n\n";
669   t << "% Used by @pre\n"
670        "\\newenvironment{DoxyPrecond}[1]{%\n"
671        "  \\begin{DoxyDesc}{#1}%\n"
672        "}{%\n"
673        "  \\end{DoxyDesc}%\n"
674        "}\n\n";
675   t << "% Used by @copyright\n"
676        "\\newenvironment{DoxyCopyright}[1]{%\n"
677        "  \\begin{DoxyDesc}{#1}%\n"
678        "}{%\n"
679        "  \\end{DoxyDesc}%\n"
680        "}\n\n";
681   t << "% Used by @remark\n"
682        "\\newenvironment{DoxyRemark}[1]{%\n"
683        "  \\begin{DoxyDesc}{#1}%\n"
684        "}{%\n"
685        "  \\end{DoxyDesc}%\n"
686        "}\n\n";
687   t << "% Used by @return\n"
688        "\\newenvironment{DoxyReturn}[1]{%\n"
689        "  \\begin{DoxyDesc}{#1}%\n"
690        "}{%\n"
691        "  \\end{DoxyDesc}%\n"
692        "}\n\n";
693   t << "% Used by @since\n"
694        "\\newenvironment{DoxySince}[1]{%\n"
695        "  \\begin{DoxyDesc}{#1}%\n"
696        "}{%\n"
697        "  \\end{DoxyDesc}%\n"
698        "}\n\n";
699   t << "% Used by @see\n"
700        "\\newenvironment{DoxySeeAlso}[1]{%\n"
701        "  \\begin{DoxyDesc}{#1}%\n"
702        "}{%\n"
703        "  \\end{DoxyDesc}%\n"
704        "}\n\n";
705   t << "% Used by @version\n"
706        "\\newenvironment{DoxyVersion}[1]{%\n"
707        "  \\begin{DoxyDesc}{#1}%\n"
708        "}{%\n"
709        "  \\end{DoxyDesc}%\n"
710        "}\n\n";
711   t << "% Used by @warning\n"
712        "\\newenvironment{DoxyWarning}[1]{%\n"
713        "  \\begin{DoxyDesc}{#1}%\n"
714        "}{%\n"
715        "  \\end{DoxyDesc}%\n"
716        "}\n\n";
717   t << "% Used by @internal\n"
718        "\\newenvironment{DoxyInternal}[1]{%\n"
719        "  \\paragraph*{#1}%\n"
720        "}{%\n"
721        "}\n\n";
722   t << "% Used by @par and @paragraph\n"
723        "\\newenvironment{DoxyParagraph}[1]{%\n"
724        "  \\begin{list}{}%\n"
725        "  {%\n"
726        "    \\settowidth{\\labelwidth}{40pt}%\n"
727        "    \\setlength{\\leftmargin}{\\labelwidth}%\n"
728        "    \\setlength{\\parsep}{0pt}%\n"
729        "    \\setlength{\\itemsep}{-4pt}%\n"
730        "    \\renewcommand{\\makelabel}{\\entrylabel}%\n"
731        "  }%\n"
732        "  \\item[#1]%\n"
733        "}{%\n"
734        "  \\end{list}%\n"
735        "}\n\n";
736   t << "% Used by parameter lists\n"
737        "\\newenvironment{DoxyParams}[2][]{%\n"
738        "  \\begin{DoxyDesc}{#2}%\n"
739        //"    \\begin{description}%\n"
740        "    \\item[] \\hspace{\\fill} \\vspace{-40pt}%\n"
741        //"      \\definecolor{tableShade}{HTML}{F8F8F8}%\n"
742        //"      \\rowcolors{1}{white}{tableShade}%\n"
743        //"      \\arrayrulecolor{gray}%\n"
744        "    \\settowidth{\\labelwidth}{40pt}%\n"
745        //"    \\setlength{\\LTleft}{\\labelwidth}%\n"
746        "    \\setlength{\\LTleft}{0pt}%\n"
747        "    \\setlength{\\tabcolsep}{0.01\\textwidth}%\n"
748        "    \\ifthenelse{\\equal{#1}{}}%\n" // default: name, docs columns
749        "    {\\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n"
750        "                        p{0.815\\textwidth}|}}%\n"
751        "    {\\ifthenelse{\\equal{#1}{1}}%\n" // inout, name, docs columns, or type, name, docs columns
752        "      {\\begin{longtable}{|>{\\centering}p{0.10\\textwidth}|%\n"
753        "                         >{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n"
754        "                         p{0.685\\textwidth}|}}%\n"
755        "      {\\begin{longtable}{|>{\\centering}p{0.10\\textwidth}|%\n" // inout, type, name, docs columns
756        "                         >{\\centering\\hspace{0pt}}p{0.15\\textwidth}|%\n"
757        "                         >{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n"
758        "                         p{0.515\\textwidth}|}}%\n"
759        "    }\\hline%\n"
760        "}{%\n"
761        "    \\end{longtable}%\n"
762        //"    \\end{description}%\n"
763        "  \\end{DoxyDesc}%\n"
764        "}\n\n";
765   t << "% Used for fields of simple structs\n"
766        "\\newenvironment{DoxyFields}[1]{%\n"
767        "  \\begin{DoxyDesc}{#1}%\n"
768        "    \\item[] \\hspace{\\fill} \\vspace{-40pt}%\n"
769        "    \\settowidth{\\labelwidth}{40pt}%\n"
770        "    \\setlength{\\LTleft}{0pt}%\n"
771        "    \\setlength{\\tabcolsep}{0.01\\textwidth}%\n"
772        "    \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.15\\textwidth}|%\n"
773        "                         p{0.15\\textwidth}|%\n"
774        "                         p{0.635\\textwidth}|}%\n"
775        //"\\hline{\\sf\\textbf{Type}} & {\\sf\\textbf{Name}} & {\\sf\\textbf{Description}}\\endhead%\n"
776        "    \\hline%\n"
777        "}{%\n"
778        "    \\end{longtable}%\n"
779        //"    \\end{description}%\n"
780        "  \\end{DoxyDesc}%\n"
781        "}\n\n";
782   t << "% is used for parameters within a detailed function description\n"
783        "\\newenvironment{DoxyParamCaption}{%\n"
784        "  \\renewcommand{\\item}[2][]{##1 {\\em ##2}}%\n"
785        "  }{%\n"
786        "}\n\n";
787   t << "% Used by return value lists\n"
788        "\\newenvironment{DoxyRetVals}[1]{%\n"
789        "  \\begin{DoxyDesc}{#1}%\n"
790        "    \\begin{description}%\n"
791        "      \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n"
792        //"      \\definecolor{tableShade}{HTML}{F8F8F8}%\n"
793        //"      \\rowcolors{1}{white}{tableShade}%\n"
794        //"      \\arrayrulecolor{gray}%\n"
795        "      \\setlength{\\tabcolsep}{0.01\\textwidth}%\n"
796        "      \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n"
797        "                          p{0.77\\textwidth}|}%\n"
798        "      \\hline%\n"
799        "}{%\n"
800        "      \\end{longtable}%\n"
801        "    \\end{description}%\n"
802        "  \\end{DoxyDesc}%\n"
803        "}\n\n";
804   t << "% Used by exception lists\n"
805        "\\newenvironment{DoxyExceptions}[1]{%\n"
806        "  \\begin{DoxyDesc}{#1}%\n"
807        "    \\begin{description}%\n"
808        "      \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n"
809        "      \\definecolor{tableShade}{HTML}{F8F8F8}%\n"
810        "      \\rowcolors{1}{white}{tableShade}%\n"
811        "      \\arrayrulecolor{gray}%\n"
812        "      \\setlength{\\tabcolsep}{0.01\\textwidth}%\n"
813        "      \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n"
814        "                          p{0.77\\textwidth}|}%\n"
815        "      \\hline%\n"
816        "}{%\n"
817        "      \\end{longtable}%\n"
818        "    \\end{description}%\n"
819        "  \\end{DoxyDesc}%\n"
820        "}\n\n";
821   t << "% Used by template parameter lists\n"
822        "\\newenvironment{DoxyTemplParams}[1]{%\n"
823        "  \\begin{DoxyDesc}{#1}%\n"
824        "    \\begin{description}%\n"
825        "      \\item[] \\hspace{\\fill} \\vspace{-25pt}%\n"
826        "      \\definecolor{tableShade}{HTML}{F8F8F8}%\n"
827        "      \\rowcolors{1}{white}{tableShade}%\n"
828        "      \\arrayrulecolor{gray}%\n"
829        "      \\setlength{\\tabcolsep}{0.01\\textwidth}%\n"
830        "      \\begin{longtable}{|>{\\raggedleft\\hspace{0pt}}p{0.25\\textwidth}|%\n"
831        "                          p{0.77\\textwidth}|}%\n"
832        "      \\hline%\n"
833        "}{%\n"
834        "      \\end{longtable}%\n"
835        "    \\end{description}%\n"
836        "  \\end{DoxyDesc}%\n"
837        "}\n\n";
838   t << "\\newcommand{\\doxyref}[3]{\\textbf{#1} (\\textnormal{#2}\\,\\pageref{#3})}\n";
839   t << "\\newenvironment{DoxyCompactList}\n";
840   t << "{\\begin{list}{}{\n";
841   t << "  \\setlength{\\leftmargin}{0.5cm}\n";
842   t << "  \\setlength{\\itemsep}{0pt}\n";
843   t << "  \\setlength{\\parsep}{0pt}\n";
844   t << "  \\setlength{\\topsep}{0pt}\n";
845   t << "  \\renewcommand{\\makelabel}{\\hfill}}}\n";
846   t << "{\\end{list}}\n";
847   t << "\\newenvironment{DoxyCompactItemize}\n";
848   t << "{\n";
849   t << "  \\begin{itemize}\n";
850   t << "  \\setlength{\\itemsep}{-3pt}\n";
851   t << "  \\setlength{\\parsep}{0pt}\n";
852   t << "  \\setlength{\\topsep}{0pt}\n";
853   t << "  \\setlength{\\partopsep}{0pt}\n";
854   t << "}\n";
855   t << "{\\end{itemize}}\n";
856   t << "\\newcommand{\\PBS}[1]{\\let\\temp=\\\\#1\\let\\\\=\\temp}\n";
857   t << "\\newlength{\\tmplength}\n";
858   t << "\\newenvironment{TabularC}[1]\n";
859   t << "{\n";
860   t << "\\setlength{\\tmplength}\n";
861   t << "     {\\linewidth/(#1)-\\tabcolsep*2-\\arrayrulewidth*(#1+1)/(#1)}\n";
862   t << "      \\par\\begin{xtabular*}{\\linewidth}\n";
863   t << "             {*{#1}{|>{\\PBS\\raggedright\\hspace{0pt}}p{\\the\\tmplength}}|}\n";
864   t << "}\n";
865   t << "{\\end{xtabular*}\\par}\n";
866   t << "\\newcommand{\\entrylabel}[1]{\n";
867   t << "   {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{%\n";
868   t << "   \\usefont{OT1}{phv}{bc}{n}\\color{darkgray}#1}\\vspace{1.5\\baselineskip}}}}\n";
869   t << "\\newenvironment{Desc}\n";
870   t << "{\\begin{list}{}\n";
871   t << "  {\n";
872   t << "    \\settowidth{\\labelwidth}{40pt}\n";
873   t << "    \\setlength{\\leftmargin}{\\labelwidth}\n";
874   t << "    \\setlength{\\parsep}{0pt}\n";
875   t << "    \\setlength{\\itemsep}{-4pt}\n";
876   t << "    \\renewcommand{\\makelabel}{\\entrylabel}\n";
877   t << "  }\n";
878   t << "}\n";
879   t << "{\\end{list}}\n";
880
881   t << "\\newsavebox{\\xrefbox}\n";
882   t << "\\newlength{\\xreflength}\n";
883   t << "\\newcommand{\\xreflabel}[1]{%\n";
884   t << "  \\sbox{\\xrefbox}{#1}%\n";
885   t << "  \\setlength{\\xreflength}{\\wd\\xrefbox}%\n";
886   t << "  \\ifthenelse{\\xreflength>\\labelwidth}{%\n";
887   t << "    \\begin{minipage}{\\textwidth}%\n";
888   t << "      \\setlength{\\parindent}{0pt}%\n";
889   t << "      \\hangindent=15pt\\bfseries #1\\vspace{1.2\\itemsep}%\n";
890   t << "    \\end{minipage}%\n";
891   t << "  }{%\n";
892   t << "   \\parbox[b]{\\labelwidth}{\\makebox[0pt][l]{\\textbf{#1}}}%\n";
893   t << "  }}%\n";
894   t << "\\newenvironment{DoxyRefList}{%\n";
895   t << "  \\begin{list}{}{%\n";
896   t << "    \\setlength{\\labelwidth}{10pt}%\n";
897   t << "    \\setlength{\\leftmargin}{\\labelwidth}%\n";
898   t << "    \\addtolength{\\leftmargin}{\\labelsep}%\n";
899   t << "    \\renewcommand{\\makelabel}{\\xreflabel}%\n";
900   t << "    }%\n";
901   t << "  }%\n";
902   t << "{\\end{list}}\n";
903   t << "\\newenvironment{DoxyRefDesc}[1]\n";
904   t << "{\\begin{list}{}{%\n";
905   t << "  \\renewcommand\\makelabel[1]{\\textbf{##1}}\n";
906   t << "  \\settowidth\\labelwidth{\\makelabel{#1}}\n";
907   t << "  \\setlength\\leftmargin{\\labelwidth+\\labelsep}}}\n";
908   t << "{\\end{list}}\n";
909   t << "\\newenvironment{Indent}\n";
910   t << "  {\\begin{list}{}{\\setlength{\\leftmargin}{0.5cm}}\n";
911   t << "      \\item[]\\ignorespaces}\n";
912   t << "  {\\unskip\\end{list}}\n";
913
914   t << "\\setlength{\\parindent}{0cm}\n";
915   t << "\\setlength{\\parskip}{0.2cm}\n";
916   t << "\\addtocounter{secnumdepth}{2}\n";
917   // \sloppy should not be used, see bug 563698 
918   //t << "\\sloppy\n";
919   t << "\\usepackage[T1]{fontenc}\n";
920   t << "\\makeatletter\n";
921   t << "\\renewcommand{\\paragraph}{\\@startsection{paragraph}{4}{0ex}%\n";
922   t << "   {-1.0ex}%\n";
923   t << "   {1.0ex}%\n";
924   t << "   {\\usefont{OT1}{phv}{bc}{n}\\color{darkgray}}}\n";
925   t << "\\renewcommand{\\subparagraph}{\\@startsection{subparagraph}{5}{0ex}%\n";
926   t << "   {-1.0ex}%\n";
927   t << "   {1.0ex}%\n";
928   t << "   {\\usefont{OT1}{phv}{bc}{n}\\color{darkgray}}}\n";
929   t << "\\makeatother\n";
930   t << "\\allsectionsfont{\\usefont{OT1}{phv}{bc}{n}\\selectfont\\color{darkgray}}\n";
931   t << "\\stepcounter{secnumdepth}\n";
932   t << "\\stepcounter{tocdepth}\n";
933   t << "\\definecolor{comment}{rgb}{0.5,0.0,0.0}\n";
934   t << "\\definecolor{keyword}{rgb}{0.0,0.5,0.0}\n";
935   t << "\\definecolor{keywordtype}{rgb}{0.38,0.25,0.125}\n";
936   t << "\\definecolor{keywordflow}{rgb}{0.88,0.5,0.0}\n";
937   t << "\\definecolor{preprocessor}{rgb}{0.5,0.38,0.125}\n";
938   t << "\\definecolor{stringliteral}{rgb}{0.0,0.125,0.25}\n";
939   t << "\\definecolor{charliteral}{rgb}{0.0,0.5,0.5}\n";
940   t << "\\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0}\n";
941   t << "\\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43}\n";
942   t << "\\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0}\n";
943   t << "\\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0}\n";
944 }
945
946 static void writeDefaultFooter(FTextStream &t)
947 {
948   Doxygen::citeDict->writeLatexBibliography(t);
949   t << "\\addcontentsline{toc}{part}{" << theTranslator->trRTFGeneralIndex() << "}\n";
950   t << "\\printindex\n";
951   t << "\\end{document}\n";
952 }
953
954 void LatexGenerator::writeHeaderFile(QFile &f)
955 {
956   FTextStream t(&f);
957   writeDefaultHeaderPart1(t);
958   t << "Your title here";
959   writeDefaultHeaderPart2(t);
960   t << "Generated by";
961   writeDefaultHeaderPart3(t);
962 }
963
964 void LatexGenerator::writeFooterFile(QFile &f)
965 {
966   FTextStream t(&f);
967   writeDefaultFooter(t);
968 }
969
970 void LatexGenerator::writeStyleSheetFile(QFile &f)
971 {
972   FTextStream t(&f);
973
974   writeDefaultStyleSheetPart1(t);
975   QCString &projectName = Config_getString("PROJECT_NAME");
976
977   t << theTranslator->trGeneratedAt( dateToString(TRUE), projectName );
978   t << " doxygen";
979   //t << " " << theTranslator->trWrittenBy() << " ";
980   //t << "Dimitri van Heesch \\copyright~1997-2012";
981   writeDefaultStyleSheetPart2(t);
982   t << theTranslator->trGeneratedAt( dateToString(TRUE), projectName );
983   t << " doxygen";
984   //t << " << theTranslator->trWrittenBy() << " ";
985   //t << "Dimitri van Heesch \\copyright~1997-2012";
986   writeDefaultStyleSheetPart3(t);
987 }
988
989 void LatexGenerator::startFile(const char *name,const char *,const char *)
990 {
991 #if 0
992   setEncoding(Config_getString("LATEX_OUTPUT_ENCODING"));
993 #endif
994   QCString fileName=name;
995   relPath = relativePathToRoot(fileName);
996   sourceFileName = stripPath(fileName);
997   if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex";
998   startPlainFile(fileName);
999 }
1000
1001 void LatexGenerator::endFile()
1002 {
1003   endPlainFile();
1004   sourceFileName.resize(0);
1005 }
1006
1007 //void LatexGenerator::writeIndex()
1008 //{
1009 //  startFile("refman.tex");
1010 //} 
1011   
1012 void LatexGenerator::startProjectNumber()
1013 {
1014   t << "\\\\[1ex]\\large "; 
1015 }
1016
1017 void LatexGenerator::startIndexSection(IndexSections is)
1018 {
1019   bool &compactLatex = Config_getBool("COMPACT_LATEX");
1020   QCString &latexHeader = Config_getString("LATEX_HEADER");
1021   switch (is)
1022   {
1023     case isTitlePageStart:
1024       {
1025         if (latexHeader.isEmpty())
1026         {
1027           writeDefaultHeaderPart1(t);
1028         }
1029         else
1030         {
1031           QCString header = fileToString(latexHeader);
1032           t << substituteKeywords(header,0,
1033               Config_getString("PROJECT_NAME"),
1034               Config_getString("PROJECT_NUMBER"),
1035               Config_getString("PROJECT_BRIEF"));
1036         }
1037       }
1038       break;
1039     case isTitlePageAuthor:
1040       if (latexHeader.isEmpty())
1041       {
1042         writeDefaultHeaderPart2(t);
1043       }
1044       break;
1045     case isMainPage:
1046       if (compactLatex) t << "\\section"; else t << "\\chapter";
1047       t << "{"; //Introduction}\n"
1048       break;
1049     //case isPackageIndex:
1050     //  if (compactLatex) t << "\\section"; else t << "\\chapter";
1051     //  t << "{"; //Package Index}\n"
1052     //  break;
1053     case isModuleIndex:
1054       if (compactLatex) t << "\\section"; else t << "\\chapter";
1055       t << "{"; //Module Index}\n"
1056       break;
1057     case isDirIndex:
1058       if (compactLatex) t << "\\section"; else t << "\\chapter";
1059       t << "{"; //Directory Index}\n"
1060       break;
1061     case isNamespaceIndex:
1062       if (compactLatex) t << "\\section"; else t << "\\chapter";
1063       t << "{"; //Namespace Index}\"
1064       break;
1065     case isClassHierarchyIndex:
1066       if (compactLatex) t << "\\section"; else t << "\\chapter";
1067       t << "{"; //Hierarchical Index}\n"
1068       break;
1069     case isCompoundIndex:
1070       if (compactLatex) t << "\\section"; else t << "\\chapter";
1071       t << "{"; //Annotated Compound Index}\n"
1072       break;
1073     case isFileIndex:
1074       if (compactLatex) t << "\\section"; else t << "\\chapter";
1075       t << "{"; //Annotated File Index}\n"
1076       break;
1077     case isPageIndex:
1078       if (compactLatex) t << "\\section"; else t << "\\chapter";
1079       t << "{"; //Annotated Page Index}\n"
1080       break;
1081     case isModuleDocumentation:
1082       {
1083         GroupSDict::Iterator gli(*Doxygen::groupSDict);
1084         GroupDef *gd;
1085         bool found=FALSE;
1086         for (gli.toFirst();(gd=gli.current()) && !found;++gli)
1087         {
1088           if (!gd->isReference())
1089           {
1090             if (compactLatex) t << "\\section"; else t << "\\chapter";
1091             t << "{"; //Module Documentation}\n";
1092             found=TRUE;
1093           }
1094         }
1095       }
1096       break;
1097     case isDirDocumentation:
1098       {
1099         SDict<DirDef>::Iterator dli(*Doxygen::directories);
1100         DirDef *dd;
1101         bool found=FALSE;
1102         for (dli.toFirst();(dd=dli.current()) && !found;++dli)
1103         {
1104           if (dd->isLinkableInProject())
1105           {
1106             if (compactLatex) t << "\\section"; else t << "\\chapter";
1107             t << "{"; //Module Documentation}\n";
1108             found=TRUE;
1109           }
1110         }
1111       }
1112       break;
1113     case isNamespaceDocumentation:
1114       {
1115         NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1116         NamespaceDef *nd;
1117         bool found=FALSE;
1118         for (nli.toFirst();(nd=nli.current()) && !found;++nli)
1119         {
1120           if (nd->isLinkableInProject())
1121           {
1122             if (compactLatex) t << "\\section"; else t << "\\chapter";
1123             t << "{"; // Namespace Documentation}\n":
1124             found=TRUE;
1125           }
1126         } 
1127       }
1128       break;
1129     case isClassDocumentation:
1130       {
1131         ClassSDict::Iterator cli(*Doxygen::classSDict);
1132         ClassDef *cd=0;
1133         bool found=FALSE;
1134         for (cli.toFirst();(cd=cli.current()) && !found;++cli)
1135         {
1136           if (cd->isLinkableInProject() && 
1137               cd->templateMaster()==0 &&
1138               !cd->isEmbeddedInOuterScope()
1139              )
1140           {
1141             if (compactLatex) t << "\\section"; else t << "\\chapter";
1142             t << "{"; //Compound Documentation}\n";
1143             found=TRUE;
1144           }
1145         }
1146       }
1147       break;
1148     case isFileDocumentation:
1149       {
1150         bool isFirst=TRUE;
1151         FileName *fn=Doxygen::inputNameList->first();
1152         while (fn)
1153         {
1154           FileDef *fd=fn->first();
1155           while (fd)
1156           {
1157             if (fd->isLinkableInProject())
1158             {
1159               if (isFirst)
1160               {
1161                 if (compactLatex) t << "\\section"; else t << "\\chapter";
1162                 t << "{"; //File Documentation}\n";
1163                 isFirst=FALSE;
1164                 break;
1165               }
1166             }
1167             fd=fn->next();
1168           }
1169           fn=Doxygen::inputNameList->next();
1170         }
1171       }
1172       break;
1173     case isExampleDocumentation:
1174       {
1175         if (compactLatex) t << "\\section"; else t << "\\chapter";
1176         t << "{"; //Example Documentation}\n";
1177       }
1178       break;
1179     case isPageDocumentation:
1180       {
1181         if (compactLatex) t << "\\section"; else t << "\\chapter";
1182         t << "{"; //Page Documentation}\n";
1183       }
1184       break;
1185     case isPageDocumentation2:
1186       break;
1187     case isEndIndex:
1188       break;
1189   }
1190 }
1191
1192 void LatexGenerator::endIndexSection(IndexSections is)
1193 {
1194   //static bool compactLatex = Config_getBool("COMPACT_LATEX");
1195   static bool sourceBrowser = Config_getBool("SOURCE_BROWSER");
1196   static QCString latexHeader = Config_getString("LATEX_HEADER");
1197   static QCString latexFooter = Config_getString("LATEX_FOOTER");
1198   switch (is)
1199   {
1200     case isTitlePageStart:
1201       break;
1202     case isTitlePageAuthor:
1203       if (latexHeader.isEmpty())
1204       {
1205         writeDefaultHeaderPart3(t);
1206       }
1207       break;
1208     case isMainPage:
1209       {
1210         //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
1211         QCString indexName="index";
1212         t << "}\n\\label{index}";
1213         if (Config_getBool("PDF_HYPERLINKS")) t << "\\hypertarget{index}{}";
1214         t << "\\input{" << indexName << "}\n";
1215       }
1216       break;
1217     case isModuleIndex:
1218       t << "}\n\\input{modules}\n";
1219       break;
1220     case isDirIndex:
1221       t << "}\n\\input{dirs}\n";
1222       break;
1223     case isNamespaceIndex:
1224       t << "}\n\\input{namespaces}\n";
1225       break;
1226     case isClassHierarchyIndex:
1227       t << "}\n\\input{hierarchy}\n";
1228       break;
1229     case isCompoundIndex:
1230       t << "}\n\\input{annotated}\n";
1231       break;
1232     case isFileIndex:
1233       t << "}\n\\input{files}\n";
1234       break;
1235     case isPageIndex:
1236       t << "}\n\\input{pages}\n";
1237       break;
1238     case isModuleDocumentation:
1239       {
1240         GroupSDict::Iterator gli(*Doxygen::groupSDict);
1241         GroupDef *gd;
1242         bool found=FALSE;
1243         for (gli.toFirst();(gd=gli.current()) && !found;++gli)
1244         {
1245           if (!gd->isReference())
1246           {
1247             t << "}\n\\input{" << gd->getOutputFileBase() << "}\n";
1248             found=TRUE;
1249           }
1250         }
1251         for (;(gd=gli.current());++gli)
1252         {
1253           if (!gd->isReference())
1254           {
1255             //if (compactLatex) t << "\\input"; else t << "\\include";
1256             t << "\\include"; 
1257             t << "{" << gd->getOutputFileBase() << "}\n";
1258           }
1259         }
1260       }
1261       break;
1262     case isDirDocumentation:
1263       {
1264         SDict<DirDef>::Iterator dli(*Doxygen::directories);
1265         DirDef *dd;
1266         bool found=FALSE;
1267         for (dli.toFirst();(dd=dli.current()) && !found;++dli)
1268         {
1269           if (dd->isLinkableInProject())
1270           {
1271             t << "}\n\\input{" << dd->getOutputFileBase() << "}\n";
1272             found=TRUE;
1273           }
1274         }
1275         for (;(dd=dli.current());++dli)
1276         {
1277           if (dd->isLinkableInProject())
1278           {
1279             //if (compactLatex) t << "\\input"; else t << "\\include";
1280             t << "\\input"; 
1281             t << "{" << dd->getOutputFileBase() << "}\n";
1282           }
1283         }
1284       }
1285       break;
1286     case isNamespaceDocumentation:
1287       {
1288         NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1289         NamespaceDef *nd;
1290         bool found=FALSE;
1291         for (nli.toFirst();(nd=nli.current()) && !found;++nli)
1292         {
1293           if (nd->isLinkableInProject())
1294           {
1295             t << "}\n\\input{" << nd->getOutputFileBase() << "}\n";
1296             found=TRUE;
1297           }
1298         }
1299         while ((nd=nli.current()))
1300         {
1301           if (nd->isLinkableInProject())
1302           {
1303             //if (compactLatex) t << "\\input"; else t << "\\include";
1304             t << "\\input"; 
1305             t << "{" << nd->getOutputFileBase() << "}\n";
1306           }
1307           ++nli;
1308         }
1309       }
1310       break;
1311     case isClassDocumentation:
1312       {
1313         ClassSDict::Iterator cli(*Doxygen::classSDict);
1314         ClassDef *cd=0;
1315         bool found=FALSE;
1316         for (cli.toFirst();(cd=cli.current()) && !found;++cli)
1317         {
1318           if (cd->isLinkableInProject() && 
1319               cd->templateMaster()==0 &&
1320              !cd->isEmbeddedInOuterScope()
1321              )
1322           {
1323             t << "}\n\\input{" << cd->getOutputFileBase() << "}\n";
1324             found=TRUE;
1325           }
1326         }
1327         for (;(cd=cli.current());++cli)
1328         {
1329           if (cd->isLinkableInProject() && 
1330               cd->templateMaster()==0 &&
1331              !cd->isEmbeddedInOuterScope()
1332              )
1333           {
1334             //if (compactLatex) t << "\\input"; else t << "\\include";
1335             t << "\\input"; 
1336             t << "{" << cd->getOutputFileBase() << "}\n";
1337           } 
1338         }
1339       }
1340       break;
1341     case isFileDocumentation:
1342       {
1343         bool isFirst=TRUE;
1344         FileName *fn=Doxygen::inputNameList->first();
1345         while (fn)
1346         {
1347           FileDef *fd=fn->first();
1348           while (fd)
1349           {
1350             if (fd->isLinkableInProject())
1351             {
1352               if (isFirst)
1353               {
1354                 t << "}\n\\input{" << fd->getOutputFileBase() << "}\n";
1355                 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1356                 {
1357                   //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1358                   t << "\\input{" << fd->getSourceFileBase() << "}\n";
1359                 }
1360                 isFirst=FALSE;
1361               }
1362               else
1363               {
1364                 //if (compactLatex) t << "\\input" ; else t << "\\include";
1365                 t << "\\input" ; 
1366                 t << "{" << fd->getOutputFileBase() << "}\n";
1367                 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1368                 {
1369                   //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1370                   t << "\\input{" << fd->getSourceFileBase() << "}\n";
1371                 }
1372               }
1373             }
1374             fd=fn->next();
1375           }
1376           fn=Doxygen::inputNameList->next();
1377         }
1378       }
1379       break;
1380     case isExampleDocumentation:
1381       {
1382         t << "}\n";
1383         PageSDict::Iterator pdi(*Doxygen::exampleSDict);
1384         PageDef *pd=pdi.toFirst();
1385         if (pd)
1386         {
1387           t << "\\input{" << pd->getOutputFileBase() << "}\n";
1388         }
1389         for (++pdi;(pd=pdi.current());++pdi)
1390         {
1391           //if (compactLatex) t << "\\input" ; else t << "\\include";
1392           t << "\\input"; 
1393           t << "{" << pd->getOutputFileBase() << "}\n";
1394         }
1395       }
1396       break;
1397     case isPageDocumentation:
1398       {
1399         t << "}\n";
1400 #if 0
1401         PageSDict::Iterator pdi(*Doxygen::pageSDict);
1402         PageDef *pd=pdi.toFirst();
1403         bool first=TRUE;
1404         for (pdi.toFirst();(pd=pdi.current());++pdi)
1405         {
1406           if (!pd->getGroupDef() && !pd->isReference())
1407           {
1408              if (compactLatex) t << "\\section"; else t << "\\chapter";
1409              t << "{" << pd->title();
1410              t << "}\n";
1411             
1412             if (compactLatex || first) t << "\\input" ; else t << "\\include";
1413             t << "{" << pd->getOutputFileBase() << "}\n";
1414             first=FALSE;
1415           }
1416         }
1417 #endif
1418       }
1419       break;
1420     case isPageDocumentation2:
1421       break;
1422     case isEndIndex:
1423       if (latexFooter.isEmpty())
1424       {
1425         writeDefaultFooter(t);
1426       }
1427       else
1428       {
1429         QCString footer = fileToString(latexFooter);
1430         t << substituteKeywords(footer,0,
1431               Config_getString("PROJECT_NAME"),
1432               Config_getString("PROJECT_NUMBER"),
1433               Config_getString("PROJECT_BRIEF"));
1434       }
1435       break;
1436   }
1437 }
1438
1439 void LatexGenerator::writePageLink(const char *name, bool /*first*/)
1440 {
1441   //bool &compactLatex = Config_getBool("COMPACT_LATEX");
1442   // next is remove for bug615957
1443   //if (compactLatex || first) t << "\\input" ; else t << "\\include";
1444   t << "\\input" ; 
1445   t << "{" << name << "}\n";
1446 }
1447
1448
1449 void LatexGenerator::writeStyleInfo(int part)
1450 {
1451   switch(part)
1452   {
1453     case 0:
1454       {
1455         //QCString pname=Config_getString("PROJECT_NAME").stripWhiteSpace();
1456         startPlainFile("doxygen.sty");
1457         writeDefaultStyleSheetPart1(t);
1458       }
1459       break;
1460     case 1:
1461     case 3:
1462       t << " Doxygen ";
1463       break;
1464     case 2:
1465       {
1466         writeDefaultStyleSheetPart2(t);
1467       }
1468       break;
1469     case 4:
1470       {
1471         writeDefaultStyleSheetPart3(t);
1472         endPlainFile();
1473       }
1474       break;
1475   }
1476 }
1477
1478 void LatexGenerator::newParagraph()
1479 {
1480   t << endl << endl;
1481 }
1482
1483 void LatexGenerator::startParagraph()
1484 {
1485   t << endl << endl;
1486 }
1487
1488 void LatexGenerator::endParagraph()
1489 {
1490   t << endl << endl;
1491 }
1492
1493 void LatexGenerator::writeString(const char *text)
1494 {
1495   t << text;
1496 }
1497
1498 void LatexGenerator::startIndexItem(const char *ref,const char *fn)
1499 {
1500   t << "\\item ";
1501   if (!ref && fn)
1502   {
1503     t << "\\contentsline{section}{";
1504   }
1505 }
1506
1507 void LatexGenerator::endIndexItem(const char *ref,const char *fn)
1508 {
1509   if (!ref && fn)
1510   {
1511     t << "}{\\pageref{" << fn << "}}{}" << endl;
1512   }
1513 }
1514
1515 //void LatexGenerator::writeIndexFileItem(const char *,const char *text)
1516 //{
1517 //  t << "\\item\\contentsline{section}{";
1518 //  docify(text);
1519 //  t << "}{\\pageref{" << text << "}}" << endl;
1520 //}
1521
1522
1523 void LatexGenerator::startHtmlLink(const char *url)
1524 {
1525   if (Config_getBool("PDF_HYPERLINKS"))
1526   {
1527     t << "\\href{";
1528     t << url;
1529     t << "}";
1530   }
1531   t << "{\\tt ";
1532 }
1533
1534 void LatexGenerator::endHtmlLink()
1535 {
1536   t << "}";
1537 }
1538
1539 //void LatexGenerator::writeMailLink(const char *url)
1540 //{
1541 //  if (Config_getBool("PDF_HYPERLINKS"))
1542 //  {
1543 //    t << "\\href{mailto:";
1544 //    t << url;
1545 //    t << "}";
1546 //  }
1547 //  t << "{\\tt "; 
1548 //  docify(url);
1549 //  t << "}";
1550 //}
1551
1552 void LatexGenerator::writeStartAnnoItem(const char *,const char *,
1553                                         const char *path,const char *name)
1554 {
1555   t << "\\item\\contentsline{section}{\\bf ";
1556   if (path) docify(path);
1557   docify(name); 
1558   t << "} ";
1559 }
1560
1561 void LatexGenerator::writeEndAnnoItem(const char *name)
1562 {
1563   t << "}{\\pageref{" << name << "}}{}" << endl;
1564 }
1565
1566 void LatexGenerator::startIndexKey()
1567 {
1568   t << "\\item\\contentsline{section}{";
1569 }
1570
1571 void LatexGenerator::endIndexKey()
1572 {
1573 }
1574
1575 void LatexGenerator::startIndexValue(bool hasBrief)
1576 {
1577   t << " ";
1578   if (hasBrief) t << "\\\\*";
1579 }
1580
1581 void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/)
1582 {
1583   //if (hasBrief) t << ")";
1584   t << "}{\\pageref{" << name << "}}{}" << endl;
1585 }
1586
1587 //void LatexGenerator::writeClassLink(const char *,const char *,
1588 //                                    const char *,const char *name)
1589 //{
1590 //  t << "{\\bf ";
1591 //  docify(name);
1592 //  t << "}"; 
1593 //}
1594
1595 void LatexGenerator::startTextLink(const char *f,const char *anchor)
1596 {
1597   if (!disableLinks && Config_getBool("PDF_HYPERLINKS"))
1598   {
1599     t << "\\hyperlink{";
1600     if (f) t << stripPath(f);
1601     if (anchor) t << "_" << anchor; 
1602     t << "}{";
1603   }
1604   else
1605   {
1606     t << "{\\bf ";
1607   }
1608 }
1609
1610 void LatexGenerator::endTextLink()
1611 {
1612   t << "}";
1613 }
1614
1615 void LatexGenerator::writeObjectLink(const char *ref, const char *f,
1616                                      const char *anchor, const char *text)
1617 {
1618   if (!disableLinks && !ref && Config_getBool("PDF_HYPERLINKS"))
1619   {
1620     t << "\\hyperlink{";
1621     if (f) t << stripPath(f);
1622     if (f && anchor) t << "_"; 
1623     if (anchor) t << anchor; 
1624     t << "}{";
1625     docify(text);
1626     t << "}";
1627   }
1628   else
1629   {
1630     t << "{\\bf ";
1631     docify(text);
1632     t << "}";
1633   } 
1634 }
1635
1636 void LatexGenerator::startPageRef()
1637 {
1638   t << " \\doxyref{}{";
1639 }
1640
1641 void LatexGenerator::endPageRef(const char *clname, const char *anchor)
1642 {
1643   t << "}{";
1644   if (clname) t << clname; 
1645   if (anchor) t << "_" << anchor;
1646   t << "}";
1647 }
1648
1649 void LatexGenerator::writeCodeLink(const char *ref,const char *f,
1650                                    const char *anchor,const char *name,
1651                                    const char *)
1652 {
1653   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1654   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1655   int l = strlen(name);
1656   if (col+l>80)
1657   {
1658     t << "\n      ";
1659     col=0;
1660   }
1661   if (/*m_prettyCode &&*/ !disableLinks && !ref && usePDFLatex && pdfHyperlinks)
1662   {
1663     t << "\\hyperlink{";
1664     if (f) t << stripPath(f);
1665     if (f && anchor) t << "_"; 
1666     if (anchor) t << anchor; 
1667     t << "}{";
1668     codify(name);
1669     t << "}";
1670   }
1671   else
1672   {
1673     t << name;
1674   }
1675   col+=l;
1676 }
1677
1678 void LatexGenerator::startTitleHead(const char *fileName)
1679 {
1680   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1681   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1682   if (usePDFLatex && pdfHyperlinks && fileName)
1683   {
1684     t << "\\hypertarget{" << stripPath(fileName) << "}{";
1685   }
1686   if (Config_getBool("COMPACT_LATEX")) 
1687   {
1688     t << "\\subsection{"; 
1689   }
1690   else 
1691   {
1692     t << "\\section{"; 
1693   }
1694 }
1695
1696 void LatexGenerator::endTitleHead(const char *fileName,const char *name)
1697 {
1698   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1699   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1700   t << "}" << endl;
1701   if (name)
1702   {
1703     t << "\\label{" << fileName << "}\\index{";
1704     escapeLabelName(name);
1705     t << "@{";
1706     escapeMakeIndexChars(name);
1707     t << "}}" << endl;
1708   }
1709   if (usePDFLatex && pdfHyperlinks && fileName)
1710   {
1711     t << "}" << endl;
1712   }
1713 }
1714
1715 void LatexGenerator::startTitle()
1716 {
1717   if (Config_getBool("COMPACT_LATEX")) 
1718   {
1719     t << "\\subsection{"; 
1720   }
1721   else 
1722   {
1723     t << "\\section{"; 
1724   }
1725 }
1726
1727 void LatexGenerator::startGroupHeader(int extraIndentLevel)
1728 {
1729   if (Config_getBool("COMPACT_LATEX")) 
1730   {
1731     extraIndentLevel++;
1732   }
1733
1734   if (extraIndentLevel==3)
1735   {
1736     t << "\\subparagraph*{"; 
1737   }
1738   else if (extraIndentLevel==2)
1739   {
1740     t << "\\paragraph{";
1741   }
1742   else if (extraIndentLevel==1)
1743   {
1744     t << "\\subsubsection{";
1745   }
1746   else // extraIndentLevel==0
1747   {
1748     t << "\\subsection{";
1749   }
1750   disableLinks=TRUE;
1751 }
1752
1753 void LatexGenerator::endGroupHeader(int)
1754 {
1755   disableLinks=FALSE;
1756   t << "}" << endl;
1757 }
1758
1759 void LatexGenerator::startMemberHeader(const char *)
1760 {
1761   if (Config_getBool("COMPACT_LATEX")) 
1762   {
1763     t << "\\subsubsection*{"; 
1764   }
1765   else 
1766   {
1767     t << "\\subsection*{";
1768   }
1769   disableLinks=TRUE;
1770 }
1771
1772 void LatexGenerator::endMemberHeader()
1773 {
1774   disableLinks=FALSE;
1775   t << "}" << endl;
1776 }
1777
1778 void LatexGenerator::startMemberDoc(const char *clname,
1779                                     const char *memname,
1780                                     const char *,
1781                                     const char *title,
1782                                     bool showInline)
1783
1784   if (memname && memname[0]!='@')
1785   {
1786     t << "\\index{";
1787     if (clname)
1788     {
1789       escapeLabelName(clname);
1790       t << "@{";
1791       escapeMakeIndexChars(clname);
1792       t << "}!";
1793     }
1794     escapeLabelName(memname);
1795     t << "@{";
1796     escapeMakeIndexChars(memname);
1797     t << "}}" << endl;
1798
1799     t << "\\index{";
1800     escapeLabelName(memname);
1801     t << "@{";
1802     escapeMakeIndexChars(memname);
1803     t << "}";
1804     if (clname)
1805     {
1806       t << "!" << clname << "@{";
1807       docify(clname);
1808       t << "}"; 
1809     }
1810     t << "}" << endl;
1811   }
1812   static const char *levelLab[] = { "subsubsection","paragraph","subparagraph", "subparagraph" };
1813   static bool compactLatex = Config_getBool("COMPACT_LATEX");
1814   int level=0;
1815   if (showInline) level+=2;
1816   if (compactLatex) level++;
1817   t << "\\" << levelLab[level]; 
1818
1819   //if (Config_getBool("PDF_HYPERLINKS") && memname) 
1820   //{
1821   //  t << "["; 
1822   //  escapeMakeIndexChars(this,t,memname);
1823   //  t << "]";
1824   //}
1825   t << "[{";
1826   escapeMakeIndexChars(title);
1827   t << "}]";
1828   t << "{\\setlength{\\rightskip}{0pt plus 5cm}";
1829   disableLinks=TRUE;
1830 }
1831
1832 void LatexGenerator::endMemberDoc(bool) 
1833
1834   disableLinks=FALSE;
1835   t << "}";
1836   //if (Config_getBool("COMPACT_LATEX")) t << "\\hfill";
1837 }
1838
1839 void LatexGenerator::startDoxyAnchor(const char *fName,const char *,
1840                                      const char *anchor, const char *,
1841                                      const char *)
1842 {
1843   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1844   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1845   if (usePDFLatex && pdfHyperlinks)
1846   {
1847     t << "\\hypertarget{";
1848     if (fName) t << stripPath(fName);
1849     if (anchor) t << "_" << anchor;
1850     t << "}{";
1851   }
1852 }
1853
1854 void LatexGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1855 {
1856   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1857   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1858   if (usePDFLatex && pdfHyperlinks)
1859   {
1860     t << "}";
1861   }
1862   t << "\\label{";
1863   if (fName) t << fName;
1864   if (anchor) t << "_" << anchor;
1865   t << "}" << endl;
1866 }
1867
1868 void LatexGenerator::writeAnchor(const char *fName,const char *name)
1869
1870   //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1871   t << "\\label{" << name << "}" << endl; 
1872   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1873   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1874   if (usePDFLatex && pdfHyperlinks)
1875   {
1876     if (fName)
1877     {
1878       t << "\\hypertarget{" << stripPath(fName) << "_" << name << "}{}" << endl;
1879     }
1880     else
1881     {
1882       t << "\\hypertarget{" << name << "}{}" << endl;
1883     }
1884   }
1885 }
1886
1887
1888 //void LatexGenerator::writeLatexLabel(const char *clName,const char *anchor)
1889 //{
1890 //  writeDoxyAnchor(0,clName,anchor,0);
1891 //}
1892
1893 void LatexGenerator::addIndexItem(const char *s1,const char *s2)
1894 {
1895   if (s1)
1896   {
1897     t << "\\index{";
1898     escapeLabelName(s1);
1899     t << "@{";
1900     escapeMakeIndexChars(s1);
1901     t << "}";
1902     if (s2)
1903     {
1904       t << "!";
1905       escapeLabelName(s2);
1906       t << "@{";
1907       escapeMakeIndexChars(s2);
1908       t << "}";
1909     }
1910     t << "}";
1911   }
1912 }
1913
1914
1915 void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
1916 {
1917   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1918   static bool usePDFLatex   = Config_getBool("USE_PDFLATEX");
1919   if (usePDFLatex && pdfHyperlinks)
1920   {
1921     t << "\\hypertarget{" << stripPath(lab) << "}{}";
1922   }
1923   t << "\\";
1924   if (Config_getBool("COMPACT_LATEX"))
1925   {
1926     switch(type)
1927     {
1928       case SectionInfo::Page:          t << "subsection"; break;
1929       case SectionInfo::Section:       t << "subsubsection"; break;
1930       case SectionInfo::Subsection:    t << "paragraph"; break;
1931       case SectionInfo::Subsubsection: t << "subparagraph"; break;
1932       case SectionInfo::Paragraph:     t << "subparagraph"; break;
1933       default: ASSERT(0); break;
1934     }
1935     t << "{";
1936   }
1937   else
1938   {
1939     switch(type)
1940     {
1941       case SectionInfo::Page:          t << "section"; break;
1942       case SectionInfo::Section:       t << "subsection"; break;
1943       case SectionInfo::Subsection:    t << "subsubsection"; break;
1944       case SectionInfo::Subsubsection: t << "paragraph"; break;
1945       case SectionInfo::Paragraph:     t << "subparagraph"; break;
1946       default: ASSERT(0); break;
1947     }
1948     t << "{";
1949   }
1950 }
1951
1952 void LatexGenerator::endSection(const char *lab,SectionInfo::SectionType)
1953 {
1954   t << "}\\label{" << lab << "}" << endl;
1955 }
1956
1957
1958 void LatexGenerator::docify(const char *str)
1959 {
1960   filterLatexString(t,str,insideTabbing,FALSE,FALSE);
1961 }
1962
1963 void LatexGenerator::codify(const char *str)
1964 {
1965   if (str)
1966   { 
1967     const char *p=str;
1968     char c;
1969     //char cs[5];
1970     int spacesToNextTabStop;
1971     static int tabSize = Config_getInt("TAB_SIZE");
1972     const int maxLineLen = 80;
1973     QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars
1974     int i;
1975     while ((c=*p))
1976     {
1977       switch(c)
1978       {
1979         case 0x0c: p++;  // remove ^L
1980                    break;
1981         case '\t': spacesToNextTabStop =
1982                          tabSize - (col%tabSize);
1983                    t << Doxygen::spaces.left(spacesToNextTabStop); 
1984                    col+=spacesToNextTabStop;
1985                    p++;
1986                    break; 
1987         case '\n': t << '\n'; col=0; p++;
1988                    break;
1989         default:   
1990                    i=0;
1991
1992 #undef  COPYCHAR
1993 // helper macro to copy a single utf8 character, dealing with multibyte chars.
1994 #define COPYCHAR() do {                                           \
1995                      result[i++]=c; p++;                          \
1996                      if (c<0) /* multibyte utf-8 character */     \
1997                      {                                            \
1998                        /* 1xxx.xxxx: >=2 byte character */        \
1999                        result[i++]=*p++;                          \
2000                        if (((uchar)c&0xE0)==0xE0)                 \
2001                        {                                          \
2002                          /* 111x.xxxx: >=3 byte character */      \
2003                          result[i++]=*p++;                        \
2004                        }                                          \
2005                        if (((uchar)c&0xF0)==0xF0)                 \
2006                        {                                          \
2007                          /* 1111.xxxx: 4 byte character */        \
2008                          result[i++]=*p++;                        \
2009                        }                                          \
2010                      }                                            \
2011                      col++;                                       \
2012                    } while(0)
2013
2014                    // gather characters until we find whitespace or are at
2015                    // the end of a line
2016                    COPYCHAR();
2017                    if (col>=maxLineLen) // force line break
2018                    {
2019                      t << "\n      ";
2020                      col=0;
2021                    }
2022                    else // copy more characters
2023                    {
2024                      while (col<maxLineLen && (c=*p) && 
2025                             c!=0x0c && c!='\t' && c!='\n' && c!=' '
2026                            )
2027                      {
2028                        COPYCHAR();
2029                      }
2030                      if (col>=maxLineLen) // force line break
2031                      {
2032                        t << "\n      ";
2033                        col=0;
2034                      }
2035                    }
2036                    result[i]=0; // add terminator
2037                    //if (m_prettyCode)
2038                    //{
2039                      filterLatexString(t,result,insideTabbing,TRUE);
2040                    //}
2041                    //else
2042                    //{
2043                    //  t << result;
2044                    //}
2045                    break;
2046       }
2047     }
2048   }
2049 }
2050
2051 void LatexGenerator::writeChar(char c)
2052 {
2053   char cs[2];
2054   cs[0]=c;
2055   cs[1]=0;
2056   docify(cs);
2057 }
2058
2059 void LatexGenerator::startClassDiagram()
2060 {
2061   //if (Config_getBool("COMPACT_LATEX")) t << "\\subsubsection"; else t << "\\subsection";
2062   //t << "{";
2063 }
2064
2065 void LatexGenerator::endClassDiagram(const ClassDiagram &d,
2066                                        const char *fileName,const char *)
2067 {
2068   d.writeFigure(t,dir,fileName);
2069 }
2070
2071
2072 void LatexGenerator::startAnonTypeScope(int indent)
2073 {
2074   if (indent==0)
2075   {
2076     t << "\\begin{tabbing}" << endl;
2077     t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill" << endl;
2078     insideTabbing=TRUE;
2079   }
2080   m_indent=indent;
2081 }
2082
2083 void LatexGenerator::endAnonTypeScope(int indent)
2084 {
2085   if (indent==0)
2086   {
2087     t << endl << "\\end{tabbing}";
2088     insideTabbing=FALSE;
2089   }
2090   m_indent=indent;
2091 }
2092
2093 void LatexGenerator::startMemberTemplateParams()
2094 {
2095   if (templateMemberItem)
2096   {
2097     t << "{\\footnotesize ";
2098   }
2099 }
2100
2101 void LatexGenerator::endMemberTemplateParams(const char *,const char *)
2102 {
2103   if (templateMemberItem)
2104   {
2105     t << "}\\\\";
2106   }
2107 }
2108
2109 void LatexGenerator::startMemberItem(const char *,int annoType,const char *) 
2110
2111   //printf("LatexGenerator::startMemberItem(%d)\n",annType);
2112   if (!insideTabbing)
2113   {
2114     t << "\\item " << endl; 
2115     templateMemberItem = (annoType == 3);
2116   }
2117 }
2118
2119 void LatexGenerator::endMemberItem() 
2120 {
2121   if (insideTabbing)
2122   {
2123     t << "\\\\";
2124   } 
2125   templateMemberItem = FALSE;
2126   t << endl; 
2127 }
2128
2129 void LatexGenerator::startMemberDescription(const char *,const char *) 
2130 {
2131   if (!insideTabbing)
2132   { 
2133     t << "\\begin{DoxyCompactList}\\small\\item\\em "; 
2134   }
2135   else
2136   {
2137     for (int i=0;i<m_indent+2;i++) t << "\\>";
2138     t << "{\\em ";
2139   }
2140 }
2141
2142 void LatexGenerator::endMemberDescription() 
2143
2144   if (!insideTabbing)
2145   {
2146     //t << "\\item\\end{DoxyCompactList}"; 
2147     t << "\\end{DoxyCompactList}"; 
2148   }
2149   else
2150   {
2151     t << "}\\\\\n";
2152   }
2153 }
2154
2155
2156 void LatexGenerator::writeNonBreakableSpace(int) 
2157 {
2158   //printf("writeNonBreakbleSpace()\n");
2159   if (insideTabbing)
2160   {
2161     t << "\\>";
2162   }
2163   else
2164   {
2165     t << "~"; 
2166   }
2167 }
2168
2169 void LatexGenerator::startMemberList()  
2170
2171   if (!insideTabbing)
2172   {
2173     t << "\\begin{DoxyCompactItemize}" << endl; 
2174   }
2175 }
2176
2177 void LatexGenerator::endMemberList()    
2178 {
2179   //printf("LatexGenerator::endMemberList(%d)\n",insideTabbing);
2180   if (!insideTabbing)
2181   {
2182     t << "\\end{DoxyCompactItemize}"   << endl; 
2183   }
2184 }
2185
2186
2187 void LatexGenerator::startMemberGroupHeader(bool hasHeader)
2188 {
2189   if (hasHeader) t << "\\begin{Indent}";
2190   t << "{\\bf ";
2191   // changed back to rev 756 due to bug 660501
2192   //if (Config_getBool("COMPACT_LATEX")) 
2193   //{
2194   //  t << "\\subparagraph*{";
2195   //}
2196   //else
2197   //{
2198   //  t << "\\paragraph*{";
2199   //}
2200 }
2201
2202 void LatexGenerator::endMemberGroupHeader()
2203 {
2204   // changed back to rev 756 due to bug 660501
2205   t << "}\\par" << endl;
2206   //t << "}" << endl;
2207 }
2208
2209 void LatexGenerator::startMemberGroupDocs()
2210 {
2211   t << "{\\em ";
2212 }
2213
2214 void LatexGenerator::endMemberGroupDocs()
2215 {
2216   t << "}";
2217 }
2218
2219 void LatexGenerator::startMemberGroup()
2220 {
2221 }
2222
2223 void LatexGenerator::endMemberGroup(bool hasHeader)
2224 {
2225   if (hasHeader)t << "\\end{Indent}"; 
2226   t << endl;
2227 }
2228
2229 void LatexGenerator::startDotGraph() 
2230 {
2231   newParagraph();
2232 }
2233
2234 void LatexGenerator::endDotGraph(const DotClassGraph &g) 
2235 {
2236   g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),fileName,relPath);
2237 }
2238
2239 void LatexGenerator::startInclDepGraph() 
2240 {
2241 }
2242
2243 void LatexGenerator::endInclDepGraph(const DotInclDepGraph &g) 
2244 {
2245   g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),fileName,relPath);
2246 }
2247
2248 void LatexGenerator::startGroupCollaboration() 
2249 {
2250 }
2251
2252 void LatexGenerator::endGroupCollaboration(const DotGroupCollaboration &g) 
2253 {
2254   g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),fileName,relPath);
2255 }
2256
2257 void LatexGenerator::startCallGraph() 
2258 {
2259 }
2260
2261 void LatexGenerator::endCallGraph(const DotCallGraph &g) 
2262 {
2263   g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),fileName,relPath);
2264 }
2265
2266 void LatexGenerator::startDirDepGraph() 
2267 {
2268 }
2269
2270 void LatexGenerator::endDirDepGraph(const DotDirDeps &g) 
2271 {
2272   g.writeGraph(t,EPS,Config_getString("LATEX_OUTPUT"),fileName,relPath);
2273 }
2274
2275 void LatexGenerator::startDescription() 
2276
2277   t << "\\begin{description}" << endl; 
2278 }
2279
2280 void LatexGenerator::endDescription()   
2281
2282   t << "\\end{description}" << endl; 
2283   firstDescItem=TRUE;
2284 }
2285
2286 void LatexGenerator::startDescItem()    
2287
2288   firstDescItem=TRUE;
2289   t << "\\item["; 
2290 }
2291
2292 void LatexGenerator::endDescItem()      
2293
2294   if (firstDescItem) 
2295   {
2296     t << "]" << endl;
2297     firstDescItem=FALSE;
2298   } 
2299   else
2300   {
2301     lineBreak();
2302   }
2303 }
2304
2305 void LatexGenerator::startSimpleSect(SectionTypes,const char *file,
2306                                      const char *anchor,const char *title)
2307 {
2308   t << "\\begin{Desc}\n\\item[";
2309   if (file)
2310   {
2311     writeObjectLink(0,file,anchor,title);
2312   }
2313   else
2314   {
2315     docify(title);
2316   }
2317   t << "]";
2318 }
2319
2320 void LatexGenerator::endSimpleSect()
2321 {
2322   t << "\\end{Desc}" << endl;
2323 }
2324
2325 void LatexGenerator::startParamList(ParamListTypes,const char *title)
2326 {
2327   t << "\\begin{Desc}\n\\item[";
2328   docify(title);
2329   t << "]";
2330 }
2331
2332 void LatexGenerator::endParamList()
2333 {
2334   t << "\\end{Desc}" << endl;
2335 }
2336
2337 void LatexGenerator::startParameterList(bool openBracket)
2338 {
2339   /* start of ParameterType ParameterName list */
2340   if (openBracket) t << "(";
2341   t << endl << "\\begin{DoxyParamCaption}" << endl;
2342 }
2343
2344 void LatexGenerator::endParameterList()
2345 {
2346 }
2347
2348 void LatexGenerator::startParameterType(bool first,const char *key)
2349 {
2350   t << "\\item[{";
2351   if (!first && key) t << key;
2352 }
2353
2354 void LatexGenerator::endParameterType()
2355 {
2356   t << "}]";
2357 }
2358
2359 void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2360 {
2361   t << "{";
2362 }
2363
2364 void LatexGenerator::endParameterName(bool last,bool /* emptyList */,bool closeBracket)
2365 {
2366   t << "}" << endl;
2367
2368   if (last)
2369   {
2370     t << "\\end{DoxyParamCaption}" << endl;
2371     if (closeBracket) t << ")";
2372   }
2373 }
2374
2375
2376 void LatexGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2377 {
2378   LatexDocVisitor *visitor = 
2379     new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),insideTabbing);
2380   n->accept(visitor);
2381   delete visitor; 
2382 }
2383
2384 void LatexGenerator::startConstraintList(const char *header)
2385 {
2386   t << "\\begin{Desc}\n\\item[";
2387   docify(header);
2388   t << "]";
2389   t << "\\begin{description}" << endl;
2390 }
2391
2392 void LatexGenerator::startConstraintParam()
2393 {
2394   t << "\\item[{\\em ";
2395 }
2396
2397 void LatexGenerator::endConstraintParam()
2398 {
2399 }
2400
2401 void LatexGenerator::startConstraintType()
2402 {
2403   t << "} : {\\em ";
2404 }
2405
2406 void LatexGenerator::endConstraintType()
2407 {
2408   t << "}]";
2409 }
2410
2411 void LatexGenerator::startConstraintDocs()
2412 {
2413 }
2414
2415 void LatexGenerator::endConstraintDocs()
2416 {
2417 }
2418
2419 void LatexGenerator::endConstraintList()
2420 {
2421   t << "\\end{description}" << endl;
2422   t << "\\end{Desc}" << endl;
2423 }
2424
2425 void LatexGenerator::escapeLabelName(const char *s)
2426 {
2427   if (s==0) return;
2428   const char *p=s;
2429   char c;
2430   QCString result(strlen(s)+1); // worst case allocation
2431   int i;
2432   while ((c=*p++))
2433   {
2434     switch (c)
2435     {
2436       case '%': t << "\\%";       break;
2437       // NOTE: adding a case here, means adding it to while below as well!
2438       default:  
2439         i=0;
2440         // collect as long string as possible, before handing it to docify
2441         result[i++]=c;
2442         while ((c=*p) && c!='%')
2443         {
2444           result[i++]=c;
2445           p++;
2446         }
2447         result[i]=0;
2448         docify(result); 
2449         break;
2450     }
2451   }
2452 }
2453
2454 void LatexGenerator::escapeMakeIndexChars(const char *s)
2455 {
2456   if (s==0) return;
2457   const char *p=s;
2458   char c;
2459   QCString result(strlen(s)+1); // worst case allocation
2460   int i;
2461   while ((c=*p++))
2462   {
2463     switch (c)
2464     {
2465       case '"': t << "\"\""; break;
2466       case '@': t << "\"@"; break;
2467       case '[': t << "["; break;
2468       case ']': t << "]"; break;
2469       // NOTE: adding a case here, means adding it to while below as well!
2470       default:  
2471         i=0;
2472         // collect as long string as possible, before handing it to docify
2473         result[i++]=c;
2474         while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']')
2475         {
2476           result[i++]=c;
2477           p++;
2478         }
2479         result[i]=0;
2480         docify(result); 
2481         break;
2482     }
2483   }
2484 }
2485
2486 void LatexGenerator::startCodeFragment()
2487 {
2488   t << "\n\\begin{DoxyCode}\n";
2489 }
2490
2491 void LatexGenerator::endCodeFragment()
2492 {
2493   t << "\\end{DoxyCode}\n";
2494 }
2495
2496 void LatexGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l)
2497 {
2498   if (m_prettyCode)
2499   {
2500     QCString lineNumber;
2501     lineNumber.sprintf("%05d",l);
2502
2503     if (fileName && !sourceFileName.isEmpty())
2504     {
2505       QCString lineAnchor;
2506       lineAnchor.sprintf("_l%05d",l);
2507       lineAnchor.prepend(sourceFileName);
2508       startCodeAnchor(lineAnchor);
2509       writeCodeLink(ref,fileName,anchor,lineNumber,0);
2510       endCodeAnchor();
2511     }
2512     else
2513     { 
2514       codify(lineNumber);
2515     }
2516     t << " ";
2517   }
2518   else
2519   {
2520     t << l << " ";
2521   }
2522 }
2523
2524 void LatexGenerator::startCodeLine(bool)
2525 {
2526   col=0;
2527 }
2528
2529 void LatexGenerator::endCodeLine()
2530 {
2531   codify("\n");
2532 }
2533
2534 void LatexGenerator::startFontClass(const char *name)
2535 {
2536   //if (!m_prettyCode) return;
2537   t << "\\textcolor{" << name << "}{";
2538 }
2539
2540 void LatexGenerator::endFontClass()
2541 {
2542   //if (!m_prettyCode) return;
2543   t << "}";
2544 }
2545
2546 void LatexGenerator::startCodeAnchor(const char *name) 
2547 {
2548   static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
2549   static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
2550   //if (!m_prettyCode) return;
2551   if (usePDFLatex && pdfHyperlinks)
2552   {
2553     t << "\\hypertarget{" << stripPath(name) << "}{}";
2554   }
2555 }
2556
2557 void LatexGenerator::endCodeAnchor() 
2558 {
2559 }
2560
2561 void LatexGenerator::startInlineHeader()
2562 {
2563   if (Config_getBool("COMPACT_LATEX")) 
2564   {
2565     t << "\\paragraph*{"; 
2566   }
2567   else 
2568   {
2569     t << "\\subsubsection*{";
2570   }
2571 }
2572
2573 void LatexGenerator::endInlineHeader()
2574 {
2575   t << "}" << endl;
2576 }
2577
2578 void LatexGenerator::lineBreak(const char *)
2579 {
2580   if (insideTabbing)
2581   {
2582     t << "\\\\\n";
2583   }
2584   else
2585   {
2586     t << "\\\\*\n";
2587   }
2588 }
2589
2590 void LatexGenerator::startMemberDocSimple()
2591 {
2592   t << "\\begin{DoxyFields}{";
2593   docify(theTranslator->trCompoundMembers());
2594   t << "}" << endl;
2595 }
2596
2597 void LatexGenerator::endMemberDocSimple()
2598 {
2599   t << "\\end{DoxyFields}" << endl;
2600 }
2601
2602 void LatexGenerator::startInlineMemberType()
2603 {
2604 }
2605
2606 void LatexGenerator::endInlineMemberType()
2607 {
2608   t << "&" << endl;
2609 }
2610
2611 void LatexGenerator::startInlineMemberName()
2612 {
2613 }
2614
2615 void LatexGenerator::endInlineMemberName()
2616 {
2617   t << "&" << endl;
2618 }
2619
2620 void LatexGenerator::startInlineMemberDoc()
2621 {
2622 }
2623
2624 void LatexGenerator::endInlineMemberDoc()
2625 {
2626   t << "\\\\\n\\hline\n" << endl;
2627 }
2628
2629 void LatexGenerator::startLabels()
2630 {
2631   t << "\\hspace{0.3cm}";
2632 }
2633
2634 void LatexGenerator::writeLabel(const char *l,bool isLast)
2635 {
2636   t << "{\\ttfamily [" << l << "]}";
2637   if (!isLast) t << ", ";
2638 }
2639
2640 void LatexGenerator::endLabels()
2641 {
2642 }
2643