Imported Upstream version 1.8.8
[platform/upstream/doxygen.git] / src / xmldocvisitor.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 "xmldocvisitor.h"
22 #include "docparser.h"
23 #include "language.h"
24 #include "doxygen.h"
25 #include "outputgen.h"
26 #include "xmlgen.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 "htmlentity.h"
34
35 XmlDocVisitor::XmlDocVisitor(FTextStream &t,CodeOutputInterface &ci) 
36   : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE) 
37 {
38 }
39
40   //--------------------------------------
41   // visitor functions for leaf nodes
42   //--------------------------------------
43
44 void XmlDocVisitor::visit(DocWord *w)
45 {
46   if (m_hide) return;
47   filter(w->word());
48 }
49
50 void XmlDocVisitor::visit(DocLinkedWord *w)
51 {
52   if (m_hide) return;
53   startLink(w->ref(),w->file(),w->anchor());
54   filter(w->word());
55   endLink();
56 }
57
58 void XmlDocVisitor::visit(DocWhiteSpace *w)
59 {
60   if (m_hide) return;
61   if (m_insidePre)
62   {
63     m_t << w->chars();
64   }
65   else
66   {
67     m_t << " ";
68   }
69 }
70
71 void XmlDocVisitor::visit(DocSymbol *s)
72 {
73   if (m_hide) return;
74   const char *res = HtmlEntityMapper::instance()->xml(s->symbol());
75   if (res)
76   {
77     m_t << res;
78   }
79   else
80   {
81     err("XML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
82   }
83 }
84
85 void XmlDocVisitor::visit(DocURL *u)
86 {
87   if (m_hide) return;
88   m_t << "<ulink url=\""; 
89   if (u->isEmail()) m_t << "mailto:";
90   filter(u->url());
91   m_t << "\">";
92   filter(u->url());
93   m_t << "</ulink>";
94 }
95
96 void XmlDocVisitor::visit(DocLineBreak *)
97 {
98   if (m_hide) return;
99   m_t << "<linebreak/>\n";
100 }
101
102 void XmlDocVisitor::visit(DocHorRuler *)
103 {
104   if (m_hide) return;
105   m_t << "<hruler/>\n";
106 }
107
108 void XmlDocVisitor::visit(DocStyleChange *s)
109 {
110   if (m_hide) return;
111   switch (s->style())
112   {
113     case DocStyleChange::Bold:
114       if (s->enable()) m_t << "<bold>";      else m_t << "</bold>";
115       break;
116     case DocStyleChange::Italic:
117       if (s->enable()) m_t << "<emphasis>";     else m_t << "</emphasis>";
118       break;
119     case DocStyleChange::Code:
120       if (s->enable()) m_t << "<computeroutput>";   else m_t << "</computeroutput>";
121       break;
122     case DocStyleChange::Subscript:
123       if (s->enable()) m_t << "<subscript>";    else m_t << "</subscript>";
124       break;
125     case DocStyleChange::Superscript:
126       if (s->enable()) m_t << "<superscript>";    else m_t << "</superscript>";
127       break;
128     case DocStyleChange::Center:
129       if (s->enable()) m_t << "<center>"; else m_t << "</center>";
130       break;
131     case DocStyleChange::Small:
132       if (s->enable()) m_t << "<small>";  else m_t << "</small>";
133       break;
134     case DocStyleChange::Preformatted:
135       if (s->enable()) 
136       {
137         m_t << "<preformatted>";  
138         m_insidePre=TRUE;
139       }
140       else 
141       {
142         m_t << "</preformatted>";
143         m_insidePre=FALSE;
144       }
145       break;
146     case DocStyleChange::Div:  /* HTML only */ break;
147     case DocStyleChange::Span: /* HTML only */ break;
148   }
149 }
150
151 void XmlDocVisitor::visit(DocVerbatim *s)
152 {
153   if (m_hide) return;
154   QCString lang = m_langExt;
155   if (!s->language().isEmpty()) // explicit language setting
156   {
157     lang = s->language();
158   }
159   SrcLangExt langExt = getLanguageFromFileName(lang);
160   switch(s->type())
161   {
162     case DocVerbatim::Code: // fall though
163       m_t << "<programlisting>"; 
164       Doxygen::parserManager->getParser(lang)
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 << "<verbatim>";
171       filter(s->text());
172       m_t << "</verbatim>"; 
173       break;
174     case DocVerbatim::HtmlOnly: 
175       m_t << "<htmlonly>";
176       filter(s->text());
177       m_t << "</htmlonly>";
178       break;
179     case DocVerbatim::RtfOnly: 
180       m_t << "<rtfonly>";
181       filter(s->text());
182       m_t << "</rtfonly>";
183       break;
184     case DocVerbatim::ManOnly: 
185       m_t << "<manonly>";
186       filter(s->text());
187       m_t << "</manonly>";
188       break;
189     case DocVerbatim::LatexOnly: 
190       m_t << "<latexonly>";
191       filter(s->text());
192       m_t << "</latexonly>";
193       break;
194     case DocVerbatim::XmlOnly: 
195       m_t << s->text();
196       break;
197     case DocVerbatim::DocbookOnly:
198       m_t << "<docbookonly>";
199       filter(s->text());
200       m_t << "</docbookonly>";
201       break;
202     case DocVerbatim::Dot: 
203       m_t << "<dot>";
204       filter(s->text());
205       m_t << "</dot>";
206       break;
207     case DocVerbatim::Msc: 
208       m_t << "<msc>";
209       filter(s->text());
210       m_t << "</msc>";
211       break;
212     case DocVerbatim::PlantUML:
213       m_t << "<plantuml>";
214       filter(s->text());
215       m_t << "</plantuml>";
216       break;
217   }
218 }
219
220 void XmlDocVisitor::visit(DocAnchor *anc)
221 {
222   if (m_hide) return;
223   m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
224 }
225
226 void XmlDocVisitor::visit(DocInclude *inc)
227 {
228   if (m_hide) return;
229   SrcLangExt langExt = getLanguageFromFileName(inc->extension());
230   switch(inc->type())
231   {
232     case DocInclude::IncWithLines:
233       { 
234          m_t << "<programlisting>";
235          QFileInfo cfi( inc->file() );
236          FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
237          Doxygen::parserManager->getParser(inc->extension())
238                                ->parseCode(m_ci,inc->context(),
239                                            inc->text(),
240                                            langExt,
241                                            inc->isExample(),
242                                            inc->exampleFile(), &fd);
243          m_t << "</programlisting>"; 
244       }
245       break;    
246     case DocInclude::Include: 
247       m_t << "<programlisting>";
248       Doxygen::parserManager->getParser(inc->extension())
249                             ->parseCode(m_ci,inc->context(),
250                                         inc->text(),
251                                         langExt,
252                                         inc->isExample(),
253                                         inc->exampleFile());
254       m_t << "</programlisting>"; 
255       break;
256     case DocInclude::DontInclude: 
257       break;
258     case DocInclude::HtmlInclude: 
259       m_t << "<htmlonly>";
260       filter(inc->text());
261       m_t << "</htmlonly>";
262       break;
263     case DocInclude::LatexInclude:
264       m_t << "<latexonly>";
265       filter(inc->text());
266       m_t << "</latexonly>";
267       break;
268     case DocInclude::VerbInclude: 
269       m_t << "<verbatim>";
270       filter(inc->text());
271       m_t << "</verbatim>"; 
272       break;
273     case DocInclude::Snippet:
274       m_t << "<programlisting>";
275       Doxygen::parserManager->getParser(inc->extension())
276                             ->parseCode(m_ci,
277                                         inc->context(),
278                                         extractBlock(inc->text(),inc->blockId()),
279                                         langExt,
280                                         inc->isExample(),
281                                         inc->exampleFile()
282                                        );
283       m_t << "</programlisting>"; 
284       break;
285   }
286 }
287
288 void XmlDocVisitor::visit(DocIncOperator *op)
289 {
290   //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
291   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
292   if (op->isFirst()) 
293   {
294     if (!m_hide)
295     {
296       m_t << "<programlisting>";
297     }
298     pushEnabled();
299     m_hide = TRUE;
300   }
301   SrcLangExt langExt = getLanguageFromFileName(m_langExt);
302   if (op->type()!=DocIncOperator::Skip) 
303   {
304     popEnabled();
305     if (!m_hide) 
306     {
307       Doxygen::parserManager->getParser(m_langExt)
308                             ->parseCode(m_ci,op->context(),
309                                         op->text(),langExt,op->isExample(),
310                                         op->exampleFile());
311     }
312     pushEnabled();
313     m_hide=TRUE;
314   }
315   if (op->isLast())  
316   {
317     popEnabled();
318     if (!m_hide) m_t << "</programlisting>"; 
319   }
320   else
321   {
322     if (!m_hide) m_t << endl;
323   }
324 }
325
326 void XmlDocVisitor::visit(DocFormula *f)
327 {
328   if (m_hide) return;
329   m_t << "<formula id=\"" << f->id() << "\">";
330   filter(f->text());
331   m_t << "</formula>";
332 }
333
334 void XmlDocVisitor::visit(DocIndexEntry *ie)
335 {
336   if (m_hide) return;
337   m_t << "<indexentry>"
338            "<primaryie>";
339   filter(ie->entry());
340   m_t << "</primaryie>"
341            "<secondaryie></secondaryie>"
342          "</indexentry>";
343 }
344
345 void XmlDocVisitor::visit(DocSimpleSectSep *sep)
346 {
347   if (sep->parent() && sep->parent()->kind()==DocNode::Kind_SimpleSect)
348   {
349     visitPost((DocSimpleSect*)sep->parent()); // end current section
350     visitPre((DocSimpleSect*)sep->parent());  // start new section
351   }
352 }
353
354 void XmlDocVisitor::visit(DocCite *cite)
355 {
356   if (m_hide) return;
357   if (!cite->file().isEmpty()) startLink(cite->ref(),cite->file(),cite->anchor());
358   filter(cite->text());
359   if (!cite->file().isEmpty()) endLink();
360 }
361
362 //--------------------------------------
363 // visitor functions for compound nodes
364 //--------------------------------------
365
366 void XmlDocVisitor::visitPre(DocAutoList *l)
367 {
368   if (m_hide) return;
369   if (l->isEnumList())
370   {
371     m_t << "<orderedlist>\n";
372   }
373   else
374   {
375     m_t << "<itemizedlist>\n";
376   }
377 }
378
379 void XmlDocVisitor::visitPost(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 XmlDocVisitor::visitPre(DocAutoListItem *)
393 {
394   if (m_hide) return;
395   m_t << "<listitem>";
396 }
397
398 void XmlDocVisitor::visitPost(DocAutoListItem *) 
399 {
400   if (m_hide) return;
401   m_t << "</listitem>";
402 }
403
404 void XmlDocVisitor::visitPre(DocPara *) 
405 {
406   if (m_hide) return;
407   m_t << "<para>";
408 }
409
410 void XmlDocVisitor::visitPost(DocPara *)
411 {
412   if (m_hide) return;
413   m_t << "</para>";
414 }
415
416 void XmlDocVisitor::visitPre(DocRoot *)
417 {
418   //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
419 }
420
421 void XmlDocVisitor::visitPost(DocRoot *)
422 {
423   //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
424 }
425
426 void XmlDocVisitor::visitPre(DocSimpleSect *s)
427 {
428   if (m_hide) return;
429   m_t << "<simplesect kind=\"";
430   switch(s->type())
431   {
432     case DocSimpleSect::See: 
433       m_t << "see"; break;
434     case DocSimpleSect::Return: 
435       m_t << "return"; break;
436     case DocSimpleSect::Author: 
437       m_t << "author"; break;
438     case DocSimpleSect::Authors: 
439       m_t << "authors"; break;
440     case DocSimpleSect::Version: 
441       m_t << "version"; break;
442     case DocSimpleSect::Since: 
443       m_t << "since"; break;
444     case DocSimpleSect::Date: 
445       m_t << "date"; break;
446     case DocSimpleSect::Note: 
447       m_t << "note"; break;
448     case DocSimpleSect::Warning:
449       m_t << "warning"; break;
450     case DocSimpleSect::Pre:
451       m_t << "pre"; break;
452     case DocSimpleSect::Post:
453       m_t << "post"; break;
454     case DocSimpleSect::Copyright:
455       m_t << "copyright"; break;
456     case DocSimpleSect::Invar:
457       m_t << "invariant"; break;
458     case DocSimpleSect::Remark:
459       m_t << "remark"; break;
460     case DocSimpleSect::Attention:
461       m_t << "attention"; break;
462     case DocSimpleSect::User: 
463       m_t << "par"; break;
464     case DocSimpleSect::Rcs: 
465       m_t << "rcs"; break;
466     case DocSimpleSect::Unknown:  break;
467   }
468   m_t << "\">";
469 }
470
471 void XmlDocVisitor::visitPost(DocSimpleSect *)
472 {
473   if (m_hide) return;
474   m_t << "</simplesect>\n";
475 }
476
477 void XmlDocVisitor::visitPre(DocTitle *)
478 {
479   if (m_hide) return;
480   m_t << "<title>";
481 }
482
483 void XmlDocVisitor::visitPost(DocTitle *)
484 {
485   if (m_hide) return;
486   m_t << "</title>";
487 }
488
489 void XmlDocVisitor::visitPre(DocSimpleList *)
490 {
491   if (m_hide) return;
492   m_t << "<itemizedlist>\n";
493 }
494
495 void XmlDocVisitor::visitPost(DocSimpleList *)
496 {
497   if (m_hide) return;
498   m_t << "</itemizedlist>\n";
499 }
500
501 void XmlDocVisitor::visitPre(DocSimpleListItem *)
502 {
503   if (m_hide) return;
504   m_t << "<listitem>";
505 }
506
507 void XmlDocVisitor::visitPost(DocSimpleListItem *) 
508 {
509   if (m_hide) return;
510   m_t << "</listitem>\n";
511 }
512
513 void XmlDocVisitor::visitPre(DocSection *s)
514 {
515   if (m_hide) return;
516   m_t << "<sect" << s->level() << " id=\"" << s->file();
517   if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor();
518   m_t << "\">" << endl;
519   m_t << "<title>";
520   filter(convertCharEntitiesToUTF8(s->title()));
521   m_t << "</title>" << endl;
522 }
523
524 void XmlDocVisitor::visitPost(DocSection *s) 
525 {
526   m_t << "</sect" << s->level() << ">\n";
527 }
528
529 void XmlDocVisitor::visitPre(DocHtmlList *s)
530 {
531   if (m_hide) return;
532   if (s->type()==DocHtmlList::Ordered) 
533     m_t << "<orderedlist>\n"; 
534   else 
535     m_t << "<itemizedlist>\n";
536 }
537
538 void XmlDocVisitor::visitPost(DocHtmlList *s) 
539 {
540   if (m_hide) return;
541   if (s->type()==DocHtmlList::Ordered) 
542     m_t << "</orderedlist>\n"; 
543   else 
544     m_t << "</itemizedlist>\n";
545 }
546
547 void XmlDocVisitor::visitPre(DocHtmlListItem *)
548 {
549   if (m_hide) return;
550   m_t << "<listitem>\n";
551 }
552
553 void XmlDocVisitor::visitPost(DocHtmlListItem *) 
554 {
555   if (m_hide) return;
556   m_t << "</listitem>\n";
557 }
558
559 void XmlDocVisitor::visitPre(DocHtmlDescList *)
560 {
561   if (m_hide) return;
562   m_t << "<variablelist>\n";
563 }
564
565 void XmlDocVisitor::visitPost(DocHtmlDescList *) 
566 {
567   if (m_hide) return;
568   m_t << "</variablelist>\n";
569 }
570
571 void XmlDocVisitor::visitPre(DocHtmlDescTitle *)
572 {
573   if (m_hide) return;
574   m_t << "<varlistentry><term>";
575 }
576
577 void XmlDocVisitor::visitPost(DocHtmlDescTitle *) 
578 {
579   if (m_hide) return;
580   m_t << "</term></varlistentry>\n";
581 }
582
583 void XmlDocVisitor::visitPre(DocHtmlDescData *)
584 {
585   if (m_hide) return;
586   m_t << "<listitem>";
587 }
588
589 void XmlDocVisitor::visitPost(DocHtmlDescData *) 
590 {
591   if (m_hide) return;
592   m_t << "</listitem>\n";
593 }
594
595 void XmlDocVisitor::visitPre(DocHtmlTable *t)
596 {
597   if (m_hide) return;
598   m_t << "<table rows=\"" << t->numRows() 
599       << "\" cols=\"" << t->numColumns() << "\">" ;
600 }
601
602 void XmlDocVisitor::visitPost(DocHtmlTable *) 
603 {
604   if (m_hide) return;
605   m_t << "</table>\n";
606 }
607
608 void XmlDocVisitor::visitPre(DocHtmlRow *)
609 {
610   if (m_hide) return;
611   m_t << "<row>\n";
612 }
613
614 void XmlDocVisitor::visitPost(DocHtmlRow *) 
615 {
616   if (m_hide) return;
617   m_t << "</row>\n";
618 }
619
620 void XmlDocVisitor::visitPre(DocHtmlCell *c)
621 {
622   if (m_hide) return;
623   if (c->isHeading()) m_t << "<entry thead=\"yes\">"; else m_t << "<entry thead=\"no\">";
624 }
625
626 void XmlDocVisitor::visitPost(DocHtmlCell *) 
627 {
628   if (m_hide) return;
629   m_t << "</entry>"; 
630 }
631
632 void XmlDocVisitor::visitPre(DocHtmlCaption *)
633 {
634   if (m_hide) return;
635   m_t << "<caption>";
636 }
637
638 void XmlDocVisitor::visitPost(DocHtmlCaption *) 
639 {
640   if (m_hide) return;
641   m_t << "</caption>\n";
642 }
643
644 void XmlDocVisitor::visitPre(DocInternal *)
645 {
646   if (m_hide) return;
647   m_t << "<internal>";
648 }
649
650 void XmlDocVisitor::visitPost(DocInternal *) 
651 {
652   if (m_hide) return;
653   m_t << "</internal>" << endl;
654 }
655
656 void XmlDocVisitor::visitPre(DocHRef *href)
657 {
658   if (m_hide) return;
659   m_t << "<ulink url=\"";
660   filter(href->url());
661   m_t << "\">";
662 }
663
664 void XmlDocVisitor::visitPost(DocHRef *) 
665 {
666   if (m_hide) return;
667   m_t << "</ulink>";
668 }
669
670 void XmlDocVisitor::visitPre(DocHtmlHeader *header)
671 {
672   if (m_hide) return;
673   m_t << "<heading level=\"" << header->level() << "\">";
674 }
675
676 void XmlDocVisitor::visitPost(DocHtmlHeader *) 
677 {
678   if (m_hide) return;
679   m_t << "</heading>\n";
680 }
681
682 void XmlDocVisitor::visitPre(DocImage *img)
683 {
684   if (m_hide) return;
685   m_t << "<image type=\"";
686   switch(img->type())
687   {
688     case DocImage::Html:    m_t << "html"; break;
689     case DocImage::Latex:   m_t << "latex"; break;
690     case DocImage::Rtf:     m_t << "rtf"; break;
691     case DocImage::DocBook: m_t << "docbook"; break;
692   }
693   m_t << "\"";
694
695   QCString baseName=img->name();
696   int i;
697   if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
698   {
699     baseName=baseName.right(baseName.length()-i-1);
700   }
701   m_t << " name=\"" << baseName << "\"";
702   if (!img->width().isEmpty())
703   {
704     m_t << " width=\"";
705     filter(img->width());
706     m_t << "\"";
707   }
708   else if (!img->height().isEmpty())
709   {
710     m_t << " height=\"";
711     filter(img->height());
712     m_t << "\"";
713   }
714   m_t << ">";
715
716   // copy the image to the output dir
717   QFile inImage(img->name());
718   QFile outImage(Config_getString("XML_OUTPUT")+"/"+baseName.data());
719   if (inImage.open(IO_ReadOnly))
720   {
721     if (outImage.open(IO_WriteOnly))
722     {
723       char *buffer = new char[inImage.size()];
724       inImage.readBlock(buffer,inImage.size());
725       outImage.writeBlock(buffer,inImage.size());
726       outImage.flush();
727       delete[] buffer;
728     }
729   }
730 }
731
732 void XmlDocVisitor::visitPost(DocImage *) 
733 {
734   if (m_hide) return;
735   m_t << "</image>" << endl;
736 }
737
738 void XmlDocVisitor::visitPre(DocDotFile *df)
739 {
740   if (m_hide) return;
741   m_t << "<dotfile name=\"" << df->file() << "\">";
742 }
743
744 void XmlDocVisitor::visitPost(DocDotFile *) 
745 {
746   if (m_hide) return;
747   m_t << "</dotfile>" << endl;
748 }
749
750 void XmlDocVisitor::visitPre(DocMscFile *df)
751 {
752   if (m_hide) return;
753   m_t << "<mscfile name=\"" << df->file() << "\">";
754 }
755
756 void XmlDocVisitor::visitPost(DocMscFile *) 
757 {
758   if (m_hide) return;
759   m_t << "</mscfile>" << endl;
760 }
761
762 void XmlDocVisitor::visitPre(DocDiaFile *df)
763 {
764   if (m_hide) return;
765   m_t << "<diafile name=\"" << df->file() << "\">";
766 }
767
768 void XmlDocVisitor::visitPost(DocDiaFile *)
769 {
770   if (m_hide) return;
771   m_t << "</diafile>" << endl;
772 }
773
774 void XmlDocVisitor::visitPre(DocLink *lnk)
775 {
776   if (m_hide) return;
777   startLink(lnk->ref(),lnk->file(),lnk->anchor());
778 }
779
780 void XmlDocVisitor::visitPost(DocLink *) 
781 {
782   if (m_hide) return;
783   endLink();
784 }
785
786 void XmlDocVisitor::visitPre(DocRef *ref)
787 {
788   if (m_hide) return;
789   if (!ref->file().isEmpty()) 
790   {
791     startLink(ref->ref(),ref->file(),ref->isSubPage() ? QCString() : ref->anchor());
792   }
793   if (!ref->hasLinkText()) filter(ref->targetTitle());
794 }
795
796 void XmlDocVisitor::visitPost(DocRef *ref) 
797 {
798   if (m_hide) return;
799   if (!ref->file().isEmpty()) endLink();
800   //m_t << " ";
801 }
802
803 void XmlDocVisitor::visitPre(DocSecRefItem *ref)
804 {
805   if (m_hide) return;
806   m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
807 }
808
809 void XmlDocVisitor::visitPost(DocSecRefItem *) 
810 {
811   if (m_hide) return;
812   m_t << "</tocitem>" << endl;
813 }
814
815 void XmlDocVisitor::visitPre(DocSecRefList *)
816 {
817   if (m_hide) return;
818   m_t << "<toclist>" << endl;
819 }
820
821 void XmlDocVisitor::visitPost(DocSecRefList *) 
822 {
823   if (m_hide) return;
824   m_t << "</toclist>" << endl;
825 }
826
827 //void XmlDocVisitor::visitPre(DocLanguage *l)
828 //{
829 //  if (m_hide) return;
830 //  m_t << "<language langid=\"" << l->id() << "\">";
831 //}
832 //
833 //void XmlDocVisitor::visitPost(DocLanguage *) 
834 //{
835 //  if (m_hide) return;
836 //  m_t << "</language>" << endl;
837 //}
838
839 void XmlDocVisitor::visitPre(DocParamSect *s)
840 {
841   if (m_hide) return;
842   m_t << "<parameterlist kind=\"";
843   switch(s->type())
844   {
845     case DocParamSect::Param: 
846       m_t << "param"; break;
847     case DocParamSect::RetVal: 
848       m_t << "retval"; break;
849     case DocParamSect::Exception: 
850       m_t << "exception"; break;
851     case DocParamSect::TemplateParam: 
852       m_t << "templateparam"; break;
853     default:
854       ASSERT(0);
855   }
856   m_t << "\">";
857 }
858
859 void XmlDocVisitor::visitPost(DocParamSect *)
860 {
861   if (m_hide) return;
862   m_t << "</parameterlist>" << endl;
863 }
864
865 void XmlDocVisitor::visitPre(DocParamList *pl)
866 {
867   if (m_hide) return;
868   m_t << "<parameteritem>" << endl;
869   m_t << "<parameternamelist>" << endl;
870   //QStrListIterator li(pl->parameters());
871   //const char *s;
872   QListIterator<DocNode> li(pl->parameters());
873   DocNode *param;
874   for (li.toFirst();(param=li.current());++li)
875   {
876     if (pl->paramTypes().count()>0)
877     {
878       QListIterator<DocNode> li(pl->paramTypes());
879       DocNode *type;
880       for (li.toFirst();(type=li.current());++li)
881       {
882         m_t << "<parametertype>";
883         if (type->kind()==DocNode::Kind_Word)
884         {
885           visit((DocWord*)type); 
886         }
887         else if (type->kind()==DocNode::Kind_LinkedWord)
888         {
889           visit((DocLinkedWord*)type); 
890         }
891         m_t << "</parametertype>" << endl;
892       }
893     }
894     m_t << "<parametername";
895     if (pl->direction()!=DocParamSect::Unspecified)
896     {
897       m_t << " direction=\"";
898       if (pl->direction()==DocParamSect::In)
899       {
900         m_t << "in";
901       }
902       else if (pl->direction()==DocParamSect::Out)
903       {
904         m_t << "out";
905       }
906       else if (pl->direction()==DocParamSect::InOut)
907       {
908         m_t << "inout";
909       }
910       m_t << "\"";
911     }
912     m_t << ">";
913     if (param->kind()==DocNode::Kind_Word)
914     {
915       visit((DocWord*)param); 
916     }
917     else if (param->kind()==DocNode::Kind_LinkedWord)
918     {
919       visit((DocLinkedWord*)param); 
920     }
921     m_t << "</parametername>" << endl;
922   }
923   m_t << "</parameternamelist>" << endl;
924   m_t << "<parameterdescription>" << endl;
925 }
926
927 void XmlDocVisitor::visitPost(DocParamList *)
928 {
929   if (m_hide) return;
930   m_t << "</parameterdescription>" << endl;
931   m_t << "</parameteritem>" << endl;
932 }
933
934 void XmlDocVisitor::visitPre(DocXRefItem *x)
935 {
936   if (m_hide) return;
937   if (x->title().isEmpty()) return;
938   m_t << "<xrefsect id=\"";
939   m_t << x->file() << "_1" << x->anchor();
940   m_t << "\">";
941   m_t << "<xreftitle>";
942   filter(x->title());
943   m_t << "</xreftitle>";
944   m_t << "<xrefdescription>";
945 }
946
947 void XmlDocVisitor::visitPost(DocXRefItem *x)
948 {
949   if (m_hide) return;
950   if (x->title().isEmpty()) return;
951   m_t << "</xrefdescription>";
952   m_t << "</xrefsect>";
953 }
954
955 void XmlDocVisitor::visitPre(DocInternalRef *ref)
956 {
957   if (m_hide) return;
958   startLink(0,ref->file(),ref->anchor());
959 }
960
961 void XmlDocVisitor::visitPost(DocInternalRef *) 
962 {
963   if (m_hide) return;
964   endLink();
965   m_t << " ";
966 }
967
968 void XmlDocVisitor::visitPre(DocCopy *c)
969 {
970   if (m_hide) return;
971   m_t << "<copydoc link=\"" << convertToXML(c->link()) << "\">";
972 }
973
974 void XmlDocVisitor::visitPost(DocCopy *)
975 {
976   if (m_hide) return;
977   m_t << "</copydoc>" << endl;
978 }
979
980 void XmlDocVisitor::visitPre(DocText *)
981 {
982 }
983
984 void XmlDocVisitor::visitPost(DocText *)
985 {
986 }
987
988 void XmlDocVisitor::visitPre(DocHtmlBlockQuote *)
989 {
990   if (m_hide) return;
991   m_t << "<blockquote>";
992 }
993
994 void XmlDocVisitor::visitPost(DocHtmlBlockQuote *)
995 {
996   if (m_hide) return;
997   m_t << "</blockquote>";
998 }
999
1000 void XmlDocVisitor::visitPre(DocVhdlFlow *)
1001 {
1002 }
1003
1004 void XmlDocVisitor::visitPost(DocVhdlFlow *)
1005 {
1006 }
1007
1008 void XmlDocVisitor::visitPre(DocParBlock *)
1009 {
1010   if (m_hide) return;
1011   m_t << "<parblock>";
1012 }
1013
1014 void XmlDocVisitor::visitPost(DocParBlock *)
1015 {
1016   if (m_hide) return;
1017   m_t << "</parblock>";
1018 }
1019
1020
1021 void XmlDocVisitor::filter(const char *str)
1022
1023   m_t << convertToXML(str);
1024 }
1025
1026 void XmlDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
1027 {
1028   //printf("XmlDocVisitor: file=%s anchor=%s\n",file.data(),anchor.data());
1029   m_t << "<ref refid=\"" << file;
1030   if (!anchor.isEmpty()) m_t << "_1" << anchor;
1031   m_t << "\" kindref=\"";
1032   if (!anchor.isEmpty()) m_t << "member"; else m_t << "compound";
1033   m_t << "\"";
1034   if (!ref.isEmpty()) m_t << " external=\"" << ref << "\"";
1035   m_t << ">";
1036 }
1037
1038 void XmlDocVisitor::endLink()
1039 {
1040   m_t << "</ref>";
1041 }
1042
1043 void XmlDocVisitor::pushEnabled()
1044 {
1045   m_enabled.push(new bool(m_hide));
1046 }
1047
1048 void XmlDocVisitor::popEnabled()
1049 {
1050   bool *v=m_enabled.pop();
1051   ASSERT(v!=0);
1052   m_hide = *v;
1053   delete v;
1054 }
1055