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