1 /*
2  * Copyright (c) 2004 Sasha Vasko <sasha@aftercode.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 #define LOCAL_DEBUG
20 #define EVENT_TRACE
21 
22 #include "../../configure.h"
23 #include "../../libAfterStep/asapp.h"
24 #include <unistd.h>
25 #include "../../libAfterStep/parser.h"
26 #include "../../libAfterConf/afterconf.h"
27 
28 #include "ASDocGen.h"
29 #include "xmlproc.h"
30 
31 #define TAG_INFO_AND_ID(tagname)	#tagname, DOCBOOK_##tagname##_ID
32 
33 #define ASFAQ_NAME "afterstep_faq"
34 
35 ASDocTagHandlingInfo SupportedDocBookTagInfo[DOCBOOK_SUPPORTED_IDS] =
36 {
37 	{ TAG_INFO_AND_ID(unknown), NULL, NULL },
38 	{ TAG_INFO_AND_ID(id), NULL, NULL },
39 	{ TAG_INFO_AND_ID(arg), start_arg_tag, end_arg_tag },
40 	{ TAG_INFO_AND_ID(url), NULL, NULL },
41 	{ TAG_INFO_AND_ID(para), start_para_tag, end_para_tag },
42 	{ TAG_INFO_AND_ID(term), start_term_tag, end_term_tag },
43 	{ TAG_INFO_AND_ID(code), start_code_tag, end_code_tag },
44 	{ TAG_INFO_AND_ID(ulink), start_ulink_tag, end_ulink_tag },
45 	{ TAG_INFO_AND_ID(title), start_title_tag, end_title_tag },
46 	{ TAG_INFO_AND_ID(group), start_group_tag, end_group_tag },
47 	{ TAG_INFO_AND_ID(label), NULL, NULL },
48 	{ TAG_INFO_AND_ID(width), NULL, NULL },
49 	{ TAG_INFO_AND_ID(depth), NULL, NULL },
50 	{ TAG_INFO_AND_ID(align), NULL, NULL },
51 	{ TAG_INFO_AND_ID(anchor), start_anchor_tag, end_anchor_tag },
52 	{ TAG_INFO_AND_ID(option), start_option_tag, end_option_tag },
53 	{ TAG_INFO_AND_ID(choice), NULL, NULL },
54 	{ TAG_INFO_AND_ID(valign), NULL, NULL },
55 	{ TAG_INFO_AND_ID(command), start_command_tag, end_command_tag },
56 	{ TAG_INFO_AND_ID(example), start_example_tag, end_example_tag },
57 	{ TAG_INFO_AND_ID(linkend), NULL, NULL },
58 	{ TAG_INFO_AND_ID(section), start_section_tag, end_section_tag },
59 	{ TAG_INFO_AND_ID(fileref), NULL, NULL },
60 	{ TAG_INFO_AND_ID(refsect1), start_refsect1_tag, end_refsect1_tag },
61 	{ TAG_INFO_AND_ID(refsect2), start_refsect1_tag, end_refsect1_tag },
62 	{ TAG_INFO_AND_ID(emphasis), start_emphasis_tag, end_emphasis_tag },
63 	{ TAG_INFO_AND_ID(listitem), start_listitem_tag, end_listitem_tag },
64 	{ TAG_INFO_AND_ID(imagedata), start_imagedata_tag, end_imagedata_tag },
65 	{ TAG_INFO_AND_ID(formalpara), start_formalpara_tag, end_formalpara_tag },
66 	{ TAG_INFO_AND_ID(cmdsynopsis), start_cmdsynopsis_tag, end_cmdsynopsis_tag },
67 	{ TAG_INFO_AND_ID(replaceable), start_emphasis_tag, end_emphasis_tag },
68 	{ TAG_INFO_AND_ID(mediaobject), NULL, NULL },
69 	{ TAG_INFO_AND_ID(imageobject), NULL, NULL },
70 	{ TAG_INFO_AND_ID(variablelist), start_variablelist_tag, end_variablelist_tag },
71 	{ TAG_INFO_AND_ID(varlistentry), start_varlistentry_tag, end_varlistentry_tag },
72 	{ TAG_INFO_AND_ID(literallayout), start_literallayout_tag, end_literallayout_tag }
73 };
74 
75 /*************************************************************************/
76 xml_elem_t*
find_super_section(xml_elem_t * owner,const char * id)77 find_super_section( xml_elem_t* owner, const char *id )
78 {
79 	xml_elem_t* sub ;
80 	for( sub = owner->child ; sub != NULL ; sub = sub->next )
81 	{
82 		Bool match_found = False ;
83 		xml_elem_t* attr, *attr_curr ;
84 		if( sub->tag_id != DOCBOOK_section_ID )
85 			continue;
86 		attr = xml_parse_parm(sub->parm, DocBookVocabulary);
87 		for( attr_curr = attr ; attr_curr ; attr_curr = attr_curr->next )
88 			if( attr_curr->tag_id == DOCBOOK_id_ID )
89 				break;
90 		match_found = ( attr_curr!= NULL && strncmp( attr_curr->parm, id, strlen(attr_curr->parm)) == 0 ) ;
91 /*		LOCAL_DEBUG_OUT( "xml_elem_delete for attr %p", attr ); */
92 		xml_elem_delete(NULL, attr);
93 
94 		if( match_found )
95 			return find_super_section( sub, id );
96 	}
97 	return owner;
98 }
99 
100 
101 
102 void
write_doc_cdata(const char * cdata,int len,ASXMLInterpreterState * state)103 write_doc_cdata( const char *cdata, int len, ASXMLInterpreterState *state )
104 {
105 	int i ;
106 	if( state->doc_type == DocType_XML ||
107 		state->doc_type == DocType_HTML ||
108 		state->doc_type == DocType_PHP )
109 	{
110 		int token_start = 0;
111 		Bool special = False ;
112 		for( i = 0 ; i < len ; ++i )
113 		{
114 			if( (!isalnum(cdata[i]) && cdata[i] != '_'  && cdata[i] != '(' && cdata[i] != ')') || special )
115 			{
116 				if( token_start < i )
117 				{
118 					if( get_flags( state->flags, ASXMLI_InsideLink) )
119 					{
120 						fwrite( &(cdata[token_start]), 1, i-token_start, state->dest_fp );
121 					}else
122 					{
123 						/* need to try and insert an URL here if token is a keyword */
124 						char *token = mystrndup( &(cdata[token_start]), i - token_start );
125 						ASHashData hdata ;
126 						if( !special && get_hash_item(Links, AS_HASHABLE(token), &(hdata.vptr)) == ASH_Success )
127 						{
128 							if( state->doc_type == DocType_HTML	)
129 								fprintf( state->dest_fp, "<A href=\"%s\">%s</A>", hdata.cptr, token );
130 							else if( state->doc_type == DocType_PHP )
131 								fprintf( state->dest_fp, PHPXrefFormat, "visualdoc",token, hdata.cptr, "" );
132 						}else
133 					 		fwrite( token, 1, i-token_start, state->dest_fp );
134 						free( token );
135 					}
136 				}
137 				token_start = i+1 ;
138 
139 				if( cdata[i] == '&' )
140 					special = ( translate_special_sequence( &(cdata[i]), len-i,  NULL ) != '\0' );
141 				else if( cdata[i] == ';' && special )
142 					special = False ;
143 				switch( cdata[i] )
144 				{
145 					case '<' : fwrite( "&lt;", 1, 4, state->dest_fp );     break ;
146 					case '>' : fwrite( "&gt;", 1, 4, state->dest_fp );     break ;
147 					case '"' : fwrite( "&quot;", 1, 6, state->dest_fp );     break ;
148 					case '&' : 	if( !special )
149 								{
150 									fwrite( "&amp;", 1, 5, state->dest_fp );
151 									break ;
152 								}
153 								/* otherwise falling through ! */
154 					default:
155 						fputc( cdata[i], state->dest_fp );
156 				}
157 			}
158 		}
159 		if( i > token_start )
160 			fwrite( &(cdata[token_start]), 1, i-token_start, state->dest_fp );
161 	}else
162 	{
163 		for( i = 0 ; i < len ; ++i )
164 		{
165 			int c_len = 0 ;
166 			int c = '\0' ;
167 
168 			if( cdata[i] == '&' )
169 				c = translate_special_sequence( &(cdata[i]), len-i, &c_len ) ;
170 			if( c != '\0' )
171 				i += c_len-1 ;
172 			else
173 				c = cdata[i];
174 			if( c == '\"' && get_flags( state->flags, ASXMLI_EscapeDQuotes) )
175 				fputc( '\"', state->dest_fp );
176 			else if ( c == '-' && state->doc_type == DocType_NROFF )
177 				fputc( '\\', state->dest_fp );
178 			else if ( c == '.' && state->doc_type == DocType_NROFF )
179 				fputs( "\\&", state->dest_fp );
180 			else if ( c == '\\' && state->doc_type == DocType_NROFF )
181 				fputc( '\\', state->dest_fp );
182 			else if ( c == 152 /*'˜'*/ && state->doc_type == DocType_NROFF )
183 				c = '~';
184 			fputc( c, state->dest_fp );
185 		}
186 	}
187 }
188 
189 
190 void
convert_xml_tag(xml_elem_t * doc,xml_elem_t ** rparm,ASXMLInterpreterState * state)191 convert_xml_tag( xml_elem_t *doc, xml_elem_t **rparm, ASXMLInterpreterState *state )
192 {
193 	xml_elem_t* parm = NULL;
194 	xml_elem_t* ptr ;
195 	const char *tag_name = doc->tag;
196 
197 	if( state->doc_type != DocType_XML )
198 	{
199 		parm = xml_parse_parm(doc->parm, DocBookVocabulary);
200 		if( doc->tag_id > 0 && doc->tag_id < DOCBOOK_SUPPORTED_IDS )
201 			if( SupportedDocBookTagInfo[doc->tag_id].handle_start_tag )
202 				SupportedDocBookTagInfo[doc->tag_id].handle_start_tag( doc, parm, state );
203 	}else
204 	{
205 
206 		if( doc->tag_id == DOCBOOK_refsect1_ID )
207 			tag_name = SupportedDocBookTagInfo[DOCBOOK_section_ID].tag;
208 
209 		fprintf( state->dest_fp, "<%s", tag_name );
210 		if( doc->parm )
211 		{
212 			char *ptr = NULL;
213 			if( doc->tag_id == DOCBOOK_ulink_ID )
214 				ptr = strchr( doc->parm, '#' );
215 			if( ptr != NULL )
216 			{
217 				*ptr = '\0' ;
218 				fprintf( state->dest_fp, " %s.html#%s", doc->parm, ptr+1 );
219 				*ptr = '#' ;
220 			}else
221 				fprintf( state->dest_fp, " %s", doc->parm );
222 		}
223 		fputc( '>', state->dest_fp );
224 
225 	}
226 	for (ptr = doc->child ; ptr ; ptr = ptr->next)
227 	{
228 		/* LOCAL_DEBUG_OUT( "handling tag's data \"%s\"", ptr->parm ); */
229 		if (ptr->tag_id == XML_CDATA_ID )
230 		{
231 			const char *data_ptr = ptr->parm ;
232 			int len = 0 ;
233 			if( state->doc_type == DocType_NROFF )
234 			{
235 				while( data_ptr[0] == '\n' )
236 					++data_ptr ;
237 			}
238 			len = strlen( data_ptr );
239 			if( len > 0 && state->doc_type == DocType_NROFF)
240 			{
241 				int i ;
242 				while( len > 0 && data_ptr[len-1] == '\n' )
243 					--len ;
244 				/* we want to skip as much whitespace as possible in NROFF */
245 				for( i = 0 ; i < len ; ++i )
246 					if( !isspace(data_ptr[i]) )
247 						break;
248 				if( i == len )
249 					len = 0 ;
250 				else if( !get_flags( state->flags, ASXMLI_LiteralLayout ) )
251 				{
252 					int from , to ;
253 					Bool written = 0 ;
254 					for( i = 0 ; i < len ; ++i )
255 					{
256 						while( isspace(data_ptr[i]) && i < len ) ++i ;
257 						from = i ;
258 						while( !isspace(data_ptr[i]) && i < len ) ++i ;
259 						to = i ;
260 						if( to > from  )
261 						{
262 							if( written > 0 )
263 								fputc( ' ', state->dest_fp );
264 							write_doc_cdata( &data_ptr[from], to-from, state );
265 							written += to - from ;
266 						}
267 					}
268 					len = 0 ;
269 				}
270 			}
271 			if( len > 0 )
272 				write_doc_cdata( data_ptr, len, state );
273 		}else
274 			convert_xml_tag( ptr, NULL, state );
275 	}
276 	/* LOCAL_DEBUG_OUT( "handling end tag with func %p", SupportedDocBookTagInfo[doc->tag_id].handle_end_tag ); */
277 	if( state->doc_type != DocType_XML )
278 	{
279 		if( doc->tag_id > 0 && doc->tag_id < DOCBOOK_SUPPORTED_IDS )
280 			if( SupportedDocBookTagInfo[doc->tag_id].handle_end_tag )
281 				SupportedDocBookTagInfo[doc->tag_id].handle_end_tag( doc, parm, state );
282 /*		LOCAL_DEBUG_OUT( "xml_elem_delete for parm %p", parm ); */
283 		if (rparm) *rparm = parm;
284 		else xml_elem_delete(NULL, parm);
285 	}else
286 	{
287 		fprintf( state->dest_fp, "</%s>", tag_name );
288 	}
289 
290 }
291 
292 Bool
convert_xml_file(const char * syntax_dir,const char * file,ASXMLInterpreterState * state)293 convert_xml_file( const char *syntax_dir, const char *file, ASXMLInterpreterState *state )
294 {
295 	char *source_file ;
296 	char *doc_str ;
297 	Bool empty_file = False ;
298 
299 	source_file = make_file_name( syntax_dir, file );
300 	doc_str = load_file(source_file);
301 	LOCAL_DEBUG_OUT( "file %s loaded", source_file );
302 	/*LOCAL_DEBUG_OUT( "file %s loaded into {%s}", source_file, doc_str ); */
303 	if( doc_str != NULL )
304 	{
305 		xml_elem_t* doc;
306 		xml_elem_t* ptr;
307 
308 		if( file[0] == '_' && !get_flags( state->flags, ASXMLI_ProcessingOptions ))
309 			state->pre_options_size += strlen(doc_str) ;
310 		else
311 			set_flags( state->flags, ASXMLI_ProcessingOptions );
312 
313 		doc = xml_parse_doc(doc_str, DocBookVocabulary);
314 		LOCAL_DEBUG_OUT( "file %s parsed, child is %p", source_file, doc->child );
315 		if( doc->child )
316 		{
317 			LOCAL_DEBUG_OUT( "child tag = \"%s\", childs child = %p", doc->child->tag, doc->child->child);
318 			empty_file  = ( doc->child->tag_id == DOCBOOK_section_ID &&
319 							doc->child->child == NULL );
320 			if( doc->child->child )
321 			{
322 				empty_file  = ( doc->child->child->tag_id == XML_CDATA_ID && doc->child->child->next == NULL );
323 				LOCAL_DEBUG_OUT( "childs child tag = \"%s\", parm = \"%s\"", doc->child->child->tag, doc->child->child->parm);
324 			}
325 	   	}
326 		LOCAL_DEBUG_OUT( "file %s %s", source_file, empty_file?"empty":"not empty" );
327 		if( !empty_file )
328 		{
329 			for (ptr = doc->child ; ptr ; ptr = ptr->next)
330 			{
331 				LOCAL_DEBUG_OUT( "converting child <%s>", ptr->tag );
332 	  			convert_xml_tag( ptr, NULL, state );
333 				LOCAL_DEBUG_OUT( "done converting child <%s>", ptr->tag );
334 			}
335 		}
336 		/* Delete the xml. */
337 		LOCAL_DEBUG_OUT( "deleting xml %p", doc );
338 		xml_elem_delete(NULL, doc);
339 		LOCAL_DEBUG_OUT( "freeing doc_str %p", doc_str );
340 		free( doc_str );
341 	}
342 	LOCAL_DEBUG_OUT( "done with %s", source_file );
343 	free( source_file );
344 	fprintf( state->dest_fp, "\n" );
345 	return !empty_file;
346 }
347 
348 int
check_xml_contents(const char * syntax_dir,const char * file)349 check_xml_contents( const char *syntax_dir, const char *file )
350 {
351 	char *source_file ;
352 	char *doc_str ;
353 	int size = 0 ;
354 
355 	source_file = make_file_name( syntax_dir, file );
356 	doc_str = load_file(source_file);
357 	if( doc_str != NULL )
358 	{
359 		xml_elem_t* doc;
360 		size = strlen( doc_str );
361 		doc = xml_parse_doc(doc_str, DocBookVocabulary);
362 		if( doc->child )
363 		{
364 			if( doc->child->tag_id == DOCBOOK_section_ID && doc->child->child == NULL )
365 				size = 0 ;
366 			else if( doc->child->child )
367 			{
368 				if( doc->child->child->tag_id == XML_CDATA_ID && doc->child->child->next == NULL )
369 					size = 0;
370 			}
371 		}
372 		/* Delete the xml. */
373 		LOCAL_DEBUG_OUT( "xml_elem_delete for doc %p", doc );
374 		xml_elem_delete(NULL, doc);
375 		free( doc_str );
376 	}
377 	free( source_file );
378 	return size;
379 }
380 
381 /*************************************************************************/
382 void
close_link(ASXMLInterpreterState * state)383 close_link( ASXMLInterpreterState *state )
384 {
385 	if( get_flags( state->flags, ASXMLI_InsideLink ) )
386 	{
387 		if( state->doc_type == DocType_HTML ||
388 			(state->doc_type == DocType_PHP && !get_flags(state->flags, ASXMLI_LinkIsLocal)))
389 		{
390 			fwrite( "</A>", 1, 4, state->dest_fp );
391 		}else if( state->doc_type == DocType_PHP )
392 		{
393 			if ( TopicIndexName == NULL )
394 			{
395 			    fprintf( state->dest_fp, "\",\"%s\",\"%s\",$subunset) ?>", state->curr_url_page, state->display_name);
396 			}
397 			else
398 			{
399 			    fprintf( state->dest_fp, "\",\"%s\",$srcunset,$subunset) ?>", state->curr_url_page);
400 			}
401 
402 		}
403 		clear_flags( state->flags, ASXMLI_InsideLink|ASXMLI_LinkIsLocal|ASXMLI_LinkIsURL );
404 		if( state->curr_url_page )
405 			free( state->curr_url_page );
406 		if( state->curr_url_anchor )
407 			free( state->curr_url_anchor );
408 		state->curr_url_anchor = state->curr_url_page = NULL ;
409 	}
410 }
411 
412 
413 void
add_anchor(xml_elem_t * attr,ASXMLInterpreterState * state)414 add_anchor( xml_elem_t *attr, ASXMLInterpreterState *state )
415 {
416 	while( attr )
417 	{
418 		if( attr->tag_id == DOCBOOK_id_ID )
419 		{
420 			close_link(state);
421 			if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP)
422 				fprintf( state->dest_fp, "\n<A NAME=\"%s\">", attr->parm );
423 			state->curr_url_anchor = mystrdup(attr->parm);
424 			clear_flags( state->flags, ASXMLI_LinkIsLocal|ASXMLI_LinkIsURL );
425 			set_flags( state->flags, ASXMLI_InsideLink );
426 			break;
427 		}
428 		attr = attr->next ;
429 	}
430 
431 }
432 
433 void
add_local_link(xml_elem_t * attr,ASXMLInterpreterState * state)434 add_local_link( xml_elem_t *attr, ASXMLInterpreterState *state )
435 {
436 	while( attr )
437 	{
438 		if( attr->tag_id == DOCBOOK_linkend_ID ||  attr->tag_id == DOCBOOK_url_ID )
439 		{
440 			char *ptr ;
441 			int l ;
442 
443 			close_link(state);
444 			ptr = strchr( attr->parm, '#' );
445 			if( ptr != NULL )
446 			{
447 				*ptr = '\0' ;
448 				state->curr_url_page = mystrdup( attr->parm );
449 				state->curr_url_anchor = mystrdup( ptr+1 );
450 				*ptr = '#' ;
451 			}else
452 			{
453 				state->curr_url_page = mystrdup( attr->parm );
454 				state->curr_url_anchor = NULL ;
455 			}
456 			l = strlen(state->curr_url_page);
457 			clear_flags( state->flags, ASXMLI_LinkIsLocal );
458 			if( state->curr_url_page[l-1] != '/' &&
459 				( l < 5 || mystrcasecmp( &(state->curr_url_page[l-5]), ".html" ) != 0) &&
460 				( l < 4 || mystrcasecmp( &(state->curr_url_page[l-4]), ".php" ) != 0) &&
461 				( l < 4 || mystrcasecmp( &(state->curr_url_page[l-4]), ".htm" ) != 0) &&
462 				( l < 4 || mystrcasecmp( &(state->curr_url_page[l-4]), ".jpg" ) != 0) &&
463 				( l < 4 || mystrcasecmp( &(state->curr_url_page[l-4]), ".png" ) != 0))
464 			{
465 				set_flags( state->flags, ASXMLI_LinkIsLocal );
466 			}
467 
468 			if( state->doc_type == DocType_HTML ||
469 				(state->doc_type == DocType_PHP && !get_flags( state->flags, ASXMLI_LinkIsLocal )))
470 			{
471 				fprintf( state->dest_fp, "\n<A href=\"%s", state->curr_url_page );
472 				if( get_flags( state->flags, ASXMLI_LinkIsLocal ) )
473 					fwrite( ".html", 1, 5, state->dest_fp );
474 				if( state->curr_url_anchor != NULL )
475 					fprintf( state->dest_fp, "#%s", state->curr_url_anchor );
476 				fwrite( "\">", 1, 2, state->dest_fp );
477 			}else if( state->doc_type == DocType_PHP )
478 			{
479 			    if (TopicIndexName == NULL) /* added for php part of data catalogue */
480 			    {
481 				fprintf( state->dest_fp, "<? local_doc_url(\"graphics.php\",\"" );
482 			    }
483 			    else
484 				fprintf( state->dest_fp, "<? local_doc_url(\"visualdoc.php\",\"" );
485 			}
486 			set_flags( state->flags, ASXMLI_InsideLink|ASXMLI_LinkIsURL  );
487 			break;
488 		}
489 		attr = attr->next ;
490 	}
491 }
492 
493 void
add_glossary_item(xml_elem_t * doc,ASXMLInterpreterState * state)494 add_glossary_item( xml_elem_t* doc, ASXMLInterpreterState *state )
495 {
496 	xml_elem_t *cdata = find_tag_by_id( doc->child, XML_CDATA_ID );
497 	char *term_text = mystrdup(cdata?cdata->parm:"") ;
498 	char *orig_term_text = term_text ;
499 	int i ;
500 
501 	LOCAL_DEBUG_OUT( "term_text = \"%s\"", term_text );
502 	while(*term_text)
503 	{
504 		if( isalnum(*term_text) )
505 			break;
506 		++term_text ;
507 	}
508 	i = 0 ;
509 	while( isalnum(term_text[i]) ) ++i ;
510 	term_text[i] = '\0' ;
511 
512 	if( term_text[0] != '\0' ) /* need to add glossary term */
513 	{
514 	 	char *target = NULL, *target2 ;
515 		char *term = NULL, *term2 ;
516 		char *ptr = &(state->dest_file[strlen(state->dest_file)-4]);
517 		size_t curr_url_anchor_len = state->curr_url_anchor ? strlen(state->curr_url_anchor) : 0;
518 		if( state->doc_type == DocType_PHP && *ptr == '.')
519 			*ptr = '\0' ;
520 		target = safemalloc( strlen( state->dest_file)+5+1+curr_url_anchor_len+1);
521 		sprintf( target, "%s#%s", state->dest_file, state->curr_url_anchor );
522 		if( state->doc_type == DocType_PHP && *ptr == '\0' )
523 			*ptr = '.' ;
524 
525 		target2 = mystrdup(target);
526 		term2 = mystrdup(term_text);
527 		if( add_hash_item( Links, AS_HASHABLE(term2), (void*)target2 ) != ASH_Success )
528 		{
529 			free( target2 );
530 			free( term2 );
531 		}
532 		term = safemalloc( strlen( term_text)+ 1 + 1 +strlen( state->doc_name ) + 1 +1 );
533 		sprintf( term, "%s (%s)", term_text, state->doc_name );
534 		LOCAL_DEBUG_OUT( "term = \"%s\"", term );
535 		if( add_hash_item( Glossary, AS_HASHABLE(term), (void*)target ) != ASH_Success )
536 		{
537 			free( target );
538 			free( term );
539 		}
540 	}
541 
542 	free(orig_term_text);
543 }
544 
545 /*************************************************************************/
546 /* DocBook XML tags handlers :											 */
547 /*************************************************************************/
548 
549 void
start_para_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)550 start_para_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
551 {
552 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP )
553 	{
554 		close_link(state);
555 		fprintf( state->dest_fp, "<P class=\"dense\">" );
556 	}else if( state->doc_type == DocType_NROFF )
557 		fprintf( state->dest_fp, "\n" );
558 
559 }
560 
561 void
end_para_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)562 end_para_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
563 {
564 	close_link(state);
565 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP )
566 	{
567 		fwrite( "</P>", 1, 4, state->dest_fp );
568 	}else if( state->doc_type == DocType_NROFF )
569 		fprintf( state->dest_fp, "\n" );
570 }
571 
572 void
start_formalpara_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)573 start_formalpara_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
574 {
575 	add_anchor( parm, state );
576 	set_flags( state->flags, ASXMLI_FormalPara );
577 }
578 
579 void
end_formalpara_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)580 end_formalpara_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
581 {
582 	close_link(state);
583 	clear_flags( state->flags, ASXMLI_FormalPara );
584 }
585 
586 void
start_command_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)587 start_command_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
588 {
589 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
590 		fwrite( "<B>", 1, 3, state->dest_fp );
591 	else if( state->doc_type == DocType_NROFF )
592 		fprintf( state->dest_fp, " \\fB");
593 }
594 
595 void
end_command_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)596 end_command_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
597 {
598 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
599 		fwrite( "</B>", 1, 4, state->dest_fp );
600 	else if( state->doc_type == DocType_NROFF )
601 		fprintf( state->dest_fp, "\\fP ");
602 }
603 
604 void
start_emphasis_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)605 start_emphasis_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
606 {
607 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
608 		fwrite( "<I>", 1, 3, state->dest_fp );
609 	else if( state->doc_type == DocType_NROFF && doc->tag_id != DOCBOOK_replaceable_ID)
610 		fprintf( state->dest_fp, " \\fI");
611 }
612 
613 void
end_emphasis_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)614 end_emphasis_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
615 {
616 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
617 		fwrite( "</I>", 1, 4, state->dest_fp );
618 	else if( state->doc_type == DocType_NROFF && doc->tag_id != DOCBOOK_replaceable_ID )
619 		fprintf( state->dest_fp, "\\fP ");
620 }
621 
622 void
start_literallayout_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)623 start_literallayout_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
624 {
625  	close_link(state);
626 	set_flags( state->flags, ASXMLI_LiteralLayout );
627 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP)
628 	{
629 		fprintf( state->dest_fp, "<PRE>");
630 	}else if( state->doc_type == DocType_NROFF )
631 		fprintf( state->dest_fp, "\n.fi\n");
632 }
633 
634 void
end_literallayout_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)635 end_literallayout_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
636 {
637 	clear_flags( state->flags, ASXMLI_LiteralLayout );
638 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP)
639 	{
640 		fwrite( "</PRE>", 1, 6, state->dest_fp );
641 	}else if( state->doc_type == DocType_NROFF )
642 		fprintf( state->dest_fp, "\n.fi ");
643 }
644 
645 void
start_variablelist_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)646 start_variablelist_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
647 {
648 	close_link(state);
649 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	)
650 		fprintf( state->dest_fp, "<DL class=\"dense\">" );
651 }
652 
653 void
end_variablelist_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)654 end_variablelist_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
655 {
656 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
657 		fwrite( "</DL>", 1, 5, state->dest_fp );
658 	else if( state->doc_type == DocType_NROFF )
659 		fprintf( state->dest_fp, "\n");
660 }
661 
662 void
start_varlistentry_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)663 start_varlistentry_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
664 {
665 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
666 		add_anchor( parm, state );
667  /*	else if( state->doc_type == DocType_NROFF )
668 		fprintf( state->dest_fp, "\n.IP "); */
669 
670 }
671 
672 void
end_varlistentry_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)673 end_varlistentry_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
674 {
675 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
676 		close_link(state);
677 //	else if( state->doc_type == DocType_NROFF )
678 //		fprintf( state->dest_fp, "\n");
679 }
680 
681 void
start_term_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)682 start_term_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
683 {
684 #if 1
685 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	 )
686 	{
687 		if( get_flags( state->flags, ASXMLI_InsideLink ) && state->curr_url_anchor != NULL )
688 		{
689 			add_glossary_item( doc, state );
690 			close_link(state);
691 		}
692 	}
693 #endif
694 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	 )
695 		fprintf( state->dest_fp, "<DT class=\"dense\"><B>" );
696 	else if( state->doc_type == DocType_NROFF )
697 	{
698 		fprintf( state->dest_fp, "\n.IP ");
699 		fprintf( state->dest_fp, "\"");
700 		set_flags( state->flags, ASXMLI_EscapeDQuotes);
701 	}
702 }
703 
704 void
end_term_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)705 end_term_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
706 {
707 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	 )
708 		fwrite( "</B></DT>", 1, 9, state->dest_fp );
709 	else if( state->doc_type == DocType_NROFF )
710 	{
711 		fprintf( state->dest_fp, "\"\n");
712 		clear_flags( state->flags, ASXMLI_EscapeDQuotes);
713 	}
714 }
715 
716 void
start_listitem_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)717 start_listitem_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
718 {
719 	if( state->doc_type == DocType_HTML	 || state->doc_type == DocType_PHP	   )
720 		fprintf( state->dest_fp, "<DD class=\"dense\">" );
721 }
722 
723 void
end_listitem_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)724 end_listitem_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
725 {
726 	close_link(state);
727 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	  	)
728 		fwrite( "</DD>", 1, 5, state->dest_fp );
729 }
730 
731 void
start_imagedata_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)732 start_imagedata_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
733 {
734 	if( state->doc_type == DocType_HTML	 || state->doc_type == DocType_PHP	   )
735 	{
736 		const char *url = NULL ;
737 		const char *align = NULL ;
738 		const char *valign = NULL ;
739 		const char *width = NULL ;
740 		const char *height = NULL ;
741 		while( parm )
742 		{
743 			switch( parm->tag_id )
744 			{
745 				case DOCBOOK_width_ID : width = parm->parm ; break ;
746 				case DOCBOOK_depth_ID : height = parm->parm ; break ;
747 				case DOCBOOK_align_ID : align = parm->parm ; break ;
748 				case DOCBOOK_valign_ID : valign = parm->parm ; break ;
749 				case DOCBOOK_fileref_ID : url = parm->parm ; break ;
750 			}
751 			parm = parm->next ;
752 		}
753 		if( url )
754 		{
755 			if (  state->doc_type == DocType_PHP )
756 		    	fprintf( state->dest_fp, "<IMG SRC=%s/%s", state->dest_dir, url );
757 			else
758 		    	fprintf( state->dest_fp, "<IMG src=\"%s\"", url );
759 			if( align != NULL )
760 				fprintf( state->dest_fp, " align=\"%s\"", align );
761 			if( valign != NULL )
762 				fprintf( state->dest_fp, " valign=\"%s\"", valign );
763 			if( width != NULL )
764 				fprintf( state->dest_fp, " width=\"%s\"", width );
765 			if( height != NULL )
766 				fprintf( state->dest_fp, " height=\"%s\"", height );
767 			fwrite( ">", 1, 1, state->dest_fp );
768 		}
769 	}
770 }
771 
772 void
end_imagedata_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)773 end_imagedata_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
774 {
775 	close_link(state);
776 	if( state->doc_type == DocType_HTML || state->doc_type == DocType_PHP	)
777 		fwrite( "</IMG>", 1, 6, state->dest_fp );
778 //		fprintf( state->dest_fp, "\n", NULL );
779 		fputc( '\n', state->dest_fp );
780 }
781 
782 
783 void
start_section_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)784 start_section_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
785 {
786 	++(state->header_depth);
787 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
788 	{
789 		/*if( state->doc_type == DocType_HTML )
790 			fwrite( "<HR>\n", 1, 5, state->dest_fp );
791 		 */
792 		add_anchor( parm, state );
793 		if( get_flags( state->flags, ASXMLI_OrderSections ) )
794 			fwrite( "<OL>", 1, 4, state->dest_fp );
795 		else
796 			fwrite( "<UL>", 1, 4, state->dest_fp );
797 	}
798 	else if (state->doc_type == DocType_NROFF && !strcmp(state->doc_name, ASFAQ_NAME))
799 	{
800 		fprintf( state->dest_fp, state->header_depth == 2 ? "\n.SH " : "\n.SS " );
801 	}
802 }
803 
804 void
end_section_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)805 end_section_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
806 {
807 	--(state->header_depth);
808 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
809 	{
810 		if( get_flags( state->flags, ASXMLI_OrderSections ) )
811 			fwrite( "</OL>", 1, 5, state->dest_fp );
812 		else
813 			fwrite( "</UL>", 1, 5, state->dest_fp );
814 	}
815 }
816 
817 void
start_refsect1_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)818 start_refsect1_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
819 {
820 	++(state->header_depth);
821 	set_flags( state->flags, ASXMLI_RefSection );
822 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
823 	{
824 		add_anchor( parm, state );
825 		fwrite( "<LI>", 1, 4, state->dest_fp );
826 	}else if( state->doc_type == DocType_NROFF )
827 		fprintf( state->dest_fp, "\n.SH ");
828 }
829 
830 void
end_refsect1_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)831 end_refsect1_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
832 {
833 	--(state->header_depth);
834 	clear_flags( state->flags, ASXMLI_RefSection );
835 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
836 	{
837 			fwrite( "</LI>", 1, 5, state->dest_fp );
838 	}
839 }
840 
841 void
start_title_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)842 start_title_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
843 {
844 	if( state->doc_type == DocType_HTML	 )
845 	{
846 		if( get_flags( state->flags, ASXMLI_FormalPara ) )
847 		{
848 			add_glossary_item( doc, state );
849 			close_link(state);
850 			fprintf( state->dest_fp, "<B>" );
851 		}else if( get_flags( state->flags, ASXMLI_RefSection ) )
852 			fprintf( state->dest_fp, "<p class=\"refsect_header\"><B>" );
853 		else
854 			fprintf( state->dest_fp, "<p class=\"sect_header\"><B>" );
855 	}else if( state->doc_type == DocType_PHP )
856 	{
857 		if( get_flags( state->flags, ASXMLI_FormalPara ) )
858 		{
859 			add_glossary_item( doc, state );
860 			close_link(state);
861 		}
862 		fprintf( state->dest_fp, "<B>");
863 	}
864 }
865 
866 void
end_title_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)867 end_title_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
868 {
869 	if( state->doc_type == DocType_HTML	 )
870 	{
871 		fprintf( state->dest_fp, "</B>" );
872 		if( !get_flags( state->flags, ASXMLI_FormalPara ) )
873 			fprintf( state->dest_fp, "</p>");
874 	}else if( state->doc_type == DocType_PHP )
875 	{
876 		fprintf( state->dest_fp, "</B>");
877 		if( !get_flags( state->flags, ASXMLI_FormalPara ) )
878 			fprintf( state->dest_fp, "<br>");
879 	}
880 	else if (state->doc_type == DocType_NROFF && !strcmp(state->doc_name, ASFAQ_NAME))
881 	{
882 	   fprintf( state->dest_fp, "\n");
883 	}
884 	close_link(state);
885 }
886 
887 void
start_cmdsynopsis_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)888 start_cmdsynopsis_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
889 {
890 	++(state->header_depth);
891 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
892 	{
893 		add_anchor( parm, state );
894 		if( state->doc_type == DocType_PHP )
895 			fprintf( state->dest_fp, "<LI><b>SYNOPSIS</b><p>" );
896 		else
897 			fprintf( state->dest_fp, "<LI><h%d>SYNOPSIS</h%d>", state->header_depth, state->header_depth );
898 		close_link(state);
899 	}else if( state->doc_type == DocType_NROFF )
900 		fprintf( state->dest_fp, ".SH SYNOPSIS\n");
901 }
902 
903 void
end_cmdsynopsis_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)904 end_cmdsynopsis_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
905 {
906 	--(state->header_depth);
907 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
908 		fwrite( "</LI>", 1, 5, state->dest_fp );
909 	else if( state->doc_type == DocType_NROFF )
910 		fprintf( state->dest_fp, "\n");
911 }
912 
913 int
check_choice(xml_elem_t * parm)914 check_choice( xml_elem_t *parm )
915 {
916 	while( parm )
917 	{
918 		if( parm->tag_id == DOCBOOK_choice_ID )
919 		{
920 			if( mystrcasecmp( parm->parm, "opt" ) == 0 )
921 				return 1;
922 			break;
923 		}
924 		parm = parm->next ;
925 	}
926 	return 0;
927 }
928 
929 void
start_group_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)930 start_group_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
931 {
932 	++(state->group_depth);
933 	set_flags(state->flags, ASXMLI_FirstArg );
934 	if( state->doc_type == DocType_NROFF )
935 		fputc( ' ', state->dest_fp );
936 	if( check_choice( parm ) )
937 		fputc( '[', state->dest_fp );
938 }
939 
940 void
end_group_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)941 end_group_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
942 {
943 	--(state->group_depth);
944 	if( state->group_depth <= 0 )
945 		set_flags(state->flags, ASXMLI_FirstArg );
946 	if( check_choice( parm ) )
947 		fputc( ']', state->dest_fp );
948 	if( state->doc_type == DocType_NROFF )
949 		fputc( ' ', state->dest_fp );
950 }
951 
952 void
start_arg_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)953 start_arg_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
954 {
955 	if( !get_flags(state->flags, ASXMLI_FirstArg ) && state->group_depth > 0 )
956 		fwrite( "| ", 1, 2, state->dest_fp );
957 	clear_flags(state->flags, ASXMLI_FirstArg );
958 	if( state->doc_type == DocType_NROFF )
959 		fputc( ' ', state->dest_fp );
960 	if( check_choice( parm ) )
961 		fputc( '[', state->dest_fp );
962 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
963 		fwrite( "<B>", 1, 3, state->dest_fp );
964 	else if( state->doc_type == DocType_NROFF )
965 		fprintf( state->dest_fp, "\\fI");
966 }
967 
968 void
end_arg_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)969 end_arg_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
970 {
971 	--(state->group_depth);
972 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP )
973 		fwrite( "</B>", 1, 4, state->dest_fp );
974 	else if( state->doc_type == DocType_NROFF )
975 		fprintf( state->dest_fp, "\\fP");
976 	if( check_choice( parm ) )
977 		fputc( ']', state->dest_fp );
978 	if( state->doc_type == DocType_NROFF )
979 		fputc( ' ', state->dest_fp );
980 }
981 
982 void
start_option_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)983 start_option_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
984 {
985 	if( state->doc_type == DocType_HTML	 )
986 		fwrite( "<B>", 1, 3, state->dest_fp );
987 }
988 
989 void
end_option_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)990 end_option_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
991 {
992 	if( state->doc_type == DocType_HTML	 )
993 		fwrite( "</B>", 1, 4, state->dest_fp );
994 }
995 
996 void
start_example_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)997 start_example_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
998 {
999 	set_flags( state->flags, ASXMLI_InsideExample );
1000 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1001 	{
1002 		add_anchor( parm, state );
1003 		close_link(state);
1004 		fprintf( state->dest_fp, "<P class=\"dense\"> <B>Example : </B> " );
1005 		fprintf( state->dest_fp, "<div class=\"container\">");
1006 	}else if( state->doc_type == DocType_NROFF )
1007 		fprintf( state->dest_fp, "\nExample : ");
1008 
1009 }
1010 
1011 void
end_example_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1012 end_example_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1013 {
1014 	clear_flags( state->flags, ASXMLI_InsideExample );
1015 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1016 	{
1017 		fprintf( state->dest_fp, "</div><br></p>");
1018 	}
1019 }
1020 
1021 void
start_code_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1022 start_code_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1023 {
1024 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1025 	{
1026 		add_anchor( parm, state );
1027 		close_link(state);
1028 		fprintf( state->dest_fp, "<P class=\"dense\">" );
1029 		fprintf( state->dest_fp, "<div class=\"container\">");
1030 	}else if( state->doc_type == DocType_NROFF )
1031 		fprintf( state->dest_fp, "\n.in +4n\n");
1032 
1033 }
1034 
1035 void
end_code_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1036 end_code_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1037 {
1038 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1039 	{
1040 		fprintf( state->dest_fp, "</div><br></p>");
1041 	}
1042 	else if( state->doc_type == DocType_NROFF )
1043 		fprintf( state->dest_fp, "\n.in\n");
1044 }
1045 
1046 
1047 void
start_ulink_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1048 start_ulink_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1049 {
1050 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1051 	{
1052 		add_local_link( parm, state );
1053 	}
1054 	if( state->doc_type == DocType_NROFF )
1055 		fputc( ' ', state->dest_fp );
1056 }
1057 
1058 void
end_ulink_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1059 end_ulink_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1060 {
1061 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1062 		close_link(state);
1063 	if( state->doc_type == DocType_NROFF )
1064 		fputc( ' ', state->dest_fp );
1065 }
1066 
1067 void
start_anchor_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1068 start_anchor_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1069 {
1070 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1071 		add_anchor( parm, state );
1072 }
1073 
1074 void
end_anchor_tag(xml_elem_t * doc,xml_elem_t * parm,ASXMLInterpreterState * state)1075 end_anchor_tag( xml_elem_t *doc, xml_elem_t *parm, ASXMLInterpreterState *state )
1076 {
1077 	if( state->doc_type == DocType_HTML	|| state->doc_type == DocType_PHP	 )
1078 		close_link(state);
1079 }
1080 
1081 /*************************************************************************/
1082 void
compile_links(xml_elem_t * doc,ASXMLInterpreterState * state)1083 compile_links( xml_elem_t *doc, ASXMLInterpreterState *state )
1084 {
1085 	while( doc )
1086 	{
1087 
1088 		if( doc->child )
1089  			compile_links( doc->child, state );
1090 		doc = doc->next ;
1091 	}
1092 
1093 }
1094