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

  1. /*
  2.  * doc2ipf.c  -- program to convert Gnuplot .DOC format to OS/2
  3.  * ipfc  (.inf/.hlp) format.
  4.  *
  5.  * Modified by Roger Fearick from doc2rtf by M Castro 
  6.  * Further modified for PM GSview by Russell Lang  1993-10-27
  7.  *   removed links to self
  8.  *   added names to panels (for HM_DISPLAY_HELP)
  9.  *   added index
  10.  *   examples now in monospaced type
  11.  *   obtain title from filename
  12.  *   third command line option for help table header file
  13.  *
  14.  * usage:  doc2ipf gnuplot.doc gnuplot.itl [idxfile]
  15.  *
  16.  */
  17.  
  18. /* note that tables must begin in at least the second column to */
  19. /* be formatted correctly and tabs are forbidden */
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <malloc.h>
  26.  
  27. #define MAX_LINE_LEN    1024
  28. #define TRUE 1
  29. #define FALSE 0
  30.  
  31. struct LIST
  32. {
  33.     int level;
  34.     int line;
  35.     char *string;
  36.     struct LIST *next;
  37.     };
  38.  
  39. struct LIST *list = NULL;
  40. struct LIST *head = NULL;
  41.  
  42. struct LIST *keylist = NULL;
  43. struct LIST *keyhead = NULL;
  44.  
  45. struct TABENTRY { /* may have 3 column tables */
  46.         struct TABENTRY *next ;
  47.         char col[3][256] ;
  48.         } ;
  49.  
  50. struct TABENTRY table = {NULL} ;
  51. struct TABENTRY *tableins = &table ;
  52. int tablecols = 0 ;
  53. int tablewidth[3] = {0,0,0} ;        
  54. int tablelines = 0 ;
  55.  
  56. int debug = FALSE;
  57. char title[256];
  58.  
  59. void parse();
  60. void refs();
  61. void convert();
  62. void process_line();
  63. int lookup();
  64.  
  65. main(argc,argv)
  66. int argc;
  67. char **argv;
  68. {
  69. FILE * infile;
  70. FILE * outfile;
  71. FILE * idxfile = (FILE *)NULL;
  72.  
  73.     if (argv[argc-1][0]=='-' && argv[argc-1][1]=='d') {
  74.         debug = TRUE;
  75.     argc--;
  76.     }
  77.  
  78.     if ( (argc > 4) || (argc == 1) ) {
  79.         fprintf(stderr,"Usage: %s infile outfile [idxfile]\n", argv[0]);
  80.         return(1);
  81.     }
  82.     if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  83.         fprintf(stderr,"%s: Can't open %s for reading\n",
  84.             argv[0], argv[1]);
  85.         return(1);
  86.     }
  87.     if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  88.         fprintf(stderr,"%s: Can't open %s for writing\n",
  89.             argv[0], argv[2]);
  90.     }
  91.     if (argc==4) {
  92.       if ( (idxfile = fopen(argv[3],"w")) == (FILE *)NULL) {
  93.         fprintf(stderr,"%s: Can't open %s for writing\n",
  94.             argv[0], argv[3]);
  95.       }
  96.     }
  97.     strcpy(title, argv[2]);
  98.     strtok(title, ".");     /* remove type */
  99.     parse(infile, idxfile);
  100.     convert(infile,outfile);
  101.     return(0);
  102. }
  103.  
  104. /* scan the file and build a list of line numbers where particular levels are */
  105. void parse(a, b)
  106. FILE *a, *b;
  107. {
  108.     static char line[MAX_LINE_LEN];
  109.     char *c;
  110.     int lineno=0;
  111.     int lastline=0;
  112.     static char *idxhead ="\
  113. /* generated by doc2ipf.c */\n\
  114. typedef struct tagHELPIDX {\n\
  115.   int id;\n\
  116.   char *name;\n\
  117. } HELPIDX;\n\
  118. HELPIDX helpidx[] = {\n";
  119.  
  120.     if (b) {
  121.     fprintf(b,idxhead);
  122.     }
  123.     while (fgets(line,MAX_LINE_LEN,a)) 
  124.     {
  125.     lineno++;
  126.     if (isdigit(line[0]))
  127.     {
  128.         if (list == NULL)    
  129.             head = (list = (struct LIST *) malloc(sizeof(struct LIST)));
  130.         else
  131.             list = (list->next = (struct LIST *) malloc(sizeof(struct LIST)));
  132.         list->line = lastline = lineno;
  133.         list->level = line[0] - '0';
  134.         list->string = (char *) malloc (strlen(line)+1);
  135.         c = strtok(&(line[1]),"\n");
  136.         strcpy(list->string, c);
  137.         list->next = NULL;
  138.     if (b)
  139.         fprintf(b, " {%d, \042%s\042},\n", lineno, c);
  140.     }
  141.     if (line[0]=='?')
  142.     {
  143.         if (keylist == NULL)    
  144.             keyhead = (keylist = (struct LIST *) malloc(sizeof(struct LIST)));
  145.         else
  146.             keylist = (keylist->next = (struct LIST *) malloc(sizeof(struct LIST)));
  147.         keylist->line = lastline;
  148.         keylist->level = line[0] - '0';
  149.         c = strtok(&(line[1]),"\n");
  150.         if( c == NULL || *c == '\0' ) c = list->string ;
  151.         keylist->string = (char *) malloc (strlen(c)+1);
  152.         strcpy(keylist->string, c);
  153.         keylist->next = NULL;
  154.     }
  155.     }
  156.     if (b)
  157.         fprintf(b, " {0,\042\042}\n};\n");
  158.     rewind(a);
  159.     }
  160.  
  161. /* look up an in text reference */
  162. int
  163. lookup(s)
  164. char *s;
  165. {
  166.     char *c;
  167.     char tokstr[MAX_LINE_LEN];
  168.     char *match; 
  169.     int l;
  170.  
  171.     strcpy(tokstr, s);
  172.  
  173.     /* first try the ? keyword entries */
  174.     keylist = keyhead;
  175.     while (keylist != NULL)
  176.     {
  177.         c = keylist->string;
  178.         while (isspace(*c)) c++;
  179.         if (!strcmp(s, c)) return(keylist->line);
  180.         keylist = keylist->next;
  181.         }
  182.  
  183.     /* then try titles */
  184.     match = strtok(tokstr, " \n\t");
  185.     l = 0; /* level */
  186.     
  187.     list = head;
  188.     while (list != NULL)
  189.     {
  190.         c = list->string;
  191.         while (isspace(*c)) c++;
  192.         if (!strcmp(match, c)) 
  193.         {
  194.             l = list->level;
  195.             match = strtok(NULL, "\n\t ");
  196.             if (match == NULL)
  197.             {
  198.                 return(list->line);
  199.                 }
  200.             }
  201.         if (l > list->level)
  202.             break;
  203.         list = list->next;
  204.         }
  205.     return(-1);
  206.     }
  207.  
  208. /* search through the list to find any references */
  209. void
  210. refs(l, f)
  211. int l;
  212. FILE *f;
  213. {
  214.     int curlevel;
  215.     char str[MAX_LINE_LEN];
  216.     char *c;
  217.     int inlist = FALSE;
  218.  
  219.     /* find current line */
  220.     list = head;
  221.     while (list->line != l)
  222.         list = list->next;
  223.     curlevel = list->level;
  224.     list = list->next;        /* look at next element before going on */
  225.     if (list != NULL)
  226.     {
  227.     inlist = TRUE;
  228.     fprintf(f,":sl compact.\n");
  229.     }
  230.  
  231.     while (list != NULL)
  232.     {
  233.         /* we are onto the next topic so stop */
  234.         if (list->level == curlevel)
  235.             break;
  236.         /* these are the next topics down the list */
  237.         if (list->level == curlevel+1)
  238.         {
  239.             c = list->string;
  240.         while (isspace(*c)) c++;
  241.         fprintf(f,":li.:link reftype=hd res=%d.%s:elink.\n", list->line, c);
  242.             }
  243.         list = list->next;
  244.         }
  245.     if (inlist)
  246.         fprintf(f,":esl.\n");
  247.     }
  248.  
  249. void
  250. convert(a,b)
  251.     FILE *a,*b;
  252. {
  253.     static char line[MAX_LINE_LEN];
  254.     
  255.     /* generate ipf header */
  256.     fprintf(b,":userdoc.\n:prolog.\n");
  257.     fprintf(b,":title.%s\n", title);
  258.     fprintf(b,":docprof toc=1234.\n:eprolog.\n");
  259.  
  260.     /* process each line of the file */
  261.         while (fgets(line,MAX_LINE_LEN,a)) {
  262.        process_line(line, b);
  263.        }
  264.  
  265.     /* close final page and generate trailer */
  266.     fprintf(b,"\n:euserdoc.\n");
  267. }
  268.  
  269. void
  270. process_line(line, b)
  271.     char *line;
  272.     FILE *b;
  273. {
  274.     static int line_count = 0;
  275.     static char line2[MAX_LINE_LEN];
  276.     static int last_line;
  277.     char hyplink1[64] ;
  278.     char *pt, *tablerow ;
  279.     int i;
  280.     int j;
  281.     static int startpage = 1;
  282.     char str[MAX_LINE_LEN];
  283.     char topic[MAX_LINE_LEN];
  284.     int k, l;
  285.     static int tabl=0;
  286.     static int para=0;
  287.     static int inquote = FALSE;
  288.     static int inref = FALSE;
  289.     static int intable = FALSE ; 
  290.     static int intablebut = FALSE ;
  291.     static FILE *bo= NULL, *bt = NULL ;
  292.  
  293.     line_count++;
  294.  
  295.     if( bo == NULL ) bo = b ;
  296.     i = 0;
  297.     j = 0;
  298.     while (line[i] != '\0')
  299.     {
  300.         switch(line[i])
  301.         {
  302.             case '$':
  303.                 if( intable && line[0] == '%' ) {                                    
  304.                    ++i ;
  305.                    if( line[i+1]=='$'|| line[i]=='x' || line[i]=='|'){
  306.                       while ( line[i] != '$' ) line2[j++]=line[i++] ;
  307.                       --j;
  308.                       }
  309.                    else {
  310.                        while( line[i] != '$' ) i++ ;
  311.                        if( line[i+1]==',' ) i++ ;
  312.                        if( line[i+1]==' ' ) i++ ;
  313.                        line2[j]=line[++i] ;
  314.                        }
  315.                    }
  316.                 break ;
  317.             case ':':
  318.                 strcpy( &line2[j], "&colon." ) ;
  319.                 j += strlen( "&colon." ) - 1 ;
  320.                 break ;
  321.  
  322.             case '&':
  323.                 strcpy( &line2[j], "&." ) ;
  324.                 j += strlen( "&." ) - 1 ;
  325.                 break ;
  326.                                 
  327.             case '\r':
  328.             case '\n':
  329.                 break;
  330.             case '`':    /* backquotes mean boldface or link */
  331.                 if ((!inref) && (!inquote))
  332.                 {
  333.                     k=i+1;    /* index into current string */
  334.                     l=0;    /* index into topic string */
  335.                     while ((line[k] != '`') && (line[k] != '\0'))
  336.                     {
  337.                         topic[l] = line[k];
  338.                         k++;
  339.                         l++;
  340.                         }
  341.                     topic[l] = '\0';
  342.                     k = lookup(topic);
  343.             if ((k > 0) && (k != last_line))
  344.                     {
  345.                         sprintf( hyplink1, ":link reftype=hd res=%d.", k ) ;
  346.                         strcpy( line2+j, hyplink1 ) ;
  347.                         j += strlen( hyplink1 )-1 ;
  348.                         
  349.                         inref = k;
  350.                         }
  351.                     else
  352.                     {
  353.                         if (debug && k != last_line)
  354.                             fprintf(stderr,"Can't make link for \042%s\042 on line %d\n",topic,line_count);
  355.                         line2[j++] = ':';
  356.                         line2[j++] = 'h';
  357.                         line2[j++] = 'p';
  358.                         line2[j++] = '2';
  359.                         line2[j] = '.';
  360.                         inquote = TRUE;
  361.                         }
  362.                     }
  363.                 else
  364.                 {
  365.                     if (inquote && inref)
  366.                         fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
  367.                     if (inquote)
  368.                     {
  369.                         line2[j++] = ':';
  370.                         line2[j++] = 'e';
  371.                         line2[j++] = 'h';
  372.                         line2[j++] = 'p';
  373.                         line2[j++] = '2';
  374.                         line2[j] = '.';
  375.                         inquote = FALSE;
  376.                         }
  377.                     if (inref)
  378.                     {
  379.                         /* must be inref */
  380.                         line2[j++] = ':';
  381.                         line2[j++] = 'e';
  382.                         line2[j++] = 'l';
  383.                         line2[j++] = 'i';
  384.                         line2[j++] = 'n';
  385.                         line2[j++] = 'k';
  386.                         line2[j] = '.';
  387.                         inref = 0;
  388.                         }
  389.                 }
  390.                 break;
  391.             default:
  392.                 line2[j] = line[i];
  393.             }
  394.         i++;
  395.         j++;
  396.         line2[j] = '\0';
  397.         }
  398.  
  399.     i = 1;
  400.  
  401.     switch(line[0]) {        /* control character */
  402.        case '?': {            /* interactive help entry */
  403.                if( intable ) intablebut = TRUE ;
  404.                fprintf(bo,"\n:i1. %s", &(line[1])); /* index entry */
  405.                break;
  406.        }
  407.        case '@': {            /* start/end table */
  408.                   intable = !intable ;  
  409.                   if( intable ) {
  410.                     tablelines = 0;
  411.                     tablecols = 0 ;
  412.                     tableins = &table ;
  413.                     for(j=0;j<3;j++)tablewidth[j]=0 ;
  414.                     }
  415.                   else { /* dump table */
  416.                     intablebut = FALSE ;
  417.                     tableins = table.next ;
  418.                     fprintf(b,":table cols=\'") ;
  419.                     for( j=0;j<3;j++)
  420.                         if(tablewidth[j]>0) fprintf(b," %d",tablewidth[j]);
  421.                     fprintf(b,"\'.\n") ;
  422.                     tableins=tableins->next ;     
  423.                     while( tableins != NULL ) {
  424.                         if( tableins->col[0][0] != '_' ) {
  425.                             fprintf(b,":row.\n" ) ;
  426.                             for( j=0;j<tablecols;j++) 
  427.                                 fprintf(b,":c.%s\n", tableins->col[j] ) ;
  428.                             }
  429.                         tableins = tableins->next ;
  430.                         }
  431.                     fprintf(b,":etable.\n") ;
  432.                     if( bt != NULL ) {
  433.                         rewind( bt ) ;
  434.                         while( fgets(str, MAX_LINE_LEN, bt) )
  435.                             fputs( str, b ) ; 
  436.                         fclose( bt ) ;
  437.                         remove( "doc2ipf.tmp" ) ;
  438.                         bt = NULL ;
  439.                         bo = b ;
  440.                         }
  441.                     }
  442.           break;            /* ignore */
  443.        }
  444.        case '#': {            /* latex table entry */
  445.           break;            /* ignore */
  446.        }
  447.        case '%': {            /* troff table entry */
  448.               if( intable ) {
  449.                     tablerow = line2 ;
  450.                     tableins->next = malloc( sizeof( struct TABENTRY ) ) ;
  451.                     tableins = tableins->next ;
  452.                     tableins->next = NULL ;
  453.                     j=0 ;
  454.                 while((pt=strtok( tablerow, "%@\n" ))!=NULL) {
  455.                     if( *pt != '\0' ) { /* ignore null columns */
  456.                         strcpy( tableins->col[j], pt ) ;
  457.                         k=strlen( pt ) ;
  458.                         if( k > tablewidth[j] ) tablewidth[j]=k ;
  459.                         ++j ;
  460.                         tablerow = NULL ;
  461.                         if( j > tablecols ) tablecols = j ;
  462.                         }
  463.                     }
  464.                 for( j; j<3; j++ ) tableins->col[j][0]='\0' ;        
  465.                 }
  466.           break;            /* ignore */
  467.        }
  468.        case '\n':            /* empty text line */
  469.         if (tabl)
  470.             fprintf(bo,":ecgraphic.\n"); /* rjl */
  471.             para = 0;
  472.             tabl = 0;
  473.             fprintf(bo,":p.");
  474.             break;
  475.        case ' ': {            /* normal text line */
  476.                   if( intable && ! intablebut ) break ;
  477.                   if( intablebut ) { /* indexed items in  table, copy
  478.                                       to file after table by saving in
  479.                                       a temp file meantime */
  480.                                 if( bt == NULL ) {
  481.                                     fflush(bo) ;
  482.                                     bt = fopen( "doc2ipf.tmp", "w+" ) ;
  483.                                     if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  484.                                     else bo = bt ; 
  485.                                     }
  486.                         }
  487.                   if( intablebut && (bt==NULL )) break ;
  488.           if ((line2[1] == '\0') || (line2[1] == '\n'))
  489.           {
  490.                 fprintf(bo,":p."); 
  491.                 para = 0;
  492.                 }
  493.           if (line2[1] == ' ') 
  494.           {
  495.                 if (!tabl)
  496.                 {
  497. /*                    fprintf(bo,":p."); */
  498.             fprintf(bo,":cgraphic.\n");
  499.                     }
  500.                 fprintf(bo,"%s\n",&line2[1]); 
  501.  
  502. /*                fprintf(bo,"\n.br\n"); */
  503.                 tabl = 1;
  504.                 para = 0;
  505.                 }
  506.           else
  507.           {
  508.         if (tabl) {
  509.             fprintf(bo,":ecgraphic.\n"); /* rjl */
  510.                     fprintf(bo,":p.");     /* rjl */
  511.         }
  512.                 tabl = 0;
  513.                 if (!para)
  514.                     para = 1;        /* not in para so start one */
  515.                   fprintf(bo,"%s \n",&line2[1]); 
  516.                 }
  517.                   fflush(bo) ;
  518.           break;
  519.        }
  520.        default: {
  521.           if (isdigit(line[0])) { /* start of section */
  522.               if (tabl)
  523.                   fprintf(bo,":ecgraphic.\n"); /* rjl */
  524.                   if( intable ) {
  525.                       intablebut = TRUE ;
  526.                                 if( bt == NULL ) {
  527.                                     fflush(bo) ;
  528.                                     bt = fopen( "doc2ipf.tmp", "w+" ) ;
  529.                                     if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  530.                                     else bo = bt ; 
  531.                                     }
  532.                                 }
  533.             if (!startpage)
  534.             {
  535.                 refs(last_line,bo);
  536.                 }
  537.             para = 0;                    /* not in a paragraph */
  538.             tabl = 0;
  539.             last_line = line_count;
  540.             startpage = 0;
  541.         if (debug)
  542.         fprintf( stderr, "%d: %s\n", line_count, &line2[1] ) ;
  543.             k=lookup(&line2[1]) ;
  544. #ifdef OLD
  545. /*            if( k<0 ) fprintf(bo,":h%c.", line[0]=='1'?line[0]:line[0]-1);
  546.             else*/ fprintf(bo,":h%c res=%d.", line[0]=='1'?line[0]:line[0]-1,line_count);
  547. #else
  548.             fprintf(bo,":h%c res=%d name='%s'.", line[0]=='1'?line[0]:line[0]-1,line_count, &(line2[1]));
  549. #endif
  550.             fprintf(bo,&(line2[1])); /* title */
  551.             fprintf(bo,"\n:p." ) ;
  552.           } else
  553.             fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
  554.                 line[0], line_count);
  555.           break;
  556.        }
  557.     }
  558. }
  559.  
  560.