Imported Upstream version 1.8.8
[platform/upstream/doxygen.git] / src / docbookvisitor.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  *
6  * Copyright (C) 1997-2014 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
19 #include <qfileinfo.h>
20
21 #include "docbookvisitor.h"
22 #include "docparser.h"
23 #include "language.h"
24 #include "doxygen.h"
25 #include "outputgen.h"
26 #include "docbookgen.h"
27 #include "dot.h"
28 #include "message.h"
29 #include "util.h"
30 #include "parserintf.h"
31 #include "filename.h"
32 #include "config.h"
33 #include "filedef.h"
34 #include "msc.h"
35 #include "dia.h"
36 #include "htmlentity.h"
37 #include "plantuml.h"
38
39 DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci)
40   : DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
41 {
42 }
43
44 //--------------------------------------
45 // visitor functions for leaf nodes
46 //--------------------------------------
47
48 void DocbookDocVisitor::visit(DocWord *w)
49 {
50   if (m_hide) return;
51   filter(w->word());
52 }
53
54 void DocbookDocVisitor::visit(DocLinkedWord *w)
55 {
56   if (m_hide) return;
57   startLink(w->file(),w->anchor());
58   filter(w->word());
59   endLink();
60 }
61
62 void DocbookDocVisitor::visit(DocWhiteSpace *w)
63 {
64   if (m_hide) return;
65   if (m_insidePre)
66   {
67     m_t << w->chars();
68   }
69   else
70   {
71     m_t << " ";
72   }
73 }
74
75 void DocbookDocVisitor::visit(DocSymbol *s)
76 {
77   if (m_hide) return;
78   const char *res = HtmlEntityMapper::instance()->docbook(s->symbol());
79   if (res)
80   {
81     m_t << res;
82   }
83   else
84   {
85     err("DocBook: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
86   }
87 }
88
89 void DocbookDocVisitor::visit(DocURL *u)
90 {
91   if (m_hide) return;
92   m_t << "<link xlink:href=\"";
93   if (u->isEmail()) m_t << "mailto:";
94   filter(u->url());
95   m_t << "\">";
96   filter(u->url());
97   m_t << "</link>";
98 }
99
100 void DocbookDocVisitor::visit(DocLineBreak *)
101 {
102   if (m_hide) return;
103   m_t << endl << "<literallayout>\n</literallayout>" << endl;
104 }
105
106 void DocbookDocVisitor::visit(DocHorRuler *)
107 {
108   if (m_hide) return;
109   m_t << "<informaltable frame='bottom'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>\n";
110   m_t << "</entry></row></tbody></tgroup></informaltable>\n";
111 }
112
113 void DocbookDocVisitor::visit(DocStyleChange *s)
114 {
115   if (m_hide) return;
116   switch (s->style())
117   {
118     case DocStyleChange::Bold:
119       if (s->enable()) m_t << "<emphasis role=\"bold\">";      else m_t << "</emphasis>";
120       break;
121     case DocStyleChange::Italic:
122       if (s->enable()) m_t << "<emphasis>";     else m_t << "</emphasis>";
123       break;
124     case DocStyleChange::Code:
125       if (s->enable()) m_t << "<computeroutput>";   else m_t << "</computeroutput>";
126       break;
127     case DocStyleChange::Subscript:
128       if (s->enable()) m_t << "<subscript>";    else m_t << "</subscript>";
129       break;
130     case DocStyleChange::Superscript:
131       if (s->enable()) m_t << "<superscript>";    else m_t << "</superscript>";
132       break;
133     case DocStyleChange::Center:
134       if (s->enable()) m_t << "<informaltable frame='none'><tgroup cols='1'><colspec align='center'/><tbody><row><entry align='center'>";
135       else m_t << "</entry></row></tbody></tgroup></informaltable>";
136       break;
137     case DocStyleChange::Preformatted:
138       if (s->enable())
139       {
140         m_t << "<literallayout>";
141         m_insidePre=TRUE;
142       }
143       else
144       {
145         m_t << "</literallayout>";
146         m_insidePre=FALSE;
147       }
148       break;
149       /* There is no equivalent Docbook tag for rendering Small text */
150     case DocStyleChange::Small: /* XSLT Stylesheets can be used */ break;
151                                                                    /* HTML only */
152     case DocStyleChange::Div:  /* HTML only */ break;
153     case DocStyleChange::Span: /* HTML only */ break;
154   }
155 }
156
157 void DocbookDocVisitor::visit(DocVerbatim *s)
158 {
159   if (m_hide) return;
160   SrcLangExt langExt = getLanguageFromFileName(m_langExt);
161   switch(s->type())
162   {
163     case DocVerbatim::Code: // fall though
164       m_t << "<literallayout><computeroutput>";
165       Doxygen::parserManager->getParser(m_langExt)
166         ->parseCode(m_ci,s->context(),s->text(),langExt,
167             s->isExample(),s->exampleFile());
168       m_t << "</computeroutput></literallayout>";
169       break;
170     case DocVerbatim::Verbatim:
171       m_t << "<literallayout>";
172       filter(s->text());
173       m_t << "</literallayout>";
174       break;
175     case DocVerbatim::HtmlOnly:    
176       break;
177     case DocVerbatim::RtfOnly:     
178       break;
179     case DocVerbatim::ManOnly:     
180       break;
181     case DocVerbatim::LatexOnly:   
182       break;
183     case DocVerbatim::XmlOnly:     
184       break;
185     case DocVerbatim::DocbookOnly: 
186       break;
187       m_t << s->text();
188       break;
189     case DocVerbatim::Dot:
190       {
191         static int dotindex = 1;
192         QCString baseName(4096);
193         QCString name;
194         QCString stext = s->text();
195         m_t << "<para>" << endl;
196         name.sprintf("%s%d", "dot_inline_dotgraph_", dotindex);
197         baseName.sprintf("%s%d",
198             (Config_getString("DOCBOOK_OUTPUT")+"/inline_dotgraph_").data(),
199             dotindex++
200             );
201         QFile file(baseName+".dot");
202         if (!file.open(IO_WriteOnly))
203         {
204           err("Could not open file %s.msc for writing\n",baseName.data());
205         }
206         file.writeBlock( stext, stext.length() );
207         file.close();
208         m_t << "    <figure>" << endl;
209         m_t << "        <title>" << name << "</title>" << endl;
210         m_t << "        <mediaobject>" << endl;
211         m_t << "            <imageobject>" << endl;
212         writeDotFile(baseName);
213         m_t << "            </imageobject>" << endl;
214         m_t << "       </mediaobject>" << endl;
215         m_t << "    </figure>" << endl;
216         m_t << "</para>" << endl;
217       }
218       break;
219     case DocVerbatim::Msc:
220       {
221         static int mscindex = 1;
222         QCString baseName(4096);
223         QCString name;
224         QCString stext = s->text();
225         m_t << "<para>" << endl;
226         name.sprintf("%s%d", "msc_inline_mscgraph_", mscindex);
227         baseName.sprintf("%s%d",
228             (Config_getString("DOCBOOK_OUTPUT")+"/inline_mscgraph_").data(),
229             mscindex++
230             );
231         QFile file(baseName+".msc");
232         if (!file.open(IO_WriteOnly))
233         {
234           err("Could not open file %s.msc for writing\n",baseName.data());
235         }
236         QCString text = "msc {";
237         text+=stext;
238         text+="}";
239         file.writeBlock( text, text.length() );
240         file.close();
241         m_t << "    <figure>" << endl;
242         m_t << "        <title>" << name << "</title>" << endl;
243         m_t << "        <mediaobject>" << endl;
244         m_t << "            <imageobject>" << endl;
245         writeMscFile(baseName);
246         m_t << "            </imageobject>" << endl;
247         m_t << "       </mediaobject>" << endl;
248         m_t << "    </figure>" << endl;
249         m_t << "</para>" << endl;
250       }
251       break;
252     case DocVerbatim::PlantUML:
253       {
254         static QCString docbookOutput = Config_getString("DOCBOOK_OUTPUT");
255         QCString baseName = writePlantUMLSource(docbookOutput,s->exampleFile(),s->text());
256         QCString shortName = baseName;
257         int i;
258         if ((i=shortName.findRev('/'))!=-1)
259         {
260           shortName=shortName.right(shortName.length()-i-1);
261         }
262         m_t << "    <figure>" << endl;
263         m_t << "        <title>" << shortName << "</title>" << endl;
264         m_t << "        <mediaobject>" << endl;
265         m_t << "            <imageobject>" << endl;
266         writePlantUMLFile(baseName);
267         m_t << "            </imageobject>" << endl;
268         m_t << "       </mediaobject>" << endl;
269         m_t << "    </figure>" << endl;
270         m_t << "</para>" << endl;
271       }
272       break;
273   }
274 }
275
276 void DocbookDocVisitor::visit(DocAnchor *anc)
277 {
278   if (m_hide) return;
279   m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
280 }
281
282 void DocbookDocVisitor::visit(DocInclude *inc)
283 {
284   if (m_hide) return;
285   SrcLangExt langExt = getLanguageFromFileName(inc->extension());
286   switch(inc->type())
287   {
288     case DocInclude::IncWithLines:
289       {
290         m_t << "<literallayout><computeroutput>";
291         QFileInfo cfi( inc->file() );
292         FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
293         Doxygen::parserManager->getParser(inc->extension())
294           ->parseCode(m_ci,inc->context(),
295               inc->text(),
296               langExt,
297               inc->isExample(),
298               inc->exampleFile(), &fd);
299         m_t << "</computeroutput></literallayout>";
300       }
301       break;
302     case DocInclude::Include:
303       m_t << "<literallayout><computeroutput>";
304       Doxygen::parserManager->getParser(inc->extension())
305         ->parseCode(m_ci,inc->context(),
306             inc->text(),
307             langExt,
308             inc->isExample(),
309             inc->exampleFile());
310       m_t << "</computeroutput></literallayout>";
311       break;
312     case DocInclude::DontInclude:
313       break;
314     case DocInclude::HtmlInclude:
315       break;
316     case DocInclude::LatexInclude:
317       break;
318     case DocInclude::VerbInclude:
319       m_t << "<verbatim>";
320       filter(inc->text());
321       m_t << "</verbatim>";
322       break;
323     case DocInclude::Snippet:
324       m_t << "<literallayout><computeroutput>";
325       Doxygen::parserManager->getParser(inc->extension())
326         ->parseCode(m_ci,
327             inc->context(),
328             extractBlock(inc->text(),inc->blockId()),
329             langExt,
330             inc->isExample(),
331             inc->exampleFile()
332             );
333       m_t << "</computeroutput></literallayout>";
334       break;
335   }
336 }
337
338 void DocbookDocVisitor::visit(DocIncOperator *op)
339 {
340   if (op->isFirst())
341   {
342     if (!m_hide)
343     {
344       m_t << "<programlisting>";
345     }
346     pushEnabled();
347     m_hide = TRUE;
348   }
349   SrcLangExt langExt = getLanguageFromFileName(m_langExt);
350   if (op->type()!=DocIncOperator::Skip)
351   {
352     popEnabled();
353     if (!m_hide)
354     {
355       Doxygen::parserManager->getParser(m_langExt)
356         ->parseCode(m_ci,op->context(),
357             op->text(),langExt,op->isExample(),
358             op->exampleFile());
359     }
360     pushEnabled();
361     m_hide=TRUE;
362   }
363   if (op->isLast())
364   {
365     popEnabled();
366     if (!m_hide) m_t << "</programlisting>";
367   }
368   else
369   {
370     if (!m_hide) m_t << endl;
371   }
372 }
373
374 void DocbookDocVisitor::visit(DocFormula *f)
375 {
376   if (m_hide) return;
377   m_t << "<equation><title>" << f->name() << "</title>";
378   filter(f->text());
379   m_t << "</equation>";
380 }
381
382 void DocbookDocVisitor::visit(DocIndexEntry *ie)
383 {
384   if (m_hide) return;
385   m_t << "<indexentry><primaryie>" << endl;
386   filter(ie->entry());
387   m_t << "</primaryie><secondaryie></secondaryie></indexentry>" << endl;
388 }
389
390 void DocbookDocVisitor::visit(DocSimpleSectSep *)
391 {
392   m_t << "<simplesect/>";
393 }
394
395 void DocbookDocVisitor::visit(DocCite *cite)
396 {
397   if (m_hide) return;
398   if (!cite->file().isEmpty()) startLink(cite->file(),cite->anchor());
399   filter(cite->text());
400   if (!cite->file().isEmpty()) endLink();
401 }
402
403 //--------------------------------------
404 // visitor functions for compound nodes
405 //--------------------------------------
406
407 void DocbookDocVisitor::visitPre(DocAutoList *l)
408 {
409   if (m_hide) return;
410   if (l->isEnumList())
411   {
412     m_t << "<orderedlist>\n";
413   }
414   else
415   {
416     m_t << "<itemizedlist>\n";
417   }
418 }
419
420 void DocbookDocVisitor::visitPost(DocAutoList *l)
421 {
422   if (m_hide) return;
423   if (l->isEnumList())
424   {
425     m_t << "</orderedlist>\n";
426   }
427   else
428   {
429     m_t << "</itemizedlist>\n";
430   }
431 }
432
433 void DocbookDocVisitor::visitPre(DocAutoListItem *)
434 {
435   if (m_hide) return;
436   m_t << "<listitem>";
437 }
438
439 void DocbookDocVisitor::visitPost(DocAutoListItem *)
440 {
441   if (m_hide) return;
442   m_t << "</listitem>";
443 }
444
445 void DocbookDocVisitor::visitPre(DocPara *)
446 {
447   if (m_hide) return;
448   m_t << endl;
449   m_t << "<para>";
450 }
451
452 void DocbookDocVisitor::visitPost(DocPara *)
453 {
454   if (m_hide) return;
455   m_t << "</para>";
456   m_t << endl;
457 }
458
459 void DocbookDocVisitor::visitPre(DocRoot *)
460 {
461   //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
462 }
463
464 void DocbookDocVisitor::visitPost(DocRoot *)
465 {
466   //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
467 }
468
469 void DocbookDocVisitor::visitPre(DocSimpleSect *s)
470 {
471   if (m_hide) return;
472   switch(s->type())
473   {
474     case DocSimpleSect::See:
475       if (m_insidePre) 
476       {
477         m_t << "<formalpara><title>" << theTranslator->trSeeAlso() << ": </title>" << endl;
478       } 
479       else 
480       {
481         m_t << "<formalpara><title>" << convertToXML(theTranslator->trSeeAlso()) << ": </title>" << endl;
482       }
483       break;
484     case DocSimpleSect::Return:
485       if (m_insidePre) 
486       {
487         m_t << "<formalpara><title>" << theTranslator->trReturns()<< ": </title>" << endl;
488       } 
489       else 
490       {
491         m_t << "<formalpara><title>" << convertToXML(theTranslator->trReturns()) << ": </title>" << endl;
492       }
493       break;
494     case DocSimpleSect::Author:
495       if (m_insidePre) 
496       {
497         m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, TRUE) << ": </title>" << endl;
498       } 
499       else 
500       {
501         m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, TRUE)) << ": </title>" << endl;
502       }
503       break;
504     case DocSimpleSect::Authors:
505       if (m_insidePre) 
506       {
507         m_t << "<formalpara><title>" << theTranslator->trAuthor(TRUE, FALSE) << ": </title>" << endl;
508       } 
509       else 
510       {
511         m_t << "<formalpara><title>" << convertToXML(theTranslator->trAuthor(TRUE, FALSE)) << ": </title>" << endl;
512       }
513       break;
514     case DocSimpleSect::Version:
515       if (m_insidePre) 
516       {
517         m_t << "<formalpara><title>" << theTranslator->trVersion() << ": </title>" << endl;
518       } 
519       else 
520       {
521         m_t << "<formalpara><title>" << convertToXML(theTranslator->trVersion()) << ": </title>" << endl;
522       }
523       break;
524     case DocSimpleSect::Since:
525       if (m_insidePre) 
526       {
527         m_t << "<formalpara><title>" << theTranslator->trSince() << ": </title>" << endl;
528       } 
529       else 
530       {
531         m_t << "<formalpara><title>" << convertToXML(theTranslator->trSince()) << ": </title>" << endl;
532       }
533       break;
534     case DocSimpleSect::Date:
535       if (m_insidePre) 
536       {
537         m_t << "<formalpara><title>" << theTranslator->trDate() << ": </title>" << endl;
538       } 
539       else 
540       {
541         m_t << "<formalpara><title>" << convertToXML(theTranslator->trDate()) << ": </title>" << endl;
542       }
543       break;
544     case DocSimpleSect::Note:
545       if (m_insidePre) 
546       {
547         m_t << "<formalpara><title>" << theTranslator->trNote() << ": </title>" << endl;
548       } 
549       else 
550       {
551         m_t << "<formalpara><title>" << convertToXML(theTranslator->trNote()) << ": </title>" << endl;
552       }
553       break;
554     case DocSimpleSect::Warning:
555       if (m_insidePre) 
556       {
557         m_t << "<formalpara><title>" << theTranslator->trWarning() << ": </title>" << endl;
558       } 
559       else 
560       {
561         m_t << "<formalpara><title>" << convertToXML(theTranslator->trWarning()) << ": </title>" << endl;
562       }
563       break;
564     case DocSimpleSect::Pre:
565       if (m_insidePre) 
566       {
567         m_t << "<formalpara><title>" << theTranslator->trPrecondition() << ": </title>" << endl;
568       } 
569       else 
570       {
571         m_t << "<formalpara><title>" << convertToXML(theTranslator->trPrecondition()) << ": </title>" << endl;
572       }
573       break;
574     case DocSimpleSect::Post:
575       if (m_insidePre) 
576       {
577         m_t << "<formalpara><title>" << theTranslator->trPostcondition() << ": </title>" << endl;
578       } 
579       else 
580       {
581         m_t << "<formalpara><title>" << convertToXML(theTranslator->trPostcondition()) << ": </title>" << endl;
582       }
583       break;
584     case DocSimpleSect::Copyright:
585       if (m_insidePre) 
586       {
587         m_t << "<formalpara><title>" << theTranslator->trCopyright() << ": </title>" << endl;
588       } 
589       else 
590       {
591         m_t << "<formalpara><title>" << convertToXML(theTranslator->trCopyright()) << ": </title>" << endl;
592       }
593       break;
594     case DocSimpleSect::Invar:
595       if (m_insidePre) 
596       {
597         m_t << "<formalpara><title>" << theTranslator->trInvariant() << ": </title>" << endl;
598       } 
599       else 
600       {
601         m_t << "<formalpara><title>" << convertToXML(theTranslator->trInvariant()) << ": </title>" << endl;
602       }
603       break;
604     case DocSimpleSect::Remark:
605       if (m_insidePre) 
606       {
607         m_t << "<formalpara><title>" << theTranslator->trRemarks() << ": </title>" << endl;
608       } 
609       else 
610       {
611         m_t << "<formalpara><title>" << convertToXML(theTranslator->trRemarks()) << ": </title>" << endl;
612       }
613       break;
614     case DocSimpleSect::Attention:
615       if (m_insidePre) 
616       {
617         m_t << "<formalpara><title>" << theTranslator->trAttention() << ": </title>" << endl;
618       } 
619       else 
620       {
621         m_t << "<formalpara><title>" << convertToXML(theTranslator->trAttention()) << ": </title>" << endl;
622       }
623       break;
624     case DocSimpleSect::User:
625       m_t << "<formalpara><title></title>" << endl;
626       break;
627     case DocSimpleSect::Rcs:
628       m_t << "<formalpara><title></title>" << endl;
629       break;
630     case DocSimpleSect::Unknown: m_t << "<formalpara><title></title>" << endl; break;
631   }
632 }
633
634 void DocbookDocVisitor::visitPost(DocSimpleSect *)
635 {
636   if (m_hide) return;
637   m_t << "</formalpara>" << endl;
638 }
639
640 void DocbookDocVisitor::visitPre(DocTitle *)
641 {
642   if (m_hide) return;
643   m_t << "<title>";
644 }
645
646 void DocbookDocVisitor::visitPost(DocTitle *)
647 {
648   if (m_hide) return;
649   m_t << "</title>";
650 }
651
652 void DocbookDocVisitor::visitPre(DocSimpleList *)
653 {
654   if (m_hide) return;
655   m_t << "<itemizedlist>\n";
656 }
657
658 void DocbookDocVisitor::visitPost(DocSimpleList *)
659 {
660   if (m_hide) return;
661   m_t << "</itemizedlist>\n";
662 }
663
664 void DocbookDocVisitor::visitPre(DocSimpleListItem *)
665 {
666   if (m_hide) return;
667   m_t << "<listitem>";
668 }
669
670 void DocbookDocVisitor::visitPost(DocSimpleListItem *)
671 {
672   if (m_hide) return;
673   m_t << "</listitem>\n";
674 }
675
676 void DocbookDocVisitor::visitPre(DocSection *s)
677 {
678   if (m_hide) return;
679   m_t << "<section xml:id=\"" << s->file();
680   if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor();
681   m_t << "\">" << endl;
682   m_t << "<title>";
683   filter(s->title());
684   m_t << "</title>" << endl;
685 }
686
687 void DocbookDocVisitor::visitPost(DocSection *)
688 {
689   m_t << "</section>\n";
690 }
691
692 void DocbookDocVisitor::visitPre(DocHtmlList *s)
693 {
694   if (m_hide) return;
695   if (s->type()==DocHtmlList::Ordered)
696     m_t << "<orderedlist>\n";
697   else
698     m_t << "<itemizedlist>\n";
699 }
700
701 void DocbookDocVisitor::visitPost(DocHtmlList *s)
702 {
703   if (m_hide) return;
704   if (s->type()==DocHtmlList::Ordered)
705     m_t << "</orderedlist>\n";
706   else
707     m_t << "</itemizedlist>\n";
708 }
709
710 void DocbookDocVisitor::visitPre(DocHtmlListItem *)
711 {
712   if (m_hide) return;
713   m_t << "<listitem>\n";
714 }
715
716 void DocbookDocVisitor::visitPost(DocHtmlListItem *)
717 {
718   if (m_hide) return;
719   m_t << "</listitem>\n";
720 }
721
722 void DocbookDocVisitor::visitPre(DocHtmlDescList *)
723 {
724   if (m_hide) return;
725   m_t << "<variablelist>\n";
726 }
727
728 void DocbookDocVisitor::visitPost(DocHtmlDescList *)
729 {
730   if (m_hide) return;
731   m_t << "</variablelist>\n";
732 }
733
734 void DocbookDocVisitor::visitPre(DocHtmlDescTitle *)
735 {
736   if (m_hide) return;
737   m_t << "<varlistentry><term>";
738 }
739
740 void DocbookDocVisitor::visitPost(DocHtmlDescTitle *)
741 {
742   if (m_hide) return;
743   m_t << "</term>\n";
744 }
745
746 void DocbookDocVisitor::visitPre(DocHtmlDescData *)
747 {
748   if (m_hide) return;
749   m_t << "<listitem>";
750 }
751
752 void DocbookDocVisitor::visitPost(DocHtmlDescData *)
753 {
754   if (m_hide) return;
755   m_t << "</listitem></varlistentry>\n";
756 }
757
758 void DocbookDocVisitor::visitPre(DocHtmlTable *t)
759 {
760   if (m_hide) return;
761   m_t << "<table frame=\"all\">" << endl;
762   m_t << "    <title></title>" << endl;
763   m_t << "    <tgroup cols=\"" << t->numColumns() << "\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl;
764   m_t << "    <tbody>" << endl;
765 }
766
767 void DocbookDocVisitor::visitPost(DocHtmlTable *)
768 {
769   if (m_hide) return;
770   m_t << "    </tbody>" << endl;
771   m_t << "    </tgroup>" << endl;
772   m_t << "</table>" << endl;
773 }
774
775 void DocbookDocVisitor::visitPre(DocHtmlRow *)
776 {
777   if (m_hide) return;
778   m_t << "<row>\n";
779 }
780
781 void DocbookDocVisitor::visitPost(DocHtmlRow *)
782 {
783   if (m_hide) return;
784   m_t << "</row>\n";
785 }
786
787 void DocbookDocVisitor::visitPre(DocHtmlCell *)
788 {
789   if (m_hide) return;
790   m_t << "<entry>";
791 }
792
793 void DocbookDocVisitor::visitPost(DocHtmlCell *)
794 {
795   if (m_hide) return;
796   m_t << "</entry>";
797 }
798
799 void DocbookDocVisitor::visitPre(DocHtmlCaption *)
800 {
801   if (m_hide) return;
802   m_t << "<caption>";
803 }
804
805 void DocbookDocVisitor::visitPost(DocHtmlCaption *)
806 {
807   if (m_hide) return;
808   m_t << "</caption>\n";
809 }
810
811 void DocbookDocVisitor::visitPre(DocInternal *)
812 {
813   if (m_hide) return;
814   // TODO: to be implemented
815 }
816
817 void DocbookDocVisitor::visitPost(DocInternal *)
818 {
819   if (m_hide) return;
820   // TODO: to be implemented
821 }
822
823 void DocbookDocVisitor::visitPre(DocHRef *href)
824 {
825   if (m_hide) return;
826   m_t << "<link xlink:href=\"" << href->url() << "\">";
827 }
828
829 void DocbookDocVisitor::visitPost(DocHRef *)
830 {
831   if (m_hide) return;
832   m_t << "</link>";
833 }
834
835 void DocbookDocVisitor::visitPre(DocHtmlHeader *)
836 {
837   if (m_hide) return;
838   m_t << "<formalpara><title>";
839 }
840
841 void DocbookDocVisitor::visitPost(DocHtmlHeader *)
842 {
843   if (m_hide) return;
844   m_t << "</title></formalpara>\n";
845 }
846
847 void DocbookDocVisitor::visitPre(DocImage *img)
848 {
849   if (img->type()==DocImage::DocBook)
850   {
851     if (m_hide) return;
852     m_t << endl;
853     m_t << "    <figure>" << endl;
854     m_t << "        <title>";
855   }
856   else
857   {
858     pushEnabled();
859     m_hide=TRUE;
860   }
861 }
862
863 void DocbookDocVisitor::visitPost(DocImage *img)
864 {
865   if (img->type()==DocImage::DocBook)
866   {
867     if (m_hide) return;
868     QCString typevar;
869     m_t << "</title>" << endl;
870     m_t << "    <mediaobject>" << endl;
871     m_t << "        <imageobject>" << endl;
872     QCString baseName=img->name();
873     int i;
874     if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
875     {
876       baseName=baseName.right(baseName.length()-i-1);
877     }
878     m_t << "            <imagedata";
879     if (!img->width().isEmpty())
880     {
881       m_t << " width=\"";
882       filter(img->width());
883       m_t << "\"";
884     }
885     else
886     {
887       m_t << " width=\"50%\"";
888     }
889     if (!img->height().isEmpty())
890     {
891       m_t << " depth=\"";
892       filter(img->height());
893       m_t << "\"";
894     }
895     m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << "\">";
896     m_t << "</imagedata>" << endl;
897     m_t << "        </imageobject>" << endl;
898     m_t << "    </mediaobject>" << endl;
899     m_t << "    </figure>" << endl;
900     // copy the image to the output dir
901     QCString m_file;
902     bool ambig;
903     FileDef *fd=findFileDef(Doxygen::imageNameDict, baseName, ambig);
904     if (fd) 
905     {
906       m_file=fd->absFilePath();
907     }
908     QFile inImage(m_file);
909     QFile outImage(Config_getString("DOCBOOK_OUTPUT")+"/"+baseName.data());
910     if (inImage.open(IO_ReadOnly))
911     {
912       if (outImage.open(IO_WriteOnly))
913       {
914         char *buffer = new char[inImage.size()];
915         inImage.readBlock(buffer,inImage.size());
916         outImage.writeBlock(buffer,inImage.size());
917         outImage.flush();
918         delete[] buffer;
919       }
920     }
921   } 
922   else 
923   {
924     popEnabled();
925   }
926 }
927
928 void DocbookDocVisitor::visitPre(DocDotFile *df)
929 {
930   if (m_hide) return;
931   startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
932 }
933
934 void DocbookDocVisitor::visitPost(DocDotFile *df)
935 {
936   if (m_hide) return;
937   endDotFile(df->hasCaption());
938 }
939
940 void DocbookDocVisitor::visitPre(DocMscFile *df)
941 {
942   if (m_hide) return;
943   startMscFile(df->file(),df->width(),df->height(),df->hasCaption());
944 }
945
946 void DocbookDocVisitor::visitPost(DocMscFile *df)
947 {
948   if (m_hide) return;
949   endMscFile(df->hasCaption());
950 }
951 void DocbookDocVisitor::visitPre(DocDiaFile *df)
952 {
953   if (m_hide) return;
954   startDiaFile(df->file(),df->width(),df->height(),df->hasCaption());
955 }
956
957 void DocbookDocVisitor::visitPost(DocDiaFile *df)
958 {
959   if (m_hide) return;
960   endDiaFile(df->hasCaption());
961 }
962
963 void DocbookDocVisitor::visitPre(DocLink *lnk)
964 {
965   if (m_hide) return;
966   startLink(lnk->file(),lnk->anchor());
967 }
968
969 void DocbookDocVisitor::visitPost(DocLink *)
970 {
971   if (m_hide) return;
972   endLink();
973 }
974
975 void DocbookDocVisitor::visitPre(DocRef *ref)
976 {
977   if (m_hide) return;
978   if (!ref->file().isEmpty()) startLink(ref->file(),ref->anchor());
979   if (!ref->hasLinkText()) filter(ref->targetTitle());
980 }
981
982 void DocbookDocVisitor::visitPost(DocRef *ref)
983 {
984   if (m_hide) return;
985   if (!ref->file().isEmpty()) endLink();
986 }
987
988 void DocbookDocVisitor::visitPre(DocSecRefItem *ref)
989 {
990   if (m_hide) return;
991   m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
992 }
993
994 void DocbookDocVisitor::visitPost(DocSecRefItem *)
995 {
996   if (m_hide) return;
997   m_t << "</tocitem>" << endl;
998 }
999
1000 void DocbookDocVisitor::visitPre(DocSecRefList *)
1001 {
1002   if (m_hide) return;
1003   m_t << "<toclist>" << endl;
1004 }
1005
1006 void DocbookDocVisitor::visitPost(DocSecRefList *)
1007 {
1008   if (m_hide) return;
1009   m_t << "</toclist>" << endl;
1010 }
1011
1012 void DocbookDocVisitor::visitPre(DocParamSect *s)
1013 {
1014   if (m_hide) return;
1015   m_t <<  endl;
1016   m_t << "                <formalpara>" << endl;
1017   m_t << "                    <title/>" << endl;
1018   m_t << "                    <table frame=\"all\">" << endl;
1019   m_t << "                        <title>";
1020   switch(s->type())
1021   {
1022     case DocParamSect::Param:         m_t << theTranslator->trParameters();         break;
1023     case DocParamSect::RetVal:        m_t << theTranslator->trReturnValues();       break;
1024     case DocParamSect::Exception:     m_t << theTranslator->trExceptions();         break;
1025     case DocParamSect::TemplateParam: m_t << theTranslator->trTemplateParameters(); break;
1026     default:
1027       ASSERT(0);
1028   }
1029   m_t << "                        </title>" << endl;
1030   m_t << "                        <tgroup cols=\"2\" align=\"left\" colsep=\"1\" rowsep=\"1\">" << endl;
1031   m_t << "                        <tbody>" << endl;
1032 }
1033
1034 void DocbookDocVisitor::visitPost(DocParamSect *)
1035 {
1036   if (m_hide) return;
1037   m_t << "                        </tbody>" << endl;
1038   m_t << "                        </tgroup>" << endl;
1039   m_t << "                    </table>" << endl;
1040   m_t << "                </formalpara>" << endl;
1041   m_t << "                ";
1042 }
1043
1044 void DocbookDocVisitor::visitPre(DocParamList *pl)
1045 {
1046   if (m_hide) return;
1047   QListIterator<DocNode> li(pl->parameters());
1048   DocNode *param;
1049   m_t << "                            <row>" << endl;
1050   if (!li.toFirst())
1051   {
1052     m_t << "                                <entry></entry>" << endl;
1053   }
1054   else
1055   {
1056     m_t << "                                <entry>";
1057     int cnt = 0;
1058     for (li.toFirst();(param=li.current());++li)
1059     {
1060       if (cnt)
1061       {
1062         m_t << ", ";
1063       }
1064       if (param->kind()==DocNode::Kind_Word)
1065       {
1066         visit((DocWord*)param);
1067       }
1068       else if (param->kind()==DocNode::Kind_LinkedWord)
1069       {
1070         visit((DocLinkedWord*)param);
1071       }
1072       cnt++;
1073     }
1074     m_t << "</entry>" << endl;
1075   }
1076   m_t << "                                <entry>";
1077 }
1078
1079 void DocbookDocVisitor::visitPost(DocParamList *)
1080 {
1081   if (m_hide) return;
1082   m_t << "</entry>" << endl;
1083   m_t << "                            </row>" << endl;
1084 }
1085
1086 void DocbookDocVisitor::visitPre(DocXRefItem *x)
1087 {
1088   if (m_hide) return;
1089   if (x->title().isEmpty()) return;
1090   m_t << "<para><link linkend=\"";
1091   m_t << x->file() << "_1" << x->anchor();
1092   m_t << "\">";
1093   filter(x->title());
1094   m_t << "</link>";
1095   m_t << " ";
1096 }
1097
1098 void DocbookDocVisitor::visitPost(DocXRefItem *x)
1099 {
1100   if (m_hide) return;
1101   if (x->title().isEmpty()) return;
1102   m_t << "</para>";
1103 }
1104
1105 void DocbookDocVisitor::visitPre(DocInternalRef *ref)
1106 {
1107   if (m_hide) return;
1108   startLink(ref->file(),ref->anchor());
1109 }
1110
1111 void DocbookDocVisitor::visitPost(DocInternalRef *)
1112 {
1113   if (m_hide) return;
1114   endLink();
1115   m_t << " ";
1116 }
1117
1118 void DocbookDocVisitor::visitPre(DocCopy *)
1119 {
1120   if (m_hide) return;
1121   // TODO: to be implemented
1122 }
1123
1124
1125 void DocbookDocVisitor::visitPost(DocCopy *)
1126 {
1127   if (m_hide) return;
1128   // TODO: to be implemented
1129 }
1130
1131
1132 void DocbookDocVisitor::visitPre(DocText *)
1133 {
1134   // TODO: to be implemented
1135 }
1136
1137
1138 void DocbookDocVisitor::visitPost(DocText *)
1139 {
1140   // TODO: to be implemented
1141 }
1142
1143
1144 void DocbookDocVisitor::visitPre(DocHtmlBlockQuote *)
1145 {
1146   if (m_hide) return;
1147   m_t << "<blockquote>";
1148 }
1149
1150 void DocbookDocVisitor::visitPost(DocHtmlBlockQuote *)
1151 {
1152   if (m_hide) return;
1153   m_t << "</blockquote>";
1154 }
1155
1156 void DocbookDocVisitor::visitPre(DocVhdlFlow *)
1157 {
1158   // TODO: to be implemented
1159 }
1160
1161
1162 void DocbookDocVisitor::visitPost(DocVhdlFlow *)
1163 {
1164   // TODO: to be implemented
1165 }
1166
1167 void DocbookDocVisitor::visitPre(DocParBlock *)
1168 {
1169 }
1170
1171 void DocbookDocVisitor::visitPost(DocParBlock *)
1172 {
1173 }
1174
1175
1176 void DocbookDocVisitor::filter(const char *str)
1177 {
1178   m_t << convertToXML(str);
1179 }
1180
1181 void DocbookDocVisitor::startLink(const QCString &file,const QCString &anchor)
1182 {
1183   m_t << "<link linkend=\"" << file;
1184   if (!anchor.isEmpty()) m_t << "_1" << anchor;
1185   m_t << "\">";
1186 }
1187
1188 void DocbookDocVisitor::endLink()
1189 {
1190   m_t << "</link>";
1191 }
1192
1193 void DocbookDocVisitor::pushEnabled()
1194 {
1195   m_enabled.push(new bool(m_hide));
1196 }
1197
1198 void DocbookDocVisitor::popEnabled()
1199 {
1200   bool *v=m_enabled.pop();
1201   ASSERT(v!=0);
1202   m_hide = *v;
1203   delete v;
1204 }
1205
1206 void DocbookDocVisitor::writeMscFile(const QCString &baseName)
1207 {
1208   QCString shortName = baseName;
1209   int i;
1210   if ((i=shortName.findRev('/'))!=-1)
1211   {
1212     shortName=shortName.right(shortName.length()-i-1);
1213   }
1214   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1215   writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_BITMAP);
1216   m_t << "                <imagedata";
1217   m_t << " width=\"50%\"";
1218   m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << ".png" << "\">";
1219   m_t << "</imagedata>" << endl;
1220 }
1221
1222 void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName)
1223 {
1224   QCString shortName = baseName;
1225   int i;
1226   if ((i=shortName.findRev('/'))!=-1)
1227   {
1228     shortName=shortName.right(shortName.length()-i-1);
1229   }
1230   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1231   generatePlantUMLOutput(baseName,outDir,PUML_BITMAP);
1232   m_t << "                <imagedata";
1233   m_t << " width=\"50%\"";
1234   m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << ".png" << "\">";
1235   m_t << "</imagedata>" << endl;
1236 }
1237
1238 void DocbookDocVisitor::startMscFile(const QCString &fileName,
1239     const QCString &width,
1240     const QCString &height,
1241     bool hasCaption
1242     )
1243 {
1244   QCString baseName=fileName;
1245   int i;
1246   if ((i=baseName.findRev('/'))!=-1)
1247   {
1248     baseName=baseName.right(baseName.length()-i-1);
1249   }
1250   if ((i=baseName.find('.'))!=-1)
1251   {
1252     baseName=baseName.left(i);
1253   }
1254   baseName.prepend("msc_");
1255   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1256   writeMscGraphFromFile(fileName,outDir,baseName,MSC_BITMAP);
1257   m_t << "<para>" << endl;
1258   m_t << "    <figure>" << endl;
1259   m_t << "        <title></title>" << endl;
1260   m_t << "        <mediaobject>" << endl;
1261   m_t << "            <imageobject>" << endl;
1262   m_t << "                <imagedata";
1263   if (!width.isEmpty())
1264   {
1265     m_t << " width=\"";
1266     m_t << width;
1267     m_t << "\"";
1268   }
1269   else
1270   {
1271     m_t << " width=\"50%\"";
1272   }
1273   if (!height.isEmpty())
1274   {
1275     m_t << " depth=\"";
1276     m_t << height;
1277     m_t << "\"";
1278   }
1279   m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << ".png" << "\">";
1280   m_t << "</imagedata>" << endl;
1281   m_t << "            </imageobject>" << endl;
1282   if (hasCaption)
1283   {
1284     m_t << "        <caption>" << endl;
1285   }
1286 }
1287
1288 void DocbookDocVisitor::endMscFile(bool hasCaption)
1289 {
1290   if (m_hide) return;
1291   m_t << "endl";
1292   if (hasCaption)
1293   {
1294     m_t << "        </caption>" << endl;
1295   }
1296   m_t << "        </mediaobject>" << endl;
1297   m_t << "    </figure>" << endl;
1298   m_t << "</para>" << endl;
1299 }
1300
1301 void DocbookDocVisitor::writeDiaFile(const QCString &baseName)
1302 {
1303   QCString shortName = baseName;
1304   int i;
1305   if ((i=shortName.findRev('/'))!=-1)
1306   {
1307     shortName=shortName.right(shortName.length()-i-1);
1308   }
1309   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1310   writeDiaGraphFromFile(baseName+".dia",outDir,shortName,DIA_BITMAP);
1311   m_t << "                <imagedata";
1312   m_t << " align=\"center\" fileref=\"" << shortName << ".png" << "\">";
1313   m_t << "</imagedata>" << endl;
1314 }
1315
1316 void DocbookDocVisitor::startDiaFile(const QCString &fileName,
1317     const QCString &width,
1318     const QCString &height,
1319     bool hasCaption
1320     )
1321 {
1322   QCString baseName=fileName;
1323   int i;
1324   if ((i=baseName.findRev('/'))!=-1)
1325   {
1326     baseName=baseName.right(baseName.length()-i-1);
1327   }
1328   if ((i=baseName.find('.'))!=-1)
1329   {
1330     baseName=baseName.left(i);
1331   }
1332   baseName.prepend("msc_");
1333   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1334   writeDiaGraphFromFile(fileName,outDir,baseName,DIA_BITMAP);
1335   m_t << "<para>" << endl;
1336   m_t << "    <figure>" << endl;
1337   m_t << "        <title></title>" << endl;
1338   m_t << "        <mediaobject>" << endl;
1339   m_t << "            <imageobject>" << endl;
1340   m_t << "                <imagedata";
1341   if (!width.isEmpty())
1342   {
1343     m_t << " width=\"";
1344     m_t << width;
1345     m_t << "\"";
1346   }
1347   else if (!height.isEmpty())
1348   {
1349     m_t << " depth=\"";
1350     m_t << height;
1351     m_t << "\"";
1352   }
1353   m_t << " align=\"center\" fileref=\"" << baseName << ".png" << "\">";
1354   m_t << "</imagedata>" << endl;
1355   m_t << "            </imageobject>" << endl;
1356   if (hasCaption)
1357   {
1358     m_t << "        <caption>" << endl;
1359   }
1360 }
1361
1362 void DocbookDocVisitor::endDiaFile(bool hasCaption)
1363 {
1364   if (m_hide) return;
1365   m_t << "endl";
1366   if (hasCaption)
1367   {
1368     m_t << "        </caption>" << endl;
1369   }
1370   m_t << "        </mediaobject>" << endl;
1371   m_t << "    </figure>" << endl;
1372   m_t << "</para>" << endl;
1373 }
1374
1375 void DocbookDocVisitor::writeDotFile(const QCString &baseName)
1376 {
1377   QCString shortName = baseName;
1378   int i;
1379   if ((i=shortName.findRev('/'))!=-1)
1380   {
1381     shortName=shortName.right(shortName.length()-i-1);
1382   }
1383   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1384   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
1385   writeDotGraphFromFile(baseName+".dot",outDir,shortName,GOF_BITMAP);
1386   m_t << "                <imagedata";
1387   //If no width is specified use default value for PDF rendering
1388   m_t << " width=\"50%\"";
1389   m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << "." << imgExt << "\">";
1390   m_t << "</imagedata>" << endl;
1391 }
1392
1393 void DocbookDocVisitor::startDotFile(const QCString &fileName,
1394     const QCString &width,
1395     const QCString &height,
1396     bool hasCaption
1397     )
1398 {
1399   QCString baseName=fileName;
1400   int i;
1401   if ((i=baseName.findRev('/'))!=-1)
1402   {
1403     baseName=baseName.right(baseName.length()-i-1);
1404   }
1405   if ((i=baseName.find('.'))!=-1)
1406   {
1407     baseName=baseName.left(i);
1408   }
1409   baseName.prepend("dot_");
1410   QCString outDir = Config_getString("DOCBOOK_OUTPUT");
1411   QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
1412   writeDotGraphFromFile(fileName,outDir,baseName,GOF_BITMAP);
1413   m_t << "<para>" << endl;
1414   m_t << "    <figure>" << endl;
1415   m_t << "        <title></title>" << endl;
1416   m_t << "        <mediaobject>" << endl;
1417   m_t << "            <imageobject>" << endl;
1418   m_t << "                <imagedata";
1419   if (!width.isEmpty())
1420   {
1421     m_t << " width=\"";
1422     m_t << width;
1423     m_t << "\"";
1424   }
1425   else
1426   {
1427     m_t << " width=\"50%\"";
1428   }
1429   if (!height.isEmpty())
1430   {
1431     m_t << " depth=\"";
1432     m_t << height;
1433     m_t << "\"";
1434   }
1435   m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << baseName << "." << imgExt << "\">";
1436   m_t << "</imagedata>" << endl;
1437   m_t << "            </imageobject>" << endl;
1438   if (hasCaption)
1439   {
1440     m_t << "        <caption>" << endl;
1441   }
1442 }
1443
1444 void DocbookDocVisitor::endDotFile(bool hasCaption)
1445 {
1446   if (m_hide) return;
1447   m_t << "endl";
1448   if (hasCaption)
1449   {
1450     m_t << "        </caption>" << endl;
1451   }
1452   m_t << "        </mediaobject>" << endl;
1453   m_t << "    </figure>" << endl;
1454   m_t << "</para>" << endl;
1455 }
1456