My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
latexgen.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  * Copyright (C) 1997-2015 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 <qdir.h>
21 #include "latexgen.h"
22 #include "config.h"
23 #include "message.h"
24 #include "doxygen.h"
25 #include "util.h"
26 #include "diagram.h"
27 #include "language.h"
28 #include "version.h"
29 #include "dot.h"
30 #include "pagedef.h"
31 #include "docparser.h"
32 #include "latexdocvisitor.h"
33 #include "dirdef.h"
34 #include "cite.h"
35 #include "groupdef.h"
36 #include "classlist.h"
37 #include "namespacedef.h"
38 #include "filename.h"
39 #include "resourcemgr.h"
40 
41 //-------------------------------
42 
43 LatexCodeGenerator::LatexCodeGenerator(FTextStream &t,const QCString &relPath,const QCString &sourceFileName)
44  : m_relPath(relPath), m_sourceFileName(sourceFileName), m_col(0)
45 {
46  m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
47  setTextStream(t);
48 }
49 
50 LatexCodeGenerator::LatexCodeGenerator() : m_streamSet(FALSE), m_col(0)
51 {
52  m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
53 }
54 
56 {
57  m_streamSet = t.device()!=0;
58  m_t.setDevice(t.device());
59 }
60 
61 void LatexCodeGenerator::setRelativePath(const QCString &path)
62 {
63  m_relPath = path;
64 }
65 
66 void LatexCodeGenerator::setSourceFileName(const QCString &name)
67 {
68  m_sourceFileName = name;
69 }
70 
71 void LatexCodeGenerator::codify(const char *str)
72 {
73  if (str)
74  {
75  const char *p=str;
76  char c;
77  //char cs[5];
78  int spacesToNextTabStop;
79  static int tabSize = Config_getInt(TAB_SIZE);
80  const int maxLineLen = 108;
81  QCString result(4*maxLineLen+1); // worst case for 1 line of 4-byte chars
82  int i;
83  while ((c=*p))
84  {
85  switch(c)
86  {
87  case 0x0c: p++; // remove ^L
88  break;
89  case '\t': spacesToNextTabStop =
90  tabSize - (m_col%tabSize);
91  m_t << Doxygen::spaces.left(spacesToNextTabStop);
92  m_col+=spacesToNextTabStop;
93  p++;
94  break;
95  case '\n': m_t << '\n'; m_col=0; p++;
96  break;
97  default:
98  i=0;
99 
100 #undef COPYCHAR
101 // helper macro to copy a single utf8 character, dealing with multibyte chars.
102 #define COPYCHAR() do { \
103  result[i++]=c; p++; \
104  if (c<0) /* multibyte utf-8 character */ \
105  { \
106  /* 1xxx.xxxx: >=2 byte character */ \
107  result[i++]=*p++; \
108  if (((uchar)c&0xE0)==0xE0) \
109  { \
110  /* 111x.xxxx: >=3 byte character */ \
111  result[i++]=*p++; \
112  } \
113  if (((uchar)c&0xF0)==0xF0) \
114  { \
115  /* 1111.xxxx: 4 byte character */ \
116  result[i++]=*p++; \
117  } \
118  } \
119  m_col++; \
120  } while(0)
121 
122  // gather characters until we find whitespace or are at
123  // the end of a line
124  COPYCHAR();
125  if (m_col>=maxLineLen) // force line break
126  {
127  m_t << "\n ";
128  m_col=0;
129  }
130  else // copy more characters
131  {
132  while (m_col<maxLineLen && (c=*p) &&
133  c!=0x0c && c!='\t' && c!='\n' && c!=' '
134  )
135  {
136  COPYCHAR();
137  }
138  if (m_col>=maxLineLen) // force line break
139  {
140  m_t << "\n ";
141  m_col=0;
142  }
143  }
144  result[i]=0; // add terminator
145  //if (m_prettyCode)
146  //{
147  filterLatexString(m_t,result,FALSE,TRUE);
148  //}
149  //else
150  //{
151  // t << result;
152  //}
153  break;
154  }
155  }
156  }
157 }
158 
159 
160 void LatexCodeGenerator::writeCodeLink(const char *ref,const char *f,
161  const char *anchor,const char *name,
162  const char *)
163 {
164  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
165  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
166  int l = qstrlen(name);
167  if (m_col+l>80)
168  {
169  m_t << "\n ";
170  m_col=0;
171  }
172  if (!ref && usePDFLatex && pdfHyperlinks)
173  {
174  m_t << "\\hyperlink{";
175  if (f) m_t << stripPath(f);
176  if (f && anchor) m_t << "_";
177  if (anchor) m_t << anchor;
178  m_t << "}{";
179  codify(name);
180  m_t << "}";
181  }
182  else
183  {
184  m_t << name;
185  }
186  m_col+=l;
187 }
188 
189 void LatexCodeGenerator::writeLineNumber(const char *ref,const char *fileName,const char *anchor,int l)
190 {
191  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
192  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
193  if (m_prettyCode)
194  {
195  QCString lineNumber;
196  lineNumber.sprintf("%05d",l);
197 
198  if (fileName && !m_sourceFileName.isEmpty())
199  {
200  QCString lineAnchor;
201  lineAnchor.sprintf("_l%05d",l);
202  lineAnchor.prepend(stripExtensionGeneral(m_sourceFileName, ".tex"));
203  //if (!m_prettyCode) return;
204  if (usePDFLatex && pdfHyperlinks)
205  {
206  m_t << "\\hypertarget{" << stripPath(lineAnchor) << "}{}";
207  }
208  writeCodeLink(ref,fileName,anchor,lineNumber,0);
209  }
210  else
211  {
212  codify(lineNumber);
213  }
214  m_t << " ";
215  }
216  else
217  {
218  m_t << l << " ";
219  }
220 }
221 
222 
224 {
225  m_col=0;
226 }
227 
229 {
230  codify("\n");
231 }
232 
234 {
235  m_t << "\\textcolor{" << name << "}{";
236 }
237 
239 {
240  m_t << "}";
241 }
242 
243 
244 //-------------------------------
245 
247 {
248  dir=Config_getString(LATEX_OUTPUT);
249  //printf("LatexGenerator::LatexGenerator() insideTabbing=FALSE\n");
250  insideTabbing=FALSE;
251  firstDescItem=TRUE;
252  disableLinks=FALSE;
253  m_indent=0;
254  templateMemberItem = FALSE;
255  m_prettyCode=Config_getBool(LATEX_SOURCE_CODE);
256 }
257 
259 {
260 }
261 
262 static void writeLatexMakefile()
263 {
264  bool generateBib = !Doxygen::citeDict->isEmpty();
265  QCString dir=Config_getString(LATEX_OUTPUT);
266  QCString fileName=dir+"/Makefile";
267  QFile file(fileName);
268  if (!file.open(IO_WriteOnly))
269  {
270  err("Could not open file %s for writing\n",fileName.data());
271  exit(1);
272  }
273  // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
274  QCString latex_command = Config_getString(LATEX_CMD_NAME);
275  QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME);
276  // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
277  FTextStream t(&file);
278  if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
279  {
280  t << "all: refman.dvi" << endl
281  << endl
282  << "ps: refman.ps" << endl
283  << endl
284  << "pdf: refman.pdf" << endl
285  << endl
286  << "ps_2on1: refman_2on1.ps" << endl
287  << endl
288  << "pdf_2on1: refman_2on1.pdf" << endl
289  << endl
290  << "refman.ps: refman.dvi" << endl
291  << "\tdvips -o refman.ps refman.dvi" << endl
292  << endl;
293  t << "refman.pdf: refman.ps" << endl;
294  t << "\tps2pdf refman.ps refman.pdf" << endl << endl;
295  t << "refman.dvi: clean refman.tex doxygen.sty" << endl
296  << "\techo \"Running latex...\"" << endl
297  << "\t" << latex_command << " refman.tex" << endl
298  << "\techo \"Running makeindex...\"" << endl
299  << "\t" << mkidx_command << " refman.idx" << endl;
300  if (generateBib)
301  {
302  t << "\techo \"Running bibtex...\"" << endl;
303  t << "\tbibtex refman" << endl;
304  t << "\techo \"Rerunning latex....\"" << endl;
305  t << "\t" << latex_command << " refman.tex" << endl;
306  }
307  t << "\techo \"Rerunning latex....\"" << endl
308  << "\t" << latex_command << " refman.tex" << endl
309  << "\tlatex_count=8 ; \\" << endl
310  << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
311  << "\t do \\" << endl
312  << "\t echo \"Rerunning latex....\" ;\\" << endl
313  << "\t " << latex_command << " refman.tex ;\\" << endl
314  << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
315  << "\t done" << endl
316  << "\t" << mkidx_command << " refman.idx" << endl
317  << "\t" << latex_command << " refman.tex" << endl << endl
318  << "refman_2on1.ps: refman.ps" << endl
319  << "\tpsnup -2 refman.ps >refman_2on1.ps" << endl
320  << endl
321  << "refman_2on1.pdf: refman_2on1.ps" << endl
322  << "\tps2pdf refman_2on1.ps refman_2on1.pdf" << endl;
323  }
324  else // use pdflatex for higher quality output
325  {
326  t << "all: refman.pdf" << endl << endl
327  << "pdf: refman.pdf" << endl << endl;
328  t << "refman.pdf: clean refman.tex" << endl;
329  t << "\tpdflatex refman" << endl;
330  t << "\t" << mkidx_command << " refman.idx" << endl;
331  if (generateBib)
332  {
333  t << "\tbibtex refman" << endl;
334  t << "\tpdflatex refman" << endl;
335  }
336  t << "\tpdflatex refman" << endl
337  << "\tlatex_count=8 ; \\" << endl
338  << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\\" << endl
339  << "\t do \\" << endl
340  << "\t echo \"Rerunning latex....\" ;\\" << endl
341  << "\t pdflatex refman ;\\" << endl
342  << "\t latex_count=`expr $$latex_count - 1` ;\\" << endl
343  << "\t done" << endl
344  << "\t" << mkidx_command << " refman.idx" << endl
345  << "\tpdflatex refman" << endl << endl;
346  }
347 
348  t << endl
349  << "clean:" << endl
350  << "\trm -f "
351  << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf" << endl;
352 }
353 
354 static void writeMakeBat()
355 {
356 #if defined(_MSC_VER)
357  QCString dir=Config_getString(LATEX_OUTPUT);
358  QCString fileName=dir+"/make.bat";
359  QCString latex_command = Config_getString(LATEX_CMD_NAME);
360  QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME);
361  QFile file(fileName);
362  bool generateBib = !Doxygen::citeDict->isEmpty();
363  if (!file.open(IO_WriteOnly))
364  {
365  err("Could not open file %s for writing\n",fileName.data());
366  exit(1);
367  }
368  FTextStream t(&file);
369  t << "set Dir_Old=%cd%\n";
370  t << "cd /D %~dp0\n\n";
371  t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf\n\n";
372  if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
373  {
374  t << latex_command << " refman.tex\n";
375  t << "echo ----\n";
376  t << mkidx_command << " refman.idx\n";
377  if (generateBib)
378  {
379  t << "bibtex refman\n";
380  t << "echo ----\n";
381  t << latex_command << " refman.tex\n";
382  }
383  t << "setlocal enabledelayedexpansion\n";
384  t << "set count=8\n";
385  t << ":repeat\n";
386  t << "set content=X\n";
387  t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
388  t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
389  t << "if !content! == X goto :skip\n";
390  t << "set /a count-=1\n";
391  t << "if !count! EQU 0 goto :skip\n\n";
392  t << "echo ----\n";
393  t << latex_command << " refman.tex\n";
394  t << "goto :repeat\n";
395  t << ":skip\n";
396  t << "endlocal\n";
397  t << mkidx_command << " refman.idx\n";
398  t << latex_command << " refman.tex\n";
399  t << "dvips -o refman.ps refman.dvi\n";
400  t << "gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
401  "-sOutputFile=refman.pdf -c save pop -f refman.ps\n";
402  }
403  else // use pdflatex
404  {
405  t << "pdflatex refman\n";
406  t << "echo ----\n";
407  t << mkidx_command << " refman.idx\n";
408  if (generateBib)
409  {
410  t << "bibtex refman" << endl;
411  t << "pdflatex refman" << endl;
412  }
413  t << "echo ----\n";
414  t << "pdflatex refman\n\n";
415  t << "setlocal enabledelayedexpansion\n";
416  t << "set count=8\n";
417  t << ":repeat\n";
418  t << "set content=X\n";
419  t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" refman.log' ) do set content=\"%%~T\"\n";
420  t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" refman.log' ) do set content=\"%%~T\"\n";
421  t << "if !content! == X goto :skip\n";
422  t << "set /a count-=1\n";
423  t << "if !count! EQU 0 goto :skip\n\n";
424  t << "echo ----\n";
425  t << "pdflatex refman\n";
426  t << "goto :repeat\n";
427  t << ":skip\n";
428  t << "endlocal\n";
429  t << mkidx_command << " refman.idx\n";
430  t << "pdflatex refman\n";
431  t << "cd /D %Dir_Old%\n";
432  t << "set Dir_Old=\n";
433  }
434 #endif
435 }
436 
438 {
439 
440  QCString dir=Config_getString(LATEX_OUTPUT);
441  QDir d(dir);
442  if (!d.exists() && !d.mkdir(dir))
443  {
444  err("Could not create output directory %s\n",dir.data());
445  exit(1);
446  }
447 
449  writeMakeBat();
450 
451  createSubDirs(d);
452 }
453 
455 {
456  // part 1
457 
458  // Handle batch mode
459  if (Config_getBool(LATEX_BATCHMODE))
460  t << "\\batchmode\n";
461 
462  // Set document class depending on configuration
463  QCString documentClass;
464  if (Config_getBool(COMPACT_LATEX))
465  documentClass = "article";
466  else
467  documentClass = "book";
468  t << "\\documentclass[twoside]{" << documentClass << "}\n"
469  "\n";
470 
471  // Load required packages
472  t << "% Packages required by doxygen\n"
473  "\\usepackage{fixltx2e}\n" // for \textsubscript
474  "\\usepackage{calc}\n"
475  "\\usepackage{doxygen}\n"
476  "\\usepackage[export]{adjustbox} % also loads graphicx\n";
477  QStrList extraLatexStyle = Config_getList(LATEX_EXTRA_STYLESHEET);
478  for (uint i=0; i<extraLatexStyle.count(); ++i)
479  {
480  QCString fileName(extraLatexStyle.at(i));
481  if (!fileName.isEmpty())
482  {
483  QFileInfo fi(fileName);
484  if (fi.exists())
485  {
486  if (checkExtension(fi.fileName().data(), latexStyleExtension))
487  {
488  // strip the extension, it will be added by the usepackage in the tex conversion process
489  t << "\\usepackage{" << stripExtensionGeneral(fi.fileName().data(), latexStyleExtension) << "}\n";
490  }
491  else
492  {
493  t << "\\usepackage{" << fi.fileName().utf8() << "}\n";
494  }
495  }
496  }
497  }
498  t << "\\usepackage{graphicx}\n"
499  "\\usepackage[utf8]{inputenc}\n"
500  "\\usepackage{makeidx}\n"
501  "\\usepackage{multicol}\n"
502  "\\usepackage{multirow}\n"
503  "\\PassOptionsToPackage{warn}{textcomp}\n"
504  "\\usepackage{textcomp}\n"
505  "\\usepackage[nointegrals]{wasysym}\n"
506  "\\usepackage[table]{xcolor}\n"
507  "\n";
508 
509  // Language support
510  QCString languageSupport = theTranslator->latexLanguageSupportCommand();
511  if (!languageSupport.isEmpty())
512  {
513  t << "% NLS support packages\n"
514  << languageSupport
515  << "\n";
516  }
517 
518  // Define default fonts
519  t << "% Font selection\n"
520  "\\usepackage[T1]{fontenc}\n"
521  "\\usepackage[scaled=.90]{helvet}\n"
522  "\\usepackage{courier}\n"
523  "\\usepackage{amssymb}\n"
524  "\\usepackage{sectsty}\n"
525  "\\renewcommand{\\familydefault}{\\sfdefault}\n"
526  "\\allsectionsfont{%\n"
527  " \\fontseries{bc}\\selectfont%\n"
528  " \\color{darkgray}%\n"
529  "}\n"
530  "\\renewcommand{\\DoxyLabelFont}{%\n"
531  " \\fontseries{bc}\\selectfont%\n"
532  " \\color{darkgray}%\n"
533  "}\n"
534  "\\newcommand{\\+}{\\discretionary{\\mbox{\\scriptsize$\\hookleftarrow$}}{}{}}\n"
535  "\n";
536 
537  // Define page & text layout
538  QCString paperName=Config_getEnum(PAPER_TYPE);
539  // "a4wide" package is obsolete (see bug 563698)
540  t << "% Page & text layout\n"
541  "\\usepackage{geometry}\n"
542  "\\geometry{%\n"
543  " " << paperName << "paper,%\n"
544  " top=2.5cm,%\n"
545  " bottom=2.5cm,%\n"
546  " left=2.5cm,%\n"
547  " right=2.5cm%\n"
548  "}\n";
549  // \sloppy is obsolete (see bug 563698)
550  // Allow a bit of overflow to go unnoticed by other means
551  t << "\\tolerance=750\n"
552  "\\hfuzz=15pt\n"
553  "\\hbadness=750\n"
554  "\\setlength{\\emergencystretch}{15pt}\n"
555  "\\setlength{\\parindent}{0cm}\n"
556  "\\setlength{\\parskip}{3ex plus 2ex minus 2ex}\n";
557  // Redefine paragraph/subparagraph environments, using sectsty fonts
558  t << "\\makeatletter\n"
559  "\\renewcommand{\\paragraph}{%\n"
560  " \\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%\n"
561  " \\normalfont\\normalsize\\bfseries\\SS@parafont%\n"
562  " }%\n"
563  "}\n"
564  "\\renewcommand{\\subparagraph}{%\n"
565  " \\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%\n"
566  " \\normalfont\\normalsize\\bfseries\\SS@subparafont%\n"
567  " }%\n"
568  "}\n"
569  "\\makeatother\n"
570  "\n";
571 
572  // Headers & footers
573  QGString genString;
574  QCString generatedBy;
575  static bool timeStamp = Config_getBool(LATEX_TIMESTAMP);
576  FTextStream tg(&genString);
577  if (timeStamp)
578  {
579  generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), Config_getString(PROJECT_NAME));
580  }
581  else
582  {
583  generatedBy = theTranslator->trGeneratedBy();
584  }
585  filterLatexString(tg, generatedBy, FALSE,FALSE,FALSE);
586  t << "% Headers & footers\n"
587  "\\usepackage{fancyhdr}\n"
588  "\\pagestyle{fancyplain}\n"
589  "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n"
590  "\\fancyhead[CE]{\\fancyplain{}{}}\n"
591  "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n"
592  "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n"
593  "\\fancyhead[CO]{\\fancyplain{}{}}\n"
594  "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n"
595  "\\fancyfoot[LE]{\\fancyplain{}{}}\n"
596  "\\fancyfoot[CE]{\\fancyplain{}{}}\n"
597  "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
598  "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
599  "\\fancyfoot[CO]{\\fancyplain{}{}}\n"
600  "\\fancyfoot[RO]{\\fancyplain{}{}}\n"
601  "\\renewcommand{\\footrulewidth}{0.4pt}\n";
602  if (!Config_getBool(COMPACT_LATEX))
603  {
604  t << "\\renewcommand{\\chaptermark}[1]{%\n"
605  " \\markboth{#1}{}%\n"
606  "}\n";
607  }
608  t << "\\renewcommand{\\sectionmark}[1]{%\n"
609  " \\markright{\\thesection\\ #1}%\n"
610  "}\n"
611  "\n";
612 
613  // ToC, LoF, LoT, bibliography, and index
614  t << "% Indices & bibliography\n"
615  "\\usepackage{natbib}\n"
616  "\\usepackage[titles]{tocloft}\n"
617  "\\setcounter{tocdepth}{3}\n"
618  "\\setcounter{secnumdepth}{5}\n"
619  "\\makeindex\n"
620  "\n";
621 
623 
624  // Hyperlinks
625  bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
626  if (pdfHyperlinks)
627  {
628  t << "% Hyperlinks (required, but should be loaded last)\n"
629  "\\usepackage{ifpdf}\n"
630  "\\ifpdf\n"
631  " \\usepackage[pdftex,pagebackref=true]{hyperref}\n"
632  "\\else\n"
633  " \\usepackage[ps2pdf,pagebackref=true]{hyperref}\n"
634  "\\fi\n"
635  "\\hypersetup{%\n"
636  " colorlinks=true,%\n"
637  " linkcolor=blue,%\n"
638  " citecolor=blue,%\n"
639  " unicode%\n"
640  "}\n"
641  "\n";
642  }
643 
644  // Custom commands used by the header
645  t << "% Custom commands\n"
646  "\\newcommand{\\clearemptydoublepage}{%\n"
647  " \\newpage{\\pagestyle{empty}\\cleardoublepage}%\n"
648  "}\n"
649  "\n";
650 
651  // caption style definition
652  t << "\\usepackage{caption}\n"
653  << "\\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}\n\n";
654 
655  // End of preamble, now comes the document contents
656  t << "%===== C O N T E N T S =====\n"
657  "\n"
658  "\\begin{document}\n";
659  if (theTranslator->idLanguage()=="greek")
660  t << "\\selectlanguage{greek}\n";
661  t << "\n";
662 
663  // Front matter
664  t << "% Titlepage & ToC\n";
665  bool usePDFLatex = Config_getBool(USE_PDFLATEX);
666  if (pdfHyperlinks && usePDFLatex)
667  {
668  // To avoid duplicate page anchors due to reuse of same numbers for
669  // the index (be it as roman numbers)
670  t << "\\hypersetup{pageanchor=false,\n"
671  // << " bookmarks=true,\n" // commented out to prevent warning
672  << " bookmarksnumbered=true,\n"
673  << " pdfencoding=unicode\n"
674  << " }\n";
675  }
676  t << "\\pagenumbering{alph}\n"
677  "\\begin{titlepage}\n"
678  "\\vspace*{7cm}\n"
679  "\\begin{center}%\n"
680  "{\\Large ";
681 }
682 
684 {
685  // part 2
686  // Finalize project name
687  t << "}\\\\\n"
688  "\\vspace*{1cm}\n"
689  "{\\large ";
690 }
691 
693 {
694  // part 3
695  // Finalize project number
696  t << " Doxygen " << versionString << "}\\\\\n";
697  if (Config_getBool(LATEX_TIMESTAMP))
698  t << "\\vspace*{0.5cm}\n"
699  "{\\small " << dateToString(TRUE) << "}\\\\\n";
700  t << "\\end{center}\n"
701  "\\end{titlepage}\n";
702  bool compactLatex = Config_getBool(COMPACT_LATEX);
703  if (!compactLatex)
704  t << "\\clearemptydoublepage\n";
705  t << "\\pagenumbering{roman}\n";
706 
707  // ToC
708  t << "\\tableofcontents\n";
709  if (!compactLatex)
710  t << "\\clearemptydoublepage\n";
711  t << "\\pagenumbering{arabic}\n";
712  bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
713  bool usePDFLatex = Config_getBool(USE_PDFLATEX);
714  if (pdfHyperlinks && usePDFLatex)
715  {
716  // re-enable anchors again
717  t << "\\hypersetup{pageanchor=true}\n";
718  }
719  t << "\n"
720  "%--- Begin generated contents ---\n";
721 }
722 
724 {
725  t << ResourceMgr::instance().getAsString("doxygen.sty");
726 }
727 
729 {
730  t << "%--- End generated contents ---\n"
731  "\n";
732 
733  // Bibliography
735 
736  // Index
737  t << "% Index\n";
738  QCString unit;
739  if (Config_getBool(COMPACT_LATEX))
740  {
741  unit = "section";
742  }
743  else
744  {
745  unit = "chapter";
746  t << "\\backmatter\n";
747  }
748  t << "\\newpage\n"
749  "\\phantomsection\n"
750  "\\clearemptydoublepage\n"
751  "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trRTFGeneralIndex() << "}\n"
752  "\\printindex\n"
753  "\n"
754  "\\end{document}\n";
755 }
756 
758 {
759  FTextStream t(&f);
760  t << "% Latex header for doxygen " << versionString << endl;
762  t << "Your title here";
764  t << "Generated by";
766 }
767 
769 {
770  FTextStream t(&f);
771  t << "% Latex footer for doxygen " << versionString << endl;
773 }
774 
776 {
777  FTextStream t(&f);
778  t << "% stylesheet for doxygen " << versionString << endl;
780 }
781 
782 void LatexGenerator::startFile(const char *name,const char *,const char *)
783 {
784 #if 0
785  setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
786 #endif
787  QCString fileName=name;
788  relPath = relativePathToRoot(fileName);
789  if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex";
790  startPlainFile(fileName);
794 }
795 
797 {
798  endPlainFile();
800 }
801 
802 //void LatexGenerator::writeIndex()
803 //{
804 // startFile("refman.tex");
805 //}
806 
808 {
809  t << "\\\\[1ex]\\large ";
810 }
811 
813 {
814  bool &compactLatex = Config_getBool(COMPACT_LATEX);
815  QCString &latexHeader = Config_getString(LATEX_HEADER);
816  switch (is)
817  {
818  case isTitlePageStart:
819  {
820  if (latexHeader.isEmpty())
821  {
823  }
824  else
825  {
826  QCString header = fileToString(latexHeader);
827  t << substituteKeywords(header,"",
828  convertToLaTeX(Config_getString(PROJECT_NAME)),
829  convertToLaTeX(Config_getString(PROJECT_NUMBER)),
830  convertToLaTeX(Config_getString(PROJECT_BRIEF)));
831  }
832  }
833  break;
834  case isTitlePageAuthor:
835  if (latexHeader.isEmpty())
836  {
838  }
839  break;
840  case isMainPage:
841  if (compactLatex) t << "\\section"; else t << "\\chapter";
842  t << "{"; //Introduction}\n"
843  break;
844  //case isPackageIndex:
845  // if (compactLatex) t << "\\section"; else t << "\\chapter";
846  // t << "{"; //Package Index}\n"
847  // break;
848  case isModuleIndex:
849  if (compactLatex) t << "\\section"; else t << "\\chapter";
850  t << "{"; //Module Index}\n"
851  break;
852  case isDirIndex:
853  if (compactLatex) t << "\\section"; else t << "\\chapter";
854  t << "{"; //Directory Index}\n"
855  break;
856  case isNamespaceIndex:
857  if (compactLatex) t << "\\section"; else t << "\\chapter";
858  t << "{"; //Namespace Index}\"
859  break;
861  if (compactLatex) t << "\\section"; else t << "\\chapter";
862  t << "{"; //Hierarchical Index}\n"
863  break;
864  case isCompoundIndex:
865  if (compactLatex) t << "\\section"; else t << "\\chapter";
866  t << "{"; //Annotated Compound Index}\n"
867  break;
868  case isFileIndex:
869  if (compactLatex) t << "\\section"; else t << "\\chapter";
870  t << "{"; //Annotated File Index}\n"
871  break;
872  case isPageIndex:
873  if (compactLatex) t << "\\section"; else t << "\\chapter";
874  t << "{"; //Annotated Page Index}\n"
875  break;
877  {
879  GroupDef *gd;
880  bool found=FALSE;
881  for (gli.toFirst();(gd=gli.current()) && !found;++gli)
882  {
883  if (!gd->isReference())
884  {
885  if (compactLatex) t << "\\section"; else t << "\\chapter";
886  t << "{"; //Module Documentation}\n";
887  found=TRUE;
888  }
889  }
890  }
891  break;
892  case isDirDocumentation:
893  {
895  DirDef *dd;
896  bool found=FALSE;
897  for (dli.toFirst();(dd=dli.current()) && !found;++dli)
898  {
899  if (dd->isLinkableInProject())
900  {
901  if (compactLatex) t << "\\section"; else t << "\\chapter";
902  t << "{"; //Module Documentation}\n";
903  found=TRUE;
904  }
905  }
906  }
907  break;
909  {
911  NamespaceDef *nd;
912  bool found=FALSE;
913  for (nli.toFirst();(nd=nli.current()) && !found;++nli)
914  {
915  if (nd->isLinkableInProject())
916  {
917  if (compactLatex) t << "\\section"; else t << "\\chapter";
918  t << "{"; // Namespace Documentation}\n":
919  found=TRUE;
920  }
921  }
922  }
923  break;
925  {
927  ClassDef *cd=0;
928  bool found=FALSE;
929  for (cli.toFirst();(cd=cli.current()) && !found;++cli)
930  {
931  if (cd->isLinkableInProject() &&
932  cd->templateMaster()==0 &&
934  )
935  {
936  if (compactLatex) t << "\\section"; else t << "\\chapter";
937  t << "{"; //Compound Documentation}\n";
938  found=TRUE;
939  }
940  }
941  }
942  break;
943  case isFileDocumentation:
944  {
945  bool isFirst=TRUE;
947  FileName *fn;
948  for (fnli.toFirst();(fn=fnli.current());++fnli)
949  {
950  FileNameIterator fni(*fn);
951  FileDef *fd;
952  for (;(fd=fni.current());++fni)
953  {
954  if (fd->isLinkableInProject())
955  {
956  if (isFirst)
957  {
958  if (compactLatex) t << "\\section"; else t << "\\chapter";
959  t << "{"; //File Documentation}\n";
960  isFirst=FALSE;
961  break;
962  }
963  }
964  }
965  }
966  }
967  break;
969  {
970  if (compactLatex) t << "\\section"; else t << "\\chapter";
971  t << "{"; //Example Documentation}\n";
972  }
973  break;
974  case isPageDocumentation:
975  {
976  if (compactLatex) t << "\\section"; else t << "\\chapter";
977  t << "{"; //Page Documentation}\n";
978  }
979  break;
981  break;
982  case isEndIndex:
983  break;
984  }
985 }
986 
988 {
989  //static bool compactLatex = Config_getBool(COMPACT_LATEX);
990  static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
991  static QCString latexHeader = Config_getString(LATEX_HEADER);
992  static QCString latexFooter = Config_getString(LATEX_FOOTER);
993  switch (is)
994  {
995  case isTitlePageStart:
996  break;
997  case isTitlePageAuthor:
998  if (latexHeader.isEmpty())
999  {
1001  }
1002  break;
1003  case isMainPage:
1004  {
1005  //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
1006  QCString indexName="index";
1007  t << "}\n\\label{index}";
1008  if (Config_getBool(PDF_HYPERLINKS)) t << "\\hypertarget{index}{}";
1009  t << "\\input{" << indexName << "}\n";
1010  }
1011  break;
1012  case isModuleIndex:
1013  t << "}\n\\input{modules}\n";
1014  break;
1015  case isDirIndex:
1016  t << "}\n\\input{dirs}\n";
1017  break;
1018  case isNamespaceIndex:
1019  t << "}\n\\input{namespaces}\n";
1020  break;
1021  case isClassHierarchyIndex:
1022  t << "}\n\\input{hierarchy}\n";
1023  break;
1024  case isCompoundIndex:
1025  t << "}\n\\input{annotated}\n";
1026  break;
1027  case isFileIndex:
1028  t << "}\n\\input{files}\n";
1029  break;
1030  case isPageIndex:
1031  t << "}\n\\input{pages}\n";
1032  break;
1033  case isModuleDocumentation:
1034  {
1036  GroupDef *gd;
1037  bool found=FALSE;
1038  for (gli.toFirst();(gd=gli.current()) && !found;++gli)
1039  {
1040  if (!gd->isReference())
1041  {
1042  t << "}\n\\input{" << gd->getOutputFileBase() << "}\n";
1043  found=TRUE;
1044  }
1045  }
1046  for (;(gd=gli.current());++gli)
1047  {
1048  if (!gd->isReference())
1049  {
1050  //if (compactLatex) t << "\\input"; else t << "\\include";
1051  t << "\\include";
1052  t << "{" << gd->getOutputFileBase() << "}\n";
1053  }
1054  }
1055  }
1056  break;
1057  case isDirDocumentation:
1058  {
1060  DirDef *dd;
1061  bool found=FALSE;
1062  for (dli.toFirst();(dd=dli.current()) && !found;++dli)
1063  {
1064  if (dd->isLinkableInProject())
1065  {
1066  t << "}\n\\input{" << dd->getOutputFileBase() << "}\n";
1067  found=TRUE;
1068  }
1069  }
1070  for (;(dd=dli.current());++dli)
1071  {
1072  if (dd->isLinkableInProject())
1073  {
1074  //if (compactLatex) t << "\\input"; else t << "\\include";
1075  t << "\\input";
1076  t << "{" << dd->getOutputFileBase() << "}\n";
1077  }
1078  }
1079  }
1080  break;
1082  {
1084  NamespaceDef *nd;
1085  bool found=FALSE;
1086  for (nli.toFirst();(nd=nli.current()) && !found;++nli)
1087  {
1088  if (nd->isLinkableInProject())
1089  {
1090  t << "}\n\\input{" << nd->getOutputFileBase() << "}\n";
1091  found=TRUE;
1092  }
1093  }
1094  while ((nd=nli.current()))
1095  {
1096  if (nd->isLinkableInProject())
1097  {
1098  //if (compactLatex) t << "\\input"; else t << "\\include";
1099  t << "\\input";
1100  t << "{" << nd->getOutputFileBase() << "}\n";
1101  }
1102  ++nli;
1103  }
1104  }
1105  break;
1106  case isClassDocumentation:
1107  {
1109  ClassDef *cd=0;
1110  bool found=FALSE;
1111  for (cli.toFirst();(cd=cli.current()) && !found;++cli)
1112  {
1113  if (cd->isLinkableInProject() &&
1114  cd->templateMaster()==0 &&
1115  !cd->isEmbeddedInOuterScope()
1116  )
1117  {
1118  t << "}\n\\input{" << cd->getOutputFileBase() << "}\n";
1119  found=TRUE;
1120  }
1121  }
1122  for (;(cd=cli.current());++cli)
1123  {
1124  if (cd->isLinkableInProject() &&
1125  cd->templateMaster()==0 &&
1126  !cd->isEmbeddedInOuterScope()
1127  )
1128  {
1129  //if (compactLatex) t << "\\input"; else t << "\\include";
1130  t << "\\input";
1131  t << "{" << cd->getOutputFileBase() << "}\n";
1132  }
1133  }
1134  }
1135  break;
1136  case isFileDocumentation:
1137  {
1138  bool isFirst=TRUE;
1140  FileName *fn;
1141  for (fnli.toFirst();(fn=fnli.current());++fnli)
1142  {
1143  FileNameIterator fni(*fn);
1144  FileDef *fd;
1145  for (;(fd=fni.current());++fni)
1146  {
1147  if (fd->isLinkableInProject())
1148  {
1149  if (isFirst)
1150  {
1151  t << "}\n\\input{" << fd->getOutputFileBase() << "}\n";
1152  if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1153  {
1154  //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1155  t << "\\input{" << fd->getSourceFileBase() << "}\n";
1156  }
1157  isFirst=FALSE;
1158  }
1159  else
1160  {
1161  //if (compactLatex) t << "\\input" ; else t << "\\include";
1162  t << "\\input" ;
1163  t << "{" << fd->getOutputFileBase() << "}\n";
1164  if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
1165  {
1166  //t << "\\include{" << fd->getSourceFileBase() << "}\n";
1167  t << "\\input{" << fd->getSourceFileBase() << "}\n";
1168  }
1169  }
1170  }
1171  }
1172  }
1173  }
1174  break;
1176  {
1177  t << "}\n";
1179  PageDef *pd=pdi.toFirst();
1180  if (pd)
1181  {
1182  t << "\\input{" << pd->getOutputFileBase() << "}\n";
1183  }
1184  for (++pdi;(pd=pdi.current());++pdi)
1185  {
1186  //if (compactLatex) t << "\\input" ; else t << "\\include";
1187  t << "\\input";
1188  t << "{" << pd->getOutputFileBase() << "}\n";
1189  }
1190  }
1191  break;
1192  case isPageDocumentation:
1193  {
1194  t << "}\n";
1195 #if 0
1197  PageDef *pd=pdi.toFirst();
1198  bool first=TRUE;
1199  for (pdi.toFirst();(pd=pdi.current());++pdi)
1200  {
1201  if (!pd->getGroupDef() && !pd->isReference())
1202  {
1203  if (compactLatex) t << "\\section"; else t << "\\chapter";
1204  t << "{" << pd->title();
1205  t << "}\n";
1206 
1207  if (compactLatex || first) t << "\\input" ; else t << "\\include";
1208  t << "{" << pd->getOutputFileBase() << "}\n";
1209  first=FALSE;
1210  }
1211  }
1212 #endif
1213  }
1214  break;
1215  case isPageDocumentation2:
1216  break;
1217  case isEndIndex:
1218  if (latexFooter.isEmpty())
1219  {
1221  }
1222  else
1223  {
1224  QCString footer = fileToString(latexFooter);
1225  t << substituteKeywords(footer,"",
1226  convertToLaTeX(Config_getString(PROJECT_NAME)),
1227  convertToLaTeX(Config_getString(PROJECT_NUMBER)),
1228  convertToLaTeX(Config_getString(PROJECT_BRIEF)));
1229  }
1230  break;
1231  }
1232 }
1233 
1234 void LatexGenerator::writePageLink(const char *name, bool /*first*/)
1235 {
1236  //bool &compactLatex = Config_getBool(COMPACT_LATEX);
1237  // next is remove for bug615957
1238  //if (compactLatex || first) t << "\\input" ; else t << "\\include";
1239  t << "\\input" ;
1240  t << "{" << name << "}\n";
1241 }
1242 
1243 
1245 {
1246  if (part > 0)
1247  return;
1248 
1249  startPlainFile("doxygen.sty");
1251  endPlainFile();
1252 }
1253 
1255 {
1256  t << endl << endl;
1257 }
1258 
1260 {
1261  t << endl << endl;
1262 }
1263 
1265 {
1266  t << endl << endl;
1267 }
1268 
1269 void LatexGenerator::writeString(const char *text)
1270 {
1271  t << text;
1272 }
1273 
1274 void LatexGenerator::startIndexItem(const char *ref,const char *fn)
1275 {
1276  t << "\\item ";
1277  if (!ref && fn)
1278  {
1279  t << "\\contentsline{section}{";
1280  }
1281 }
1282 
1283 void LatexGenerator::endIndexItem(const char *ref,const char *fn)
1284 {
1285  if (!ref && fn)
1286  {
1287  t << "}{\\pageref{" << stripPath(fn) << "}}{}" << endl;
1288  }
1289 }
1290 
1291 //void LatexGenerator::writeIndexFileItem(const char *,const char *text)
1292 //{
1293 // t << "\\item\\contentsline{section}{";
1294 // docify(text);
1295 // t << "}{\\pageref{" << stripPath(text) << "}}" << endl;
1296 //}
1297 
1298 
1299 void LatexGenerator::startHtmlLink(const char *url)
1300 {
1301  if (Config_getBool(PDF_HYPERLINKS))
1302  {
1303  t << "\\href{";
1304  t << url;
1305  t << "}";
1306  }
1307  t << "{\\tt ";
1308 }
1309 
1311 {
1312  t << "}";
1313 }
1314 
1315 //void LatexGenerator::writeMailLink(const char *url)
1316 //{
1317 // if (Config_getBool(PDF_HYPERLINKS))
1318 // {
1319 // t << "\\href{mailto:";
1320 // t << url;
1321 // t << "}";
1322 // }
1323 // t << "{\\tt ";
1324 // docify(url);
1325 // t << "}";
1326 //}
1327 
1328 void LatexGenerator::writeStartAnnoItem(const char *,const char *,
1329  const char *path,const char *name)
1330 {
1331  t << "\\item\\contentsline{section}{\\bf ";
1332  if (path) docify(path);
1333  docify(name);
1334  t << "} ";
1335 }
1336 
1337 void LatexGenerator::writeEndAnnoItem(const char *name)
1338 {
1339  t << "}{\\pageref{" << stripPath(name) << "}}{}" << endl;
1340 }
1341 
1343 {
1344  t << "\\item\\contentsline{section}{";
1345 }
1346 
1348 {
1349 }
1350 
1352 {
1353  t << " ";
1354  if (hasBrief) t << "\\\\*";
1355 }
1356 
1357 void LatexGenerator::endIndexValue(const char *name,bool /*hasBrief*/)
1358 {
1359  //if (hasBrief) t << ")";
1360  t << "}{\\pageref{" << stripPath(name) << "}}{}" << endl;
1361 }
1362 
1363 //void LatexGenerator::writeClassLink(const char *,const char *,
1364 // const char *,const char *name)
1365 //{
1366 // t << "{\\bf ";
1367 // docify(name);
1368 // t << "}";
1369 //}
1370 
1371 void LatexGenerator::startTextLink(const char *f,const char *anchor)
1372 {
1373  if (!disableLinks && Config_getBool(PDF_HYPERLINKS))
1374  {
1375  t << "\\hyperlink{";
1376  if (f) t << stripPath(f);
1377  if (anchor) t << "_" << anchor;
1378  t << "}{";
1379  }
1380  else
1381  {
1382  t << "{\\bf ";
1383  }
1384 }
1385 
1387 {
1388  t << "}";
1389 }
1390 
1391 void LatexGenerator::writeObjectLink(const char *ref, const char *f,
1392  const char *anchor, const char *text)
1393 {
1394  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1395  if (!disableLinks && !ref && pdfHyperlinks)
1396  {
1397  t << "\\hyperlink{";
1398  if (f) t << stripPath(f);
1399  if (f && anchor) t << "_";
1400  if (anchor) t << anchor;
1401  t << "}{";
1402  docify(text);
1403  t << "}";
1404  }
1405  else
1406  {
1407  t << "{\\bf ";
1408  docify(text);
1409  t << "}";
1410  }
1411 }
1412 
1414 {
1415  t << " \\doxyref{}{";
1416 }
1417 
1418 void LatexGenerator::endPageRef(const char *clname, const char *anchor)
1419 {
1420  t << "}{";
1421  if (clname) t << clname;
1422  if (anchor) t << "_" << anchor;
1423  t << "}";
1424 }
1425 
1426 
1427 void LatexGenerator::startTitleHead(const char *fileName)
1428 {
1429  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1430  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1431  if (usePDFLatex && pdfHyperlinks && fileName)
1432  {
1433  t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1434  }
1435  if (Config_getBool(COMPACT_LATEX))
1436  {
1437  t << "\\subsection{";
1438  }
1439  else
1440  {
1441  t << "\\section{";
1442  }
1443 }
1444 
1445 void LatexGenerator::endTitleHead(const char *fileName,const char *name)
1446 {
1447  t << "}" << endl;
1448  if (name)
1449  {
1450  t << "\\label{" << stripPath(fileName) << "}\\index{";
1452  t << "@{";
1454  t << "}}" << endl;
1455  }
1456 }
1457 
1459 {
1460  if (Config_getBool(COMPACT_LATEX))
1461  {
1462  t << "\\subsection{";
1463  }
1464  else
1465  {
1466  t << "\\section{";
1467  }
1468 }
1469 
1470 void LatexGenerator::startGroupHeader(int extraIndentLevel)
1471 {
1472  if (Config_getBool(COMPACT_LATEX))
1473  {
1474  extraIndentLevel++;
1475  }
1476 
1477  if (extraIndentLevel==3)
1478  {
1479  t << "\\subparagraph*{";
1480  }
1481  else if (extraIndentLevel==2)
1482  {
1483  t << "\\paragraph{";
1484  }
1485  else if (extraIndentLevel==1)
1486  {
1487  t << "\\subsubsection{";
1488  }
1489  else // extraIndentLevel==0
1490  {
1491  t << "\\subsection{";
1492  }
1493  disableLinks=TRUE;
1494 }
1495 
1497 {
1498  disableLinks=FALSE;
1499  t << "}" << endl;
1500 }
1501 
1503 {
1504  if (Config_getBool(COMPACT_LATEX))
1505  {
1506  t << "\\subsubsection*{";
1507  }
1508  else
1509  {
1510  t << "\\subsection*{";
1511  }
1512  disableLinks=TRUE;
1513 }
1514 
1516 {
1517  disableLinks=FALSE;
1518  t << "}" << endl;
1519 }
1520 
1521 void LatexGenerator::startMemberDoc(const char *clname,
1522  const char *memname,
1523  const char *,
1524  const char *title,
1525  int memCount,
1526  int memTotal,
1527  bool showInline)
1528 {
1529  if (memname && memname[0]!='@')
1530  {
1531  t << "\\index{";
1532  if (clname)
1533  {
1535  t << "@{";
1537  t << "}!";
1538  }
1539  t << latexEscapeLabelName(memname,insideTabbing);
1540  t << "@{";
1542  t << "}}" << endl;
1543 
1544  t << "\\index{";
1545  t << latexEscapeLabelName(memname,insideTabbing);
1546  t << "@{";
1548  t << "}";
1549  if (clname)
1550  {
1551  t << "!";
1553  t << "@{";
1555  t << "}";
1556  }
1557  t << "}" << endl;
1558  }
1559  static const char *levelLab[] = { "subsubsection","paragraph","subparagraph", "subparagraph" };
1560  static bool compactLatex = Config_getBool(COMPACT_LATEX);
1561  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1562  int level=0;
1563  if (showInline) level+=2;
1564  if (compactLatex) level++;
1565  t << "\\" << levelLab[level];
1566 
1567  t << "{";
1568  if (pdfHyperlinks)
1569  {
1570  t << "\\texorpdfstring{";
1571  }
1573  if (pdfHyperlinks)
1574  {
1575  t << "}{" << latexEscapePDFString(title) << "}";
1576  }
1577  if (memTotal>1)
1578  {
1579  t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1580  }
1581  t << "}";
1582  t << "\n{\\footnotesize\\ttfamily ";
1583  //disableLinks=TRUE;
1584 }
1585 
1587 {
1588  disableLinks=FALSE;
1589  t << "}\n\n";
1590  //if (Config_getBool(COMPACT_LATEX)) t << "\\hfill";
1591 }
1592 
1593 void LatexGenerator::startDoxyAnchor(const char *fName,const char *,
1594  const char *anchor, const char *,
1595  const char *)
1596 {
1597  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1598  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1599  if (usePDFLatex && pdfHyperlinks)
1600  {
1601  t << "\\hypertarget{";
1602  if (fName) t << stripPath(fName);
1603  if (anchor) t << "_" << anchor;
1604  t << "}{}";
1605  }
1606  t << "\\label{";
1607  if (fName) t << stripPath(fName);
1608  if (anchor) t << "_" << anchor;
1609  t << "} " << endl;
1610 }
1611 
1612 void LatexGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1613 {
1614 }
1615 
1616 void LatexGenerator::writeAnchor(const char *fName,const char *name)
1617 {
1618  //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1619  t << "\\label{" << stripPath(name) << "}" << endl;
1620  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1621  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1622  if (usePDFLatex && pdfHyperlinks)
1623  {
1624  if (fName)
1625  {
1626  t << "\\hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}{}" << endl;
1627  }
1628  else
1629  {
1630  t << "\\hypertarget{" << stripPath(name) << "}{}" << endl;
1631  }
1632  }
1633 }
1634 
1635 
1636 //void LatexGenerator::writeLatexLabel(const char *clName,const char *anchor)
1637 //{
1638 // writeDoxyAnchor(0,clName,anchor,0);
1639 //}
1640 
1641 void LatexGenerator::addIndexItem(const char *s1,const char *s2)
1642 {
1643  if (s1)
1644  {
1645  t << "\\index{";
1647  t << "@{";
1649  t << "}";
1650  if (s2)
1651  {
1652  t << "!";
1654  t << "@{";
1656  t << "}";
1657  }
1658  t << "}";
1659  }
1660 }
1661 
1662 
1663 void LatexGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
1664 {
1665  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1666  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1667  if (usePDFLatex && pdfHyperlinks)
1668  {
1669  t << "\\hypertarget{" << stripPath(lab) << "}{}";
1670  }
1671  t << "\\";
1672  if (Config_getBool(COMPACT_LATEX))
1673  {
1674  switch(type)
1675  {
1676  case SectionInfo::Page: t << "subsection"; break;
1677  case SectionInfo::Section: t << "subsubsection"; break;
1678  case SectionInfo::Subsection: t << "paragraph"; break;
1679  case SectionInfo::Subsubsection: t << "subparagraph"; break;
1680  case SectionInfo::Paragraph: t << "subparagraph"; break;
1681  default: ASSERT(0); break;
1682  }
1683  t << "{";
1684  }
1685  else
1686  {
1687  switch(type)
1688  {
1689  case SectionInfo::Page: t << "section"; break;
1690  case SectionInfo::Section: t << "subsection"; break;
1691  case SectionInfo::Subsection: t << "subsubsection"; break;
1692  case SectionInfo::Subsubsection: t << "paragraph"; break;
1693  case SectionInfo::Paragraph: t << "subparagraph"; break;
1694  default: ASSERT(0); break;
1695  }
1696  t << "{";
1697  }
1698 }
1699 
1701 {
1702  t << "}\\label{" << lab << "}" << endl;
1703 }
1704 
1705 
1706 void LatexGenerator::docify(const char *str)
1707 {
1708  filterLatexString(t,str,insideTabbing,FALSE,FALSE);
1709 }
1710 
1712 {
1713  char cs[2];
1714  cs[0]=c;
1715  cs[1]=0;
1716  docify(cs);
1717 }
1718 
1720 {
1721  //if (Config_getBool(COMPACT_LATEX)) t << "\\subsubsection"; else t << "\\subsection";
1722  //t << "{";
1723 }
1724 
1726  const char *fileName,const char *)
1727 {
1728  d.writeFigure(t,dir,fileName);
1729 }
1730 
1731 
1733 {
1734  if (indent==0)
1735  {
1736  t << "\\begin{tabbing}" << endl;
1737  t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill" << endl;
1738  insideTabbing=TRUE;
1739  }
1740  m_indent=indent;
1741 }
1742 
1744 {
1745  if (indent==0)
1746  {
1747  t << endl << "\\end{tabbing}";
1748  insideTabbing=FALSE;
1749  }
1750  m_indent=indent;
1751 }
1752 
1754 {
1755  if (templateMemberItem)
1756  {
1757  t << "{\\footnotesize ";
1758  }
1759 }
1760 
1761 void LatexGenerator::endMemberTemplateParams(const char *,const char *)
1762 {
1763  if (templateMemberItem)
1764  {
1765  t << "}\\\\";
1766  }
1767 }
1768 
1769 void LatexGenerator::startMemberItem(const char *,int annoType,const char *)
1770 {
1771  //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1772  if (!insideTabbing)
1773  {
1774  t << "\\item " << endl;
1775  templateMemberItem = (annoType == 3);
1776  }
1777 }
1778 
1780 {
1781  if (insideTabbing)
1782  {
1783  t << "\\\\";
1784  }
1785  templateMemberItem = FALSE;
1786  t << endl;
1787 }
1788 
1789 void LatexGenerator::startMemberDescription(const char *,const char *)
1790 {
1791  if (!insideTabbing)
1792  {
1793  t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1794  }
1795  else
1796  {
1797  for (int i=0;i<m_indent+2;i++) t << "\\>";
1798  t << "{\\em ";
1799  }
1800 }
1801 
1803 {
1804  if (!insideTabbing)
1805  {
1806  //t << "\\item\\end{DoxyCompactList}";
1807  t << "\\end{DoxyCompactList}";
1808  }
1809  else
1810  {
1811  t << "}\\\\\n";
1812  }
1813 }
1814 
1815 
1817 {
1818  //printf("writeNonBreakbleSpace()\n");
1819  if (insideTabbing)
1820  {
1821  t << "\\>";
1822  }
1823  else
1824  {
1825  t << "~";
1826  }
1827 }
1828 
1829 // ----------------------------------------------
1830 // nesting of functions below:
1831 // startDescTable()
1832 // - startDescTableRow()
1833 // - startDescTableTitle()
1834 // - endDescTabelTitle()
1835 // - startDescTableData()
1836 // - endDescTableData()
1837 // - endDescTableRow()
1838 // - startDescTableRow()
1839 // - ...
1840 // - endDescTableRow()
1841 // endDescTable()
1842 
1843 void LatexGenerator::startDescTable(const char *title)
1844 {
1845  t << "\\begin{DoxyEnumFields}{" << title << "}" << endl;
1846 }
1847 
1849 {
1850  t << "\\end{DoxyEnumFields}" << endl;
1851 }
1852 
1854 {
1855  // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1856  // the row height (based on http://tex.stackexchange.com/a/186102)
1857  t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1858 }
1859 
1861 {
1862 }
1863 
1865 {
1866  t << "}";
1867 }
1868 
1870 {
1871 }
1872 
1874 {
1875  t << "&";
1876 }
1877 
1879 {
1880  t << "\\\\\n\\hline\n" << endl;
1881 }
1882 
1884 {
1885 }
1886 
1887 
1889 {
1890  if (!insideTabbing)
1891  {
1892  t << "\\begin{DoxyCompactItemize}" << endl;
1893  }
1894 }
1895 
1897 {
1898  //printf("LatexGenerator::endMemberList(%d)\n",insideTabbing);
1899  if (!insideTabbing)
1900  {
1901  t << "\\end{DoxyCompactItemize}" << endl;
1902  }
1903 }
1904 
1905 
1907 {
1908  if (hasHeader) t << "\\begin{Indent}";
1909  t << "{\\bf ";
1910  // changed back to rev 756 due to bug 660501
1911  //if (Config_getBool(COMPACT_LATEX))
1912  //{
1913  // t << "\\subparagraph*{";
1914  //}
1915  //else
1916  //{
1917  // t << "\\paragraph*{";
1918  //}
1919 }
1920 
1922 {
1923  // changed back to rev 756 due to bug 660501
1924  t << "}\\par" << endl;
1925  //t << "}" << endl;
1926 }
1927 
1929 {
1930  t << "{\\em ";
1931 }
1932 
1934 {
1935  t << "}";
1936 }
1937 
1939 {
1940 }
1941 
1943 {
1944  if (hasHeader)t << "\\end{Indent}";
1945  t << endl;
1946 }
1947 
1949 {
1950  newParagraph();
1951 }
1952 
1954 {
1956 }
1957 
1959 {
1960 }
1961 
1963 {
1965 }
1966 
1968 {
1969 }
1970 
1972 {
1974 }
1975 
1977 {
1978 }
1979 
1981 {
1983 }
1984 
1986 {
1987 }
1988 
1990 {
1992 }
1993 
1995 {
1996  t << "\\begin{description}" << endl;
1997 }
1998 
2000 {
2001  t << "\\end{description}" << endl;
2002  firstDescItem=TRUE;
2003 }
2004 
2006 {
2007  firstDescItem=TRUE;
2008  t << "\\item[";
2009 }
2010 
2012 {
2013  if (firstDescItem)
2014  {
2015  t << "]" << endl;
2016  firstDescItem=FALSE;
2017  }
2018  else
2019  {
2020  lineBreak();
2021  }
2022 }
2023 
2025  const char *anchor,const char *title)
2026 {
2027  t << "\\begin{Desc}\n\\item[";
2028  if (file)
2029  {
2030  writeObjectLink(0,file,anchor,title);
2031  }
2032  else
2033  {
2034  docify(title);
2035  }
2036  t << "]";
2037 }
2038 
2040 {
2041  t << "\\end{Desc}" << endl;
2042 }
2043 
2045 {
2046  t << "\\begin{Desc}\n\\item[";
2047  docify(title);
2048  t << "]";
2049 }
2050 
2052 {
2053  t << "\\end{Desc}" << endl;
2054 }
2055 
2057 {
2058  /* start of ParameterType ParameterName list */
2059  if (openBracket) t << "(";
2060  t << "\\begin{DoxyParamCaption}";
2061 }
2062 
2064 {
2065 }
2066 
2067 void LatexGenerator::startParameterType(bool first,const char *key)
2068 {
2069  t << "\\item[{";
2070  if (!first && key) t << key;
2071 }
2072 
2074 {
2075  t << "}]";
2076 }
2077 
2078 void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2079 {
2080  t << "{";
2081 }
2082 
2083 void LatexGenerator::endParameterName(bool last,bool /*emptyList*/,bool closeBracket)
2084 {
2085  t << " }";
2086  if (last)
2087  {
2088  t << "\\end{DoxyParamCaption}";
2089  if (closeBracket) t << ")";
2090  }
2091 }
2092 
2093 void LatexGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2094 {
2095  if (prefix)
2096  t << " " << prefix;
2097  else if (closeBracket)
2098  t << ")";
2099  t << " ";
2100 }
2101 
2103 {
2104  LatexDocVisitor *visitor =
2105  new LatexDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""),insideTabbing);
2106  n->accept(visitor);
2107  delete visitor;
2108 }
2109 
2110 void LatexGenerator::startConstraintList(const char *header)
2111 {
2112  t << "\\begin{Desc}\n\\item[";
2113  docify(header);
2114  t << "]";
2115  t << "\\begin{description}" << endl;
2116 }
2117 
2119 {
2120  t << "\\item[{\\em ";
2121 }
2122 
2124 {
2125 }
2126 
2128 {
2129  t << "} : {\\em ";
2130 }
2131 
2133 {
2134  t << "}]";
2135 }
2136 
2138 {
2139 }
2140 
2142 {
2143 }
2144 
2146 {
2147  t << "\\end{description}" << endl;
2148  t << "\\end{Desc}" << endl;
2149 }
2150 
2152 {
2153  t << "\n\\begin{DoxyCode}\n";
2154 }
2155 
2157 {
2158  t << "\\end{DoxyCode}\n";
2159 }
2160 
2162 {
2163  if (Config_getBool(COMPACT_LATEX))
2164  {
2165  t << "\\paragraph*{";
2166  }
2167  else
2168  {
2169  t << "\\subsubsection*{";
2170  }
2171 }
2172 
2174 {
2175  t << "}" << endl;
2176 }
2177 
2178 void LatexGenerator::lineBreak(const char *)
2179 {
2180  if (insideTabbing)
2181  {
2182  t << "\\\\\n";
2183  }
2184  else
2185  {
2186  t << "\\newline\n";
2187  }
2188 }
2189 
2191 {
2192  if (isEnum)
2193  {
2194  t << "\\begin{DoxyEnumFields}{";
2196  }
2197  else
2198  {
2199  t << "\\begin{DoxyFields}{";
2201  }
2202  t << "}" << endl;
2203 }
2204 
2206 {
2207  if (isEnum)
2208  {
2209  t << "\\end{DoxyEnumFields}" << endl;
2210  }
2211  else
2212  {
2213  t << "\\end{DoxyFields}" << endl;
2214  }
2215 }
2216 
2218 {
2219 }
2220 
2222 {
2223  t << "&" << endl;
2224 }
2225 
2227 {
2228 }
2229 
2231 {
2232  t << "&" << endl;
2233 }
2234 
2236 {
2237 }
2238 
2240 {
2241  t << "\\\\\n\\hline\n" << endl;
2242 }
2243 
2245 {
2246  t << "\\hspace{0.3cm}";
2247 }
2248 
2249 void LatexGenerator::writeLabel(const char *l,bool isLast)
2250 {
2251  t << "{\\ttfamily [" << l << "]}";
2252  if (!isLast) t << ", ";
2253 }
2254 
2256 {
2257 }
2258 
2259