Orb/Doxygen/src/latexdocvisitor.cpp
changeset 3 d8fccb2cd802
parent 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
2:932c358ece3e 3:d8fccb2cd802
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  *
       
     6  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     7  *
       
     8  * Permission to use, copy, modify, and distribute this software and its
       
     9  * documentation under the terms of the GNU General Public License is hereby 
       
    10  * granted. No representations are made about the suitability of this software 
       
    11  * for any purpose. It is provided "as is" without express or implied warranty.
       
    12  * See the GNU General Public License for more details.
       
    13  *
       
    14  * Documents produced by Doxygen are derivative works derived from the
       
    15  * input used in their production; they are not affected by this license.
       
    16  *
       
    17  */
       
    18 #include <qfileinfo.h> 
       
    19 #include "latexdocvisitor.h"
       
    20 #include "docparser.h"
       
    21 #include "language.h"
       
    22 #include "doxygen.h"
       
    23 #include "outputgen.h"
       
    24 #include "dot.h"
       
    25 #include "util.h"
       
    26 #include "message.h"
       
    27 #include "parserintf.h"
       
    28 #include "msc.h"
       
    29 #include "htmlattrib.h"
       
    30 
       
    31 static QString escapeLabelName(const char *s)
       
    32 {
       
    33   QString result;
       
    34   const char *p=s;
       
    35   char c;
       
    36   while ((c=*p++))
       
    37   {
       
    38     switch (c)
       
    39     {
       
    40       case '%': result+="\\%"; break;
       
    41       case '|': result+="\\texttt{\"|}"; break;
       
    42       case '!': result+="\"!"; break;
       
    43       default: result+=c;
       
    44     }
       
    45   }
       
    46   return result;
       
    47 }
       
    48 
       
    49 const int maxLevels=5;
       
    50 static const char *secLabels[maxLevels] = 
       
    51    { "section","subsection","subsubsection","paragraph","subparagraph" };
       
    52 
       
    53 static const char *getSectionName(int level)
       
    54 {
       
    55   int l = level;
       
    56   if (Config_getBool("COMPACT_LATEX")) l++;
       
    57   if (Doxygen::insideMainPage) l--;
       
    58   return secLabels[QMIN(maxLevels-1,l)];
       
    59 }
       
    60 
       
    61 static int rowspan(DocHtmlCell *cell)
       
    62 {
       
    63   int retval = 0;
       
    64   HtmlAttribList attrs = cell->attribs ();
       
    65   for (unsigned int i = 0; i < attrs.count(); ++i) 
       
    66   {
       
    67     if ("rowspan" == attrs.at(i)->name.lower())
       
    68     {
       
    69       retval = attrs.at(i)->value.toInt();
       
    70       break;
       
    71     }
       
    72   }
       
    73   return retval;
       
    74 }
       
    75 
       
    76 QString LatexDocVisitor::escapeMakeIndexChars(const char *s)
       
    77 {
       
    78   QString result;
       
    79   const char *p=s;
       
    80   char str[2]; str[1]=0;
       
    81   char c;
       
    82   while ((c=*p++))
       
    83   {
       
    84     switch (c)
       
    85     {
       
    86       case '!': m_t << "\"!"; break;
       
    87       case '"': m_t << "\"\""; break;
       
    88       case '@': m_t << "\"@"; break;
       
    89       case '|': m_t << "\\texttt{\"|}"; break;
       
    90       case '[': m_t << "["; break;
       
    91       case ']': m_t << "]"; break;
       
    92       default:  str[0]=c; filter(str); break;
       
    93     }
       
    94   }
       
    95   return result;
       
    96 }
       
    97 
       
    98 
       
    99 LatexDocVisitor::LatexDocVisitor(QTextStream &t,CodeOutputInterface &ci,
       
   100                                  const char *langExt,bool insideTabbing) 
       
   101   : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE), 
       
   102     m_insideItem(FALSE), m_hide(FALSE), m_insideTabbing(insideTabbing),
       
   103     m_langExt(langExt), m_currentColumn(0), m_inRowspan(FALSE)
       
   104 {
       
   105 }
       
   106 
       
   107   //--------------------------------------
       
   108   // visitor functions for leaf nodes
       
   109   //--------------------------------------
       
   110 
       
   111 void LatexDocVisitor::visit(DocWord *w)
       
   112 {
       
   113   if (m_hide) return;
       
   114   filter(w->word());
       
   115 }
       
   116 
       
   117 void LatexDocVisitor::visit(DocLinkedWord *w)
       
   118 {
       
   119   if (m_hide) return;
       
   120   startLink(w->ref(),w->file(),w->anchor());
       
   121   filter(w->word());
       
   122   endLink(w->ref(),w->file(),w->anchor());
       
   123 }
       
   124 
       
   125 void LatexDocVisitor::visit(DocWhiteSpace *w)
       
   126 {
       
   127   if (m_hide) return;
       
   128   if (m_insidePre)
       
   129   {
       
   130     m_t << w->chars();
       
   131   }
       
   132   else
       
   133   {
       
   134     m_t << " ";
       
   135   }
       
   136 }
       
   137 
       
   138 void LatexDocVisitor::visit(DocSymbol *s)
       
   139 {
       
   140   if (m_hide) return;
       
   141   switch(s->symbol())
       
   142   {
       
   143     case DocSymbol::BSlash:  m_t << "$\\backslash$"; break;
       
   144     case DocSymbol::At:      m_t << "@"; break;
       
   145     case DocSymbol::Less:    if (m_insidePre) m_t << "<"; else m_t << "$<$"; 
       
   146                              break;
       
   147     case DocSymbol::Greater: if (m_insidePre) m_t << ">"; else m_t << "$>$"; break;
       
   148     case DocSymbol::Amp:     m_t << "\\&"; break;
       
   149     case DocSymbol::Dollar:  m_t << "\\$"; break;
       
   150     case DocSymbol::Hash:    m_t << "\\#"; break;
       
   151     case DocSymbol::Percent: m_t << "\\%"; break;
       
   152     case DocSymbol::Copy:    m_t << "\\copyright"; break;
       
   153     case DocSymbol::Tm:      m_t << "\\texttrademark"; break;
       
   154     case DocSymbol::Reg:     m_t << "\\textregistered"; break;
       
   155     case DocSymbol::Apos:    m_t << "'"; break;
       
   156     case DocSymbol::Quot:    m_t << "\""; break;
       
   157     case DocSymbol::Lsquo:   m_t << "`"; break;
       
   158     case DocSymbol::Rsquo:   m_t << "'"; break;
       
   159     case DocSymbol::Ldquo:   m_t << "``"; break;
       
   160     case DocSymbol::Rdquo:   m_t << "''"; break;
       
   161     case DocSymbol::Ndash:   m_t << "--"; break;
       
   162     case DocSymbol::Mdash:   m_t << "---"; break;
       
   163     case DocSymbol::Uml:     
       
   164                              if (s->letter()=='i') 
       
   165                                m_t << "\\\"{\\i}"; 
       
   166                              else                  
       
   167                                m_t << "\\\"{" << s->letter() << "}"; 
       
   168                              break;
       
   169     case DocSymbol::Acute:   
       
   170                              if (s->letter()=='i') 
       
   171                                m_t << "\\'{\\i}"; 
       
   172                              else                  
       
   173                                m_t << "\\'{" << s->letter() << "}"; 
       
   174                              break;
       
   175     case DocSymbol::Grave:   
       
   176                              if (s->letter()=='i') 
       
   177                                m_t << "\\`{\\i}"; 
       
   178                              else                  
       
   179                                m_t << "\\`{" << s->letter() << "}"; 
       
   180                              break;
       
   181     case DocSymbol::Circ:    
       
   182                              if (s->letter()=='i') 
       
   183                                m_t << "\\^{\\i}"; 
       
   184                              else                  
       
   185                                m_t << "\\^{" << s->letter() << "}"; 
       
   186                              break;
       
   187     case DocSymbol::Slash:   if (tolower(s->letter())=='o')
       
   188                                m_t << "\\" << s->letter();
       
   189                              else
       
   190                                m_t << s->letter();
       
   191                              break;
       
   192     case DocSymbol::Tilde:   m_t << "\\~{"  << s->letter() << "}"; break;
       
   193     case DocSymbol::Szlig:   m_t << "{\\ss}"; break;
       
   194     case DocSymbol::Cedil:   m_t << "\\c{" << s->letter() << "}"; break;
       
   195     case DocSymbol::Ring:    m_t << "\\" << s->letter() << s->letter(); break;
       
   196     case DocSymbol::Nbsp:    m_t << "~"; break;
       
   197     case DocSymbol::AElig:   m_t << "{\\AE}"; break;
       
   198     case DocSymbol::Aelig:   m_t << "{\\ae}"; break;
       
   199     default:
       
   200                              err("Error: unknown symbol found\n");
       
   201   }
       
   202 }
       
   203 
       
   204 void LatexDocVisitor::visit(DocURL *u)
       
   205 {
       
   206   if (m_hide) return;
       
   207   if (Config_getBool("PDF_HYPERLINKS"))
       
   208   {
       
   209     m_t << "\\href{";
       
   210     if (u->isEmail()) m_t << "mailto:";
       
   211     m_t << u->url() << "}";
       
   212   }
       
   213   m_t << "{\\tt ";
       
   214   filter(u->url());
       
   215   m_t << "}";
       
   216 }
       
   217 
       
   218 void LatexDocVisitor::visit(DocLineBreak *)
       
   219 {
       
   220   if (m_hide) return;
       
   221   m_t << "\\par\n";
       
   222 }
       
   223 
       
   224 void LatexDocVisitor::visit(DocHorRuler *)
       
   225 {
       
   226   if (m_hide) return;
       
   227   m_t << "\n\n";
       
   228 }
       
   229 
       
   230 void LatexDocVisitor::visit(DocStyleChange *s)
       
   231 {
       
   232   if (m_hide) return;
       
   233   switch (s->style())
       
   234   {
       
   235     case DocStyleChange::Bold:
       
   236       if (s->enable()) m_t << "{\\bfseries ";      else m_t << "}";
       
   237       break;
       
   238     case DocStyleChange::Italic:
       
   239       if (s->enable()) m_t << "{\\itshape ";     else m_t << "\\/}";
       
   240       break;
       
   241     case DocStyleChange::Code:
       
   242       if (s->enable()) m_t << "{\\ttfamily ";   else m_t << "}";
       
   243       break;
       
   244     case DocStyleChange::Subscript:
       
   245       if (s->enable()) m_t << "$_{\\mbox{";    else m_t << "}}$ ";
       
   246       break;
       
   247     case DocStyleChange::Superscript:
       
   248       if (s->enable()) m_t << "$^{\\mbox{";    else m_t << "}}$ ";
       
   249       break;
       
   250     case DocStyleChange::Center:
       
   251       if (s->enable()) m_t << "\\begin{center}"; else m_t << "\\end{center} ";
       
   252       break;
       
   253     case DocStyleChange::Small:
       
   254       if (s->enable()) m_t << "\n\\footnotesize ";  else m_t << "\n\\normalsize ";
       
   255       break;
       
   256     case DocStyleChange::Preformatted:
       
   257       if (s->enable()) 
       
   258       {
       
   259         m_t << "\n\\begin{DoxyPre}";
       
   260         m_insidePre=TRUE;
       
   261       }
       
   262       else
       
   263       {
       
   264         m_insidePre=FALSE;
       
   265         m_t << "\\end{DoxyPre}\n";
       
   266       }
       
   267       break;
       
   268     case DocStyleChange::Div:  /* HTML only */ break;
       
   269     case DocStyleChange::Span: /* HTML only */ break;
       
   270   }
       
   271 }
       
   272 
       
   273 void LatexDocVisitor::visit(DocVerbatim *s)
       
   274 {
       
   275   static bool latexSourceCode = Config_getBool("LATEX_SOURCE_CODE");
       
   276   if (m_hide) return;
       
   277   switch(s->type())
       
   278   {
       
   279     case DocVerbatim::Code: 
       
   280       if (latexSourceCode)
       
   281       {
       
   282         m_t << "\n\n\\begin{footnotesize}\\begin{alltt}" << endl; 
       
   283       }
       
   284       else
       
   285       {
       
   286         m_t << "\n\\begin{DoxyCode}\n";
       
   287       }
       
   288       Doxygen::parserManager->getParser(m_langExt)
       
   289                             ->parseCode(m_ci,s->context(),s->text().latin1(),
       
   290                                         s->isExample(),s->exampleFile());
       
   291       if (latexSourceCode)
       
   292       {
       
   293         m_t << "\\end{alltt}\\end{footnotesize}" << endl; 
       
   294       }
       
   295       else
       
   296       {
       
   297         m_t << "\\end{DoxyCode}\n";
       
   298       }
       
   299       break;
       
   300     case DocVerbatim::Verbatim: 
       
   301       m_t << "\\begin{DoxyVerb}";
       
   302       m_t << s->text();
       
   303       m_t << "\\end{DoxyVerb}\n";
       
   304       break;
       
   305     case DocVerbatim::HtmlOnly: 
       
   306     case DocVerbatim::XmlOnly: 
       
   307     case DocVerbatim::ManOnly: 
       
   308       /* nothing */ 
       
   309       break;
       
   310     case DocVerbatim::LatexOnly: 
       
   311       m_t << s->text(); 
       
   312       break;
       
   313     case DocVerbatim::Dot: 
       
   314       {
       
   315         static int dotindex = 1;
       
   316         QCString fileName(4096);
       
   317 
       
   318         fileName.sprintf("%s%d%s", 
       
   319             (Config_getString("LATEX_OUTPUT")+"/inline_dotgraph_").data(), 
       
   320             dotindex++,
       
   321             ".dot"
       
   322            );
       
   323         QFile file(fileName);
       
   324         if (!file.open(IO_WriteOnly))
       
   325         {
       
   326           err("Could not open file %s for writing\n",fileName.data());
       
   327         }
       
   328         file.writeBlock( s->text(), s->text().length() );
       
   329         file.close();
       
   330 
       
   331         m_t << "\\begin{center}\n";
       
   332         startDotFile(fileName,"","",FALSE);
       
   333         endDotFile(FALSE);
       
   334         m_t << "\\end{center}\n";
       
   335 
       
   336         if (Config_getBool("DOT_CLEANUP")) file.remove();
       
   337       }
       
   338       break;
       
   339     case DocVerbatim::Msc: 
       
   340       {
       
   341         static int mscindex = 1;
       
   342         QCString baseName(4096);
       
   343 
       
   344         baseName.sprintf("%s%d", 
       
   345             (Config_getString("LATEX_OUTPUT")+"/inline_mscgraph_").data(), 
       
   346             mscindex++
       
   347            );
       
   348         QFile file(baseName+".msc");
       
   349         if (!file.open(IO_WriteOnly))
       
   350         {
       
   351           err("Could not open file %s.msc for writing\n",baseName.data());
       
   352         }
       
   353         QCString text = "msc {";
       
   354         text+=s->text();
       
   355         text+="}";
       
   356         file.writeBlock( text, text.length() );
       
   357         file.close();
       
   358 
       
   359         m_t << "\\begin{center}\n";
       
   360         writeMscFile(baseName);
       
   361         m_t << "\\end{center}\n";
       
   362 
       
   363         if (Config_getBool("DOT_CLEANUP")) file.remove();
       
   364       }
       
   365       break;
       
   366   }
       
   367 }
       
   368 
       
   369 void LatexDocVisitor::visit(DocAnchor *anc)
       
   370 {
       
   371   if (m_hide) return;
       
   372   m_t << "\\label{" << anc->file() << "_" << anc->anchor() << "}" << endl;
       
   373   if (!anc->file().isEmpty() && Config_getBool("PDF_HYPERLINKS")) 
       
   374   {
       
   375     m_t << "\\hypertarget{" << anc->file() << "_" << anc->anchor() 
       
   376       << "}{}" << endl;
       
   377   }    
       
   378 }
       
   379 
       
   380 void LatexDocVisitor::visit(DocInclude *inc)
       
   381 {
       
   382   if (m_hide) return;
       
   383   switch(inc->type())
       
   384   {
       
   385     case DocInclude::IncWithLines:
       
   386       { 
       
   387          m_t << "\n\\begin{DoxyCodeInclude}\n";
       
   388          QFileInfo cfi( inc->file() );
       
   389          FileDef fd( cfi.dirPath(), cfi.fileName() );
       
   390          Doxygen::parserManager->getParser(inc->extension())
       
   391                                ->parseCode(m_ci,inc->context(),
       
   392                                            inc->text().latin1(),
       
   393                                            inc->isExample(),
       
   394                                            inc->exampleFile(), &fd);
       
   395          m_t << "\\end{DoxyCodeInclude}" << endl;
       
   396       }
       
   397       break;    
       
   398     case DocInclude::Include: 
       
   399       m_t << "\n\\begin{DoxyCodeInclude}\n";
       
   400       Doxygen::parserManager->getParser(inc->extension())
       
   401                             ->parseCode(m_ci,inc->context(),
       
   402                                         inc->text().latin1(),inc->isExample(),
       
   403                                         inc->exampleFile());
       
   404       m_t << "\\end{DoxyCodeInclude}\n";
       
   405       break;
       
   406     case DocInclude::DontInclude: 
       
   407       break;
       
   408     case DocInclude::HtmlInclude: 
       
   409       break;
       
   410     case DocInclude::VerbInclude: 
       
   411       m_t << "\n\\begin{DoxyVerbInclude}\n";
       
   412       m_t << inc->text();
       
   413       m_t << "\\end{DoxyVerbInclude}\n";
       
   414       break;
       
   415   }
       
   416 }
       
   417 
       
   418 void LatexDocVisitor::visit(DocIncOperator *op)
       
   419 {
       
   420   //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
       
   421   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
       
   422   if (op->isFirst()) 
       
   423   {
       
   424     if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}\n";
       
   425     pushEnabled();
       
   426     m_hide = TRUE;
       
   427   }
       
   428   if (op->type()!=DocIncOperator::Skip) 
       
   429   {
       
   430     popEnabled();
       
   431     if (!m_hide) 
       
   432     {
       
   433       Doxygen::parserManager->getParser(m_langExt)
       
   434                             ->parseCode(m_ci,op->context(),op->text().latin1(),
       
   435                                         op->isExample(),op->exampleFile());
       
   436     }
       
   437     pushEnabled();
       
   438     m_hide=TRUE;
       
   439   }
       
   440   if (op->isLast())  
       
   441   {
       
   442     popEnabled();
       
   443     if (!m_hide) m_t << "\n\\end{DoxyCodeInclude}\n";
       
   444   }
       
   445   else
       
   446   {
       
   447     if (!m_hide) m_t << endl;
       
   448   }
       
   449 }
       
   450 
       
   451 void LatexDocVisitor::visit(DocFormula *f)
       
   452 {
       
   453   if (m_hide) return;
       
   454   m_t << f->text();
       
   455 }
       
   456 
       
   457 void LatexDocVisitor::visit(DocIndexEntry *i)
       
   458 {
       
   459   if (m_hide) return;
       
   460   m_t << "\\index{" << escapeLabelName(i->entry()) << "@{";
       
   461   escapeMakeIndexChars(i->entry());
       
   462   m_t << "}}";
       
   463 }
       
   464 
       
   465 void LatexDocVisitor::visit(DocSimpleSectSep *)
       
   466 {
       
   467 }
       
   468 
       
   469 //--------------------------------------
       
   470 // visitor functions for compound nodes
       
   471 //--------------------------------------
       
   472 
       
   473 void LatexDocVisitor::visitPre(DocAutoList *l)
       
   474 {
       
   475   if (m_hide) return;
       
   476   if (l->isEnumList())
       
   477   {
       
   478     m_t << "\n\\begin{DoxyEnumerate}";
       
   479   }
       
   480   else
       
   481   {
       
   482     m_t << "\n\\begin{DoxyItemize}";
       
   483   }
       
   484 }
       
   485 
       
   486 void LatexDocVisitor::visitPost(DocAutoList *l)
       
   487 {
       
   488   if (m_hide) return;
       
   489   if (l->isEnumList())
       
   490   {
       
   491     m_t << "\n\\end{DoxyEnumerate}";
       
   492   }
       
   493   else
       
   494   {
       
   495     m_t << "\n\\end{DoxyItemize}";
       
   496   }
       
   497 }
       
   498 
       
   499 void LatexDocVisitor::visitPre(DocAutoListItem *)
       
   500 {
       
   501   if (m_hide) return;
       
   502   m_t << "\n\\item ";
       
   503 }
       
   504 
       
   505 void LatexDocVisitor::visitPost(DocAutoListItem *) 
       
   506 {
       
   507 }
       
   508 
       
   509 void LatexDocVisitor::visitPre(DocPara *) 
       
   510 {
       
   511 }
       
   512 
       
   513 void LatexDocVisitor::visitPost(DocPara *p)
       
   514 {
       
   515   if (m_hide) return;
       
   516   if (!p->isLast() &&            // omit <p> for last paragraph
       
   517       !(p->parent() &&           // and for parameter sections
       
   518         p->parent()->kind()==DocNode::Kind_ParamSect
       
   519        )
       
   520      ) m_t << endl << endl;
       
   521 }
       
   522 
       
   523 void LatexDocVisitor::visitPre(DocRoot *)
       
   524 {
       
   525 }
       
   526 
       
   527 void LatexDocVisitor::visitPost(DocRoot *)
       
   528 {
       
   529 }
       
   530 
       
   531 void LatexDocVisitor::visitPre(DocSimpleSect *s)
       
   532 {
       
   533   if (m_hide) return;
       
   534   switch(s->type())
       
   535   {
       
   536     case DocSimpleSect::See:
       
   537       m_t << "\\begin{DoxySeeAlso}{";
       
   538       filter(theTranslator->trSeeAlso());
       
   539       break;
       
   540     case DocSimpleSect::Return:
       
   541       m_t << "\\begin{DoxyReturn}{";
       
   542       filter(theTranslator->trReturns());
       
   543       break;
       
   544     case DocSimpleSect::Author:
       
   545       m_t << "\\begin{DoxyAuthor}{";
       
   546       filter(theTranslator->trAuthor(TRUE,TRUE));
       
   547       break;
       
   548     case DocSimpleSect::Authors:
       
   549       m_t << "\\begin{DoxyAuthor}{";
       
   550       filter(theTranslator->trAuthor(TRUE,FALSE));
       
   551       break;
       
   552     case DocSimpleSect::Version:
       
   553       m_t << "\\begin{DoxyVersion}{";
       
   554       filter(theTranslator->trVersion());
       
   555       break;
       
   556     case DocSimpleSect::Since:
       
   557       m_t << "\\begin{DoxySince}{";
       
   558       filter(theTranslator->trSince());
       
   559       break;
       
   560     case DocSimpleSect::Date:
       
   561       m_t << "\\begin{DoxyDate}{";
       
   562       filter(theTranslator->trDate());
       
   563       break;
       
   564     case DocSimpleSect::Note:
       
   565       m_t << "\\begin{DoxyNote}{";
       
   566       filter(theTranslator->trNote());
       
   567       break;
       
   568     case DocSimpleSect::Warning:
       
   569       m_t << "\\begin{DoxyWarning}{";
       
   570       filter(theTranslator->trWarning());
       
   571       break;
       
   572     case DocSimpleSect::Pre:
       
   573       m_t << "\\begin{DoxyPrecond}{";
       
   574       filter(theTranslator->trPrecondition());
       
   575       break;
       
   576     case DocSimpleSect::Post:
       
   577       m_t << "\\begin{DoxyPostcond}{";
       
   578       filter(theTranslator->trPostcondition());
       
   579       break;
       
   580     case DocSimpleSect::Invar:
       
   581       m_t << "\\begin{DoxyInvariant}{";
       
   582       filter(theTranslator->trInvariant());
       
   583       break;
       
   584     case DocSimpleSect::Remark:
       
   585       m_t << "\\begin{DoxyRemark}{";
       
   586       filter(theTranslator->trRemarks());
       
   587       break;
       
   588     case DocSimpleSect::Attention:
       
   589       m_t << "\\begin{DoxyAttention}{";
       
   590       filter(theTranslator->trAttention());
       
   591       break;
       
   592     case DocSimpleSect::User:
       
   593       m_t << "\\begin{DoxyParagraph}{";
       
   594       break;
       
   595     case DocSimpleSect::Rcs: 
       
   596       m_t << "\\begin{DoxyParagraph}{";
       
   597       break;
       
   598     case DocSimpleSect::Unknown:  break;
       
   599   }
       
   600 
       
   601   // special case 1: user defined title
       
   602   if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
       
   603   {
       
   604     m_t << "}\n";
       
   605   }
       
   606   else
       
   607   {
       
   608     m_insideItem=TRUE;
       
   609   }
       
   610 }
       
   611 
       
   612 void LatexDocVisitor::visitPost(DocSimpleSect *s)
       
   613 {
       
   614   if (m_hide) return;
       
   615   switch(s->type())
       
   616   {
       
   617     case DocSimpleSect::See:
       
   618       m_t << "\n\\end{DoxySeeAlso}\n";
       
   619       break;
       
   620     case DocSimpleSect::Return:
       
   621       m_t << "\n\\end{DoxyReturn}\n";
       
   622       break;
       
   623     case DocSimpleSect::Author:
       
   624       m_t << "\n\\end{DoxyAuthor}\n";
       
   625       break;
       
   626     case DocSimpleSect::Authors:
       
   627       m_t << "\n\\end{DoxyAuthor}\n";
       
   628       break;
       
   629     case DocSimpleSect::Version:
       
   630       m_t << "\n\\end{DoxyVersion}\n";
       
   631       break;
       
   632     case DocSimpleSect::Since:
       
   633       m_t << "\n\\end{DoxySince}\n";
       
   634       break;
       
   635     case DocSimpleSect::Date:
       
   636       m_t << "\n\\end{DoxyDate}\n";
       
   637       break;
       
   638     case DocSimpleSect::Note:
       
   639       m_t << "\n\\end{DoxyNote}\n";
       
   640       break;
       
   641     case DocSimpleSect::Warning:
       
   642       m_t << "\n\\end{DoxyWarning}\n";
       
   643       break;
       
   644     case DocSimpleSect::Pre:
       
   645       m_t << "\n\\end{DoxyPrecond}\n";
       
   646       break;
       
   647     case DocSimpleSect::Post:
       
   648       m_t << "\n\\end{DoxyPostcond}\n";
       
   649       break;
       
   650     case DocSimpleSect::Invar:
       
   651       m_t << "\n\\end{DoxyInvariant}\n";
       
   652       break;
       
   653     case DocSimpleSect::Remark:
       
   654       m_t << "\n\\end{DoxyRemark}\n";
       
   655       break;
       
   656     case DocSimpleSect::Attention:
       
   657       m_t << "\n\\end{DoxyAttention}\n";
       
   658       break;
       
   659     case DocSimpleSect::User:
       
   660       m_t << "\n\\end{DoxyParagraph}\n";
       
   661       break;
       
   662     case DocSimpleSect::Rcs: 
       
   663       m_t << "\n\\end{DoxyParagraph}\n";
       
   664       break;
       
   665     default:
       
   666       break;
       
   667   }
       
   668 }
       
   669 
       
   670 void LatexDocVisitor::visitPre(DocTitle *)
       
   671 {
       
   672 }
       
   673 
       
   674 void LatexDocVisitor::visitPost(DocTitle *)
       
   675 {
       
   676   if (m_hide) return;
       
   677   m_insideItem=FALSE;
       
   678   m_t << "}\n";
       
   679 }
       
   680 
       
   681 void LatexDocVisitor::visitPre(DocSimpleList *)
       
   682 {
       
   683   if (m_hide) return;
       
   684   m_t << "\\begin{DoxyItemize}" << endl;
       
   685 }
       
   686 
       
   687 void LatexDocVisitor::visitPost(DocSimpleList *)
       
   688 {
       
   689   if (m_hide) return;
       
   690   m_t << "\\end{DoxyItemize}" << endl;
       
   691 }
       
   692 
       
   693 void LatexDocVisitor::visitPre(DocSimpleListItem *)
       
   694 {
       
   695   if (m_hide) return;
       
   696   m_t << "\\item ";
       
   697 }
       
   698 
       
   699 void LatexDocVisitor::visitPost(DocSimpleListItem *) 
       
   700 {
       
   701 }
       
   702 
       
   703 void LatexDocVisitor::visitPre(DocSection *s)
       
   704 {
       
   705   if (m_hide) return;
       
   706   if (Config_getBool("PDF_HYPERLINKS"))
       
   707   {
       
   708     m_t << "\\hypertarget{" << s->file() << "_" << s->anchor() << "}{}";
       
   709   }
       
   710   m_t << "\\" << getSectionName(s->level()) << "{";
       
   711   filter(convertCharEntitiesToUTF8(s->title().data()));
       
   712   m_t << "}\\label{" << s->file() << "_" << s->anchor() << "}" << endl;
       
   713 }
       
   714 
       
   715 void LatexDocVisitor::visitPost(DocSection *) 
       
   716 {
       
   717 }
       
   718 
       
   719 void LatexDocVisitor::visitPre(DocHtmlList *s)
       
   720 {
       
   721   if (m_hide) return;
       
   722   if (s->type()==DocHtmlList::Ordered) 
       
   723     m_t << "\n\\begin{DoxyEnumerate}";
       
   724   else 
       
   725     m_t << "\n\\begin{DoxyItemize}";
       
   726 }
       
   727 
       
   728 void LatexDocVisitor::visitPost(DocHtmlList *s) 
       
   729 {
       
   730   if (m_hide) return;
       
   731   if (s->type()==DocHtmlList::Ordered) 
       
   732     m_t << "\n\\end{DoxyEnumerate}";
       
   733   else 
       
   734     m_t << "\n\\end{DoxyItemize}";
       
   735 }
       
   736 
       
   737 void LatexDocVisitor::visitPre(DocHtmlListItem *)
       
   738 {
       
   739   if (m_hide) return;
       
   740   m_t << "\n\\item ";
       
   741 }
       
   742 
       
   743 void LatexDocVisitor::visitPost(DocHtmlListItem *) 
       
   744 {
       
   745 }
       
   746 
       
   747 //void LatexDocVisitor::visitPre(DocHtmlPre *)
       
   748 //{
       
   749 //  m_t << "\\small\\begin{alltt}";
       
   750 //  m_insidePre=TRUE;
       
   751 //}
       
   752 
       
   753 //void LatexDocVisitor::visitPost(DocHtmlPre *) 
       
   754 //{
       
   755 //  m_insidePre=FALSE;
       
   756 //  m_t << "\\end{alltt}\\normalsize " << endl;
       
   757 //}
       
   758 
       
   759 void LatexDocVisitor::visitPre(DocHtmlDescList *)
       
   760 {
       
   761   if (m_hide) return;
       
   762   m_t << "\n\\begin{DoxyDescription}";
       
   763 }
       
   764 
       
   765 void LatexDocVisitor::visitPost(DocHtmlDescList *) 
       
   766 {
       
   767   if (m_hide) return;
       
   768   m_t << "\n\\end{DoxyDescription}";
       
   769 }
       
   770 
       
   771 void LatexDocVisitor::visitPre(DocHtmlDescTitle *)
       
   772 {
       
   773   if (m_hide) return;
       
   774   m_t << "\n\\item[";
       
   775   m_insideItem=TRUE;
       
   776 }
       
   777 
       
   778 void LatexDocVisitor::visitPost(DocHtmlDescTitle *) 
       
   779 {
       
   780   if (m_hide) return;
       
   781   m_insideItem=FALSE;
       
   782   m_t << "]";
       
   783 }
       
   784 
       
   785 void LatexDocVisitor::visitPre(DocHtmlDescData *)
       
   786 {
       
   787 }
       
   788 
       
   789 void LatexDocVisitor::visitPost(DocHtmlDescData *) 
       
   790 {
       
   791 }
       
   792 
       
   793 void LatexDocVisitor::visitPre(DocHtmlTable *t)
       
   794 {
       
   795   m_rowspanIndices.clear();
       
   796   if (m_hide) return;
       
   797   if (t->hasCaption()) 
       
   798   {
       
   799     m_t << "\\begin{table}[h]";
       
   800   }
       
   801   m_t << "\\begin{TabularC}{" << t->numCols() << "}\n\\hline\n";
       
   802 }
       
   803 
       
   804 void LatexDocVisitor::visitPost(DocHtmlTable *t) 
       
   805 {
       
   806   if (m_hide) return;
       
   807   if (t->hasCaption())
       
   808   {
       
   809     m_t << "\\end{table}\n";
       
   810   }
       
   811   else
       
   812   {
       
   813     m_t << "\\end{TabularC}\n";
       
   814   }
       
   815 }
       
   816 
       
   817 void LatexDocVisitor::visitPre(DocHtmlCaption *)
       
   818 {
       
   819   if (m_hide) return;
       
   820   m_t << "\\end{TabularC}\n\\centering\n\\caption{";
       
   821 }
       
   822 
       
   823 void LatexDocVisitor::visitPost(DocHtmlCaption *) 
       
   824 {
       
   825   if (m_hide) return;
       
   826   m_t << "}\n";
       
   827 }
       
   828 
       
   829 void LatexDocVisitor::visitPre(DocHtmlRow *)
       
   830 {
       
   831   m_currentColumn = 0;
       
   832 }
       
   833 
       
   834 void LatexDocVisitor::visitPost(DocHtmlRow *) 
       
   835 {
       
   836   if (m_hide) return;
       
   837 
       
   838   m_t << "\\\\";
       
   839   
       
   840   QMap<int, int>::Iterator it;
       
   841   int col = 1;
       
   842     for (it = m_rowspanIndices.begin(); it != m_rowspanIndices.end(); ++it) 
       
   843   {
       
   844     it.data()--;
       
   845     if (it.data () <= 0)
       
   846       m_rowspanIndices.remove (it);
       
   847     else if (0 < it.data() - col)
       
   848       m_t << "\\cline{" << col << "-" << it.data() - col << "}";
       
   849       
       
   850     col = 1 + it.data ();
       
   851     }
       
   852 
       
   853   if (col <= m_currentColumn)
       
   854     m_t << "\\cline{" << col << "-" << m_currentColumn << "}";
       
   855 
       
   856   m_t << "\n";
       
   857 }
       
   858 
       
   859 void LatexDocVisitor::visitPre(DocHtmlCell *cell)
       
   860 {
       
   861   if (m_hide) return;
       
   862   
       
   863   m_currentColumn++;
       
   864   //Skip columns that span from above.
       
   865   QMap<int, int>::Iterator it = m_rowspanIndices.find(m_currentColumn);
       
   866   while (0 < it.data() && it != m_rowspanIndices.end())
       
   867   {
       
   868     m_t << "&";
       
   869     m_currentColumn++;
       
   870     it++;
       
   871   }
       
   872 
       
   873   int rs = rowspan(cell);
       
   874   if (0 < rs)
       
   875   {
       
   876     m_inRowspan = TRUE;
       
   877     m_rowspanIndices[m_currentColumn] = rs;
       
   878     m_t << "\\multirow{" << rs << "}{\\linewidth}{";
       
   879   }
       
   880 }
       
   881 
       
   882 void LatexDocVisitor::visitPost(DocHtmlCell *c) 
       
   883 {
       
   884   if (m_hide) return;
       
   885   if (m_inRowspan)
       
   886   {
       
   887     m_inRowspan = FALSE;
       
   888     m_t << "}";
       
   889   }
       
   890   if (!c->isLast()) m_t << "&";
       
   891 }
       
   892 
       
   893 void LatexDocVisitor::visitPre(DocInternal *)
       
   894 {
       
   895   if (m_hide) return;
       
   896   m_t << "\\begin{DoxyInternal}{";
       
   897   filter(theTranslator->trForInternalUseOnly());
       
   898   m_t << "}\n";
       
   899 }
       
   900 
       
   901 void LatexDocVisitor::visitPost(DocInternal *) 
       
   902 {
       
   903   if (m_hide) return;
       
   904   m_t << "\\end{DoxyInternal}" << endl;
       
   905 }
       
   906 
       
   907 void LatexDocVisitor::visitPre(DocHRef *href)
       
   908 {
       
   909   if (m_hide) return;
       
   910   if (Config_getBool("PDF_HYPERLINKS"))
       
   911   {
       
   912     m_t << "\\href{";
       
   913     m_t << href->url();
       
   914     m_t << "}";
       
   915   }
       
   916   m_t << "{\\tt ";
       
   917 }
       
   918 
       
   919 void LatexDocVisitor::visitPost(DocHRef *) 
       
   920 {
       
   921   if (m_hide) return;
       
   922   m_t << "}";
       
   923 }
       
   924 
       
   925 void LatexDocVisitor::visitPre(DocHtmlHeader *header)
       
   926 {
       
   927   if (m_hide) return;
       
   928   m_t << "\\" << getSectionName(header->level()) << "*{";
       
   929 }
       
   930 
       
   931 void LatexDocVisitor::visitPost(DocHtmlHeader *) 
       
   932 {
       
   933   if (m_hide) return;
       
   934   m_t << "}";
       
   935 }
       
   936 
       
   937 void LatexDocVisitor::visitPre(DocImage *img)
       
   938 {
       
   939   if (img->type()==DocImage::Latex)
       
   940   {
       
   941     if (m_hide) return;
       
   942     if (img->hasCaption())
       
   943     {
       
   944       m_t << "\n\\begin{DoxyImage}\n";
       
   945     }
       
   946     else
       
   947     {
       
   948       m_t << "\n\\begin{DoxyImageNoCaption}\n"
       
   949              "  \\mbox{";
       
   950     }
       
   951     QString gfxName = img->name();
       
   952     if (gfxName.right(4)==".eps" || gfxName.right(4)==".pdf")
       
   953     {
       
   954       gfxName=gfxName.left(gfxName.length()-4);
       
   955     }
       
   956     m_t << "\\includegraphics";
       
   957     if (!img->width().isEmpty())
       
   958     {
       
   959       m_t << "[width=" << img->width() << "]";
       
   960     }
       
   961     else if (!img->height().isEmpty())
       
   962     {
       
   963       m_t << "[height=" << img->height() << "]";
       
   964     }
       
   965     m_t << "{" << gfxName << "}";
       
   966     if (img->hasCaption())
       
   967     {
       
   968       m_t << "\n\\caption{";
       
   969     }
       
   970   }
       
   971   else // other format -> skip
       
   972   {
       
   973     pushEnabled();
       
   974     m_hide=TRUE;
       
   975   }
       
   976 }
       
   977 
       
   978 void LatexDocVisitor::visitPost(DocImage *img) 
       
   979 {
       
   980   if (img->type()==DocImage::Latex)
       
   981   {
       
   982     if (m_hide) return;
       
   983     m_t << "}\n"; // end mbox or caption
       
   984     if (img->hasCaption())
       
   985     {
       
   986       m_t << "\\end{DoxyImage}\n";
       
   987     }
       
   988     else{
       
   989       m_t << "\\end{DoxyImageNoCaption}\n";
       
   990     }
       
   991   }
       
   992   else // other format
       
   993   {
       
   994     popEnabled();
       
   995   }
       
   996 }
       
   997 
       
   998 void LatexDocVisitor::visitPre(DocDotFile *df)
       
   999 {
       
  1000   if (m_hide) return;
       
  1001   startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
       
  1002 }
       
  1003 
       
  1004 void LatexDocVisitor::visitPost(DocDotFile *df) 
       
  1005 {
       
  1006   if (m_hide) return;
       
  1007   endDotFile(df->hasCaption());
       
  1008 }
       
  1009 
       
  1010 void LatexDocVisitor::visitPre(DocLink *lnk)
       
  1011 {
       
  1012   if (m_hide) return;
       
  1013   startLink(lnk->ref(),lnk->file(),lnk->anchor());
       
  1014 }
       
  1015 
       
  1016 void LatexDocVisitor::visitPost(DocLink *lnk) 
       
  1017 {
       
  1018   if (m_hide) return;
       
  1019   endLink(lnk->ref(),lnk->file(),lnk->anchor());
       
  1020 }
       
  1021 
       
  1022 void LatexDocVisitor::visitPre(DocRef *ref)
       
  1023 {
       
  1024   if (m_hide) return;
       
  1025   if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
       
  1026   if (!ref->hasLinkText()) filter(ref->targetTitle());
       
  1027 }
       
  1028 
       
  1029 void LatexDocVisitor::visitPost(DocRef *ref) 
       
  1030 {
       
  1031   if (m_hide) return;
       
  1032   if (!ref->file().isEmpty()) endLink(ref->ref(),ref->file(),ref->anchor());
       
  1033 }
       
  1034 
       
  1035 void LatexDocVisitor::visitPre(DocSecRefItem *)
       
  1036 {
       
  1037   if (m_hide) return;
       
  1038   m_t << "\\item \\contentsline{section}{";
       
  1039 }
       
  1040 
       
  1041 void LatexDocVisitor::visitPost(DocSecRefItem *ref) 
       
  1042 {
       
  1043   if (m_hide) return;
       
  1044   m_t << "}{\\ref{" << ref->file() << "_" << ref->anchor() << "}}{}" << endl;
       
  1045 }
       
  1046 
       
  1047 void LatexDocVisitor::visitPre(DocSecRefList *)
       
  1048 {
       
  1049   if (m_hide) return;
       
  1050   m_t << "\\footnotesize" << endl;
       
  1051   m_t << "\\begin{multicols}{2}" << endl;
       
  1052   m_t << "\\begin{DoxyCompactList}" << endl;
       
  1053 }
       
  1054 
       
  1055 void LatexDocVisitor::visitPost(DocSecRefList *) 
       
  1056 {
       
  1057   if (m_hide) return;
       
  1058   m_t << "\\end{DoxyCompactList}" << endl;
       
  1059   m_t << "\\end{multicols}" << endl;
       
  1060   m_t << "\\normalsize" << endl;
       
  1061 }
       
  1062 
       
  1063 //void LatexDocVisitor::visitPre(DocLanguage *l)
       
  1064 //{
       
  1065 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
       
  1066 //  if (l->id().lower()!=langId.lower())
       
  1067 //  {
       
  1068 //    pushEnabled();
       
  1069 //    m_hide = TRUE;
       
  1070 //  }
       
  1071 //}
       
  1072 //
       
  1073 //void LatexDocVisitor::visitPost(DocLanguage *l) 
       
  1074 //{
       
  1075 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
       
  1076 //  if (l->id().lower()!=langId.lower())
       
  1077 //  {
       
  1078 //    popEnabled();
       
  1079 //  }
       
  1080 //}
       
  1081 
       
  1082 void LatexDocVisitor::visitPre(DocParamSect *s)
       
  1083 {
       
  1084   if (m_hide) return;
       
  1085   switch(s->type())
       
  1086   {
       
  1087     case DocParamSect::Param:
       
  1088       m_t << "\n\\begin{DoxyParams}{";
       
  1089       filter(theTranslator->trParameters());
       
  1090       break;
       
  1091     case DocParamSect::RetVal:
       
  1092       m_t << "\n\\begin{DoxyRetVals}{";
       
  1093       filter(theTranslator->trReturnValues());
       
  1094       break;
       
  1095     case DocParamSect::Exception: 
       
  1096       m_t << "\n\\begin{DoxyExceptions}{";
       
  1097       filter(theTranslator->trExceptions());
       
  1098       break;
       
  1099     case DocParamSect::TemplateParam: 
       
  1100       /* TODO: add this 
       
  1101       filter(theTranslator->trTemplateParam()); break;
       
  1102       */
       
  1103       m_t << "\n\\begin{DoxyTemplParams}{";
       
  1104       filter("Template Parameters");
       
  1105       break;
       
  1106     default:
       
  1107       ASSERT(0);
       
  1108   }
       
  1109   m_t << "}\n";
       
  1110 }
       
  1111 
       
  1112 void LatexDocVisitor::visitPost(DocParamSect *s)
       
  1113 {
       
  1114   if (m_hide) return;
       
  1115   switch(s->type())
       
  1116   {
       
  1117     case DocParamSect::Param:
       
  1118       m_t << "\\end{DoxyParams}\n";
       
  1119       break;
       
  1120     case DocParamSect::RetVal:
       
  1121       m_t << "\\end{DoxyRetVals}\n";
       
  1122       break;
       
  1123     case DocParamSect::Exception: 
       
  1124       m_t << "\\end{DoxyExceptions}\n";
       
  1125       break;
       
  1126     case DocParamSect::TemplateParam: 
       
  1127       m_t << "\\end{DoxyTemplParams}\n";
       
  1128       break;
       
  1129     default:
       
  1130       ASSERT(0);
       
  1131   }
       
  1132 }
       
  1133 
       
  1134 void LatexDocVisitor::visitPre(DocParamList *pl)
       
  1135 {
       
  1136   if (m_hide) return;
       
  1137   m_t << "\\item[";
       
  1138   if (pl->direction()!=DocParamSect::Unspecified)
       
  1139   {
       
  1140     m_t << "\\mbox{";
       
  1141     if (pl->direction()==DocParamSect::In)
       
  1142     {
       
  1143       m_t << "$\\leftarrow$";
       
  1144     }
       
  1145     else if (pl->direction()==DocParamSect::Out)
       
  1146     {
       
  1147       m_t << "$\\rightarrow$";
       
  1148     }
       
  1149     else if (pl->direction()==DocParamSect::InOut)
       
  1150     {
       
  1151       m_t << "$\\leftrightarrow$";
       
  1152     }
       
  1153     m_t << "} ";
       
  1154   }
       
  1155   m_t << "{\\em ";
       
  1156   //QStrListIterator li(pl->parameters());
       
  1157   //const char *s;
       
  1158   QListIterator<DocNode> li(pl->parameters());
       
  1159   DocNode *param;
       
  1160   bool first=TRUE;
       
  1161   for (li.toFirst();(param=li.current());++li)
       
  1162   {
       
  1163     if (!first) m_t << ","; else first=FALSE;
       
  1164     m_insideItem=TRUE;
       
  1165     if (param->kind()==DocNode::Kind_Word)
       
  1166     {
       
  1167       visit((DocWord*)param); 
       
  1168     }
       
  1169     else if (param->kind()==DocNode::Kind_LinkedWord)
       
  1170     {
       
  1171       visit((DocLinkedWord*)param); 
       
  1172     }
       
  1173     m_insideItem=FALSE;
       
  1174   }
       
  1175   m_t << "}]";
       
  1176 }
       
  1177 
       
  1178 void LatexDocVisitor::visitPost(DocParamList *)
       
  1179 {
       
  1180 }
       
  1181 
       
  1182 void LatexDocVisitor::visitPre(DocXRefItem *x)
       
  1183 {
       
  1184   if (m_hide) return;
       
  1185   m_t << "\\begin{Desc}" << endl;
       
  1186   bool anonymousEnum = x->file()=="@";
       
  1187   m_t << "\\item[";
       
  1188   if (Config_getBool("PDF_HYPERLINKS") && !anonymousEnum)
       
  1189   {
       
  1190     m_t << "\\hyperlink{" << stripPath(x->file()) << "_" << x->anchor() << "}{";
       
  1191   }
       
  1192   else
       
  1193   {
       
  1194     m_t << "{\\bf ";
       
  1195   }
       
  1196   m_insideItem=TRUE;
       
  1197   filter(x->title());
       
  1198   m_insideItem=FALSE;
       
  1199   m_t << "}]";
       
  1200 }
       
  1201 
       
  1202 void LatexDocVisitor::visitPost(DocXRefItem *)
       
  1203 {
       
  1204   if (m_hide) return;
       
  1205   m_t << "\\end{Desc}" << endl;
       
  1206 }
       
  1207 
       
  1208 void LatexDocVisitor::visitPre(DocInternalRef *ref)
       
  1209 {
       
  1210   if (m_hide) return;
       
  1211   startLink(0,ref->file(),ref->anchor());
       
  1212 }
       
  1213 
       
  1214 void LatexDocVisitor::visitPost(DocInternalRef *ref) 
       
  1215 {
       
  1216   if (m_hide) return;
       
  1217   endLink(0,ref->file(),ref->anchor());
       
  1218 }
       
  1219 
       
  1220 void LatexDocVisitor::visitPre(DocCopy *)
       
  1221 {
       
  1222 }
       
  1223 
       
  1224 void LatexDocVisitor::visitPost(DocCopy *)
       
  1225 {
       
  1226 }
       
  1227 
       
  1228 void LatexDocVisitor::visitPre(DocText *)
       
  1229 {
       
  1230 }
       
  1231 
       
  1232 void LatexDocVisitor::visitPost(DocText *)
       
  1233 {
       
  1234 }
       
  1235 
       
  1236 void LatexDocVisitor::filter(const char *str)
       
  1237 { 
       
  1238   filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem);
       
  1239 }
       
  1240 
       
  1241 void LatexDocVisitor::startLink(const QString &ref,const QString &file,const QString &anchor)
       
  1242 {
       
  1243   if (ref.isEmpty() && Config_getBool("PDF_HYPERLINKS")) // internal PDF link 
       
  1244   {
       
  1245     if (ref.isEmpty()) {
       
  1246       m_t << "\\hyperlink{";
       
  1247       if (!file.isEmpty()) m_t << stripPath(file);
       
  1248       if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
       
  1249       if (!anchor.isEmpty()) m_t << anchor;
       
  1250       m_t << "}{";
       
  1251     }
       
  1252     else
       
  1253     {
       
  1254       QCString *dest;
       
  1255       m_t << "\\href{";
       
  1256       if ((dest=Doxygen::tagDestinationDict[ref])) m_t << *dest << "/";
       
  1257       if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
       
  1258       if (!anchor.isEmpty()) m_t << "#" << anchor;
       
  1259       m_t << "}{";
       
  1260     }
       
  1261   }
       
  1262   else if (ref.isEmpty()) // internal non-PDF link
       
  1263   {
       
  1264     m_t << "\\doxyref{";
       
  1265   }
       
  1266   else // external link
       
  1267   { 
       
  1268     m_t << "{\\bf ";
       
  1269   }
       
  1270 }
       
  1271 
       
  1272 void LatexDocVisitor::endLink(const QString &ref,const QString &file,const QString &anchor)
       
  1273 {
       
  1274   m_t << "}";
       
  1275   if (ref.isEmpty() && !Config_getBool("PDF_HYPERLINKS"))
       
  1276   {
       
  1277     m_t << "{"; 
       
  1278     filter(theTranslator->trPageAbbreviation());
       
  1279     m_t << "}{" << file;
       
  1280     if (!anchor.isEmpty()) m_t << "_" << anchor;
       
  1281     m_t << "}";
       
  1282   }
       
  1283 }
       
  1284 
       
  1285 void LatexDocVisitor::pushEnabled()
       
  1286 {
       
  1287   m_enabled.push(new bool(m_hide));
       
  1288 }
       
  1289 
       
  1290 void LatexDocVisitor::popEnabled()
       
  1291 {
       
  1292   bool *v=m_enabled.pop();
       
  1293   ASSERT(v!=0);
       
  1294   m_hide = *v;
       
  1295   delete v;
       
  1296 }
       
  1297 
       
  1298 void LatexDocVisitor::startDotFile(const QString &fileName,
       
  1299                                    const QString &width,
       
  1300                                    const QString &height,
       
  1301                                    bool hasCaption
       
  1302                                   )
       
  1303 {
       
  1304   QString baseName=fileName;
       
  1305   int i;
       
  1306   if ((i=baseName.findRev('/'))!=-1)
       
  1307   {
       
  1308     baseName=baseName.right(baseName.length()-i-1);
       
  1309   } 
       
  1310   if (baseName.right(4)==".eps" || baseName.right(4)==".pdf")
       
  1311   {
       
  1312     baseName=baseName.left(baseName.length()-4);
       
  1313   }
       
  1314   if (baseName.right(4)==".dot")
       
  1315   {
       
  1316     baseName=baseName.left(baseName.length()-4);
       
  1317   }
       
  1318   QString outDir = Config_getString("LATEX_OUTPUT");
       
  1319   QString name = fileName;
       
  1320   writeDotGraphFromFile(name,outDir,baseName,EPS);
       
  1321   if (hasCaption)
       
  1322   {
       
  1323     m_t << "\n\\begin{DoxyImage}\n";
       
  1324   }
       
  1325   else
       
  1326   {
       
  1327     m_t << "\n\\begin{DoxyImageNoCaption}\n"
       
  1328            "  \\mbox{";
       
  1329   }
       
  1330   m_t << "\\includegraphics";
       
  1331   if (!width.isEmpty())
       
  1332   {
       
  1333     m_t << "[width=" << width << "]";
       
  1334   }
       
  1335   else if (!height.isEmpty())
       
  1336   {
       
  1337     m_t << "[height=" << height << "]";
       
  1338   }
       
  1339   m_t << "{" << baseName << "}";
       
  1340 
       
  1341   if (hasCaption)
       
  1342   {
       
  1343     m_t << "\n\\caption{";
       
  1344   }
       
  1345 }
       
  1346 
       
  1347 void LatexDocVisitor::endDotFile(bool hasCaption)
       
  1348 {
       
  1349   if (m_hide) return;
       
  1350   m_t << "}\n"; // end caption or mbox
       
  1351   if (hasCaption)
       
  1352   {
       
  1353     m_t << "\\end{DoxyImage}\n";
       
  1354   }
       
  1355   else
       
  1356   {
       
  1357     m_t << "\\end{DoxyImageNoCaption}\n";
       
  1358   }
       
  1359 }
       
  1360 
       
  1361 void LatexDocVisitor::writeMscFile(const QString &baseName)
       
  1362 {
       
  1363   QString outDir = Config_getString("LATEX_OUTPUT");
       
  1364   writeMscGraphFromFile(baseName,outDir,baseName,MSC_EPS);
       
  1365   m_t << "\n\\begin{DoxyImageNoCaption}"
       
  1366          "  \\mbox{\\includegraphics";
       
  1367   //if (!width.isEmpty())
       
  1368   //{
       
  1369   //  m_t << "[width=" << width << "]";
       
  1370   //}
       
  1371   //else if (!height.isEmpty())
       
  1372   //{
       
  1373   //  m_t << "[height=" << height << "]";
       
  1374   //}
       
  1375   m_t << "{" << baseName << "}";
       
  1376 
       
  1377   m_t << "}\n"; // end mbox
       
  1378   m_t << "\\end{DoxyImageNoCaption}\n";
       
  1379 }
       
  1380