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