/* $Header: /bioy2/biocomputing/doelz/development/jam/RCS/jam.c,v 2.0 1995/07/23 08:59:46 doelz Exp doelz $
/* JAM processor */ 
/*
         ***********************************************************
         *                                                         *
         *                         J A M                           * 
         *        J u s t   A n o t h e r   M e t a f i l e        *
         *                                                         *
         *                                                         *
         * This program package has been written starting from '94 *
         * at the Biocomputing Laboratory, University of Basel, by *
         * Reinhard Doelz. Valuable  suggestions from various col- *
         * leagues, including code contributions (as  documented), *
         * allowed to make this code portable, and  running on the *
         * different platforms.  Though it has been a major effort *
         * to make this language and its  production  tools  work, *
         * no   responsibility  can   be  taken for  errors  which *
         * might occur while running or result from processing the *
         * program's output. The program writing was supported  by *
         * Basel University, and a grant from the  Swiss  National *
         * Science Foundation  (NF). The  software  resembling JAM *
         * may be copied and resdistributed only if this statement *
         * is  preserved.  JAM  may  not,  as  a whole or in part, *
         * sold or used by commercial institutions to gain  profit *
         * from the services accessed on the basis of academic re- *
         * search. Users should acknowledge  the  program  package *
         * (Doelz, R., Just Another Metafile (JAM) (submitted)).   *
         ***********************************************************


If the definition JAMGUI is active, the program will generate a graphical user 
interface which is based on the VIBRANT toolkit as available from the NCBI. The
help and support from the NCBI for the VIBRANT product is very much appreciated. 

Vibrant is a multi-platform user interface development library that runs 
on the Macintosh, Microsoft Windows on the PC, or X11 and OSF/Motif on 
UNIX and VAX computers [separate documentation].  It is used to build 
the graphical interface for the Entrez application (whose source code is 
in the browser directory). The philosophy behind Vibrant is that 
everything in the published user interface guidelines (the generic 
behavior of windows, menus, buttons, etc.), as well as positioning and 
sizing of graphical control objects, is taken care of automatically.  
The program provides callback functions that are notified when the user 
has manipulated an object. Vibrant and Entrez code are not supported, 
but are provided on an as-is basis.
Questions or comments can be directed to toolbox@ncbi.nlm.nih.gov.


=====================================================================================
*/


#ifdef JAMGUI
#include "vibrant.h"
#include "document.h"

#define DEALEXIT ArrowCursor(); 
#else
#define MSG_ERROR stdout
#define MSG_POST stdout
#define MSG_OK stdout
#define DEALEXIT perror("Error in JAM"); 
#define Message fprintf
#endif
#include "jam.h"    
#include "jamproto.h"

static char code_id[] = "$Id: jam.c,v 2.0 1995/07/23 08:59:46 doelz Exp doelz $";

/* Global variables */ 

#ifdef DEBUG 
int jam_debug=1;
#else
int jam_debug=0; 
#endif 
char yesno[2][2] ; 

char jam_line[MAXLINE],jam_link[MAXLINE];
char jam_file[MAXINC][MAXFIL],jam_out[MAXLINE]; 
char myline[MAXLINE]; 
int jam_lineno[MAXINC],jam_indexdone;
int linecounter=0; 
int blockcounter=0; 

FILE *jam_fp[MAXINC], *jam_op, *jam_index,*jam_all,*jam_cts, *jam_lnk, *jam_ref, *jam_inx; 
int current_jam;      /* current open jam file */ 
int def_flag= TRUE;   /* for ifdeff'ing */
 
/* conditionals */ 
int if_tstack;
int if_dstack; 
char if_token[MAXIF][MAXDEF];  
char if_defined[MAXIF][MAXDEF]; 

/* output modus */ 
int modus,sitespecific=TRUE; 
int did_a_print=FALSE; 
int vms_status=FALSE; 
int single_file=FALSE; 

/* chapters */ 
int chapter_number=0; 
int section_number;
int subsection_number; 
int line_number; 
int line_in_file; 
int line_in_input[MAXINC]; 

/* styles */ 
int verbatim = FALSE; 
int special = FALSE;  
int item = FALSE; 
int last_verbatim; 
int special_on=FALSE; 
int emphasis_on=FALSE; 
int item_on=FALSE; 
int link_on=FALSE;   
int did_feed = TRUE; /* OLD CODE was FALSE */ 
int behaviour= NONE; 

/* item formatter */
char item_prefix[MAXLINE];

/* reflector prefix */ 
char reflec_prefix[MAXLINE];

/*======================================= V I B R A N T =====================*/
#ifdef JAMGUI

extern char if_defined[MAXIF][MAXDEF]; 
extern int if_dstack, sitespecific; 
extern char infileName[MAXLINE]; 
extern char reflec_prefix[MAXLINE];   
extern int modus; 
extern ButtoN  bSRS, bENTREZ, bDECNET, bRCP, bPEARSON, bATLAS, bREADSEQ, bEGCG;
extern ButtoN bUSR1,bUSR2; 	
extern GrouP bOS,bSTE,bBEHAVIOUR, bSINGLE, ReflecG; 

