home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gsview13 / src / doc2html.c next >
C/C++ Source or Header  |  1995-12-09  |  12KB  |  435 lines

  1. /*
  2.  * doc2html.c  -- program to convert Gnuplot .DOC format to 
  3.  *        World Wide Web (WWW) HyperText Markup Language (HTML) format
  4.  *
  5.  * Created by Russell Lang from doc2ipf by Roger Fearick from 
  6.  * doc2rtf by M Castro from doc2gih by Thomas Williams.
  7.  * 1994-11-03
  8.  *
  9.  * usage:  doc2html gnuplot.doc gnuplot.htm
  10.  *
  11.  */
  12.  
  13. /* note that tables must begin in at least the second column to */
  14. /* be formatted correctly and tabs are forbidden */
  15.  
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <malloc.h>
  21.  
  22. #define MAX_LINE_LEN    1024
  23. #define TRUE 1
  24. #define FALSE 0
  25.  
  26. struct LIST
  27. {
  28.     int level;
  29.     int line;
  30.     char *string;
  31.     struct LIST *next;
  32.     };
  33.  
  34. struct LIST *list = NULL;
  35. struct LIST *head = NULL;
  36.  
  37. struct LIST *keylist = NULL;
  38. struct LIST *keyhead = NULL;
  39.  
  40. int debug = FALSE;
  41. char title[256];
  42.  
  43. void parse();
  44. void refs();
  45. void convert();
  46. void process_line();
  47. int lookup();
  48.  
  49. main(argc,argv)
  50. int argc;
  51. char **argv;
  52. {
  53. FILE * infile;
  54. FILE * outfile;
  55.  
  56.     if (argv[argc-1][0]=='-' && argv[argc-1][1]=='d') {
  57.         debug = TRUE;
  58.     argc--;
  59.     }
  60.  
  61.     if ( (argc > 3) || (argc == 1) ) {
  62.         fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  63.         return(1);
  64.     }
  65.     if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  66.         fprintf(stderr,"%s: Can't open %s for reading\n",
  67.             argv[0], argv[1]);
  68.         return(1);
  69.     }
  70.     if (argc == 3) {
  71.       if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  72.         fprintf(stderr,"%s: Can't open %s for writing\n",
  73.             argv[0], argv[2]);
  74.       }
  75.       strcpy(title, argv[2]);
  76.     }
  77.     else {
  78.         outfile = stdout;
  79.         strcpy(title, argv[1]);
  80.     }
  81.     strtok(title, ".");     /* remove type */
  82.     parse(infile);
  83.     convert(infile,outfile);
  84.     return(0);
  85. }
  86.  
  87. /* scan the file and build a list of line numbers where particular levels are */
  88. void parse(a)
  89. FILE *a;
  90. {
  91.     static char line[MAX_LINE_LEN];
  92.     char *c;
  93.     int lineno=0;
  94.     int lastline=0;
  95.  
  96.     while (fgets(line,MAX_LINE_LEN,a)) 
  97.     {
  98.       lineno++;
  99.       if (isdigit(line[0]))
  100.       {
  101.         if (list == NULL)    
  102.             head = (list = (struct LIST *) malloc(sizeof(struct LIST)));
  103.         else
  104.             list = (list->next = (struct LIST *) malloc(sizeof(struct LIST)));
  105.         list->line = lastline = lineno;
  106.         list->level = line[0] - '0';
  107.         list->string = (char *) malloc (strlen(line)+1);
  108.         c = strtok(&(line[1]),"\n");
  109.         strcpy(list->string, c);
  110.         list->next = NULL;
  111.       }
  112.       if (line[0]=='?')
  113.       {
  114.         if (keylist == NULL)    
  115.             keyhead = (keylist = (struct LIST *) malloc(sizeof(struct LIST)));
  116.         else
  117.             keylist = (keylist->next = (struct LIST *) malloc(sizeof(struct LIST)));
  118.         keylist->line = lastline;
  119.         keylist->level = line[0] - '0';
  120.         c = strtok(&(line[1]),"\n");
  121.         if( c == NULL || *c == '\0' ) c = list->string ;
  122.         keylist->string = (char *) malloc (strlen(c)+1);
  123.         strcpy(keylist->string, c);
  124.         keylist->next = NULL;
  125.       }
  126.     }
  127.     rewind(a);
  128.     }
  129.  
  130. /* look up an in text reference */
  131. int
  132. lookup(s)
  133. char *s;
  134. {
  135.     char *c;
  136.     char tokstr[MAX_LINE_LEN];
  137.     char *match; 
  138.     int l;
  139.  
  140.     strcpy(tokstr, s);
  141.  
  142.     /* first try the ? keyword entries */
  143.     keylist = keyhead;
  144.     while (keylist != NULL)
  145.     {
  146.         c = keylist->string;
  147.         while (isspace(*c)) c++;
  148.         if (!strcmp(s, c)) return(keylist->line);
  149.         keylist = keylist->next;
  150.         }
  151.  
  152.     /* then try titles */
  153.     match = strtok(tokstr, " \n\t");
  154.     l = 0; /* level */
  155.     
  156.     list = head;
  157.     while (list != NULL)
  158.     {
  159.         c = list->string;
  160.         while (isspace(*c)) c++;
  161.         if (!strcmp(match, c)) 
  162.         {
  163.             l = list->level;
  164.             match = strtok(NULL, "\n\t ");
  165.             if (match == NULL)
  166.             {
  167.                 return(list->line);
  168.                 }
  169.             }
  170.         if (l > list->level)
  171.             break;
  172.         list = list->next;
  173.         }
  174.     return(-1);
  175.     }
  176.  
  177. /* search through the list to find any references */
  178. void
  179. refs(l, f)
  180. int l;
  181. FILE *f;
  182. {
  183.     int curlevel;
  184.     char str[MAX_LINE_LEN];
  185.     char *c;
  186.     int inlist = FALSE;
  187.  
  188.     /* find current line */
  189.     list = head;
  190.     while (list->line != l)
  191.         list = list->next;
  192.     curlevel = list->level;
  193.     list = list->next;        /* look at next element before going on */
  194.     if (list != NULL)
  195.     {
  196.     inlist = TRUE;
  197.     fprintf(f,"<P>\n");
  198.     }
  199.  
  200.     while (list != NULL)
  201.     {
  202.         /* we are onto the next topic so stop */
  203.         if (list->level == curlevel)
  204.             break;
  205.         /* these are the next topics down the list */
  206.         if (list->level == curlevel+1)
  207.         {
  208.             c = list->string;
  209.         while (isspace(*c)) c++;
  210.         fprintf(f,"<A HREF=\042#%d\042>%s</A><BR>\n", list->line, c);
  211.             }
  212.         list = list->next;
  213.         }
  214.     if (inlist)
  215.         fprintf(f,"<P>\n");
  216.     }
  217.  
  218. void
  219. convert(a,b)
  220.     FILE *a,*b;
  221. {
  222.     static char line[MAX_LINE_LEN];
  223.     
  224.     /* generate html header */
  225.     fprintf(b,"<HTML>\n");
  226.     fprintf(b,"<HEAD>\n");
  227.     fprintf(b,"<TITLE>%s</TITLE>\n", title);
  228.     fprintf(b,"</HEAD>\n");
  229.     fprintf(b,"<BODY>\n");
  230.     fprintf(b,"<H1>%s</H1><P>\n", title);
  231.  
  232.     /* process each line of the file */
  233.         while (fgets(line,MAX_LINE_LEN,a)) {
  234.        process_line(line, b);
  235.        }
  236.  
  237.     /* close final page and generate trailer */
  238.     fprintf(b,"\n<P><HR>Created automatically by doc2html\n");
  239.     fprintf(b,"</BODY>\n");
  240.     fprintf(b,"</HTML>\n");
  241. }
  242.  
  243. void
  244. process_line(line, b)
  245.     char *line;
  246.     FILE *b;
  247. {
  248.     static int line_count = 0;
  249.     static char line2[MAX_LINE_LEN];
  250.     static int last_line;
  251.     char hyplink1[64] ;
  252.     char *pt, *tablerow ;
  253.     int i;
  254.     int j;
  255.     static int startpage = 1;
  256.     char str[MAX_LINE_LEN];
  257.     char topic[MAX_LINE_LEN];
  258.     int k, l;
  259.     static int tabl=0;
  260.     static int para=0;
  261.     static int inquote = FALSE;
  262.     static int inref = FALSE;
  263.  
  264.     line_count++;
  265.  
  266.     i = 0;
  267.     j = 0;
  268.     while (line[i] != '\0')
  269.     {
  270.         switch(line[i])
  271.         {
  272.             case '<':
  273.                 strcpy( &line2[j], "<" ) ;
  274.                 j += strlen( "<." ) - 1 ;
  275.                 break ;
  276.  
  277.             case '>':
  278.                 strcpy( &line2[j], ">" ) ;
  279.                 j += strlen( ">." ) - 1 ;
  280.                 break ;
  281.  
  282.             case '&':
  283.                 strcpy( &line2[j], "&" ) ;
  284.                 j += strlen( "&" ) - 1 ;
  285.                 break ;
  286.                                 
  287.             case '\r':
  288.             case '\n':
  289.                 break;
  290.             case '`':    /* backquotes mean boldface or link */
  291.                 if ((!inref) && (!inquote))
  292.                 {
  293.                     k=i+1;    /* index into current string */
  294.                     l=0;    /* index into topic string */
  295.                     while ((line[k] != '`') && (line[k] != '\0'))
  296.                     {
  297.                         topic[l] = line[k];
  298.                         k++;
  299.                         l++;
  300.                         }
  301.                     topic[l] = '\0';
  302.                     k = lookup(topic);
  303.             if ((k > 0) && (k != last_line))
  304.                     {
  305.                         sprintf( hyplink1, "<A HREF=\042#%d\042>", k ) ;
  306.                         strcpy( line2+j, hyplink1 ) ;
  307.                         j += strlen( hyplink1 )-1 ;
  308.                         
  309.                         inref = k;
  310.                         }
  311.                     else
  312.                     {
  313.                         if (debug && k != last_line)
  314.                             fprintf(stderr,"Can't make link for \042%s\042 on line %d\n",topic,line_count);
  315.                         line2[j++] = '<';
  316.                         line2[j++] = 'B';
  317.                         line2[j] = '>';
  318.                         inquote = TRUE;
  319.                         }
  320.                     }
  321.                 else
  322.                 {
  323.                     if (inquote && inref)
  324.                         fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
  325.                     if (inquote)
  326.                     {
  327.                         line2[j++] = '<';
  328.                         line2[j++] = '/';
  329.                         line2[j++] = 'B';
  330.                         line2[j] = '>';
  331.                         inquote = FALSE;
  332.                         }
  333.                     if (inref)
  334.                     {
  335.                         /* must be inref */
  336.                         line2[j++] = '<';
  337.                         line2[j++] = '/';
  338.                         line2[j++] = 'A';
  339.                         line2[j] = '>';
  340.                         inref = 0;
  341.                         }
  342.                 }
  343.                 break;
  344.             default:
  345.                 line2[j] = line[i];
  346.             }
  347.         i++;
  348.         j++;
  349.         line2[j] = '\0';
  350.         }
  351.  
  352.     i = 1;
  353.  
  354.     switch(line[0]) {        /* control character */
  355.        case '?': {            /* interactive help entry */
  356. #ifdef FIXLATER
  357.                if( intable ) intablebut = TRUE ;
  358.                fprintf(b,"\n:i1. %s", &(line[1])); /* index entry */
  359. #endif
  360.                break;
  361.        }
  362.        case '@': {            /* start/end table */
  363.           break;            /* ignore */
  364.        }
  365.        case '#': {            /* latex table entry */
  366.           break;            /* ignore */
  367.        }
  368.        case '%': {            /* troff table entry */
  369.           break;            /* ignore */
  370.        }
  371.        case '\n':            /* empty text line */
  372.         if (tabl)
  373.             fprintf(b,"</PRE>\n"); /* rjl */
  374.             para = 0;
  375.             tabl = 0;
  376.             fprintf(b,"<P>");
  377.             break;
  378.        case ' ': {            /* normal text line */
  379.           if ((line2[1] == '\0') || (line2[1] == '\n'))
  380.           {
  381.                 fprintf(b,"<P>"); 
  382.                 para = 0;
  383.         tabl = 0;
  384.                 }
  385.           if (line2[1] == ' ') 
  386.           {
  387.                 if (!tabl)
  388.                 {
  389.             fprintf(b,"<PRE>\n");
  390.                     }
  391.                 fprintf(b,"%s\n",&line2[1]); 
  392.                 tabl = 1;
  393.                 para = 0;
  394.                 }
  395.           else
  396.           {
  397.         if (tabl) {
  398.             fprintf(b,"</PRE>\n"); /* rjl */
  399.                     fprintf(b,"<P>");     /* rjl */
  400.         }
  401.                 tabl = 0;
  402.                 if (!para)
  403.                     para = 1;        /* not in para so start one */
  404.                   fprintf(b,"%s \n",&line2[1]); 
  405.                 }
  406.           break;
  407.        }
  408.        default: {
  409.           if (isdigit(line[0])) { /* start of section */
  410.         if (tabl)
  411.               fprintf(b,"</PRE>\n"); /* rjl */
  412.             if (!startpage)
  413.             {
  414.                 refs(last_line,b);
  415.                 }
  416.             para = 0;                    /* not in a paragraph */
  417.             tabl = 0;
  418.             last_line = line_count;
  419.             startpage = 0;
  420.         if (debug)
  421.         fprintf( stderr, "%d: %s\n", line_count, &line2[1] ) ;
  422.             k=lookup(&line2[1]) ;
  423.         /* output unique ID and section title */
  424.             fprintf(b,"<HR><A NAME=\042%d\042>\n<H%c>", line_count, line[0]=='1'?line[0]:line[0]-1);
  425.             fprintf(b,&(line2[1])); /* title */
  426.             fprintf(b,"</H%c>\n<P>", line[0]=='1'?line[0]:line[0]-1) ;
  427.           } else
  428.             fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
  429.                 line[0], line_count);
  430.           break;
  431.        }
  432.     }
  433. }
  434.  
  435.