Orb/Doxygen/src/xmlditadocvisitor.cpp
changeset 3 d8fccb2cd802
child 4 468f4c8d3d5b
equal deleted inserted replaced
2:932c358ece3e 3:d8fccb2cd802
       
     1 
       
     2 #include "xmldita.h"
       
     3 #include "xmlditadocvisitor.h"
       
     4 #include "xmlditatrace.h"
       
     5 #include "docparser.h"
       
     6 #include "language.h"
       
     7 #include "doxygen.h"
       
     8 #include "outputgen.h"
       
     9 #include "xmlgen.h"
       
    10 #include "dot.h"
       
    11 #include "message.h"
       
    12 #include "util.h"
       
    13 #include <qfileinfo.h> 
       
    14 #include "parserintf.h"
       
    15 
       
    16 //#define DITA_DOT_HACK_REMOVE_XREFS
       
    17 #undef DITA_DOT_HACK_REMOVE_XREFS
       
    18 // If 0 there is no <simpletable> support
       
    19 // Need to lazily evaluate this so that <simpletable> is only written if
       
    20 // there is content in the table
       
    21 #define DITA_SIMPLETABLE_SUPPORT 0
       
    22 
       
    23 XmlDitaDocVisitor::XmlDitaDocVisitor(XmlStream &s,CodeOutputInterface &ci) 
       
    24   : DocVisitor(DocVisitor_XML), xmlStream(s), xmlElemStack(s), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE), 
       
    25     m_insideParamlist(FALSE), paramMap(), paramDict(), currParam()
       
    26 {
       
    27 	paramDict.setAutoDelete(true);
       
    28 }
       
    29 
       
    30  
       
    31   //--------------------------------------
       
    32   // visitor functions for leaf nodes
       
    33   //--------------------------------------
       
    34 
       
    35 void XmlDitaDocVisitor::visit(DocWord *w)
       
    36 {
       
    37 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocWord*)", w)
       
    38 	if (m_hide) {
       
    39 		return;
       
    40 	}
       
    41 	// Catches normal text (text outside of a tag or command)
       
    42 	// and puts it in a "p"
       
    43 	if (xmlElemStack.isEmpty()) {
       
    44 		visitPreDefault("p");
       
    45 	}	
       
    46 	write(w->word());
       
    47 }
       
    48 
       
    49 void XmlDitaDocVisitor::visit(DocLinkedWord *w)
       
    50 {
       
    51 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocLinkedWord*)", w)
       
    52 	if (m_hide) {
       
    53 		return;
       
    54 	}
       
    55 	//printf("XmlDitaDocVisitor calling startLink() DocLinkedWord=`%s'\n", w->word().data());
       
    56 	Definition *d = w->getDefinition();
       
    57 	if (0) {
       
    58 		QString myName;
       
    59 		myName = d->qualifiedName();
       
    60 		//printf("XmlDitaDocVisitor calling startLink() DocLinkedWord [name]=`%s'\n", myName.data());
       
    61 		startLink("", myName, "");
       
    62 	} else {
       
    63 		//printf("XmlDitaDocVisitor calling startLink() DocLinkedWord [file]=`%s'\n", w->file().data());
       
    64 #if DITA_SUPRESS_NAMESPACE_LINKS
       
    65 		if (w->file().find("namespace") != 0) {
       
    66 			startLink(w->ref(), w->file(), w->anchor());
       
    67 		}
       
    68 #else
       
    69 		startLink(w->ref(), w->file(), w->anchor());
       
    70 #endif
       
    71 	}
       
    72 	write(w->word());
       
    73 #if DITA_SUPRESS_NAMESPACE_LINKS
       
    74 	if (w->file().find("namespace") != 0) {
       
    75 		endLink();
       
    76 	}
       
    77 #else
       
    78 	endLink();
       
    79 #endif
       
    80 }
       
    81 
       
    82 void XmlDitaDocVisitor::visit(DocWhiteSpace *w)
       
    83 {
       
    84 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocWhiteSpace*)", w)
       
    85 	if (m_hide) {
       
    86 		return;
       
    87 	}
       
    88 	if (m_insidePre) {
       
    89 		write(w->chars());
       
    90 	} else {
       
    91 		write(" ");
       
    92 	}
       
    93 }
       
    94 
       
    95 void XmlDitaDocVisitor::visit(DocSymbol *s)
       
    96 {
       
    97 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocSymbol*)", s)
       
    98   if (m_hide) {
       
    99 	return;
       
   100   }
       
   101 
       
   102   switch(s->symbol())
       
   103   {
       
   104     case DocSymbol::BSlash:  write("\\"); break;
       
   105     case DocSymbol::At:      write("@"); break;
       
   106 	// NOTE: The XMl stream will translate entities i.e. "&" to "&amp;"
       
   107     case DocSymbol::Less:    write("<"); break;
       
   108     case DocSymbol::Greater: write(">"); break;
       
   109     case DocSymbol::Amp:     write("&"); break;
       
   110     case DocSymbol::Dollar:  write("$"); break;
       
   111     case DocSymbol::Hash:    write("#"); break;
       
   112     case DocSymbol::Percent: write("%"); break;
       
   113 	case DocSymbol::Apos:    write("'"); break;
       
   114     case DocSymbol::Quot:    write("\""); break;
       
   115 	case DocSymbol::Copy:    xmlStream.writeUnicode("copy");	break;
       
   116     case DocSymbol::Tm:      xmlStream.writeUnicode("trade");	break;
       
   117     case DocSymbol::Reg:     xmlStream.writeUnicode("reg");		break;
       
   118     case DocSymbol::Lsquo:   xmlStream.writeUnicode("lsquo");		break;
       
   119     case DocSymbol::Rsquo:	 xmlStream.writeUnicode("rsquo");		break;
       
   120     case DocSymbol::Ldquo:	 xmlStream.writeUnicode("ldquo");		break;
       
   121     case DocSymbol::Rdquo:	 xmlStream.writeUnicode("rdquo");		break;
       
   122     case DocSymbol::Ndash:	 xmlStream.writeUnicode("ndash");		break;
       
   123     case DocSymbol::Mdash:	 xmlStream.writeUnicode("mdash");		break;
       
   124 	case DocSymbol::Uml:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"uml")); break;
       
   125 	case DocSymbol::Acute:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"acute")); break;
       
   126 	case DocSymbol::Grave:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"grave")); break;
       
   127 	case DocSymbol::Circ:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"circ")); break;
       
   128 	case DocSymbol::Tilde:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"tilde")); break;
       
   129 	case DocSymbol::Cedil:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"cedil")); break;
       
   130 	case DocSymbol::Ring:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"ring")); break;
       
   131 	case DocSymbol::Slash:	 xmlStream.writeUnicode((const char*)(QString(QChar(s->letter()))+"slash")); break;
       
   132     case DocSymbol::Szlig:	 xmlStream.writeUnicode("szlig");					   break;
       
   133     case DocSymbol::Nbsp:    xmlStream.writeUnicode("nbsp");					   break;
       
   134     case DocSymbol::Aelig:	 xmlStream.writeUnicode("aelig");					   break;
       
   135     case DocSymbol::AElig:   xmlStream.writeUnicode("AElig");					   break;
       
   136     default:
       
   137 		err("Error: unknown symbol found\n");
       
   138   }
       
   139 }
       
   140 
       
   141 void XmlDitaDocVisitor::visit(DocURL *u)
       
   142 {
       
   143 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocURL*)", u)
       
   144 	if (m_hide) {
       
   145 	  return;
       
   146 	}
       
   147 	if (u->isEmail()) {
       
   148 		startXref(QString("mailto:")+QString(u->url()), u->url());
       
   149 	} else {
       
   150 		// Need format attribute
       
   151 		AttributeMap myMap;
       
   152 		myMap["href"] = u->url();
       
   153 		myMap["format"] = "html";
       
   154 		push("xref", myMap);
       
   155 		write(u->url());	
       
   156 		//startXref(u->url(), u->url());
       
   157 	}
       
   158 	endXref();
       
   159 }
       
   160 
       
   161 void XmlDitaDocVisitor::visit(DocLineBreak *lb)
       
   162 {
       
   163 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocLineBreak*)", lb)
       
   164 	if (m_hide){
       
   165 	  return;
       
   166 	}
       
   167 	//pushpop("linebreak");
       
   168 	//if (lb->parent()->kind() == lb->Kind_Verbatim) {
       
   169 	if (m_insidePre) {
       
   170 		write("\n");
       
   171 	}
       
   172 }
       
   173 
       
   174 void XmlDitaDocVisitor::visit(DocHorRuler *)
       
   175 {
       
   176 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHorRuler*)")
       
   177 	if (m_hide) {
       
   178 	  return;
       
   179 	}
       
   180 	//pushpop("hruler");
       
   181 	xmlStream.comment("hruler not supported by DITA 1.1");
       
   182 }
       
   183 
       
   184 void XmlDitaDocVisitor::visit(DocStyleChange *s)
       
   185 {
       
   186 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocStyleChange*)", s)
       
   187 	if (m_hide) {
       
   188 	  return;
       
   189 	}
       
   190 	switch (s->style())
       
   191 	{
       
   192 	case DocStyleChange::Bold:
       
   193 		if (s->enable()) {
       
   194 			push("b");
       
   195 		} else { 
       
   196 			pop("b");
       
   197 		}
       
   198 		break;
       
   199 	case DocStyleChange::Italic:
       
   200 		if (s->enable()) {
       
   201 			push("i");
       
   202 		} else {
       
   203 			pop("i");
       
   204 		}
       
   205 		break;
       
   206 	case DocStyleChange::Code:
       
   207 		if (s->enable()) {
       
   208 			push("tt");
       
   209 		} else {
       
   210 			pop("tt");
       
   211 		}
       
   212 		break;
       
   213 	case DocStyleChange::Subscript:
       
   214 		if (s->enable()) {
       
   215 			push("sub");
       
   216 		} else {
       
   217 			pop("sub");
       
   218 		}
       
   219 		break;
       
   220 	case DocStyleChange::Superscript:
       
   221 		if (s->enable()) {
       
   222 			push("sup");
       
   223 		} else {
       
   224 			pop("sup");
       
   225 		}
       
   226 		break;
       
   227 	case DocStyleChange::Center:
       
   228 		if (s->enable()) {
       
   229 			xmlStream.comment("center not supported by DITA 1.1");
       
   230 			//push("center");
       
   231 		} else {
       
   232 			//pop("center");
       
   233 		}
       
   234 		break;
       
   235 	case DocStyleChange::Small:
       
   236 		if (s->enable()) {
       
   237 			xmlStream.comment("small not supported by DITA 1.1");
       
   238 			//push("small");
       
   239 		} else {
       
   240 			//pop("small");
       
   241 		}
       
   242 		break;
       
   243 	case DocStyleChange::Preformatted:
       
   244 		if (s->enable()) 
       
   245 		{
       
   246 			push("pre");  
       
   247 			m_insidePre = TRUE;
       
   248 		} else {
       
   249 			pop("pre");
       
   250 			m_insidePre = FALSE;
       
   251 		}
       
   252 		break;
       
   253 	case DocStyleChange::Div:  /* HTML only */ break;
       
   254 	case DocStyleChange::Span: /* HTML only */ break;
       
   255 	}
       
   256 }
       
   257 
       
   258 void XmlDitaDocVisitor::visit(DocVerbatim *s)
       
   259 {
       
   260 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocVerbatim*)", s)
       
   261 	if (m_hide) {
       
   262 	  return;
       
   263 	}
       
   264 	switch(s->type())
       
   265 	{
       
   266 		case DocVerbatim::Code:
       
   267 			push("codeblock");
       
   268 			write(s->text());
       
   269 			pop("codeblock");
       
   270 			break;
       
   271 		case DocVerbatim::Verbatim:
       
   272 			pushpop("pre", s->text());
       
   273 			break;
       
   274 		case DocVerbatim::HtmlOnly: 
       
   275 			//pushpop("htmlonly", s->text());
       
   276 			break;
       
   277 		case DocVerbatim::ManOnly: 
       
   278 			//pushpop("manonly", s->text());
       
   279 			break;
       
   280 		case DocVerbatim::LatexOnly: 
       
   281 			//pushpop("latexonly", s->text());
       
   282 			break;
       
   283 		case DocVerbatim::XmlOnly: 
       
   284 			write(s->text());
       
   285 			break;
       
   286 		case DocVerbatim::Dot: 
       
   287 			//pushpop("dot", s->text());
       
   288 			break;
       
   289 		case DocVerbatim::Msc: 
       
   290 			//pushpop("msc", s->text());
       
   291 			break;
       
   292 	}
       
   293 }
       
   294 
       
   295 void XmlDitaDocVisitor::visit(DocAnchor *anc)
       
   296 {
       
   297 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocAnchor*)", anc)
       
   298 	if (m_hide) {
       
   299 	  return;
       
   300 	}
       
   301 	xmlElemStack.addAttribute("id", anc->file()+"_1"+anc->anchor());
       
   302 	//push("anchor", "id", anc->file()+"_1"+anc->anchor());
       
   303 	//pop("anchor");
       
   304 }
       
   305 
       
   306 void XmlDitaDocVisitor::visit(DocInclude *inc)
       
   307 {
       
   308 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocInclude*)", inc)
       
   309 	if (m_hide) {
       
   310 	  return;
       
   311 	}
       
   312   switch(inc->type())
       
   313   {
       
   314     case DocInclude::IncWithLines:
       
   315       { 
       
   316          push("codeblock");
       
   317          QFileInfo cfi( inc->file() );
       
   318          FileDef fd( cfi.dirPath(), cfi.fileName() );
       
   319          Doxygen::parserManager->getParser(inc->extension())
       
   320                                ->parseCode(m_ci,inc->context(),
       
   321                                            inc->text().latin1(),
       
   322                                            inc->isExample(),
       
   323                                            inc->exampleFile(), &fd);
       
   324          pop("codeblock"); 
       
   325       }
       
   326       break;    
       
   327     case DocInclude::Include: 
       
   328       push("codeblock");
       
   329       Doxygen::parserManager->getParser(inc->extension())
       
   330                             ->parseCode(m_ci,inc->context(),
       
   331                                         inc->text().latin1(),
       
   332                                         inc->isExample(),
       
   333                                         inc->exampleFile());
       
   334       pop("codeblock"); 
       
   335       break;
       
   336     case DocInclude::DontInclude: 
       
   337       break;
       
   338     case DocInclude::HtmlInclude: 
       
   339 	  //pushpop("htmlonly", inc->text());
       
   340       break;
       
   341     case DocInclude::VerbInclude: 
       
   342 	  pushpop("pre", inc->text());
       
   343       break;
       
   344   }
       
   345 }
       
   346 
       
   347 void XmlDitaDocVisitor::visit(DocIncOperator *op)
       
   348 {
       
   349 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocIncOperator*)", op)
       
   350   if (op->isFirst()) 
       
   351   {
       
   352     if (!m_hide) {
       
   353 		push("codeblock");
       
   354     }
       
   355     pushEnabled();
       
   356     m_hide = TRUE;
       
   357   }
       
   358   if (op->type()!=DocIncOperator::Skip) 
       
   359   {
       
   360     popEnabled();
       
   361     if (!m_hide) {
       
   362       Doxygen::parserManager->getParser(m_langExt)
       
   363                             ->parseCode(m_ci,op->context(),
       
   364                                         op->text().latin1(),op->isExample(),
       
   365                                         op->exampleFile());
       
   366     }
       
   367     pushEnabled();
       
   368     m_hide=TRUE;
       
   369   }
       
   370   if (op->isLast())  
       
   371   {
       
   372     popEnabled();
       
   373 	if (!m_hide) {
       
   374 		pop("codeblock"); 
       
   375 	}
       
   376   }
       
   377 }
       
   378 
       
   379 void XmlDitaDocVisitor::visit(DocFormula *f)
       
   380 {
       
   381 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocFormula*)", f)
       
   382 	write(f->text());
       
   383 #if 0
       
   384 	if (m_hide) {
       
   385 	  return;
       
   386 	}
       
   387   QString s;
       
   388   s.setNum(f->id());
       
   389   push("formula", "id", s);
       
   390   write(f->text());
       
   391   pop("formula");
       
   392 #endif
       
   393 }
       
   394 
       
   395 void XmlDitaDocVisitor::visit(DocIndexEntry *ie)
       
   396 {
       
   397 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visit(DocIndexEntry*)", ie)
       
   398 	if (m_hide) {
       
   399 	  return;
       
   400 	}
       
   401 
       
   402 	push("indexterm");
       
   403 	write(ie->entry());
       
   404 	pop("indexterm");
       
   405 #if 0
       
   406 	push("indexentry");
       
   407 	push("primaryie");
       
   408 	write(ie->entry());
       
   409 	pop("primaryie");
       
   410 	pushpop("secondaryie");
       
   411 	pop("indexentry");
       
   412 #endif
       
   413 }
       
   414 
       
   415 void XmlDitaDocVisitor::visit(DocSimpleSectSep *)
       
   416 {
       
   417   //pushpop("simplesectsep");
       
   418 }
       
   419 
       
   420 //--------------------------------------
       
   421 // visitor functions for compound nodes
       
   422 //--------------------------------------
       
   423 
       
   424 void XmlDitaDocVisitor::visitPre(DocAutoList *l)
       
   425 {
       
   426 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocAutoList*)", l)
       
   427 	if (m_hide) {
       
   428 	  return;
       
   429 	}
       
   430 	if (l->isEnumList()) {
       
   431 		push("ol");
       
   432 	} else {
       
   433 		push("ul");
       
   434 	}
       
   435 }
       
   436 
       
   437 void XmlDitaDocVisitor::visitPost(DocAutoList *l)
       
   438 {
       
   439 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocAutoList*)", l)
       
   440 	if (l->isEnumList()) {
       
   441 		visitPostDefault("ol");
       
   442 	} else {
       
   443 		visitPostDefault("ul");
       
   444 	}
       
   445 }
       
   446 
       
   447 void XmlDitaDocVisitor::visitPre(DocAutoListItem *)
       
   448 {
       
   449 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocAutoListItem*)")
       
   450 	visitPreDefault("li");
       
   451 }
       
   452 
       
   453 void XmlDitaDocVisitor::visitPost(DocAutoListItem *) 
       
   454 {
       
   455 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocAutoListItem*)")
       
   456 	visitPostDefault("li");
       
   457 }
       
   458 
       
   459 void XmlDitaDocVisitor::visitPre(DocPara *p) 
       
   460 {
       
   461 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocPara*)", p)
       
   462 	if (canPushPara()) {
       
   463 		visitPreDefault("p");
       
   464 	}
       
   465 }
       
   466 
       
   467 void XmlDitaDocVisitor::visitPost(DocPara *)
       
   468 {
       
   469 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocPara*)")
       
   470 	if (canPopPara()) {
       
   471 		visitPostDefault("p");
       
   472 	}
       
   473 }
       
   474 
       
   475 void XmlDitaDocVisitor::visitPre(DocRoot *)
       
   476 {
       
   477 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocRoot*)")
       
   478 }
       
   479 
       
   480 void XmlDitaDocVisitor::visitPost(DocRoot *)
       
   481 {
       
   482 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocRoot*)")
       
   483 }
       
   484 
       
   485 void XmlDitaDocVisitor::visitPre(DocSimpleSect *s)
       
   486 {
       
   487 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocSimpleSect*)", s)
       
   488 	if (m_hide) {
       
   489 	  return;
       
   490 	}
       
   491 	switch(s->type())
       
   492 	{
       
   493 		// Fall through
       
   494 		case DocSimpleSect::See:		
       
   495 		case DocSimpleSect::Return:		
       
   496 		case DocSimpleSect::Author:		
       
   497 		case DocSimpleSect::Authors:	
       
   498 		case DocSimpleSect::Version:	
       
   499 		case DocSimpleSect::Since:		
       
   500 		case DocSimpleSect::Date:		
       
   501 		case DocSimpleSect::Pre:		
       
   502 		case DocSimpleSect::Post:		
       
   503 		case DocSimpleSect::Invar:		
       
   504 		case DocSimpleSect::User:		
       
   505 		case DocSimpleSect::Rcs:		
       
   506 			if (canPushPara()) {
       
   507 				push("p"); 
       
   508 			}
       
   509 			break;
       
   510 		case DocSimpleSect::Note:		
       
   511 			push("note", "type", "note"); 
       
   512 			break;
       
   513 		case DocSimpleSect::Warning:	
       
   514 			push("note", "type", "caution"); 
       
   515 			break;
       
   516 		case DocSimpleSect::Remark:		
       
   517 			push("note", "type", "other"); 
       
   518 			break;
       
   519 		case DocSimpleSect::Attention:	
       
   520 			push("note", "type", "attention"); 
       
   521 			break;
       
   522 		case DocSimpleSect::Unknown:	
       
   523 			break;
       
   524 		default:
       
   525 			ASSERT(0);
       
   526 #if 0
       
   527 		case DocSimpleSect::See:		push("simplesect", "kind", "see"); break;
       
   528 		case DocSimpleSect::Return:		push("simplesect", "kind", "return"); break;
       
   529 		case DocSimpleSect::Author:		push("simplesect", "kind", "author"); break;
       
   530 		case DocSimpleSect::Authors:	push("simplesect", "kind", "authors"); break;
       
   531 		case DocSimpleSect::Version:	push("simplesect", "kind", "version"); break;
       
   532 		case DocSimpleSect::Since:		push("simplesect", "kind", "since"); break;
       
   533 		case DocSimpleSect::Date:		push("simplesect", "kind", "date"); break;
       
   534 		case DocSimpleSect::Note:		push("simplesect", "kind", "note"); break;
       
   535 		case DocSimpleSect::Warning:	push("simplesect", "kind", "warning"); break;
       
   536 		case DocSimpleSect::Pre:		push("simplesect", "kind", "pre"); break;
       
   537 		case DocSimpleSect::Post:		push("simplesect", "kind", "post"); break;
       
   538 		case DocSimpleSect::Invar:		push("simplesect", "kind", "invariant"); break;
       
   539 		case DocSimpleSect::Remark:		push("simplesect", "kind", "remark"); break;
       
   540 		case DocSimpleSect::Attention:	push("simplesect", "kind", "attention"); break;
       
   541 		case DocSimpleSect::User:		push("simplesect", "kind", "par"); break;
       
   542 		case DocSimpleSect::Rcs:		push("simplesect", "kind", "rcs"); break;
       
   543 		case DocSimpleSect::Unknown:	break;
       
   544 #endif
       
   545 	}
       
   546 }
       
   547 
       
   548 void XmlDitaDocVisitor::visitPost(DocSimpleSect *s)
       
   549 {
       
   550 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocSimpleSect*)", s)
       
   551 	if (m_hide) {
       
   552 	  return;
       
   553 	}	
       
   554 	switch(s->type())
       
   555 	{
       
   556 		// Fall through
       
   557 		case DocSimpleSect::Note:		
       
   558 		case DocSimpleSect::Warning:	
       
   559 		case DocSimpleSect::Remark:		
       
   560 		case DocSimpleSect::Attention:	
       
   561 			pop("note"); 
       
   562 			break;
       
   563 		case DocSimpleSect::Unknown:	
       
   564 			break;
       
   565 		default:
       
   566 			if (canPopPara()) {
       
   567 				pop("p"); 
       
   568 			}
       
   569 			break;
       
   570 	}
       
   571   //visitPostDefault("simplesect");
       
   572 }
       
   573 
       
   574 void XmlDitaDocVisitor::visitPre(DocTitle *)
       
   575 {	
       
   576 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocTitle*)")
       
   577 	if (!xmlElemStack.isEmpty() && xmlElemStack.peek().getElemName() == "concept") {
       
   578 		visitPreDefault("title");
       
   579 	} else {
       
   580 		if (canPushPara()) {
       
   581 			visitPreDefault("p");
       
   582 		}
       
   583 		visitPreDefault("b");
       
   584 	}
       
   585 
       
   586 }
       
   587 
       
   588 void XmlDitaDocVisitor::visitPost(DocTitle *)
       
   589 {
       
   590 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocTitle*)")
       
   591 	if (xmlElemStack.peek().getElemName() == "title") {
       
   592 		visitPostDefault("title");
       
   593 	} else {
       
   594 		visitPostDefault("b");
       
   595 		if (canPopPara()) {
       
   596 			visitPostDefault("p");
       
   597 		}
       
   598 	}
       
   599 }
       
   600 
       
   601 void XmlDitaDocVisitor::visitPre(DocSimpleList *)
       
   602 {
       
   603 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocSimpleList*)")
       
   604 	visitPreDefault("ul");
       
   605 }
       
   606 
       
   607 void XmlDitaDocVisitor::visitPost(DocSimpleList *)
       
   608 {
       
   609 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocSimpleList*)")
       
   610 	visitPostDefault("ul");
       
   611 }
       
   612 
       
   613 void XmlDitaDocVisitor::visitPre(DocSimpleListItem *)
       
   614 {
       
   615 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocSimpleListItem*)")
       
   616 	visitPreDefault("li");
       
   617 }
       
   618 
       
   619 void XmlDitaDocVisitor::visitPost(DocSimpleListItem *) 
       
   620 {
       
   621 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocSimpleListItem*)")
       
   622 	visitPostDefault("li");
       
   623 }
       
   624 
       
   625 void XmlDitaDocVisitor::visitPre(DocSection *s)
       
   626 {
       
   627 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocSection*)", s)
       
   628 	// Currently unsupported
       
   629 #if 0
       
   630 	if (m_hide) {
       
   631 	  return;
       
   632 	}
       
   633 	QString sectNum;
       
   634 	sectNum.setNum(s->level());
       
   635 	QString sectAnchor(s->file());
       
   636 	if (!s->anchor().isEmpty()) {
       
   637 		sectAnchor.append("_1");
       
   638 		sectAnchor.append(s->anchor());
       
   639 	}
       
   640 	push("sect"+sectNum, "id", sectAnchor);
       
   641 	pushpop("title", s->title());
       
   642 #endif
       
   643 }
       
   644 
       
   645 void XmlDitaDocVisitor::visitPost(DocSection *s) 
       
   646 {
       
   647 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocSection*)", s)
       
   648 #if 0
       
   649 	// The original did not have the if(m_hide) test.
       
   650 	// I assume that is an error so visitPostDefault() uses it.
       
   651 	QString level;
       
   652 	level.setNum(s->level());
       
   653 	visitPostDefault("sect" + level);
       
   654 #endif
       
   655 }
       
   656 
       
   657 void XmlDitaDocVisitor::visitPre(DocHtmlList *s)
       
   658 {
       
   659 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocHtmlList*)", s)
       
   660 	if (m_hide) {
       
   661 	  return;
       
   662 	}
       
   663 	if (s->type()==DocHtmlList::Ordered) {
       
   664 		push("ol"); 
       
   665 	} else {
       
   666 		push("ul"); 
       
   667 	}
       
   668 }
       
   669 
       
   670 void XmlDitaDocVisitor::visitPost(DocHtmlList *s) 
       
   671 {
       
   672 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocHtmlList*)", s)
       
   673 	if (s->type()==DocHtmlList::Ordered) {
       
   674 		visitPostDefault("ol"); 
       
   675 	} else {
       
   676 		visitPostDefault("ul");
       
   677 	}
       
   678 }
       
   679 
       
   680 void XmlDitaDocVisitor::visitPre(DocHtmlListItem *)
       
   681 {
       
   682 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlListItem*)")
       
   683 	visitPreDefault("li");
       
   684 }
       
   685 
       
   686 void XmlDitaDocVisitor::visitPost(DocHtmlListItem *) 
       
   687 {
       
   688 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlListItem*)")
       
   689 	visitPostDefault("li");
       
   690 }
       
   691 
       
   692 void XmlDitaDocVisitor::visitPre(DocHtmlDescList *)
       
   693 {
       
   694 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlDescList*)")
       
   695 	visitPreDefault("dl");
       
   696 }
       
   697 
       
   698 void XmlDitaDocVisitor::visitPost(DocHtmlDescList *) 
       
   699 {
       
   700 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlDescList*)")
       
   701 	visitPostDefault("dl");
       
   702 }
       
   703 
       
   704 void XmlDitaDocVisitor::visitPre(DocHtmlDescTitle *)
       
   705 {
       
   706 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlDescTitle*)")
       
   707 	if (m_hide) {
       
   708 	  return;
       
   709 	}
       
   710 	push("dlentry");
       
   711 	push("dt");
       
   712 	//push("varlistentry");
       
   713 	//push("term");
       
   714 }
       
   715 
       
   716 void XmlDitaDocVisitor::visitPost(DocHtmlDescTitle *) 
       
   717 {
       
   718 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlDescTitle*)")
       
   719 	if (m_hide) {
       
   720 	  return;
       
   721 	}
       
   722 	pop("dt");
       
   723 	//pop("dlentry");
       
   724 	// pop("term");
       
   725 	// pop("varlistentry");
       
   726 }
       
   727 
       
   728 void XmlDitaDocVisitor::visitPre(DocHtmlDescData *)
       
   729 {
       
   730 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlDescData*)")
       
   731 	push("dd");
       
   732 	//visitPreDefault("li");
       
   733 }
       
   734 
       
   735 void XmlDitaDocVisitor::visitPost(DocHtmlDescData *) 
       
   736 {
       
   737 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlDescData*)")
       
   738 	pop("dd");
       
   739 	pop("dlentry");
       
   740 	//visitPostDefault("li");  
       
   741 }
       
   742 
       
   743 void XmlDitaDocVisitor::visitPre(DocHtmlTable *t)
       
   744 {
       
   745 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocHtmlTable*)", t)
       
   746 	if (m_hide) {
       
   747 	  return;
       
   748 	}
       
   749 #if DITA_SIMPLETABLE_SUPPORT
       
   750 	push("simpletable");
       
   751 #endif
       
   752 #if 0
       
   753 	AttributeMap attrs;
       
   754 	QString vR, vC;
       
   755 	vR.setNum(t->numRows());
       
   756 	attrs["rows"] = vR;
       
   757 	vC.setNum(t->numCols());
       
   758 	attrs["cols"] = vC;
       
   759 	push("table", attrs);
       
   760 #endif
       
   761 }
       
   762 
       
   763 void XmlDitaDocVisitor::visitPost(DocHtmlTable *) 
       
   764 {
       
   765 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlTable*)")
       
   766 #if DITA_SIMPLETABLE_SUPPORT
       
   767 	visitPostDefault("simpletable");
       
   768 #endif
       
   769 }
       
   770 
       
   771 void XmlDitaDocVisitor::visitPre(DocHtmlRow *)
       
   772 {
       
   773 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlRow*)")
       
   774 	// FIXME look ahead to first cell
       
   775 	// if isHeading is true do
       
   776 	// visitPreDefault("sthead");
       
   777 	// else
       
   778 	visitPreDefault("strow");
       
   779 }
       
   780 
       
   781 void XmlDitaDocVisitor::visitPost(DocHtmlRow *) 
       
   782 {
       
   783 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlRow*)")
       
   784 	visitPostDefault("strow");
       
   785 }
       
   786 
       
   787 void XmlDitaDocVisitor::visitPre(DocHtmlCell *c)
       
   788 {
       
   789 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocHtmlCell*)", c)
       
   790 	visitPreDefault("stentry");
       
   791 #if 0
       
   792 	if (m_hide) {
       
   793 	  return;
       
   794 	}
       
   795 	if (c->isHeading()) {
       
   796 	  push("entry", "thead", "yes");
       
   797 	} else {
       
   798 	  push("entry", "thead", "no");
       
   799 	}
       
   800 #endif
       
   801 }
       
   802 
       
   803 void XmlDitaDocVisitor::visitPost(DocHtmlCell *c) 
       
   804 {
       
   805 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocHtmlCell*)", c)
       
   806   visitPostDefault("stentry");
       
   807 }
       
   808 
       
   809 void XmlDitaDocVisitor::visitPre(DocHtmlCaption *)
       
   810 {
       
   811 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocHtmlCaption*)")
       
   812 	// Caption is unsupported
       
   813 }
       
   814 
       
   815 void XmlDitaDocVisitor::visitPost(DocHtmlCaption *) 
       
   816 {
       
   817 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlCaption*)")
       
   818 	// Caption is unsupported
       
   819 }
       
   820 
       
   821 void XmlDitaDocVisitor::visitPre(DocInternal *)
       
   822 {
       
   823 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocInternal*)")
       
   824 	//visitPreDefault("internal");
       
   825 }
       
   826 
       
   827 void XmlDitaDocVisitor::visitPost(DocInternal *) 
       
   828 {
       
   829 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocInternal*)")
       
   830   //visitPostDefault("internal");
       
   831 }
       
   832 
       
   833 void XmlDitaDocVisitor::visitPre(DocHRef *href)
       
   834 {
       
   835 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocHRef*)", href)
       
   836 	push("xref", "href", href->url());
       
   837 }
       
   838 
       
   839 void XmlDitaDocVisitor::visitPost(DocHRef *) 
       
   840 {
       
   841 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHRef*)")
       
   842 	visitPostDefault("xref");
       
   843 }
       
   844 
       
   845 void XmlDitaDocVisitor::visitPre(DocHtmlHeader *header)
       
   846 {
       
   847 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocHtmlHeader*)", header)
       
   848 	visitPreDefault("b");
       
   849 #if 0
       
   850   QString hdgLevel;
       
   851   hdgLevel.setNum(header->level());
       
   852   push("heading", "level", hdgLevel);
       
   853 #endif
       
   854 }
       
   855 
       
   856 void XmlDitaDocVisitor::visitPost(DocHtmlHeader *) 
       
   857 {
       
   858 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocHtmlHeader*)")
       
   859 	visitPostDefault("b");
       
   860 }
       
   861 
       
   862 void XmlDitaDocVisitor::visitPre(DocImage *img)
       
   863 {
       
   864 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocImage*)", img)
       
   865 	// Currently unsupported
       
   866 #if 0
       
   867   AttributeMap imgAttrs;
       
   868   // First the image type
       
   869   switch(img->type())
       
   870   {
       
   871     case DocImage::Html:
       
   872 		imgAttrs["type"] = "html";
       
   873 		break;
       
   874     case DocImage::Latex:
       
   875 		imgAttrs["type"] = "latex";
       
   876 		break;
       
   877 	case DocImage::Rtf:
       
   878 		imgAttrs["type"] = "rtf";
       
   879 		break;
       
   880 	default:
       
   881 		ASSERT(0);
       
   882 		break;
       
   883   }
       
   884   // Now the image name
       
   885   QString baseName=img->name();
       
   886   int i;
       
   887   if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
       
   888   {
       
   889     baseName=baseName.right(baseName.length()-i-1);
       
   890   }
       
   891   imgAttrs["name"] = baseName;
       
   892   // Image width
       
   893   if (!img->width().isEmpty())
       
   894   {
       
   895     imgAttrs["width"] = img->width();
       
   896   }
       
   897   // Image height
       
   898   // NOTE: In the original this was an else if. I assume that this is an error
       
   899   if (!img->height().isEmpty())
       
   900   {
       
   901     imgAttrs["height"] = img->height();
       
   902   }
       
   903   push("image", imgAttrs);
       
   904 
       
   905   // copy the image to the output dir
       
   906   QFile inImage(img->name());
       
   907   QFile outImage(Config_getString("XML_DITA_OUTPUT")+"/"+baseName.ascii());
       
   908   if (inImage.open(IO_ReadOnly))
       
   909   {
       
   910     if (outImage.open(IO_WriteOnly))
       
   911     {
       
   912       char *buffer = new char[inImage.size()];
       
   913       inImage.readBlock(buffer,inImage.size());
       
   914       outImage.writeBlock(buffer,inImage.size());
       
   915       outImage.flush();
       
   916       delete[] buffer;
       
   917     }
       
   918   }
       
   919 #endif
       
   920 }
       
   921 
       
   922 void XmlDitaDocVisitor::visitPost(DocImage *) 
       
   923 {
       
   924 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocImage*)")
       
   925   //visitPostDefault("image");
       
   926 }
       
   927 
       
   928 void XmlDitaDocVisitor::visitPre(DocDotFile *df)
       
   929 {
       
   930 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocDotFile*)", df)
       
   931 	// Currently unsupported
       
   932 #if 0
       
   933 	if (m_hide) {
       
   934 	  return;
       
   935 	}
       
   936 	push("dotfile", "name", df->file());
       
   937 #endif
       
   938 }
       
   939 
       
   940 void XmlDitaDocVisitor::visitPost(DocDotFile *) 
       
   941 {
       
   942 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocDotFile*)")
       
   943 	//visitPostDefault("dotfile");
       
   944 }
       
   945 
       
   946 void XmlDitaDocVisitor::visitPre(DocLink *lnk)
       
   947 {
       
   948 	// The result of a \link...\endlink command
       
   949 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocLink*)", lnk)
       
   950 	if (m_hide) {
       
   951 	  return;
       
   952 	}
       
   953 	if (0) {//lnk->getDefinition() != 0) {
       
   954 		//printf("XmlDitaDocVisitor calling startLink() DocLink [name]=`%s'\n", lnk->getDefinition()->qualifiedName().data());
       
   955 		startLink("", lnk->getDefinition()->qualifiedName(), "");
       
   956 	} else {
       
   957 		//printf("XmlDitaDocVisitor calling startLink() DocLink [file]=`%s'\n", lnk->file().data());
       
   958 		//startLink(lnk->ref(),lnk->file(),lnk->anchor());
       
   959 		startLink(lnk->ref(), lnk->file(), lnk->anchor());
       
   960 	}	
       
   961 }
       
   962 
       
   963 void XmlDitaDocVisitor::visitPost(DocLink *) 
       
   964 {
       
   965 	// The result of a \link...\endlink command
       
   966 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocLink*)")
       
   967 	if (m_hide) {
       
   968 	  return;
       
   969 	}
       
   970 	endLink();
       
   971 }
       
   972 
       
   973 void XmlDitaDocVisitor::visitPre(DocRef *ref)
       
   974 {
       
   975 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocRef*)", ref)
       
   976 	if (m_hide) {
       
   977 	  return;
       
   978 	}
       
   979 	if (!ref->file().isEmpty()) {
       
   980 		if (ref->getDefinition() != 0) {
       
   981 			//printf("XmlDitaDocVisitor calling startLink() DocRef [name]=`%s'\n", ref->getDefinition()->qualifiedName().data());
       
   982 			startLink("", ref->getDefinition()->qualifiedName(), "");
       
   983 		} else {
       
   984 			//printf("XmlDitaDocVisitor calling startLink() DocRef [file]=`%s'\n", ref->file().data());
       
   985 			startLink(ref->ref(), ref->file(), ref->anchor());
       
   986 		}	
       
   987 	}
       
   988 	if (!ref->hasLinkText()) {
       
   989 	  write(ref->targetTitle());
       
   990 	}
       
   991 }
       
   992 
       
   993 void XmlDitaDocVisitor::visitPost(DocRef *ref) 
       
   994 {
       
   995 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPost(DocRef*)", ref)
       
   996 	if (m_hide) {
       
   997 	  return;
       
   998 	}
       
   999 	if (!ref->file().isEmpty()) {
       
  1000 	  endLink();
       
  1001 	}
       
  1002 	write(" ");
       
  1003 }
       
  1004 
       
  1005 void XmlDitaDocVisitor::visitPre(DocSecRefItem *ref)
       
  1006 {
       
  1007 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocSecRefItem*)", ref)
       
  1008 	if (m_hide) {
       
  1009 	  return;
       
  1010 	}
       
  1011 	push("li", "id", ref->file()+"_1"+ref->anchor());
       
  1012 }
       
  1013 
       
  1014 void XmlDitaDocVisitor::visitPost(DocSecRefItem *) 
       
  1015 {
       
  1016 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocSecRefItem*)")
       
  1017 	visitPostDefault("li");
       
  1018 }
       
  1019 
       
  1020 void XmlDitaDocVisitor::visitPre(DocSecRefList *)
       
  1021 {
       
  1022 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocSecRefList*)")
       
  1023 	visitPreDefault("ul");
       
  1024 }
       
  1025 
       
  1026 void XmlDitaDocVisitor::visitPost(DocSecRefList *) 
       
  1027 {
       
  1028 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocSecRefList*)")
       
  1029 	visitPostDefault("ul");
       
  1030 }
       
  1031 
       
  1032 void XmlDitaDocVisitor::visitPre(DocParamSect *s)
       
  1033 {
       
  1034 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocParamSect*)", s)
       
  1035 	m_insideParamlist = TRUE;
       
  1036 	if (m_hide) {
       
  1037 	  return;
       
  1038 	}
       
  1039 	switch(s->type()) {
       
  1040 		case DocParamSect::Param: 
       
  1041 			push("paraml", "class", "param"); 
       
  1042 			break;
       
  1043 		case DocParamSect::RetVal: 
       
  1044 			push("paraml", "class", "retval"); 
       
  1045 			break;
       
  1046 		case DocParamSect::Exception: 
       
  1047 			push("paraml", "class", "exception"); 
       
  1048 			break;
       
  1049 		case DocParamSect::TemplateParam: 
       
  1050 			push("paraml", "class", "templateparam"); 
       
  1051 			break;
       
  1052 		default:
       
  1053 		  ASSERT(0);
       
  1054 	}
       
  1055 }
       
  1056 
       
  1057 void XmlDitaDocVisitor::visitPost(DocParamSect *)
       
  1058 {
       
  1059 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocParamSect*)")
       
  1060 	visitPostDefault("paraml");
       
  1061 	m_insideParamlist = FALSE;
       
  1062 }
       
  1063 
       
  1064 void XmlDitaDocVisitor::visitPre(DocParamList *pl)
       
  1065 {
       
  1066 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocParamList*)", pl)
       
  1067 	if (m_hide) {
       
  1068 	  return;
       
  1069 	}
       
  1070 	QListIterator<DocNode> li(pl->parameters());
       
  1071 	DocNode *param;
       
  1072 	for (li.toFirst();(param=li.current());++li) {
       
  1073 		if (param->kind() == DocNode::Kind_Word) {			
       
  1074 			currParam = ((DocWord*)param)->word();
       
  1075 		} else if (param->kind() == DocNode::Kind_LinkedWord) {
       
  1076 			currParam = ((DocLinkedWord*)param)->word();
       
  1077 		} else {
       
  1078 			// FIXME, what should we use here
       
  1079 			currParam = "";
       
  1080 		}
       
  1081 		paramDict.insert(currParam, new QString(""));
       
  1082 	}
       
  1083 
       
  1084 #if 0
       
  1085 	push("parameteritem");
       
  1086 	push("parameternamelist");
       
  1087 	QListIterator<DocNode> li(pl->parameters());
       
  1088 	DocNode *param;
       
  1089 	for (li.toFirst();(param=li.current());++li) {
       
  1090 		AttributeMap attrs;
       
  1091 		if (pl->direction() != DocParamSect::Unspecified) {
       
  1092 			if (pl->direction() == DocParamSect::In) {
       
  1093 				attrs["direction"] = "in";
       
  1094 			} else if (pl->direction() == DocParamSect::Out) {
       
  1095 				attrs["direction"] = "out";
       
  1096 			} else if (pl->direction() == DocParamSect::InOut) {
       
  1097 				attrs["direction"] = "inout";
       
  1098 			} else{
       
  1099 				ASSERT(0);
       
  1100 			}
       
  1101 		}
       
  1102 		push("parametername", attrs);
       
  1103 		if (param->kind() == DocNode::Kind_Word)
       
  1104 		{
       
  1105 		  visit((DocWord*)param); 		
       
  1106 		}
       
  1107 		else if (param->kind() == DocNode::Kind_LinkedWord)
       
  1108 		{
       
  1109 		  visit((DocLinkedWord*)param); 
       
  1110 		}
       
  1111 		pop("parametername");
       
  1112 	}
       
  1113 	pop("parameternamelist");
       
  1114 	push("parameterdescription");
       
  1115 #endif
       
  1116 }
       
  1117 
       
  1118 void XmlDitaDocVisitor::visitPost(DocParamList *)
       
  1119 {
       
  1120 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocParamList*)")
       
  1121 	if (m_hide) {
       
  1122 	  return;
       
  1123 	}
       
  1124 	pop("parameterdescription");
       
  1125 	pop("parameteritem");
       
  1126 }
       
  1127 
       
  1128 void XmlDitaDocVisitor::visitPre(DocXRefItem *x)
       
  1129 {
       
  1130 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocXRefItem*)", x)
       
  1131 	if (m_hide) {
       
  1132 	  return;
       
  1133 	}
       
  1134 	// \deprecated commands result in DocXRefItem
       
  1135 	// with "deprecated" as the filename
       
  1136 	if (x->file() == "deprecated"){
       
  1137 		// Fall through to start new paragraph for deprecated description
       
  1138 	} else {
       
  1139 		QString hrefStr = x->file();
       
  1140 		hrefStr.append(Config_getString("XML_DITA_EXTENSION"));
       
  1141 		hrefStr.append("#");
       
  1142 		hrefStr.append(x->file());
       
  1143 		hrefStr.append("_1");
       
  1144 		hrefStr.append(x->anchor());
       
  1145 		push("xref", "href", hrefStr);
       
  1146 		write(x->title());
       
  1147 	}
       
  1148 #if 0
       
  1149 	push("xrefsect", "id", x->file()+"_1"+x->anchor());
       
  1150 	pushpop("xreftitle", x->title());
       
  1151 	push("xrefdescription");
       
  1152 #endif
       
  1153 }
       
  1154 
       
  1155 void XmlDitaDocVisitor::visitPost(DocXRefItem *)
       
  1156 {
       
  1157 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocXRefItem*)")
       
  1158 	if (m_hide) {
       
  1159 	  return;
       
  1160 	}
       
  1161 	// An xref will be top of stack unless the current 
       
  1162 	// DocXRefItem was caused by a \deprecated command
       
  1163 	if (!xmlElemStack.isEmpty() && xmlElemStack.peek().getElemName() == "xref") {
       
  1164 		pop("xref");
       
  1165 	}
       
  1166 	
       
  1167 #if 0
       
  1168 	pop("xrefdescription");
       
  1169 	pop("xrefsect");
       
  1170 #endif
       
  1171 }
       
  1172 
       
  1173 void XmlDitaDocVisitor::visitPre(DocInternalRef *ref)
       
  1174 {
       
  1175 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocInternalRef*)", ref)
       
  1176 	if (m_hide) {
       
  1177 	  return;
       
  1178 	}
       
  1179 	//printf("XmlDitaDocVisitor calling startLink() DocInternalRef [file]=`%s'\n", ref->file().data());
       
  1180 	startLink(0, ref->file(), ref->anchor());
       
  1181 }
       
  1182 
       
  1183 void XmlDitaDocVisitor::visitPost(DocInternalRef *) 
       
  1184 {
       
  1185 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocXRefItem*)")
       
  1186 	if (m_hide) {
       
  1187 	  return;
       
  1188 	}
       
  1189 	endLink();
       
  1190 	write(" ");
       
  1191 }
       
  1192 
       
  1193 void XmlDitaDocVisitor::visitPre(DocCopy *c)
       
  1194 {
       
  1195 	DITA_DOC_VISITOR_TRACE("XmlDitaDocVisitor::visitPre(DocCopy*)", c)
       
  1196 	// Currently unsupported
       
  1197 #if 0
       
  1198 	if (m_hide) {
       
  1199 	  return;
       
  1200 	}
       
  1201 	push("copydoc", "link", c->link());
       
  1202 #endif
       
  1203 }
       
  1204 
       
  1205 void XmlDitaDocVisitor::visitPost(DocCopy *)
       
  1206 {
       
  1207 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocCopy*)")
       
  1208 //	visitPostDefault("copydoc");
       
  1209 }
       
  1210 
       
  1211 void XmlDitaDocVisitor::visitPre(DocText *)
       
  1212 {
       
  1213 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPre(DocText*)")
       
  1214 }
       
  1215 
       
  1216 void XmlDitaDocVisitor::visitPost(DocText *)
       
  1217 {
       
  1218 	DITA_DOC_VISITOR_TRACE_NOARG("XmlDitaDocVisitor::visitPost(DocText*)")
       
  1219 }
       
  1220 
       
  1221 void XmlDitaDocVisitor::startXref(const QString &href,const QString &text)
       
  1222 {
       
  1223 #ifndef DITA_DOT_HACK_REMOVE_XREFS
       
  1224 	push("xref", "href", href);
       
  1225 #endif
       
  1226 	write(text);	
       
  1227 }
       
  1228 
       
  1229 void XmlDitaDocVisitor::endXref()
       
  1230 {
       
  1231 #ifndef DITA_DOT_HACK_REMOVE_XREFS
       
  1232 	pop("xref");
       
  1233 #endif
       
  1234 }
       
  1235 
       
  1236 void XmlDitaDocVisitor::startLink(const QString &ref,const QString &file,const QString &anchor)
       
  1237 {
       
  1238   AttributeMap refAttrs;
       
  1239   /*
       
  1240   printf("XmlDitaDocVisitor::startLink(): ref: \"%s\", file: \"%s\", anchor: \"%s\"\n",
       
  1241 	  ref.data(),
       
  1242 	  file.data(),
       
  1243 	  anchor.data());
       
  1244   */
       
  1245   if (!anchor.isEmpty()) {
       
  1246 	  refAttrs["href"] = file+".xml#"+file+"_1"+anchor;
       
  1247   } else {
       
  1248 	  refAttrs["href"] = file+".xml#"+file;
       
  1249   }
       
  1250 #ifndef DITA_DOT_HACK_REMOVE_XREFS
       
  1251   push("xref", refAttrs);
       
  1252 #endif
       
  1253 #if 0
       
  1254   AttributeMap refAttrs;
       
  1255   if (!anchor.isEmpty()) {
       
  1256 	  refAttrs["refid"] = file+"_1"+anchor;
       
  1257 	  refAttrs["kindref"] = "member";
       
  1258   } else {
       
  1259 	  refAttrs["refid"] = file;
       
  1260 	  refAttrs["kindref"] = "compound";
       
  1261   }
       
  1262   if (!ref.isEmpty()) {
       
  1263 	  refAttrs["external"] = ref;
       
  1264   }
       
  1265   push("ref", refAttrs);
       
  1266 #endif
       
  1267 }
       
  1268 
       
  1269 void XmlDitaDocVisitor::endLink()
       
  1270 {
       
  1271 #ifndef DITA_DOT_HACK_REMOVE_XREFS
       
  1272   visitPostDefault("xref");
       
  1273 #endif
       
  1274 }
       
  1275 
       
  1276 void XmlDitaDocVisitor::pushEnabled()
       
  1277 {
       
  1278   m_enabled.push(new bool(m_hide));
       
  1279 }
       
  1280 
       
  1281 void XmlDitaDocVisitor::popEnabled()
       
  1282 {
       
  1283   bool *v = m_enabled.pop();
       
  1284   ASSERT(v!=0);
       
  1285   m_hide = *v;
       
  1286   delete v;
       
  1287 }
       
  1288 
       
  1289 
       
  1290 void XmlDitaDocVisitor::write(const QString &string)
       
  1291 {
       
  1292 	if (m_insideParamlist) {
       
  1293 		// TODO: Review the use of paramDict as I think that there is a
       
  1294 		// memory leak here [PaulRo 2010-01-20]
       
  1295 		QString *pStr = paramDict.find(currParam);
       
  1296 		if (pStr) {
       
  1297 			paramDict.replace(currParam, new QString(*pStr + string));
       
  1298 		} else {
       
  1299 			paramDict.replace(currParam, new QString(string));
       
  1300 		}
       
  1301 	} else {
       
  1302 		xmlStream << string;
       
  1303 	}
       
  1304 }
       
  1305 
       
  1306 void XmlDitaDocVisitor::push(const QString &tagName)
       
  1307 {
       
  1308 	if (m_insideParamlist) {
       
  1309 		// TODO
       
  1310 	} else {
       
  1311 		xmlElemStack.push(tagName);
       
  1312 	}
       
  1313 }
       
  1314 
       
  1315 void XmlDitaDocVisitor::push(const QString &tagName, const QString &key, const QString &value)
       
  1316 {
       
  1317 	if (m_insideParamlist) {
       
  1318 		// TODO
       
  1319 	} else {
       
  1320 		xmlElemStack.push(tagName, key, value);
       
  1321 	}
       
  1322 }
       
  1323 
       
  1324 void XmlDitaDocVisitor::push(const QString &tagName, AttributeMap &map)
       
  1325 {
       
  1326 	if (m_insideParamlist) {
       
  1327 		// TODO
       
  1328 	} else {
       
  1329 		xmlElemStack.push(tagName, map);
       
  1330 	}
       
  1331 }
       
  1332 
       
  1333 void XmlDitaDocVisitor::pop(const QString &tagName)
       
  1334 {
       
  1335 	if (m_insideParamlist) {
       
  1336 		// TODO
       
  1337 	} else {
       
  1338 		xmlElemStack.pop(tagName);
       
  1339 	}
       
  1340 }
       
  1341 
       
  1342 void XmlDitaDocVisitor::pushpop(const QString &tagName)
       
  1343 {
       
  1344 	if (m_insideParamlist) {
       
  1345 		// TODO
       
  1346 	} else {
       
  1347 		xmlElemStack.pushpop(tagName);
       
  1348 	}
       
  1349 }
       
  1350 
       
  1351 void XmlDitaDocVisitor::pushpop(const QString &tagName, const QString &text)
       
  1352 {
       
  1353 	if (m_insideParamlist) {
       
  1354 		paramDict.replace(currParam, new QString(*paramDict[currParam] + text));
       
  1355 	} else {
       
  1356 		xmlElemStack.pushpop(tagName, text);
       
  1357 	}
       
  1358 }
       
  1359 
       
  1360 const QString XmlDitaDocVisitor::query(const QString &paramName) const
       
  1361 {
       
  1362 	if (paramDict.find(paramName)) {
       
  1363 		return *paramDict[paramName];
       
  1364 	} else {
       
  1365 		// TODO positional option
       
  1366 		return "";
       
  1367 	}
       
  1368 }
       
  1369 
       
  1370 /// Returns true if it is OK to write a para element
       
  1371 bool XmlDitaDocVisitor::canPushPara() const
       
  1372 {
       
  1373 	if (!xmlElemStack.isEmpty()) {
       
  1374 		QString e = xmlElemStack.peek().getElemName();
       
  1375 		if (e == "xref" || e == "p") {
       
  1376 			return false;
       
  1377 		}
       
  1378 	}
       
  1379 	return true;
       
  1380 }
       
  1381 
       
  1382 bool XmlDitaDocVisitor::canPopPara() const
       
  1383 {
       
  1384 	if (!xmlElemStack.isEmpty() && xmlElemStack.peek().getElemName() == "p") {
       
  1385 			return true;
       
  1386 	}
       
  1387 	return false;
       
  1388 }
       
  1389 
       
  1390 /** Default treatment of a post traversal visit, this just
       
  1391 pushes a single element with no attributes. */
       
  1392 void XmlDitaDocVisitor::visitPreDefault(const QString& elem)
       
  1393 {
       
  1394 	if (m_hide) {
       
  1395 	  return;
       
  1396 	}
       
  1397 	push(elem);
       
  1398 }
       
  1399 
       
  1400 /** Default treatment of a post traversal visit, this just
       
  1401 pops a single element. */
       
  1402 void XmlDitaDocVisitor::visitPostDefault(const QString& elem)
       
  1403 {
       
  1404 	if (m_hide) {
       
  1405 	  return;
       
  1406 	}
       
  1407 	pop(elem);
       
  1408 }
       
  1409