latexdocvisitor.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: $
00004  *
00005  *
00006  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation under the terms of the GNU General Public License is hereby 
00010  * granted. No representations are made about the suitability of this software 
00011  * for any purpose. It is provided "as is" without express or implied warranty.
00012  * See the GNU General Public License for more details.
00013  *
00014  * Documents produced by Doxygen are derivative works derived from the
00015  * input used in their production; they are not affected by this license.
00016  *
00017  */
00018 #include <qfileinfo.h> 
00019 #include "latexdocvisitor.h"
00020 #include "docparser.h"
00021 #include "language.h"
00022 #include "doxygen.h"
00023 #include "outputgen.h"
00024 #include "dot.h"
00025 #include "util.h"
00026 #include "message.h"
00027 #include "parserintf.h"
00028 #include "msc.h"
00029 
00030 static QString escapeLabelName(const char *s)
00031 {
00032   QString result;
00033   const char *p=s;
00034   char c;
00035   while ((c=*p++))
00036   {
00037     switch (c)
00038     {
00039       case '%': result+="\\%"; break;
00040       case '|': result+="\\texttt{\"|}"; break;
00041       case '!': result+="\"!"; break;
00042       default: result+=c;
00043     }
00044   }
00045   return result;
00046 }
00047 
00048 const int maxLevels=5;
00049 static const char *secLabels[maxLevels] = 
00050    { "section","subsection","subsubsection","paragraph","subparagraph" };
00051 
00052 static const char *getSectionName(int level)
00053 {
00054   int l = level;
00055   if (Config_getBool("COMPACT_LATEX")) l++;
00056   if (Doxygen::insideMainPage) l--;
00057   return secLabels[QMIN(maxLevels-1,l)];
00058 }
00059 
00060 QString LatexDocVisitor::escapeMakeIndexChars(const char *s)
00061 {
00062   QString result;
00063   const char *p=s;
00064   char str[2]; str[1]=0;
00065   char c;
00066   while ((c=*p++))
00067   {
00068     switch (c)
00069     {
00070       case '!': m_t << "\"!"; break;
00071       case '"': m_t << "\"\""; break;
00072       case '@': m_t << "\"@"; break;
00073       case '|': m_t << "\\texttt{\"|}"; break;
00074       case '[': m_t << "["; break;
00075       case ']': m_t << "]"; break;
00076       default:  str[0]=c; filter(str); break;
00077     }
00078   }
00079   return result;
00080 }
00081 
00082 
00083 LatexDocVisitor::LatexDocVisitor(QTextStream &t,CodeOutputInterface &ci,
00084                                  const char *langExt,bool insideTabbing) 
00085   : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE), 
00086     m_insideItem(FALSE), m_hide(FALSE), m_insideTabbing(insideTabbing),
00087     m_langExt(langExt)
00088 {
00089 }
00090 
00091   //--------------------------------------
00092   // visitor functions for leaf nodes
00093   //--------------------------------------
00094 
00095 void LatexDocVisitor::visit(DocWord *w)
00096 {
00097   if (m_hide) return;
00098   filter(w->word());
00099 }
00100 
00101 void LatexDocVisitor::visit(DocLinkedWord *w)
00102 {
00103   if (m_hide) return;
00104   startLink(w->ref(),w->file(),w->anchor());
00105   filter(w->word());
00106   endLink(w->ref(),w->file(),w->anchor());
00107 }
00108 
00109 void LatexDocVisitor::visit(DocWhiteSpace *w)
00110 {
00111   if (m_hide) return;
00112   if (m_insidePre)
00113   {
00114     m_t << w->chars();
00115   }
00116   else
00117   {
00118     m_t << " ";
00119   }
00120 }
00121 
00122 void LatexDocVisitor::visit(DocSymbol *s)
00123 {
00124   if (m_hide) return;
00125   switch(s->symbol())
00126   {
00127     case DocSymbol::BSlash:  m_t << "$\\backslash$"; break;
00128     case DocSymbol::At:      m_t << "@"; break;
00129     case DocSymbol::Less:    if (m_insidePre) m_t << "<"; else m_t << "$<$"; 
00130                              break;
00131     case DocSymbol::Greater: if (m_insidePre) m_t << ">"; else m_t << "$>$"; break;
00132     case DocSymbol::Amp:     m_t << "\\&"; break;
00133     case DocSymbol::Dollar:  m_t << "\\$"; break;
00134     case DocSymbol::Hash:    m_t << "\\#"; break;
00135     case DocSymbol::Percent: m_t << "\\%"; break;
00136     case DocSymbol::Copy:    m_t << "\\copyright"; break;
00137     case DocSymbol::Tm:      m_t << "\\texttrademark"; break;
00138     case DocSymbol::Reg:     m_t << "\\textregistered"; break;
00139     case DocSymbol::Apos:    m_t << "'"; break;
00140     case DocSymbol::Quot:    m_t << "\""; break;
00141     case DocSymbol::Lsquo:   m_t << "`"; break;
00142     case DocSymbol::Rsquo:   m_t << "'"; break;
00143     case DocSymbol::Ldquo:   m_t << "``"; break;
00144     case DocSymbol::Rdquo:   m_t << "''"; break;
00145     case DocSymbol::Ndash:   m_t << "--"; break;
00146     case DocSymbol::Mdash:   m_t << "---"; break;
00147     case DocSymbol::Uml:     
00148                              if (s->letter()=='i') 
00149                                m_t << "\\\"{\\i}"; 
00150                              else                  
00151                                m_t << "\\\"{" << s->letter() << "}"; 
00152                              break;
00153     case DocSymbol::Acute:   
00154                              if (s->letter()=='i') 
00155                                m_t << "\\'{\\i}"; 
00156                              else                  
00157                                m_t << "\\'{" << s->letter() << "}"; 
00158                              break;
00159     case DocSymbol::Grave:   
00160                              if (s->letter()=='i') 
00161                                m_t << "\\`{\\i}"; 
00162                              else                  
00163                                m_t << "\\`{" << s->letter() << "}"; 
00164                              break;
00165     case DocSymbol::Circ:    
00166                              if (s->letter()=='i') 
00167                                m_t << "\\^{\\i}"; 
00168                              else                  
00169                                m_t << "\\^{" << s->letter() << "}"; 
00170                              break;
00171     case DocSymbol::Slash:   if (tolower(s->letter())=='o')
00172                                m_t << "\\" << s->letter();
00173                              else
00174                                m_t << s->letter();
00175                              break;
00176     case DocSymbol::Tilde:   m_t << "\\~{"  << s->letter() << "}"; break;
00177     case DocSymbol::Szlig:   m_t << "{\\ss}"; break;
00178     case DocSymbol::Cedil:   m_t << "\\c{" << s->letter() << "}"; break;
00179     case DocSymbol::Ring:    m_t << "\\" << s->letter() << s->letter(); break;
00180     case DocSymbol::Nbsp:    m_t << "~"; break;
00181     default:
00182                              err("Error: unknown symbol found\n");
00183   }
00184 }
00185 
00186 void LatexDocVisitor::visit(DocURL *u)
00187 {
00188   if (m_hide) return;
00189   if (Config_getBool("PDF_HYPERLINKS"))
00190   {
00191     m_t << "\\href{";
00192     if (u->isEmail()) m_t << "mailto:";
00193     m_t << u->url() << "}";
00194   }
00195   m_t << "{\\tt ";
00196   filter(u->url());
00197   m_t << "}";
00198 }
00199 
00200 void LatexDocVisitor::visit(DocLineBreak *)
00201 {
00202   if (m_hide) return;
00203   m_t << "\\par\n";
00204 }
00205 
00206 void LatexDocVisitor::visit(DocHorRuler *)
00207 {
00208   if (m_hide) return;
00209   m_t << "\n\n";
00210 }
00211 
00212 void LatexDocVisitor::visit(DocStyleChange *s)
00213 {
00214   if (m_hide) return;
00215   switch (s->style())
00216   {
00217     case DocStyleChange::Bold:
00218       if (s->enable()) m_t << "{\\bf ";      else m_t << "}";
00219       break;
00220     case DocStyleChange::Italic:
00221       if (s->enable()) m_t << "{\\em ";     else m_t << "\\/}";
00222       break;
00223     case DocStyleChange::Code:
00224       if (s->enable()) m_t << "{\\tt ";   else m_t << "}";
00225       break;
00226     case DocStyleChange::Subscript:
00227       if (s->enable()) m_t << "$_{\\mbox{";    else m_t << "}}$ ";
00228       break;
00229     case DocStyleChange::Superscript:
00230       if (s->enable()) m_t << "$^{\\mbox{";    else m_t << "}}$ ";
00231       break;
00232     case DocStyleChange::Center:
00233       if (s->enable()) m_t << "\\begin{center}"; else m_t << "\\end{center} ";
00234       break;
00235     case DocStyleChange::Small:
00236       if (s->enable()) m_t << "\n\\footnotesize ";  else m_t << "\n\\normalsize ";
00237       break;
00238     case DocStyleChange::Preformatted:
00239       if (s->enable()) 
00240       {
00241         m_t << "\\small\\begin{alltt}";
00242         m_insidePre=TRUE;
00243       }
00244       else
00245       {
00246         m_insidePre=FALSE;
00247         m_t << "\\end{alltt}\n\\normalsize " << endl;
00248       }
00249       break;
00250     case DocStyleChange::Div:  /* HTML only */ break;
00251     case DocStyleChange::Span: /* HTML only */ break;
00252   }
00253 }
00254 
00255 void LatexDocVisitor::visit(DocVerbatim *s)
00256 {
00257   if (m_hide) return;
00258   switch(s->type())
00259   {
00260     case DocVerbatim::Code: 
00261       m_t << "\n\n\\begin{Code}\\begin{verbatim}"; 
00262       Doxygen::parserManager->getParser(m_langExt)
00263                             ->parseCode(m_ci,s->context(),s->text().latin1(),
00264                                         s->isExample(),s->exampleFile());
00265       m_t << "\\end{verbatim}\n\\end{Code}\n" << endl; 
00266       break;
00267     case DocVerbatim::Verbatim: 
00268       m_t << "\n\n\\footnotesize\\begin{verbatim}"; 
00269       m_t << s->text();
00270       m_t << "\\end{verbatim}\n\\normalsize" << endl; 
00271       break;
00272     case DocVerbatim::HtmlOnly: 
00273     case DocVerbatim::XmlOnly: 
00274     case DocVerbatim::ManOnly: 
00275       /* nothing */ 
00276       break;
00277     case DocVerbatim::LatexOnly: 
00278       m_t << s->text(); 
00279       break;
00280     case DocVerbatim::Dot: 
00281       {
00282         static int dotindex = 1;
00283         QCString fileName(4096);
00284 
00285         fileName.sprintf("%s%d%s", 
00286             (Config_getString("LATEX_OUTPUT")+"/inline_dotgraph_").data(), 
00287             dotindex++,
00288             ".dot"
00289            );
00290         QFile file(fileName);
00291         if (!file.open(IO_WriteOnly))
00292         {
00293           err("Could not open file %s for writing\n",fileName.data());
00294         }
00295         file.writeBlock( s->text(), s->text().length() );
00296         file.close();
00297 
00298         m_t << "\\begin{center}\n";
00299         startDotFile(fileName,"","",FALSE);
00300         endDotFile(FALSE);
00301         m_t << "\\end{center}\n";
00302 
00303         if (Config_getBool("DOT_CLEANUP")) file.remove();
00304       }
00305       break;
00306     case DocVerbatim::Msc: 
00307       {
00308         static int mscindex = 1;
00309         QCString baseName(4096);
00310 
00311         baseName.sprintf("%s%d", 
00312             (Config_getString("LATEX_OUTPUT")+"/inline_mscgraph_").data(), 
00313             mscindex++
00314            );
00315         QFile file(baseName+".msc");
00316         if (!file.open(IO_WriteOnly))
00317         {
00318           err("Could not open file %s.msc for writing\n",baseName.data());
00319         }
00320         QCString text = "msc {";
00321         text+=s->text();
00322         text+="}";
00323         file.writeBlock( text, text.length() );
00324         file.close();
00325 
00326         m_t << "\\begin{center}\n";
00327         writeMscFile(baseName);
00328         m_t << "\\end{center}\n";
00329 
00330         if (Config_getBool("DOT_CLEANUP")) file.remove();
00331       }
00332       break;
00333   }
00334 }
00335 
00336 void LatexDocVisitor::visit(DocAnchor *anc)
00337 {
00338   if (m_hide) return;
00339   m_t << "\\label{" << anc->file() << "_" << anc->anchor() << "}" << endl;
00340   if (!anc->file().isEmpty() && Config_getBool("PDF_HYPERLINKS")) 
00341   {
00342     m_t << "\\hypertarget{" << anc->file() << "_" << anc->anchor() 
00343       << "}{}" << endl;
00344   }    
00345 }
00346 
00347 void LatexDocVisitor::visit(DocInclude *inc)
00348 {
00349   if (m_hide) return;
00350   switch(inc->type())
00351   {
00352     case DocInclude::IncWithLines:
00353       { 
00354          m_t << "\n\n\\begin{DocInclude}\\begin{verbatim}"; 
00355          QFileInfo cfi( inc->file() );
00356          FileDef fd( cfi.dirPath(), cfi.fileName() );
00357          Doxygen::parserManager->getParser(inc->extension())
00358                                ->parseCode(m_ci,inc->context(),
00359                                            inc->text().latin1(),
00360                                            inc->isExample(),
00361                                            inc->exampleFile(), &fd);
00362          m_t << "\\end{verbatim}\n\\end{DocInclude}" << endl; 
00363       }
00364       break;    
00365     case DocInclude::Include: 
00366       m_t << "\n\n\\begin{DocInclude}\\begin{verbatim}"; 
00367       Doxygen::parserManager->getParser(inc->extension())
00368                             ->parseCode(m_ci,inc->context(),
00369                                         inc->text().latin1(),inc->isExample(),
00370                                         inc->exampleFile());
00371       m_t << "\\end{verbatim}\n\\end{DocInclude}" << endl; 
00372       break;
00373     case DocInclude::DontInclude: 
00374       break;
00375     case DocInclude::HtmlInclude: 
00376       break;
00377     case DocInclude::VerbInclude: 
00378       m_t << "\n\n\\begin{VerbInclude}\\begin{verbatim}"; 
00379       m_t << inc->text();
00380       m_t << "\\end{verbatim}\n\\end{VerbInclude}" << endl; 
00381       break;
00382   }
00383 }
00384 
00385 void LatexDocVisitor::visit(DocIncOperator *op)
00386 {
00387   //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
00388   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
00389   if (op->isFirst()) 
00390   {
00391     if (!m_hide) m_t << "\n\n\\begin{DocInclude}\\begin{verbatim}"; 
00392     pushEnabled();
00393     m_hide = TRUE;
00394   }
00395   if (op->type()!=DocIncOperator::Skip) 
00396   {
00397     popEnabled();
00398     if (!m_hide) 
00399     {
00400       Doxygen::parserManager->getParser(m_langExt)
00401                             ->parseCode(m_ci,op->context(),op->text().latin1(),
00402                                         op->isExample(),op->exampleFile());
00403     }
00404     pushEnabled();
00405     m_hide=TRUE;
00406   }
00407   if (op->isLast())  
00408   {
00409     popEnabled();
00410     if (!m_hide) m_t << "\\end{verbatim}\n\\end{DocInclude}" << endl; 
00411   }
00412   else
00413   {
00414     if (!m_hide) m_t << endl;
00415   }
00416 }
00417 
00418 void LatexDocVisitor::visit(DocFormula *f)
00419 {
00420   if (m_hide) return;
00421   m_t << f->text();
00422 }
00423 
00424 void LatexDocVisitor::visit(DocIndexEntry *i)
00425 {
00426   if (m_hide) return;
00427   m_t << "\\index{" << escapeLabelName(i->entry()) << "@{";
00428   escapeMakeIndexChars(i->entry());
00429   m_t << "}}";
00430 }
00431 
00432 //--------------------------------------
00433 // visitor functions for compound nodes
00434 //--------------------------------------
00435 
00436 void LatexDocVisitor::visitPre(DocAutoList *l)
00437 {
00438   if (m_hide) return;
00439   if (l->isEnumList())
00440   {
00441     m_t << "\\begin{enumerate}" << endl;
00442   }
00443   else
00444   {
00445     m_t << "\\begin{itemize}" << endl;
00446   }
00447 }
00448 
00449 void LatexDocVisitor::visitPost(DocAutoList *l)
00450 {
00451   if (m_hide) return;
00452   if (l->isEnumList())
00453   {
00454     m_t << "\\end{enumerate}" << endl;
00455   }
00456   else
00457   {
00458     m_t << "\\end{itemize}" << endl;
00459   }
00460 }
00461 
00462 void LatexDocVisitor::visitPre(DocAutoListItem *)
00463 {
00464   if (m_hide) return;
00465   m_t << "\\item ";
00466 }
00467 
00468 void LatexDocVisitor::visitPost(DocAutoListItem *) 
00469 {
00470 }
00471 
00472 void LatexDocVisitor::visitPre(DocPara *) 
00473 {
00474 }
00475 
00476 void LatexDocVisitor::visitPost(DocPara *p)
00477 {
00478   if (m_hide) return;
00479   if (!p->isLast() &&            // omit <p> for last paragraph
00480       !(p->parent() &&           // and for parameter sections
00481         p->parent()->kind()==DocNode::Kind_ParamSect
00482        )
00483      ) m_t << endl << endl;
00484 }
00485 
00486 void LatexDocVisitor::visitPre(DocRoot *)
00487 {
00488 }
00489 
00490 void LatexDocVisitor::visitPost(DocRoot *)
00491 {
00492 }
00493 
00494 void LatexDocVisitor::visitPre(DocSimpleSect *s)
00495 {
00496   if (m_hide) return;
00497   m_t << "\\begin{Desc}\n\\item[";
00498   switch(s->type())
00499   {
00500     case DocSimpleSect::See: 
00501       filter(theTranslator->trSeeAlso()); break;
00502     case DocSimpleSect::Return: 
00503       filter(theTranslator->trReturns()); break;
00504     case DocSimpleSect::Author: 
00505       filter(theTranslator->trAuthor(TRUE,TRUE)); break;
00506     case DocSimpleSect::Authors: 
00507       filter(theTranslator->trAuthor(TRUE,FALSE)); break;
00508     case DocSimpleSect::Version: 
00509       filter(theTranslator->trVersion()); break;
00510     case DocSimpleSect::Since: 
00511       filter(theTranslator->trSince()); break;
00512     case DocSimpleSect::Date: 
00513       filter(theTranslator->trDate()); break;
00514     case DocSimpleSect::Note: 
00515       filter(theTranslator->trNote()); break;
00516     case DocSimpleSect::Warning:
00517       filter(theTranslator->trWarning()); break;
00518     case DocSimpleSect::Pre:
00519       filter(theTranslator->trPrecondition()); break;
00520     case DocSimpleSect::Post:
00521       filter(theTranslator->trPostcondition()); break;
00522     case DocSimpleSect::Invar:
00523       filter(theTranslator->trInvariant()); break;
00524     case DocSimpleSect::Remark:
00525       filter(theTranslator->trRemarks()); break;
00526     case DocSimpleSect::Attention:
00527       filter(theTranslator->trAttention()); break;
00528     case DocSimpleSect::User: break;
00529     case DocSimpleSect::Rcs: break;
00530     case DocSimpleSect::Unknown:  break;
00531   }
00532 
00533   // special case 1: user defined title
00534   if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
00535   {
00536     m_t << ":]";
00537   }
00538   else
00539   {
00540     m_insideItem=TRUE;
00541   }
00542 }
00543 
00544 void LatexDocVisitor::visitPost(DocSimpleSect *)
00545 {
00546   if (m_hide) return;
00547   m_t << "\\end{Desc}" << endl;
00548 }
00549 
00550 void LatexDocVisitor::visitPre(DocTitle *)
00551 {
00552 }
00553 
00554 void LatexDocVisitor::visitPost(DocTitle *)
00555 {
00556   if (m_hide) return;
00557   m_insideItem=FALSE;
00558   m_t << "]";
00559 }
00560 
00561 void LatexDocVisitor::visitPre(DocSimpleList *)
00562 {
00563   if (m_hide) return;
00564   m_t << "\\begin{itemize}" << endl;
00565 }
00566 
00567 void LatexDocVisitor::visitPost(DocSimpleList *)
00568 {
00569   if (m_hide) return;
00570   m_t << "\\end{itemize}" << endl;
00571 }
00572 
00573 void LatexDocVisitor::visitPre(DocSimpleListItem *)
00574 {
00575   if (m_hide) return;
00576   m_t << "\\item ";
00577 }
00578 
00579 void LatexDocVisitor::visitPost(DocSimpleListItem *) 
00580 {
00581 }
00582 
00583 void LatexDocVisitor::visitPre(DocSection *s)
00584 {
00585   if (m_hide) return;
00586   if (Config_getBool("PDF_HYPERLINKS"))
00587   {
00588     m_t << "\\hypertarget{" << s->file() << "_" << s->anchor() << "}{}";
00589   }
00590   m_t << "\\" << getSectionName(s->level()) << "{";
00591   filter(convertCharEntitiesToUTF8(s->title().data()));
00592   m_t << "}\\label{" << s->file() << "_" << s->anchor() << "}" << endl;
00593 }
00594 
00595 void LatexDocVisitor::visitPost(DocSection *) 
00596 {
00597 }
00598 
00599 void LatexDocVisitor::visitPre(DocHtmlList *s)
00600 {
00601   if (m_hide) return;
00602   if (s->type()==DocHtmlList::Ordered) 
00603     m_t << "\\begin{enumerate}" << endl; 
00604   else 
00605     m_t << "\\begin{itemize}" << endl;
00606 }
00607 
00608 void LatexDocVisitor::visitPost(DocHtmlList *s) 
00609 {
00610   if (m_hide) return;
00611   if (s->type()==DocHtmlList::Ordered) 
00612     m_t << "\\end{enumerate}" << endl; 
00613   else 
00614     m_t << "\\end{itemize}" << endl;
00615 }
00616 
00617 void LatexDocVisitor::visitPre(DocHtmlListItem *)
00618 {
00619   if (m_hide) return;
00620   m_t << "\\item ";
00621 }
00622 
00623 void LatexDocVisitor::visitPost(DocHtmlListItem *) 
00624 {
00625 }
00626 
00627 //void LatexDocVisitor::visitPre(DocHtmlPre *)
00628 //{
00629 //  m_t << "\\small\\begin{alltt}";
00630 //  m_insidePre=TRUE;
00631 //}
00632 
00633 //void LatexDocVisitor::visitPost(DocHtmlPre *) 
00634 //{
00635 //  m_insidePre=FALSE;
00636 //  m_t << "\\end{alltt}\\normalsize " << endl;
00637 //}
00638 
00639 void LatexDocVisitor::visitPre(DocHtmlDescList *)
00640 {
00641   if (m_hide) return;
00642   m_t << "\\begin{description}" << endl;
00643 }
00644 
00645 void LatexDocVisitor::visitPost(DocHtmlDescList *) 
00646 {
00647   if (m_hide) return;
00648   m_t << "\\end{description}" << endl;
00649 }
00650 
00651 void LatexDocVisitor::visitPre(DocHtmlDescTitle *)
00652 {
00653   if (m_hide) return;
00654   m_t << "\\item[";
00655   m_insideItem=TRUE;
00656 }
00657 
00658 void LatexDocVisitor::visitPost(DocHtmlDescTitle *) 
00659 {
00660   if (m_hide) return;
00661   m_insideItem=FALSE;
00662   m_t << "]";
00663 }
00664 
00665 void LatexDocVisitor::visitPre(DocHtmlDescData *)
00666 {
00667 }
00668 
00669 void LatexDocVisitor::visitPost(DocHtmlDescData *) 
00670 {
00671 }
00672 
00673 void LatexDocVisitor::visitPre(DocHtmlTable *t)
00674 {
00675   if (m_hide) return;
00676   if (t->hasCaption()) 
00677   {
00678     m_t << "\\begin{table}[h]";
00679   }
00680   m_t << "\\begin{TabularC}{" << t->numCols() << "}\n\\hline\n";
00681 }
00682 
00683 void LatexDocVisitor::visitPost(DocHtmlTable *t) 
00684 {
00685   if (m_hide) return;
00686   if (t->hasCaption())
00687   {
00688     m_t << "\\end{table}\n";
00689   }
00690   else
00691   {
00692     m_t << "\\end{TabularC}\n";
00693   }
00694 }
00695 
00696 void LatexDocVisitor::visitPre(DocHtmlCaption *)
00697 {
00698   if (m_hide) return;
00699   m_t << "\\end{TabularC}\n\\centering\n\\caption{";
00700 }
00701 
00702 void LatexDocVisitor::visitPost(DocHtmlCaption *) 
00703 {
00704   if (m_hide) return;
00705   m_t << "}\n";
00706 }
00707 
00708 void LatexDocVisitor::visitPre(DocHtmlRow *)
00709 {
00710 }
00711 
00712 void LatexDocVisitor::visitPost(DocHtmlRow *) 
00713 {
00714   if (m_hide) return;
00715   m_t << "\\\\\\hline\n";
00716 }
00717 
00718 void LatexDocVisitor::visitPre(DocHtmlCell *)
00719 {
00720 }
00721 
00722 void LatexDocVisitor::visitPost(DocHtmlCell *c) 
00723 {
00724   if (m_hide) return;
00725   if (!c->isLast()) m_t << "&";
00726 }
00727 
00728 void LatexDocVisitor::visitPre(DocInternal *)
00729 {
00730   if (m_hide) return;
00731   m_t << "\\begin{Desc}" << endl 
00732     << "\\item["; filter(theTranslator->trForInternalUseOnly()); m_t << "]" << endl;
00733 }
00734 
00735 void LatexDocVisitor::visitPost(DocInternal *) 
00736 {
00737   if (m_hide) return;
00738   m_t << "\\end{Desc}" << endl;
00739 }
00740 
00741 void LatexDocVisitor::visitPre(DocHRef *href)
00742 {
00743   if (m_hide) return;
00744   if (Config_getBool("PDF_HYPERLINKS"))
00745   {
00746     m_t << "\\href{";
00747     m_t << href->url();
00748     m_t << "}";
00749   }
00750   m_t << "{\\tt ";
00751 }
00752 
00753 void LatexDocVisitor::visitPost(DocHRef *) 
00754 {
00755   if (m_hide) return;
00756   m_t << "}";
00757 }
00758 
00759 void LatexDocVisitor::visitPre(DocHtmlHeader *header)
00760 {
00761   if (m_hide) return;
00762   m_t << "\\" << getSectionName(header->level()) << "*{";
00763 }
00764 
00765 void LatexDocVisitor::visitPost(DocHtmlHeader *) 
00766 {
00767   if (m_hide) return;
00768   m_t << "}";
00769 }
00770 
00771 void LatexDocVisitor::visitPre(DocImage *img)
00772 {
00773   if (img->type()==DocImage::Latex)
00774   {
00775     if (m_hide) return;
00776     if (img->hasCaption())
00777     {
00778       m_t << "\\begin{Image}" << endl;
00779       m_t << "\\begin{center}" << endl;
00780     }
00781     else
00782     {
00783       m_t << "\\begin{ImageNoCaption}\\mbox{";
00784     }
00785     QString gfxName = img->name();
00786     if (gfxName.right(4)==".eps" || gfxName.right(4)==".pdf")
00787     {
00788       gfxName=gfxName.left(gfxName.length()-4);
00789     }
00790     m_t << "\\includegraphics";
00791     if (!img->width().isEmpty())
00792     {
00793       m_t << "[width=" << img->width() << "]";
00794     }
00795     else if (!img->height().isEmpty())
00796     {
00797       m_t << "[height=" << img->height() << "]";
00798     }
00799     m_t << "{" << gfxName << "}";
00800     if (img->hasCaption())
00801     {
00802       m_t << "\\caption{";
00803     }
00804   }
00805   else // other format -> skip
00806   {
00807     pushEnabled();
00808     m_hide=TRUE;
00809   }
00810 }
00811 
00812 void LatexDocVisitor::visitPost(DocImage *img) 
00813 {
00814   if (img->type()==DocImage::Latex)
00815   {
00816     if (m_hide) return;
00817     m_t << "}" << endl; // end mbox or caption
00818     if (img->hasCaption())
00819     {
00820       m_t << "\\end{center}" << endl;
00821       m_t << "\\end{Image}" << endl;
00822     }
00823     else{
00824       m_t << "\\end{ImageNoCaption}" << endl;
00825     }
00826   }
00827   else // other format
00828   {
00829     popEnabled();
00830   }
00831 }
00832 
00833 void LatexDocVisitor::visitPre(DocDotFile *df)
00834 {
00835   if (m_hide) return;
00836   startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
00837 }
00838 
00839 void LatexDocVisitor::visitPost(DocDotFile *df) 
00840 {
00841   if (m_hide) return;
00842   endDotFile(df->hasCaption());
00843 }
00844 
00845 void LatexDocVisitor::visitPre(DocLink *lnk)
00846 {
00847   if (m_hide) return;
00848   startLink(lnk->ref(),lnk->file(),lnk->anchor());
00849 }
00850 
00851 void LatexDocVisitor::visitPost(DocLink *lnk) 
00852 {
00853   if (m_hide) return;
00854   endLink(lnk->ref(),lnk->file(),lnk->anchor());
00855 }
00856 
00857 void LatexDocVisitor::visitPre(DocRef *ref)
00858 {
00859   if (m_hide) return;
00860   if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
00861   if (!ref->hasLinkText()) filter(ref->targetTitle());
00862 }
00863 
00864 void LatexDocVisitor::visitPost(DocRef *ref) 
00865 {
00866   if (m_hide) return;
00867   if (!ref->file().isEmpty()) endLink(ref->ref(),ref->file(),ref->anchor());
00868 }
00869 
00870 void LatexDocVisitor::visitPre(DocSecRefItem *)
00871 {
00872   if (m_hide) return;
00873   m_t << "\\item \\contentsline{section}{";
00874 }
00875 
00876 void LatexDocVisitor::visitPost(DocSecRefItem *ref) 
00877 {
00878   if (m_hide) return;
00879   m_t << "}{\\ref{" << ref->file() << "_" << ref->anchor() << "}}{}" << endl;
00880 }
00881 
00882 void LatexDocVisitor::visitPre(DocSecRefList *)
00883 {
00884   if (m_hide) return;
00885   m_t << "\\footnotesize" << endl;
00886   m_t << "\\begin{multicols}{2}" << endl;
00887   m_t << "\\begin{CompactList}" << endl;
00888 }
00889 
00890 void LatexDocVisitor::visitPost(DocSecRefList *) 
00891 {
00892   if (m_hide) return;
00893   m_t << "\\end{CompactList}" << endl;
00894   m_t << "\\end{multicols}" << endl;
00895   m_t << "\\normalsize" << endl;
00896 }
00897 
00898 //void LatexDocVisitor::visitPre(DocLanguage *l)
00899 //{
00900 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
00901 //  if (l->id().lower()!=langId.lower())
00902 //  {
00903 //    pushEnabled();
00904 //    m_hide = TRUE;
00905 //  }
00906 //}
00907 //
00908 //void LatexDocVisitor::visitPost(DocLanguage *l) 
00909 //{
00910 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
00911 //  if (l->id().lower()!=langId.lower())
00912 //  {
00913 //    popEnabled();
00914 //  }
00915 //}
00916 
00917 void LatexDocVisitor::visitPre(DocParamSect *s)
00918 {
00919   if (m_hide) return;
00920   m_t << "\\begin{Desc}" << endl;
00921   m_t << "\\item[";
00922   switch(s->type())
00923   {
00924     case DocParamSect::Param: 
00925       filter(theTranslator->trParameters()); break;
00926     case DocParamSect::RetVal: 
00927       filter(theTranslator->trReturnValues()); break;
00928     case DocParamSect::Exception: 
00929       filter(theTranslator->trExceptions()); break;
00930     case DocParamSect::TemplateParam: 
00931       /* TODO: add this 
00932       filter(theTranslator->trTemplateParam()); break;
00933       */
00934       filter("Template Parameters"); break;
00935     default:
00936       ASSERT(0);
00937   }
00938   m_t << ":]" << endl;
00939   m_t << "\\begin{description}" << endl;
00940 }
00941 
00942 void LatexDocVisitor::visitPost(DocParamSect *)
00943 {
00944   if (m_hide) return;
00945   m_t << "\\end{description}" << endl;
00946   m_t << "\\end{Desc}" << endl;
00947 }
00948 
00949 void LatexDocVisitor::visitPre(DocParamList *pl)
00950 {
00951   if (m_hide) return;
00952   m_t << "\\item[";
00953   if (pl->direction()!=DocParamSect::Unspecified)
00954   {
00955     m_t << "\\mbox{";
00956     if (pl->direction()==DocParamSect::In)
00957     {
00958       m_t << "$\\leftarrow$";
00959     }
00960     else if (pl->direction()==DocParamSect::Out)
00961     {
00962       m_t << "$\\rightarrow$";
00963     }
00964     else if (pl->direction()==DocParamSect::InOut)
00965     {
00966       m_t << "$\\leftrightarrow$";
00967     }
00968     m_t << "} ";
00969   }
00970   m_t << "{\\em ";
00971   //QStrListIterator li(pl->parameters());
00972   //const char *s;
00973   QListIterator<DocNode> li(pl->parameters());
00974   DocNode *param;
00975   bool first=TRUE;
00976   for (li.toFirst();(param=li.current());++li)
00977   {
00978     if (!first) m_t << ","; else first=FALSE;
00979     m_insideItem=TRUE;
00980     if (param->kind()==DocNode::Kind_Word)
00981     {
00982       visit((DocWord*)param); 
00983     }
00984     else if (param->kind()==DocNode::Kind_LinkedWord)
00985     {
00986       visit((DocLinkedWord*)param); 
00987     }
00988     m_insideItem=FALSE;
00989   }
00990   m_t << "}]";
00991 }
00992 
00993 void LatexDocVisitor::visitPost(DocParamList *)
00994 {
00995 }
00996 
00997 void LatexDocVisitor::visitPre(DocXRefItem *x)
00998 {
00999   if (m_hide) return;
01000   m_t << "\\begin{Desc}" << endl;
01001   bool anonymousEnum = x->file()=="@";
01002   m_t << "\\item[";
01003   if (Config_getBool("PDF_HYPERLINKS") && !anonymousEnum)
01004   {
01005     m_t << "\\hyperlink{" << stripPath(x->file()) << "_" << x->anchor() << "}{";
01006   }
01007   else
01008   {
01009     m_t << "{\\bf ";
01010   }
01011   m_insideItem=TRUE;
01012   filter(x->title());
01013   m_insideItem=FALSE;
01014   m_t << "}]";
01015 }
01016 
01017 void LatexDocVisitor::visitPost(DocXRefItem *)
01018 {
01019   if (m_hide) return;
01020   m_t << "\\end{Desc}" << endl;
01021 }
01022 
01023 void LatexDocVisitor::visitPre(DocInternalRef *ref)
01024 {
01025   if (m_hide) return;
01026   startLink(0,ref->file(),ref->anchor());
01027 }
01028 
01029 void LatexDocVisitor::visitPost(DocInternalRef *ref) 
01030 {
01031   if (m_hide) return;
01032   endLink(0,ref->file(),ref->anchor());
01033 }
01034 
01035 void LatexDocVisitor::visitPre(DocCopy *)
01036 {
01037 }
01038 
01039 void LatexDocVisitor::visitPost(DocCopy *)
01040 {
01041 }
01042 
01043 void LatexDocVisitor::visitPre(DocText *)
01044 {
01045 }
01046 
01047 void LatexDocVisitor::visitPost(DocText *)
01048 {
01049 }
01050 
01051 void LatexDocVisitor::filter(const char *str)
01052 { 
01053   filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem);
01054 }
01055 
01056 void LatexDocVisitor::startLink(const QString &ref,const QString &file,const QString &anchor)
01057 {
01058   if (ref.isEmpty() && Config_getBool("PDF_HYPERLINKS")) // internal PDF link 
01059   {
01060     if (ref.isEmpty()) {
01061       m_t << "\\hyperlink{";
01062       if (!file.isEmpty()) m_t << stripPath(file);
01063       if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
01064       if (!anchor.isEmpty()) m_t << anchor;
01065       m_t << "}{";
01066     }
01067     else
01068     {
01069       QCString *dest;
01070       m_t << "\\href{";
01071       if ((dest=Doxygen::tagDestinationDict[ref])) m_t << *dest << "/";
01072       if (!file.isEmpty()) m_t << file << Doxygen::htmlFileExtension;
01073       if (!anchor.isEmpty()) m_t << "#" << anchor;
01074       m_t << "}{";
01075     }
01076   }
01077   else if (ref.isEmpty()) // internal non-PDF link
01078   {
01079     m_t << "\\doxyref{";
01080   }
01081   else // external link
01082   { 
01083     m_t << "{\\bf ";
01084   }
01085 }
01086 
01087 void LatexDocVisitor::endLink(const QString &ref,const QString &file,const QString &anchor)
01088 {
01089   m_t << "}";
01090   if (ref.isEmpty() && !Config_getBool("PDF_HYPERLINKS"))
01091   {
01092     m_t << "{"; 
01093     filter(theTranslator->trPageAbbreviation());
01094     m_t << "}{" << file;
01095     if (!anchor.isEmpty()) m_t << "_" << anchor;
01096     m_t << "}";
01097   }
01098 }
01099 
01100 void LatexDocVisitor::pushEnabled()
01101 {
01102   m_enabled.push(new bool(m_hide));
01103 }
01104 
01105 void LatexDocVisitor::popEnabled()
01106 {
01107   bool *v=m_enabled.pop();
01108   ASSERT(v!=0);
01109   m_hide = *v;
01110   delete v;
01111 }
01112 
01113 void LatexDocVisitor::startDotFile(const QString &fileName,
01114                                    const QString &width,
01115                                    const QString &height,
01116                                    bool hasCaption
01117                                   )
01118 {
01119   QString baseName=fileName;
01120   int i;
01121   if ((i=baseName.findRev('/'))!=-1)
01122   {
01123     baseName=baseName.right(baseName.length()-i-1);
01124   } 
01125   if (baseName.right(4)==".eps" || baseName.right(4)==".pdf")
01126   {
01127     baseName=baseName.left(baseName.length()-4);
01128   }
01129   if (baseName.right(4)==".dot")
01130   {
01131     baseName=baseName.left(baseName.length()-4);
01132   }
01133   QString outDir = Config_getString("LATEX_OUTPUT");
01134   QString name = fileName;
01135   writeDotGraphFromFile(name,outDir,baseName,EPS);
01136   if (hasCaption)
01137   {
01138     m_t << "\\begin{Image}" << endl;
01139     m_t << "\\begin{center}" << endl;
01140   }
01141   else
01142   {
01143     m_t << "\\begin{ImageNoCaption}\\mbox{";
01144   }
01145   m_t << "\\includegraphics";
01146   if (!width.isEmpty())
01147   {
01148     m_t << "[width=" << width << "]";
01149   }
01150   else if (!height.isEmpty())
01151   {
01152     m_t << "[height=" << height << "]";
01153   }
01154   m_t << "{" << baseName << "}";
01155 
01156   if (hasCaption)
01157   {
01158     m_t << "\\caption{";
01159   }
01160 }
01161 
01162 void LatexDocVisitor::endDotFile(bool hasCaption)
01163 {
01164   if (m_hide) return;
01165   m_t << "}" << endl; // end caption or mbox
01166   if (hasCaption)
01167   {
01168     m_t << "\\end{center}" << endl;
01169     m_t << "\\end{Image}" << endl;
01170   }
01171   else
01172   {
01173     m_t << "\\end{ImageNoCaption}" << endl;
01174   }
01175 }
01176 
01177 void LatexDocVisitor::writeMscFile(const QString &baseName)
01178 {
01179   QString outDir = Config_getString("LATEX_OUTPUT");
01180   writeMscGraphFromFile(baseName,outDir,baseName,MSC_EPS);
01181   m_t << "\\begin{ImageNoCaption}\\mbox{";
01182   m_t << "\\includegraphics";
01183   //if (!width.isEmpty())
01184   //{
01185   //  m_t << "[width=" << width << "]";
01186   //}
01187   //else if (!height.isEmpty())
01188   //{
01189   //  m_t << "[height=" << height << "]";
01190   //}
01191   m_t << "{" << baseName << "}";
01192 
01193   m_t << "}" << endl; // end mbox
01194   m_t << "\\end{ImageNoCaption}" << endl;
01195 }
01196 



Generated on Mon Mar 31 10:58:39 2008 by  doxygen 1.5.1