My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
xmldocvisitor.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  *
6  * Copyright (C) 1997-2015 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 static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children)
36 {
37  QListIterator<DocNode> cli(children);
38  DocNode *n;
39  for (cli.toFirst();(n=cli.current());++cli) n->accept(parent);
40 }
41 
42 static void visitPreStart(FTextStream &t, const char *cmd, const bool doCaption,
43  XmlDocVisitor *parent, QList<DocNode> children,
44  const QCString &name, bool writeType, DocImage::Type type, const QCString &width,
45  const QCString &height)
46 {
47  t << "<" << cmd;
48  if (writeType)
49  {
50  t << " type=\"";
51  switch(type)
52  {
53  case DocImage::Html: t << "html"; break;
54  case DocImage::Latex: t << "latex"; break;
55  case DocImage::Rtf: t << "rtf"; break;
56  case DocImage::DocBook: t << "docbook"; break;
57  }
58  t << "\"";
59  }
60  if (!name.isEmpty())
61  {
62  t << " name=\"" << name << "\"";
63  }
64  if (!width.isEmpty())
65  {
66  t << " width=\"" << convertToXML(width) << "\"";
67  }
68  else if (!height.isEmpty())
69  {
70  t << " height=\"" << convertToXML(height) << "\"";
71  }
72  if (doCaption)
73  {
74  t << " caption=\"";
75  visitCaption(parent, children);
76  t << "\"";
77  }
78  t << ">";
79 }
80 
81 static void visitPostEnd(FTextStream &t, const char *cmd)
82 {
83  t << "</" << cmd << ">" << endl;
84 }
85 
87  : DocVisitor(DocVisitor_XML), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
88 {
89 }
90 
91  //--------------------------------------
92  // visitor functions for leaf nodes
93  //--------------------------------------
94 
96 {
97  if (m_hide) return;
98  filter(w->word());
99 }
100 
102 {
103  if (m_hide) return;
104  startLink(w->ref(),w->file(),w->anchor());
105  filter(w->word());
106  endLink();
107 }
108 
110 {
111  if (m_hide) return;
112  if (m_insidePre)
113  {
114  m_t << w->chars();
115  }
116  else
117  {
118  m_t << " ";
119  }
120 }
121 
123 {
124  if (m_hide) return;
125  const char *res = HtmlEntityMapper::instance()->xml(s->symbol());
126  if (res)
127  {
128  m_t << res;
129  }
130  else
131  {
132  err("XML: non supported HTML-entity found: %s\n",HtmlEntityMapper::instance()->html(s->symbol(),TRUE));
133  }
134 }
135 
137 {
138  if (m_hide) return;
139  m_t << "<ulink url=\"";
140  if (u->isEmail()) m_t << "mailto:";
141  filter(u->url());
142  m_t << "\">";
143  filter(u->url());
144  m_t << "</ulink>";
145 }
146 
148 {
149  if (m_hide) return;
150  m_t << "<linebreak/>\n";
151 }
152 
154 {
155  if (m_hide) return;
156  m_t << "<hruler/>\n";
157 }
158 
160 {
161  if (m_hide) return;
162  switch (s->style())
163  {
165  if (s->enable()) m_t << "<bold>"; else m_t << "</bold>";
166  break;
168  if (s->enable()) m_t << "<emphasis>"; else m_t << "</emphasis>";
169  break;
171  if (s->enable()) m_t << "<computeroutput>"; else m_t << "</computeroutput>";
172  break;
174  if (s->enable()) m_t << "<subscript>"; else m_t << "</subscript>";
175  break;
177  if (s->enable()) m_t << "<superscript>"; else m_t << "</superscript>";
178  break;
180  if (s->enable()) m_t << "<center>"; else m_t << "</center>";
181  break;
183  if (s->enable()) m_t << "<small>"; else m_t << "</small>";
184  break;
186  if (s->enable())
187  {
188  m_t << "<preformatted>";
189  m_insidePre=TRUE;
190  }
191  else
192  {
193  m_t << "</preformatted>";
194  m_insidePre=FALSE;
195  }
196  break;
197  case DocStyleChange::Div: /* HTML only */ break;
198  case DocStyleChange::Span: /* HTML only */ break;
199  }
200 }
201 
203 {
204  if (m_hide) return;
205  QCString lang = m_langExt;
206  if (!s->language().isEmpty()) // explicit language setting
207  {
208  lang = s->language();
209  }
210  SrcLangExt langExt = getLanguageFromFileName(lang);
211  switch(s->type())
212  {
213  case DocVerbatim::Code: // fall though
214  m_t << "<programlisting>";
216  ->parseCode(m_ci,s->context(),s->text(),langExt,
217  s->isExample(),s->exampleFile());
218  m_t << "</programlisting>";
219  break;
220  case DocVerbatim::Verbatim:
221  m_t << "<verbatim>";
222  filter(s->text());
223  m_t << "</verbatim>";
224  break;
225  case DocVerbatim::HtmlOnly:
226  case DocVerbatim::RtfOnly:
227  case DocVerbatim::ManOnly:
230  /* nothing */
231  break;
232  case DocVerbatim::XmlOnly:
233  m_t << s->text();
234  break;
235  case DocVerbatim::Dot:
236  visitPreStart(m_t, "dot", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height());
237  filter(s->text());
238  visitPostEnd(m_t, "dot");
239  break;
240  case DocVerbatim::Msc:
241  visitPreStart(m_t, "msc", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height());
242  filter(s->text());
243  visitPostEnd(m_t, "msc");
244  break;
246  visitPreStart(m_t, "plantuml", s->hasCaption(), this, s->children(), QCString(""), FALSE, DocImage::Html, s->width(), s->height());
247  filter(s->text());
248  visitPostEnd(m_t, "plantuml");
249  break;
250  }
251 }
252 
254 {
255  if (m_hide) return;
256  m_t << "<anchor id=\"" << anc->file() << "_1" << anc->anchor() << "\"/>";
257 }
258 
260 {
261  if (m_hide) return;
262  SrcLangExt langExt = getLanguageFromFileName(inc->extension());
263  switch(inc->type())
264  {
266  {
267  m_t << "<programlisting>";
268  QFileInfo cfi( inc->file() );
269  FileDef fd( cfi.dirPath().utf8(), cfi.fileName().utf8() );
271  ->parseCode(m_ci,inc->context(),
272  inc->text(),
273  langExt,
274  inc->isExample(),
275  inc->exampleFile(),
276  &fd, // fileDef,
277  -1, // start line
278  -1, // end line
279  FALSE, // inline fragment
280  0, // memberDef
281  TRUE // show line numbers
282  );
283  m_t << "</programlisting>";
284  }
285  break;
286  case DocInclude::Include:
287  m_t << "<programlisting>";
289  ->parseCode(m_ci,inc->context(),
290  inc->text(),
291  langExt,
292  inc->isExample(),
293  inc->exampleFile(),
294  0, // fileDef
295  -1, // startLine
296  -1, // endLine
297  TRUE, // inlineFragment
298  0, // memberDef
299  FALSE // show line numbers
300  );
301  m_t << "</programlisting>";
302  break;
304  break;
306  m_t << "<htmlonly>";
307  filter(inc->text());
308  m_t << "</htmlonly>";
309  break;
311  m_t << "<latexonly>";
312  filter(inc->text());
313  m_t << "</latexonly>";
314  break;
316  m_t << "<verbatim>";
317  filter(inc->text());
318  m_t << "</verbatim>";
319  break;
320  case DocInclude::Snippet:
321  m_t << "<programlisting>";
323  ->parseCode(m_ci,
324  inc->context(),
325  extractBlock(inc->text(),inc->blockId()),
326  langExt,
327  inc->isExample(),
328  inc->exampleFile()
329  );
330  m_t << "</programlisting>";
331  break;
334  err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s"
335  "Please create a bug report\n",__FILE__);
336  break;
337  }
338 }
339 
341 {
342  //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
343  // op->type(),op->isFirst(),op->isLast(),op->text().data());
344  if (op->isFirst())
345  {
346  if (!m_hide)
347  {
348  m_t << "<programlisting>";
349  }
350  pushEnabled();
351  m_hide = TRUE;
352  }
354  if (op->type()!=DocIncOperator::Skip)
355  {
356  popEnabled();
357  if (!m_hide)
358  {
360  ->parseCode(m_ci,op->context(),
361  op->text(),langExt,op->isExample(),
362  op->exampleFile());
363  }
364  pushEnabled();
365  m_hide=TRUE;
366  }
367  if (op->isLast())
368  {
369  popEnabled();
370  if (!m_hide) m_t << "</programlisting>";
371  }
372  else
373  {
374  if (!m_hide) m_t << endl;
375  }
376 }
377 
379 {
380  if (m_hide) return;
381  m_t << "<formula id=\"" << f->id() << "\">";
382  filter(f->text());
383  m_t << "</formula>";
384 }
385 
387 {
388  if (m_hide) return;
389  m_t << "<indexentry>"
390  "<primaryie>";
391  filter(ie->entry());
392  m_t << "</primaryie>"
393  "<secondaryie></secondaryie>"
394  "</indexentry>";
395 }
396 
398 {
399  if (sep->parent() && sep->parent()->kind()==DocNode::Kind_SimpleSect)
400  {
401  visitPost((DocSimpleSect*)sep->parent()); // end current section
402  visitPre((DocSimpleSect*)sep->parent()); // start new section
403  }
404 }
405 
407 {
408  if (m_hide) return;
409  if (!cite->file().isEmpty()) startLink(cite->ref(),cite->file(),cite->anchor());
410  filter(cite->text());
411  if (!cite->file().isEmpty()) endLink();
412 }
413 
414 //--------------------------------------
415 // visitor functions for compound nodes
416 //--------------------------------------
417 
419 {
420  if (m_hide) return;
421  if (l->isEnumList())
422  {
423  m_t << "<orderedlist>\n";
424  }
425  else
426  {
427  m_t << "<itemizedlist>\n";
428  }
429 }
430 
432 {
433  if (m_hide) return;
434  if (l->isEnumList())
435  {
436  m_t << "</orderedlist>\n";
437  }
438  else
439  {
440  m_t << "</itemizedlist>\n";
441  }
442 }
443 
445 {
446  if (m_hide) return;
447  m_t << "<listitem>";
448 }
449 
451 {
452  if (m_hide) return;
453  m_t << "</listitem>";
454 }
455 
457 {
458  if (m_hide) return;
459  m_t << "<para>";
460 }
461 
463 {
464  if (m_hide) return;
465  m_t << "</para>";
466 }
467 
469 {
470  //m_t << "<hr><h4><font color=\"red\">New parser:</font></h4>\n";
471 }
472 
474 {
475  //m_t << "<hr><h4><font color=\"red\">Old parser:</font></h4>\n";
476 }
477 
479 {
480  if (m_hide) return;
481  m_t << "<simplesect kind=\"";
482  switch(s->type())
483  {
484  case DocSimpleSect::See:
485  m_t << "see"; break;
486  case DocSimpleSect::Return:
487  m_t << "return"; break;
488  case DocSimpleSect::Author:
489  m_t << "author"; break;
491  m_t << "authors"; break;
493  m_t << "version"; break;
494  case DocSimpleSect::Since:
495  m_t << "since"; break;
496  case DocSimpleSect::Date:
497  m_t << "date"; break;
498  case DocSimpleSect::Note:
499  m_t << "note"; break;
501  m_t << "warning"; break;
502  case DocSimpleSect::Pre:
503  m_t << "pre"; break;
504  case DocSimpleSect::Post:
505  m_t << "post"; break;
507  m_t << "copyright"; break;
509  m_t << "invariant"; break;
511  m_t << "remark"; break;
513  m_t << "attention"; break;
514  case DocSimpleSect::User:
515  m_t << "par"; break;
516  case DocSimpleSect::Rcs:
517  m_t << "rcs"; break;
518  case DocSimpleSect::Unknown: break;
519  }
520  m_t << "\">";
521 }
522 
524 {
525  if (m_hide) return;
526  m_t << "</simplesect>\n";
527 }
528 
530 {
531  if (m_hide) return;
532  m_t << "<title>";
533 }
534 
536 {
537  if (m_hide) return;
538  m_t << "</title>";
539 }
540 
542 {
543  if (m_hide) return;
544  m_t << "<itemizedlist>\n";
545 }
546 
548 {
549  if (m_hide) return;
550  m_t << "</itemizedlist>\n";
551 }
552 
554 {
555  if (m_hide) return;
556  m_t << "<listitem>";
557 }
558 
560 {
561  if (m_hide) return;
562  m_t << "</listitem>\n";
563 }
564 
566 {
567  if (m_hide) return;
568  m_t << "<sect" << s->level() << " id=\"" << s->file();
569  if (!s->anchor().isEmpty()) m_t << "_1" << s->anchor();
570  m_t << "\">" << endl;
571  m_t << "<title>";
573  m_t << "</title>" << endl;
574 }
575 
577 {
578  m_t << "</sect" << s->level() << ">\n";
579 }
580 
582 {
583  if (m_hide) return;
584  if (s->type()==DocHtmlList::Ordered)
585  m_t << "<orderedlist>\n";
586  else
587  m_t << "<itemizedlist>\n";
588 }
589 
591 {
592  if (m_hide) return;
593  if (s->type()==DocHtmlList::Ordered)
594  m_t << "</orderedlist>\n";
595  else
596  m_t << "</itemizedlist>\n";
597 }
598 
600 {
601  if (m_hide) return;
602  m_t << "<listitem>\n";
603 }
604 
606 {
607  if (m_hide) return;
608  m_t << "</listitem>\n";
609 }
610 
612 {
613  if (m_hide) return;
614  m_t << "<variablelist>\n";
615 }
616 
618 {
619  if (m_hide) return;
620  m_t << "</variablelist>\n";
621 }
622 
624 {
625  if (m_hide) return;
626  m_t << "<varlistentry><term>";
627 }
628 
630 {
631  if (m_hide) return;
632  m_t << "</term></varlistentry>\n";
633 }
634 
636 {
637  if (m_hide) return;
638  m_t << "<listitem>";
639 }
640 
642 {
643  if (m_hide) return;
644  m_t << "</listitem>\n";
645 }
646 
648 {
649  if (m_hide) return;
650  m_t << "<table rows=\"" << t->numRows()
651  << "\" cols=\"" << t->numColumns() << "\">" ;
652 }
653 
655 {
656  if (m_hide) return;
657  m_t << "</table>\n";
658 }
659 
661 {
662  if (m_hide) return;
663  m_t << "<row>\n";
664 }
665 
667 {
668  if (m_hide) return;
669  m_t << "</row>\n";
670 }
671 
673 {
674  if (m_hide) return;
675  if (c->isHeading()) m_t << "<entry thead=\"yes\">"; else m_t << "<entry thead=\"no\">";
676 }
677 
679 {
680  if (m_hide) return;
681  m_t << "</entry>";
682 }
683 
685 {
686  if (m_hide) return;
687  m_t << "<caption>";
688 }
689 
691 {
692  if (m_hide) return;
693  m_t << "</caption>\n";
694 }
695 
697 {
698  if (m_hide) return;
699  m_t << "<internal>";
700 }
701 
703 {
704  if (m_hide) return;
705  m_t << "</internal>" << endl;
706 }
707 
709 {
710  if (m_hide) return;
711  m_t << "<ulink url=\"";
712  filter(href->url());
713  m_t << "\">";
714 }
715 
717 {
718  if (m_hide) return;
719  m_t << "</ulink>";
720 }
721 
723 {
724  if (m_hide) return;
725  m_t << "<heading level=\"" << header->level() << "\">";
726 }
727 
729 {
730  if (m_hide) return;
731  m_t << "</heading>\n";
732 }
733 
735 {
736  if (m_hide) return;
737 
738  QCString baseName=img->name();
739  int i;
740  if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
741  {
742  baseName=baseName.right(baseName.length()-i-1);
743  }
744  visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height());
745 
746  // copy the image to the output dir
747  QFile inImage(img->name());
748  QFile outImage(Config_getString(XML_OUTPUT)+"/"+baseName.data());
749  if (inImage.open(IO_ReadOnly))
750  {
751  if (outImage.open(IO_WriteOnly))
752  {
753  char *buffer = new char[inImage.size()];
754  inImage.readBlock(buffer,inImage.size());
755  outImage.writeBlock(buffer,inImage.size());
756  outImage.flush();
757  delete[] buffer;
758  }
759  }
760 }
761 
763 {
764  if (m_hide) return;
765  visitPostEnd(m_t, "image");
766 }
767 
769 {
770  if (m_hide) return;
771  visitPreStart(m_t, "dotfile", FALSE, this, df->children(), df->file(), FALSE, DocImage::Html, df->width(), df->height());
772 }
773 
775 {
776  if (m_hide) return;
777  visitPostEnd(m_t, "dotfile");
778 }
779 
781 {
782  if (m_hide) return;
783  visitPreStart(m_t, "mscfile", FALSE, this, df->children(), df->file(), FALSE, DocImage::Html, df->width(), df->height());
784 }
785 
787 {
788  if (m_hide) return;
789  visitPostEnd(m_t, "mscfile");
790 }
791 
793 {
794  if (m_hide) return;
795  visitPreStart(m_t, "diafile", FALSE, this, df->children(), df->file(), FALSE, DocImage::Html, df->width(), df->height());
796 }
797 
799 {
800  if (m_hide) return;
801  visitPostEnd(m_t, "diafile");
802 }
803 
805 {
806  if (m_hide) return;
807  startLink(lnk->ref(),lnk->file(),lnk->anchor());
808 }
809 
811 {
812  if (m_hide) return;
813  endLink();
814 }
815 
817 {
818  if (m_hide) return;
819  if (!ref->file().isEmpty())
820  {
821  startLink(ref->ref(),ref->file(),ref->isSubPage() ? QCString() : ref->anchor());
822  }
823  if (!ref->hasLinkText()) filter(ref->targetTitle());
824 }
825 
827 {
828  if (m_hide) return;
829  if (!ref->file().isEmpty()) endLink();
830  //m_t << " ";
831 }
832 
834 {
835  if (m_hide) return;
836  m_t << "<tocitem id=\"" << ref->file() << "_1" << ref->anchor() << "\">";
837 }
838 
840 {
841  if (m_hide) return;
842  m_t << "</tocitem>" << endl;
843 }
844 
846 {
847  if (m_hide) return;
848  m_t << "<toclist>" << endl;
849 }
850 
852 {
853  if (m_hide) return;
854  m_t << "</toclist>" << endl;
855 }
856 
857 //void XmlDocVisitor::visitPre(DocLanguage *l)
858 //{
859 // if (m_hide) return;
860 // m_t << "<language langid=\"" << l->id() << "\">";
861 //}
862 //
863 //void XmlDocVisitor::visitPost(DocLanguage *)
864 //{
865 // if (m_hide) return;
866 // m_t << "</language>" << endl;
867 //}
868 
870 {
871  if (m_hide) return;
872  m_t << "<parameterlist kind=\"";
873  switch(s->type())
874  {
875  case DocParamSect::Param:
876  m_t << "param"; break;
877  case DocParamSect::RetVal:
878  m_t << "retval"; break;
880  m_t << "exception"; break;
882  m_t << "templateparam"; break;
883  default:
884  ASSERT(0);
885  }
886  m_t << "\">";
887 }
888 
890 {
891  if (m_hide) return;
892  m_t << "</parameterlist>" << endl;
893 }
894 
896 {
897  if (m_hide) return;
898  m_t << "<parameteritem>" << endl;
899  m_t << "<parameternamelist>" << endl;
900  //QStrListIterator li(pl->parameters());
901  //const char *s;
902  QListIterator<DocNode> li(pl->parameters());
903  DocNode *param;
904  for (li.toFirst();(param=li.current());++li)
905  {
906  if (pl->paramTypes().count()>0)
907  {
908  QListIterator<DocNode> li(pl->paramTypes());
909  DocNode *type;
910  for (li.toFirst();(type=li.current());++li)
911  {
912  m_t << "<parametertype>";
913  if (type->kind()==DocNode::Kind_Word)
914  {
915  visit((DocWord*)type);
916  }
917  else if (type->kind()==DocNode::Kind_LinkedWord)
918  {
919  visit((DocLinkedWord*)type);
920  }
921  m_t << "</parametertype>" << endl;
922  }
923  }
924  m_t << "<parametername";
926  {
927  m_t << " direction=\"";
928  if (pl->direction()==DocParamSect::In)
929  {
930  m_t << "in";
931  }
932  else if (pl->direction()==DocParamSect::Out)
933  {
934  m_t << "out";
935  }
936  else if (pl->direction()==DocParamSect::InOut)
937  {
938  m_t << "inout";
939  }
940  m_t << "\"";
941  }
942  m_t << ">";
943  if (param->kind()==DocNode::Kind_Word)
944  {
945  visit((DocWord*)param);
946  }
947  else if (param->kind()==DocNode::Kind_LinkedWord)
948  {
949  visit((DocLinkedWord*)param);
950  }
951  m_t << "</parametername>" << endl;
952  }
953  m_t << "</parameternamelist>" << endl;
954  m_t << "<parameterdescription>" << endl;
955 }
956 
958 {
959  if (m_hide) return;
960  m_t << "</parameterdescription>" << endl;
961  m_t << "</parameteritem>" << endl;
962 }
963 
965 {
966  if (m_hide) return;
967  if (x->title().isEmpty()) return;
968  m_t << "<xrefsect id=\"";
969  m_t << x->file() << "_1" << x->anchor();
970  m_t << "\">";
971  m_t << "<xreftitle>";
972  filter(x->title());
973  m_t << "</xreftitle>";
974  m_t << "<xrefdescription>";
975 }
976 
978 {
979  if (m_hide) return;
980  if (x->title().isEmpty()) return;
981  m_t << "</xrefdescription>";
982  m_t << "</xrefsect>";
983 }
984 
986 {
987  if (m_hide) return;
988  startLink(0,ref->file(),ref->anchor());
989 }
990 
992 {
993  if (m_hide) return;
994  endLink();
995  m_t << " ";
996 }
997 
999 {
1000  if (m_hide) return;
1001  m_t << "<copydoc link=\"" << convertToXML(c->link()) << "\">";
1002 }
1003 
1005 {
1006  if (m_hide) return;
1007  m_t << "</copydoc>" << endl;
1008 }
1009 
1011 {
1012 }
1013 
1015 {
1016 }
1017 
1019 {
1020  if (m_hide) return;
1021  m_t << "<blockquote>";
1022 }
1023 
1025 {
1026  if (m_hide) return;
1027  m_t << "</blockquote>";
1028 }
1029 
1031 {
1032 }
1033 
1035 {
1036 }
1037 
1039 {
1040  if (m_hide) return;
1041  m_t << "<parblock>";
1042 }
1043 
1045 {
1046  if (m_hide) return;
1047  m_t << "</parblock>";
1048 }
1049 
1050 
1051 void XmlDocVisitor::filter(const char *str)
1052 {
1053  m_t << convertToXML(str);
1054 }
1055 
1056 void XmlDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor)
1057 {
1058  //printf("XmlDocVisitor: file=%s anchor=%s\n",file.data(),anchor.data());
1059  m_t << "<ref refid=\"" << file;
1060  if (!anchor.isEmpty()) m_t << "_1" << anchor;
1061  m_t << "\" kindref=\"";
1062  if (!anchor.isEmpty()) m_t << "member"; else m_t << "compound";
1063  m_t << "\"";
1064  if (!ref.isEmpty()) m_t << " external=\"" << ref << "\"";
1065  m_t << ">";
1066 }
1067 
1069 {
1070  m_t << "</ref>";
1071 }
1072 
1074 {
1075  m_enabled.push(new bool(m_hide));
1076 }
1077 
1079 {
1080  bool *v=m_enabled.pop();
1081  ASSERT(v!=0);
1082  m_hide = *v;
1083  delete v;
1084 }
1085