extern  PopuP  popModus;


void SetupObjects (WindoW w);                    /* help to setup main window */ 
void SetupMenus (WindoW w);                      /* the setup of main windows menu */ 

void jamstart(ButtoN dummy)

#else
/*================================= end    V I B R A N T =====================*/
main(int argc,char** argv)
#endif
{ 
  int status; 
  int i,ib,ii; 
  int need_item_prefix; 
  int process=TRUE;
  int define_process[MAXINC]; 
  char currentline[MAXLINE];   
  char token[MAXLINE]; 
  char tokenline[MAXLINE]; 
  char* tok; 
  char* headline; 
  char link[MAXLINE], linkbody[MAXLINE], tmplink[MAXLINE]; 
  int curpointer; 
  int linkpointer; 
  int linktype; 
  int special; 

  need_item_prefix=0; 
  current_jam =0; 
  strcpy (jam_file[0], "MASTER.JAM"); 
  yesno[1][0]= 'Y'; 
  yesno[0][0]= 'N'; 
  modus = HTML; 
#ifdef JAMGUI  

/*======================================= V I B R A N T =====================*/
  
  WatchCursor(); 
  TurnOnDefines(); 
  modus = GetValue(popModus); 
  Jam_HTML(); 
  Jam_SINGLE();  
  Jam_STE(); 
  Jam_OS(); 
 
  /* The following settings are GUI specific and cannot be mimicked in ASCII mode */
  
    if (strlen(infileName) > 0 ) {
  	strcpy (jam_file[0], infileName); 
  	Message (MSG_OK, "Master file: %s", jam_file[0]); 
  	}   
  	                       
   if (modus == HTML) if (behaviour == JAMREFLECTOR) {	                       
     if (strlen(reflec_prefix) == 0 ) { 
     	strcpy (reflec_prefix, REFLECTOR); 
     	}
  	  Message (MSG_OK, "Reflector prefix: %s", reflec_prefix); 
  	}
  	

  /*================================== end  V I B R A N T =====================*/
#else
  /*                                                           */
  /****                                                     ****/
  /********                                             ********/
  /**************                                  *************/
  /***********************                 *********************/
  /*************************************************************/
  
  /* Default is to produce a single RTF file for international UNIX. */ 
  
  modus        = RTF;      /*options are RTF, HTML, LATEX */ 
  behaviour    = JAMDUMMY; /* options are JAMDUMMY, JAMREFLECTOR, JAMPROCESSOR */ 
  single_file  = TRUE;     /* makes one RTF rather than many */ 
  sitespecific = FALSE;    /* international code here */ 
 
  printf ("%s\n",CODE_CRN);
#ifdef COMMANDLINE
  commin(argc, argv); 
#else  
  if (argc > 1) { 
    /* Message (stdout,"commandline arguments detected - trying to process correctly.\n...\n\n "); */
    modus = 0;
    
    if (strcmp(argv[1],"RTF") == 0){ 
      modus = RTF; 
      Message (stdout,"setting MODUS to be RTF\n"); 
    } 
    if (strcmp(argv[1],"LATEX") == 0){ 
		modus = LATEX;
		Message (stdout,"setting MODUS to be LATEX\n");
	 }
	 if (strcmp(argv[1],"HTML") == 0){
      modus = HTML; 
      Message (MSG_OK,"setting MODUS to be HTML\n"); 
    } 
    if (modus == 0){ 
      modus = RTF; 
      Message (MSG_POST,"possible values for MODUS are  RTF, LATEX,HTML\n"); 
      Message (MSG_POST,"as '%s' was a non-recongized MODUS.\n\n\n",argv[1]);
      Message (MSG_OK,"Syntax: %s MODUS SCOPE [SINGLE|NONE] [... defines]\n", argv[0]); 
      exit(1); 
    } 
    sitespecific = -1;     
    if (argc > 2) { 
      if (strcmp(argv[2],"I") == 0){ 
	sitespecific = FALSE; 
	Message (MSG_POST,"setting SCOPE to be International\n"); 
      } 
      if (strcmp(argv[2],"S") == 0){ 
	sitespecific = TRUE; 
	Message (MSG_POST,"setting SCOPE to be Site-specific\n"); 
      } 
      if (sitespecific == -1){ 
	modus = RTF; 
	Message (MSG_POST,"possible values for SCOPE are  I, S (International/Site-specific).\n"); 
	Message (MSG_POST,"as '%s' was a non-recongized SCOPE.\n\n\n",argv[2]);
	Message (MSG_OK,"Syntax: %s MODUS SCOPE [SINGLE|NONE] [... defines]\n",argv[0]); 
	exit(1); 
      } 
      single_file=FALSE; 
      behaviour= JAMDUMMY; 
      if (argc > 3 ) { 
	for (i=3;i<argc;i++) { 
	  if (strcmp(argv[i],"SINGLE")==0) { 
	    single_file = TRUE; 
	    if (modus == RTF) {  
	      Message (MSG_POST,"defining a single file as output.\n"); 
	    } else { 
	      Message (MSG_OK,"SINGLE does not make sense - only in RTF modus\n"); 
	    } 
	  } else {
	    if (modus == RTF) {  
	      Message (MSG_POST,"defining multiple files as output.\n"); 
	    }  
	    if (strcmp(argv[i],"NONE")==0) { 

	    if (modus == HTML) { 
		  Message (MSG_POST,"defining no REFLECTOR in HTML.\n"); 
	      } else { 
		  Message (MSG_OK,"NONE does not make sense - only in HTML modus\n"); 
	      } 
	    } else { 
	      if (strcmp(argv[i],"REFLECTOR")==0) { 
	      behaviour = JAMREFLECTOR;
	      if (modus == HTML) {        
	      i++;                         
	      strcpy (reflec_prefix, argv[i]); 
		  Message (MSG_POST,"defining REFLECTOR prefix %s.\n",reflec_prefix); 
	      } else { 
		  Message (MSG_OK,"NONE does not make sense - only in HTML modus\n"); 
	      } 
	    
	      } else {
	      strcpy(if_defined[if_dstack], argv[i]);
	      if_dstack++; 
	      Message (MSG_POST,"defining '%s' as logical.\n",argv[i] );
	      } 
	    } 
	  } 
	} 
      } 
    } else {
#ifdef JAMGUI
    i=0; 
#else
    printf ("default modus: international \n");
#endif
    }
  } else { 
    Message (MSG_OK,"using default values: single RTF file for international UNIX.\n");
  } 
  
#endif
#endif

  /*.............................................................................*/
  /*                                                                             */
  /*            A C T U A L    C O D E    S T A R T   H E R E                    */ 
  /*                                                                             */
  
  /* initialize */ 
  status = jam_init(jam_file[0]); 
  define_process[0] = TRUE;  
  strcpy(if_token[0], "ELEMENTARY"); 
  
  /*.............................................................................*/
  /*                                                                             */
  /*            B I G   P A R S I N G    L O O P   S T A R T                     */ 
  /*                                                                             */
  
  
  while ((status =readline(currentline)) >= 0 ) {

if (strncmp(currentline,"GAGA", 4) == 0 ) { 
  printf ("%s\n", currentline); 
} 
#ifndef JAMGUI
  if (linecounter > 10) {
    printf ("."); 
    linecounter=0; 
    blockcounter++; 
    }
  linecounter++; 
  if (blockcounter > 25) {
    printf (" @line %d\n",jam_lineno[current_jam] ); 
    blockcounter=0; 
    }
#endif     
    jam_lineno[current_jam]++;
     if (status == 0) { 
      readline(currentline); 
    } 
    if (currentline[0] != '%') {
      process = FALSE; 
    } else { 
      process = TRUE; 
    } 
    status = jam_parse(currentline); 
    i=0; 
    headline = currentline; 
    while (((currentline[i] != ' ') &&(currentline[i] != '\0'))  && (i < MAXLINE))  {
      i++; 
      headline++; 
    } 
    headline++; 
    
    
    switch (status) { 
      
    case LINEFEED:
      pprint(myline);
      strcpy(myline,"!x!"); 
      pprint(myline); 
      strcpy(myline,"");
      break; 

    case PAGEFEED:   
      pprint(myline); 
      strcpy(myline,"!X!"); 

      pprint(myline); 
       strcpy(myline,"");
      break; 
      
      /*..................................................................*/ 
    case STARTIFDEF: 
      if_tstack++;   
      for (i=0; i < MAXLINE; i++) token[i]='\0'; 
      strcpy(token," "); 
      strcpy (tokenline,currentline);
      tok = strtok(tokenline," "); 
      tok = strtok(NULL," \n\t"); 
      if (tok != NULL) strcpy (token, tok); 
      strcpy( if_token[if_tstack], token); 
      if (jam_debug) Message (MSG_OK,"start ifdef with %s [%d]\n", if_token[if_tstack],if_tstack);
      def_flag = FALSE; 
      for (i=0; i<= if_dstack; i++) { 
	if (jam_debug) Message (MSG_OK, " %d: testing %s with %s\n",i, if_token[if_tstack], if_defined[i]); 
	if (strcmp(if_token[if_tstack], if_defined[i]) == 0) { 
	  if (strcmp(if_token[if_tstack], "VMS") == 0) { 
	    vms_status=TRUE; 
	  } 
	  def_flag = TRUE; 
	} 
      }
      if (def_flag) 
	define_process[if_tstack] = TRUE; 
      else
	define_process[if_tstack] = FALSE;
      if (jam_debug) { 
	Message (MSG_OK,"[%4.0d][%2.0d:%s] %10s in %s\n", line_in_input[current_jam],if_tstack, yesno[define_process[if_tstack]], if_token[if_tstack],jam_file[current_jam]);
      } 
      def_flag=TRUE; 
      for (i=0; i<=if_tstack; i++){ 
	def_flag = def_flag*define_process[i];
      } 
      break; 
      
      /*..................................................................*/ 
    case ELSEIFDEF: 
      if (define_process[if_tstack] == TRUE) { 
	define_process[if_tstack] = FALSE; 
      } else { 
	define_process[if_tstack] = TRUE; 
      } 
      if (jam_debug) { Message (MSG_POST,"else ifdef with %s\n", if_token[if_tstack]); 
		       Message (MSG_POST,"[%4.0d][%2.0d:%s] %10s in %s\n", line_in_input[current_jam],if_tstack, yesno[define_process[if_tstack]], if_token[if_tstack],jam_file[current_jam]);} 
      def_flag=TRUE; 
      for (i=0; i<=if_tstack; i++){ 
	def_flag = def_flag*define_process[i]; 
      } 
      break; 
      
      /*..................................................................*/ 
    case ENDIFDEF:
      if_tstack --; 
      if (jam_debug) { Message (MSG_OK,"end ifdef with %s\n", if_token[if_tstack+1]); 
		       Message (MSG_OK,"[%4.0d][%2.0d:%s] %10s in %s; remaining %s %10s\n", line_in_input[current_jam],if_tstack+1,"E", if_token[if_tstack+1], jam_file[current_jam], yesno[define_process[if_tstack]], if_token[if_tstack]);
		     } 
      def_flag=TRUE; 
      for (i=0; i<=if_tstack; i++){ 
	def_flag = def_flag*define_process[i]; 
      } 
      break; 
      
      /*..................................................................*/ 
    case COMMENT: 
      break; 
      
      /*..................................................................*/ 
    case CHAPTER:
      if (jam_debug)  Message (MSG_POST,"headline with %s\n", headline);
      if (def_flag) makeachapter(headline); 
      break; 
      
      /*..................................................................*/ 
    case SECTION:
      if (jam_debug)  Message (MSG_POST,"zection with %s\n", headline);
      if (def_flag) makeasection(headline); 
      break; 
      
      /*..................................................................*/ 
    case SUBSECTION:
      if (jam_debug)  Message (MSG_POST,"zubsection with %s\n", headline);
      if (def_flag) makeasubsection(headline); 
      break; 
      
      /*..................................................................*/ 
    case INCLUDE:
      if (def_flag) { 
    for (i=0; i < MAXLINE; i++) token[i]='\0'; 
	strcpy(token," ");
	sscanf(currentline, "%s %s", token,token);
	current_jam++; 
	strcpy( jam_file[current_jam], token);
	
	/* clean buffer */ 
	
	switch(modus){ 
	case LATEX: 
	  strcpy(myline,"\\mbox{}"); 
	  break; 
	case HTML: 
	  strcpy(myline,"<p>"); 
	  break; 
	case RTF: 
	  strcpy(myline,"\\par "); 
	  break; 
	default: 
	  break; 
	} 
	pprint(myline); 
	strcpy(myline,"!!!"); 
	pprint(myline); 
	strcpy(myline,"");
	
	
	/* inclusion means to open a new file and read from there till end */ 
	/* if we are international replace STE file by INT file */ 
	
	if ((strstr(jam_file[current_jam],".STE") != NULL) && (sitespecific != 1) ) {
	  /* replace by netural file, INT */
	  i=0; 
	  while ((jam_file[current_jam][i] != '.' ) && ( i < (int) strlen(jam_file[current_jam]) ) )
	    i++; i++; 
	  jam_file[current_jam][i] = 'I'; i++; 
	  jam_file[current_jam][i] = 'N'; i++; 
	  jam_file[current_jam][i] = 'T'; i++; 
	}
	
	/* tell the user what you did */ 
	if (jam_debug)  Message (MSG_POST,"start include with %s\n", jam_file[current_jam]);	
	Message (MSG_POST,"inclusion of %s\n", jam_file[current_jam]);
	jam_fp[current_jam] = fopen(jam_file[current_jam], "r"); 
	jam_lineno[current_jam] =0; 
	if (jam_fp[current_jam] == NULL) { 
	  Message (MSG_ERROR,"FATAL: Cannot open input JAM file %s\n",jam_file[current_jam] ); 
	  DEALEXIT 
	    exit (-1); 
	}                    
	
	if (chapter_number > 0) { /* tell them who we are. We have no file 
                  	          open if chapter is 0. */
  	switch (modus) {
  		case RTF: 
  			sprintf (myline, "{\\v JAM file: %s}",jam_file[current_jam]);     
 			break; 
 		case HTML: 
  			sprintf (myline, "<!--- JAM file: %s -->",jam_file[current_jam]);     
  			break; 
 		case LATEX:
  			sprintf (myline, "%s JAM file: %s","%",jam_file[current_jam]);     
			pprint(myline); 
    		sprintf (myline,"!!!");  
 			break; 
		default: 
			break; 
		}
	}
	pprint(myline); 
    sprintf (myline,"");  

	status = readline(jam_line);
	if (strncmp(jam_line,"% JAM 2.",strlen("% JAM 2.")) != 0) { 
	  Message (MSG_ERROR,"FATAL: Not a recognized version or JAM file: %s\n",jam_file[current_jam] ); 
	  Message (MSG_ERROR,"expected: 'JAM 2.x' found: %s", jam_line); 
	  DEALEXIT
	    exit (-1); 
	}   
      }
      
      break; 
      
      
      /*..................................................................*/ 
    case VERBATIM: 
      if (jam_debug)  Message (MSG_POST,"toggle VERBATIM in %s\n", jam_file[current_jam]);
      if (def_flag) process_verbatim(); 
      strcpy (myline, ""); 
      break; 
      
      /*..................................................................*/ 
    case SPECIAL: 
      if (jam_debug)  Message (MSG_POST,"toggle SPECIAL in %s\n", jam_file[current_jam]);
      if (def_flag) process_special(); 
      strcpy (myline, ""); 
      break; 

      /*..................................................................*/ 
    case EMPHASIS: 
      if (jam_debug)  Message (MSG_POST,"toggle EMPHASIS in %s\n", jam_file[current_jam]);
      if (def_flag) process_emphasis(); 
      strcpy (myline, ""); 
      break; 
      
      /*..................................................................*/ 
    case ITEM: 
      if (jam_debug)  Message (MSG_POST,"toggle ITEM in %s\n", jam_file[current_jam]);
      if (def_flag) process_item();
      strcpy (myline, "");  
      break; 

      /*..................................................................*/ 
    case REFERENCE: 
      if (jam_debug)  Message (MSG_POST,"find REFERENCE in %s\n", jam_file[current_jam]);
      if (def_flag) {
      	process_reference(currentline); 
      }
      strcpy (myline, ""); 
      break; 
      
      /*..................................................................*/ 
    case ANITEM: 
      if (jam_debug)  Message (MSG_POST,"find ANITEM in %s\n", jam_file[current_jam]);
      if (def_flag) {
      	process_anitem(currentline); 
      	need_item_prefix = TRUE; 
      }
      /***** NOTE!!! Item lines must be normal processed as they might have links! ****/ 
      /* no break here, therefore. */ 

      /*..................................................................*/ 
    default:   
    
      
      /* NEW CODE 2.1: If we find a -v- we must not print verbatim 
	 in LATEX. If we come here after processing a new line this is
	 that we HAVE something to process. 
	 */
      if ((modus == LATEX) && (verbatim) ) {  
	/* printf (" %d %d %s\n", did_a_print,verbatim,currentline); */
	if (did_a_print == 0 ) {	
	  sprintf (myline, "\n\\begin{verbatim}\n"); 
	  did_a_print++; 
	  pprint (myline); 
	  sprintf (myline, ""); 
	}
      } 
      
      /* scan current line for a link */ 
      
      if (def_flag) { 
	curpointer=0;
	linkpointer=0; 
	i=0; 
	/* token is the processing buffer for links */ 
	/* i is the pointer to token */ 
	
	for (i=0; i < MAXLINE; i++) token[i]='\0'; 
	i=0; 
	strcpy(token, currentline); 
	linktype = NONE; 

	while ((token[i] != '\n') && (i < MAXLINE) && (token[i] != '\0')) {
	  
	  special = NONE; 
	  
	  /* - - - - - - - - - - - - preprocessing link - - - -  */ 
	  strcpy (myline,token); 
	  myline[i]='!'; 
	  
	  if (token[i+1] == '|') { 
	    if (token[i] == '+')
	      { 
		linktype = ANCHOR; 
		i++; 
		i++; 
		special = TRUE; 
		linkpointer=0; 
	      } 
	    if (token[i] == '*')
	      { 
		linktype = POINTER; 
		i++; 
		i++; 
		special = TRUE;
		strcpy (linkbody, "NULL"); 
		linkpointer=0;  
	      } 
	    if (token[i] == '#')
	      { 
		linktype = INDEX; 
		i++; 
		i++; 
		special = TRUE;
		linkpointer=0;  
	      } 
	    if (token[i] == '[')
	      { 
		linktype = LINK; 
		i++; 
		i++; 
		special = TRUE;
		strcpy (linkbody, "NULL"); 
		linkpointer=0;  
	      } 
	    ; /* other link types here */ 
	    
	  } 
	  
	  
	  /* - - - - - - - - - - - - postprocessing link - - - -  */ 
	  if (token[i] == '|') { 
	    if (token[i+1] == '+') { 
	      linktype = ANCHOR;  
	      ; 
	      i++; 
	      i++; 
	      /* process finished link here */
	      /* linkpointer++; */
	      link[linkpointer]='\0';
	      currentline[curpointer]='\0';
	      pprint(currentline);                   
	      /* the linkbody must be clean of all non-ascii characters */
	      ii=0;           
	      
	      if (modus != RTF)  {
		for (ib=0; ib<= (int) strlen(link); ib++) {
		  if (modus == HTML) {  
		    if (isalnum(link[ib])) {
		      link[ii]=link[ib];
		      ii++;
		    } 
		  } else { 
		    if ((isalnum(link[ib])) ||( link[ib] == ' '))  {
		      link[ii]=link[ib];
		      ii++;
		    } 
		  } 
		  
		}   
		
		link[ii]=0; 
	      } else {
		for (ib=0; ib<= (int) strlen(link); ib++) {
		  if (isprint(link[ib])) {
		    link[ii]=link[ib];
		    ii++;
		  }
		}   
		
		link[ii]=0; 
	      }
	      
	      
	      if (def_flag){  
		switch (modus) { 
		case LATEX: 
		  sprintf(myline, "\\label{%s} \\index{%s} ", link,link);
		  break; 
		case RTF: 
		  sprintf(myline, "{\\v {\\xe \\pard \\plain {\\v %s}}}", link);
		  break; 
		case HTML:
		  sprintf(myline, "<a name=%s_%d_%d_%d>",link,
			  chapter_number,section_number,subsection_number);    
		  fprintf(jam_index,"%s %s%s#%s_%d_%d_%d\n",link, JAMPATH,jam_out,link,
			  chapter_number,section_number,subsection_number);  
		  
		  break;
		default:
		  break; 
		} 
 		if (jam_ref != NULL) 
		  fprintf(jam_ref,"%s ANCHOR \no *|%s_%d_%d_%d|%s|* in %s%s\n",
			  "%",link, chapter_number,section_number,subsection_number, 
			  link, JAMPATH,jam_out);  
		pprint(myline);
		strcpy(currentline,"");
		curpointer=0; 
	      } 
	      linktype = NONE; 
	      special = TRUE; 
	    } 
	    if (token[i+1] == '*') { 
	      linktype = POINTER;  
	      ; 
	      i++; 
	      i++; 
	      /* process finished link here */
	      /* linkpointer++; */  
	      
	      currentline[curpointer]='\0';
	      link[linkpointer]='\0';
	      if (need_item_prefix) {
		strcat (item_prefix,currentline);
		need_item_prefix = 0 ;
	      }else { 
		strcpy(item_prefix,currentline); 
	      }
	      pprint(item_prefix); 
	      
	      if (def_flag) { 
		if (strcmp(linkbody,"NULL") == 0 ) { 
		  strcpy(linkbody, link) ; 
		  switch (modus) { 
		  case LATEX: 
		  case RTF:
		    strcpy(link,"");
		    break; 
		  case HTML: 
		    strcpy (link, "(*)"); 
		    break; 
		  default: 
		    break; 
		  } 
		}
		
		/* the linkbody must be clean of all non-ascii characters */
		ii=0; 
		for (ib=0; ib<= (int) strlen(linkbody); ib++) {
		  switch (modus) {
		  case LATEX:
		    if ((isalnum(linkbody[ib])) ||( linkbody[ib] == ' '))  {
		      linkbody[ii]=linkbody[ib];
		      ii++;
		    }
		    break; 
		  case RTF:
		    if (isprint(linkbody[ib])) {
		      linkbody[ii]=linkbody[ib];
		      ii++;
		    }
		    break; 
		  case HTML: 
		    if ((isalnum(linkbody[ib])) && (linkbody[ib] != ' ') )  {
		      linkbody[ii]=linkbody[ib];
		      ii++;
		    }  
		    if (linkbody[ib] == '_')   {
		      linkbody[ii]=linkbody[ib];
		      ii++;
		    }
		    break;    
		  default: 
		    break; 
		  }		  	    
		} 
		linkbody[ii]=0;
		
		/* we have to search it in the index file */ 
		switch (modus) { 
		case LATEX: 
		  sprintf(myline, "%s (see page \\pageref{%s}) ", link,linkbody);
		  break;
		case HTML:                   
		  strcpy (jam_link, linkbody); 
		  status = jam_find(jam_link); 
		  if (status == FALSE) {
		    sprintf (jam_link, "%s_%d_%d_%d", link, chapter_number ,section_number,subsection_number); 
		    status = jam_find(jam_link); 
		    if (status == FALSE) {
#ifndef JAMGUI
		      printf ("\n");           
#endif 
		      Message (MSG_POST, "Warning: Link '%s' could not be resolved in 2nd attempt",linkbody); 
#ifndef JAMGUI
		      printf ("\n");        
#endif 
		    }			 
		  } else {
		    if (status == FALSE) {
#ifndef JAMGUI
		      printf ("\n");           
#endif 
		      Message (MSG_POST, "Warning: Link '%s' could not be resolved",linkbody); 
#ifndef JAMGUI
		      printf ("\n");           
#endif 
		    }    
		  }
		  if (status == FALSE ) {
		    sprintf(myline, "<em> %s </em> ",link);
		  } else {
		    sprintf(myline, "<a href=%s> %s </a> ", jam_link,link);
		  }
		  break;
		case RTF:
		  sprintf(myline, "%s (also described under keyword {\\i %s} ) ", link,linkbody);
		  break; 
		default:
		  break; 
		}          
		if (jam_ref != NULL)
 		fprintf(jam_ref,"%s POINTER \no *|%s|%s|* in %s%s \n",
			"%",linkbody, 
			link, JAMPATH,jam_out);  
		pprint(myline); 
		strcpy(currentline,"");
		curpointer=0; 
	      } 
	      linktype = NONE; 
	      special = TRUE; 
	    } 
	    if (token[i+1] == '#') { 
	      linktype = INDEX;  
	      ; 
	      i++; 
	      i++; 
	      /* process finished link here */
	      /*linkpointer++; */
	      link[linkpointer]='\0';
	      currentline[curpointer]='\0';
	      if (need_item_prefix) {
		strcat (item_prefix,currentline);
		need_item_prefix = 0 ; 
	      }else { 
		strcpy(item_prefix,currentline);
	      } 
	      pprint(item_prefix);  
	      if (def_flag) { 
		
		/* the linkbody must be clean of all non-ascii characters */
		ii=0; 
		for (ib=0; ib<= (int) strlen(link); ib++) {
		  switch (modus) {
		  case LATEX: 
		    if ((isalnum(link[ib])) ||( link[ib] == ' '))  {
		      tmplink[ii]=link[ib];
		      ii++;
		    }
		    break;     
		  case RTF: 
		    if (isprint(link[ib])) {
		      tmplink[ii]=link[ib];
		      ii++;
		    }  
		    break; 
		  case HTML: 
		    if ((isalnum(link[ib])) && (link[ib] != ' ') )  {
		      tmplink[ii]=link[ib];
		      ii++;
		    } 
		    if (link[ib] == '_')   {
		      tmplink[ii]=link[ib];
		      ii++;
		    }
		    
		    break;    
		  default:	
		    break;
		  }
		}		        
		tmplink[ii]=0;
		
		switch (modus) { 
		case LATEX: 
		  sprintf(myline, "\\index{%s} ", tmplink);
		  break;
		case RTF: 
		  sprintf(myline, "{\\v {\\xe \\pard \\plain {\\v %s}}}", tmplink);
		  break; 
		case HTML: 
		  sprintf(myline, "<a name=%s_%d_%d_%d> ",tmplink,
			  chapter_number,section_number,subsection_number);
		  fprintf(jam_index,"%s_%d_%d_%d %s%s#%s_%d_%d_%d\n",tmplink,
			  chapter_number,section_number,subsection_number, JAMPATH,jam_out,tmplink,
			  chapter_number,section_number,subsection_number);
		  break;
		default: 
		  break; 
		}   
		if (jam_ref != NULL)
		  fprintf(jam_ref,"%s INDEX \no *|%s_%d_%d_%d|%s|* in %s%s\n",
			  "%",tmplink, chapter_number,section_number,subsection_number, 
			  link, JAMPATH,jam_out);  
		pprint(myline);
		strcpy(currentline,"");
		curpointer=0; 
	      } 
	      linktype = NONE; 
	      special = TRUE; 
	    } 
	    if (token[i+1] == ']') { 
	      linktype = ANCHOR;  
	      ; 
	      i++; 
	      i++; 
	      /* process finished link here */
	      /* linkpointer++; */
	      currentline[curpointer]='\0';
	      if (need_item_prefix) {
		strcat (item_prefix,currentline);
		need_item_prefix = 0 ;
	      }else { 
		strcpy(item_prefix,currentline); 
	      }
	      pprint(item_prefix); 
	      link[linkpointer]='\0';
	      if (def_flag) { 
		if (strcmp(linkbody,"NULL") == 0 ) { 
		  strcpy(linkbody, link) ; 
		  switch (modus) { 
		  case LATEX: 
		  case RTF:
		    strcpy(link,"");
		    break; 
		  case HTML: 
		    strcpy (link, "(*)"); 
		    break; 
		  default: 
		    break;  
		  }
		}
		if (def_flag) { 
		  
		  /* the linkbody must be clean of all non-ascii characters */
		  ii=0; 
		  if (modus == LATEX) {
		    for (ib=0; ib<= (int) strlen(linkbody); ib++) {
		    if ((isalnum(linkbody[ib])) ||( linkbody[ib] == ' '))  {
			linkbody[ii]=linkbody[ib];
			ii++;
		      }
		    }  
		    linkbody[ii]=0; 
		  }else {
		    for (ib=0; ib<= (int) strlen(linkbody); ib++) {
		      if (isprint(linkbody[ib])) {
			linkbody[ii]=linkbody[ib];
			ii++;
		      }
		    }  
		    linkbody[ii]=0; 
		  }
		  
		  switch (modus) { 
		  case LATEX: 
		    if (special_on) 
		      sprintf(myline, "}\\index{%s} \\fbox{{\\em %s}}{\\em ", linkbody,link);
		    else
		      sprintf(myline, "\\index{%s} \\fbox{{\\em %s}} ", linkbody,link);
		    break; 
		  case RTF: 
		    if (special || verbatim) { 
		      sprintf(myline, "{\\v {\\xe \\pard \\pain {\\v %s}}} {\\fs24 \\b \\i %s }\\fs20 \\ql \n", link,link);
		    } else { 
		      sprintf(myline, "{\\v {\\xe \\pard \\pain {\\v %s}}} {\\fs24 \\b \\i %s} \\fs20 \\qj \n", link,link);
		    } 
		    break; 
		  case HTML:                                   
		    switch (behaviour) { 
		    case JAMDUMMY: 
		      sprintf(myline,"<strong> %s </strong> ",link);
		      break; 
		    case JAMRECEPTOR: 
		      sprintf(myline,"<a href=http://%s/%s> %s </a>",RECEPTOR,linkbody, link);
		      break; 
		    case JAMREFLECTOR: 
		      sprintf(myline,"<a href=http://%s/%s> %s </a>",reflec_prefix,linkbody, link);
		      break; 
		    default:
		      break;
		    } 
		    fprintf(jam_index,"%s_%d_%d_%d %s%s#%s_%d_%d_%d\n",link,
			    chapter_number,section_number,subsection_number, JAMPATH,jam_out,link,
			    chapter_number,section_number,subsection_number, jam_lineno[current_jam]);  
		    
		    break; 	    
		  default: 
		    break; 
		  }
		  if (jam_ref != NULL) 
		    fprintf(jam_ref,"%s REFLECTOR \no *|%s_%d_%d_%d|%s|* in %s%s\n",
			    "%",link, chapter_number,section_number,subsection_number, 
			    link, JAMPATH,jam_out);  
		  pprint (myline);
		  strcpy(currentline,"");
		  curpointer=0; 
		} 
		linktype = NONE; 
		special = TRUE; 
	      } 
	      /* other stop linktypes here */ 
	    }
	    
	  }
	  /* - - - - - - - - - processing link / linkbody  - - - -  */ 
	  
	  if (!special && (linktype != NONE) )   {  
	    if (token[i] == '|') { 
	      link[linkpointer]='\0'; 
	      strcpy(linkbody, link); 
	      linkpointer=0; 
	      i++; 
	      /* we have the link saved in linkbody, and wait for the link now*/ 
	    } 
	  }  
	  
	  
	  /* - - - - - -  make extra characters look OK in certain formats */ 
	  if  (!special)  { 
	    if ((linktype == NONE))   {  
	      if (strcmp(linkbody,"NULL") != 0 ) 
		switch (modus){
		  
		case LATEX:  
		  if (!verbatim)  { 
		    clean_latex (i,token,currentline,&curpointer,linkbody);
		  }
		  break; 
		case HTML: 
		  if (token[i] == '>') { 
		    currentline[curpointer] = '&';
		    currentline[curpointer+1] = 'g';
		    currentline[curpointer+2] = 't';
		    token[i] = ';';
		    curpointer= curpointer+3;
		  } 
		  if (token[i] == '<') { 
		    currentline[curpointer] = '&';
		    currentline[curpointer+1] = 'l';
		    currentline[curpointer+2] = 't';
		    token[i] = ';';
		    curpointer= curpointer+3;
		  } 
		  break; 
		case RTF:  
		  if (token[i] <  ' ') { 
		    token[i] = ' ';
		  } 
		  if (token[i] == '\\') { 
		    currentline[curpointer] = '\\';
		    curpointer++; 
		  } 
		  if (token[i] == '{') { 
		    currentline[curpointer] = '\\';
		    curpointer++; 
		  } 
		  if (token[i] == '}') { 
		    currentline[curpointer] = '\\';
		    curpointer++; 
		  } 
		  
		  break; 
		default:
		  break; 
		  
		  
		  
		} 
	      currentline[curpointer]=token[i]; 
	      curpointer++; 
	    } else { 
	      switch (modus) { 
	      case LATEX: 
		clean_latex (i,token,link,&linkpointer,linkbody); 
		break; 
	      case RTF: 
		if (token[i] <  ' ') { 
		  token[i] = ' ';
		} 
		if (token[i] == '\\') { 
		  link[linkpointer] = '\\';
		  linkpointer++; 
		} 
		if (token[i] == '{') { 
		  link[linkpointer] = '\\';
		  curpointer++; 
		} 
		if (token[i] == '}') { 
		  link[linkpointer] = '\\';
		  linkpointer++; 
		} 
		
	      case HTML:
		break; 
	      default:
		break; 
	      } 
	      link[linkpointer]=token[i]; 
	      linkpointer++;
	    } 
	    
	    i++; 
	    
	  } 
	  
	} 
	
      } 
      
      
      if (def_flag) { 
	currentline[curpointer]=' '; 
	currentline[curpointer+1]='\0';  
	
	switch  (modus) { 
	case LATEX:
	case RTF:
	case HTML: 
	  if (need_item_prefix) {
	    sprintf (myline,"%s%s\n\0",item_prefix,currentline);
	    need_item_prefix = 0 ; 
	  } else {
	    sprintf(myline,"%s\n\0",currentline); 
	  }
	  break; 
	default: 
	  break; 
	} 
	pprint (myline);
	strcpy (myline,""); 
      } 
      break; 
      
    }   
}      
  
#ifdef JAMGUI
      DEALEXIT 
#else    
    return(0);
#endif      


}

#ifdef JAMGUI
/*======================================= V I B R A N T =====================*/


Int2 Main (void)

{
  WindoW  w;

#ifdef WIN_MAC
  SetupMenus (NULL);
#endif
  w = FixedWindow (-50, -33, -10, -10, CODE_CRN, NULL);
#ifndef WIN_MAC
  SetupMenus (w);
#endif

  SetupObjects (w);

  Show (w);
  ProcessEvents ();
  return 0;
}

#endif
/*======================================= V I B R A N T =====================*/
 int dummy (void) {
  return 1;
  }
  

 

