home *** CD-ROM | disk | FTP | other *** search
/ Dream 45 / Amiga_Dream_45.iso / Amiga / Magazine / Dossier-LaTeX / rtf2latex.lha / latex2rtf / main.c < prev    next >
C/C++ Source or Header  |  1997-02-28  |  21KB  |  798 lines

  1. /*
  2.  * $Id: main.c,v 1.3 1994/06/21 08:14:11 ralf Exp $
  3.  * History:
  4.  * $Log: main.c,v $
  5.  * Revision 1.3  1994/06/21  08:14:11  ralf
  6.  * Corrected some bugs
  7.  *
  8.  * Revision 1.2  1994/06/17  14:19:41  ralf
  9.  * Corrected various bugs, for example interactive read of arguments
  10.  *
  11.  * Revision 1.1  1994/06/17  11:26:29  ralf
  12.  * Initial revision
  13.  */
  14. /***************************************************************************
  15.      name : main.c
  16.     autor : DORNER Fernando, GRANZER Andreas
  17.   purpose : main convert-routine from LaTex2Rtf
  18.  *****************************************************************************/
  19.  
  20.  
  21. /****************************** includes *************************************/
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include "main.h"
  27. #include "commands.h"
  28. #include "funct1.h"
  29. #include "fonts.h"
  30. #include "stack.h"
  31. #include "funct2.h"
  32. #include "direct.h"
  33. #include "ignore.h"
  34. #include "version.h"
  35. /****************************************************************************/
  36.  
  37.  
  38. /********************************* global variables *************************/
  39. FILE *fTex;         /* file pointer to Latex file */
  40. FILE *fRtf;         /* file pointer to RTF file */
  41. char *progname;            /* name of the executable file */
  42. char *latexname= "stdin";    /* name of LaTex-File */
  43. char alignment = JUSTIFIED;    /* default for justified: */
  44. fpos_t pos_begin_kill;
  45.  
  46. /****************************************************************************/
  47. /*** function prototypes ***/
  48. BOOL PrepareTex(char *filename, FILE **f);  /* opens file for reading */
  49. BOOL PrepareRtf(char * filename, FILE **f); /* creates file and writes */
  50.                        /* RTF header */
  51. BOOL CloseTex(FILE **f);
  52. BOOL CloseRtf(FILE **f);
  53.  
  54. BOOL TranslateCommand();  /* converts commands */
  55. BOOL TranslateSpecKey();  /* converts special keys */
  56. void *GetCommandFunc(char *cCommand);
  57. void numerror(int num);
  58. BOOL ConvertFormula(char * command);
  59.  
  60.  
  61.  
  62. /****************************************************************************/
  63. int main(int argc, char **argv)
  64. /****************************************************************************
  65. purpose: checks parameter and starts convert routine
  66. params:  command line arguments argc, argv
  67. globals: initializes in- and outputfile fTex, fRtf
  68.  ****************************************************************************/
  69. {
  70.  
  71.   int c, errflag = 0;
  72.   char *input = NULL, *output = NULL;
  73.   char tmpText[PATHMAX];
  74. /*  extern int getopt;*/
  75.   extern char *optarg;
  76.   extern int optind, opterr;
  77.   fTex=stdin;
  78.   fRtf=stdout;
  79.   PushEnvironment(HEADER);
  80.   PushEnvironment(DOCUMENT);
  81.   progname=argv[0];
  82.   while((c = getopt(argc, argv, "Vo:")) != EOF)
  83.   {
  84.     switch(c)
  85.     {
  86.       case 'V':
  87.     printf("%s: %s\n", progname, Version);
  88.     return(0);
  89.       case 'o':
  90.     output = optarg;
  91.     break;
  92.       default:
  93.     errflag = 1;
  94.     }
  95.   }
  96.   if(argc > optind + 1 || errflag)
  97.   {
  98.     fprintf(stderr,"%s: Usage: %s [-o outfile] inputfile\n",
  99.       progname, progname);
  100.     return(1);
  101.   }
  102.   if(argc == optind + 1)
  103.   {
  104.     input = argv[optind];
  105.     latexname = input;
  106.   }
  107.  
  108.   PrepareTex(input,&fTex);
  109.   PrepareRtf(output,&fRtf);
  110.   WriteFontHeader(fRtf);
  111.   Push(1,0);
  112.   Convert(fTex, fRtf);
  113.   /* For vi {{{{{ */
  114.   fprintf(fRtf,"}}}}}");
  115.   CloseTex(&fTex);
  116.   CloseRtf(&fRtf);
  117.   RemoveFontlist();
  118.   /* fprintf(stderr,"Convert successfull\n"); */
  119.   return(0);
  120. }
  121.  
  122.  
  123. /****************************************************************************/
  124. /* Global Flags for Convert Routine */
  125. /****************************************************************************/
  126. int RecursLevel = 0;
  127. int BracketLevel = 1;
  128. int ret = 0;
  129. BOOL mbox = FALSE;
  130. BOOL MathMode = FALSE;
  131. BOOL bNewPar = FALSE;
  132. int indent = 0;
  133. BOOL NoNewLine = FALSE;
  134. int ConvertFlag;
  135. BOOL bPard = TRUE;
  136. BOOL bInDocument = FALSE;
  137. int tabcounter = 0;
  138. int fontsize = 20;
  139. BOOL twocolumn = FALSE;
  140. BOOL titlepage = FALSE;
  141. BOOL article = TRUE;
  142. BOOL TABBING_ON = FALSE;
  143. BOOL TABBING_RETURN = FALSE;
  144. BOOL TABBING_ON_itself = FALSE;
  145. BOOL TITLE_AUTHOR_ON = FALSE;
  146. BOOL GermanMode = FALSE;  /* switches support for germanstyle on or off */
  147. /* the Germand Mode supports most of the commands defined in GERMAN.STY file
  148.    by H.Partl(TU Wien) 87-06-17 */
  149.  
  150. long linenumber=1;               /* counts lines in the LaTex-document */
  151.  
  152.  
  153. /****************************************************************************/
  154. BOOL Convert()
  155. /****************************************************************************
  156. purpose: convertes inputfile and writes result to outputfile
  157. globals: fTex, fRtf and all global flags for convert (see above)
  158.  ****************************************************************************/
  159. {
  160.   char cThis = '\n';
  161.   char cLast = '\n';
  162.   char cLast2 = '\n';
  163.   char cLastNoSpace = 'a';
  164.   int PopLevel=0,PopBrack,PPopLevel,PPopBrack,size,retlevel;
  165.   int count = 0;
  166.   int i;
  167.   char cThishilf;
  168.  
  169.   RecursLevel++;
  170.   Push(RecursLevel,BracketLevel);
  171.   ++ConvertFlag;
  172.   while (fread(&cThis, 1,1,fTex) == 1)
  173.   {
  174.     switch(cThis)
  175.     {
  176.     case '\\':{
  177.           int SaveFlag;
  178.           fpos_t pos1,pos2;
  179.           fgetpos(fRtf,&pos1);
  180.           Push(RecursLevel,BracketLevel);
  181.           SaveFlag=ConvertFlag;
  182.           TranslateCommand();
  183.  
  184.           /*if ((TABBING_ON_itself) ||
  185.           ((TABBING_ON) &&
  186.           (TABBING_RETURN)))
  187.           {
  188.           TABBING_RETURN = FALSE;
  189.           if (TABBING_ON_itself)
  190.              TABBING_ON = FALSE;
  191.           TABBING_ON_itself = FALSE;
  192.           return TRUE;
  193.           } */
  194.  
  195.           /* erase double identic values on stack top */
  196.           for(;;)
  197.           {
  198.         if ((size = Pop(&PPopLevel, &PPopBrack)) <= 0 )
  199.         {
  200.           Push(PPopLevel,PPopBrack);
  201.           break;
  202.         }
  203.         if ((size = Pop(&PopLevel, &PopBrack)) <= 0 )
  204.         {
  205.           Push(PopLevel,PopBrack);
  206.           break;
  207.         }
  208.         if ( (PPopLevel == PopLevel) && (PPopBrack == PopBrack) )
  209.         {
  210.           Push(PopLevel,PopBrack);
  211.         }
  212.         else
  213.         {
  214.           Push(PopLevel,PopBrack);
  215.           Push(PPopLevel,PPopBrack);
  216.           break;
  217.         }
  218.           };
  219.  
  220.           if (ret > 0)
  221.           {
  222.         --ret;
  223.         --RecursLevel;
  224.         return TRUE;
  225.           }
  226.           /* remove SaveFlag */
  227.           /*if (ConvertFlag == SaveFlag)    Convert was not called 
  228.           {
  229.         //cThis = ' ';     error 
  230.           }
  231.               */
  232.           cThis = '\\';
  233.           fgetpos(fRtf,&pos2);
  234.           if (pos1 == pos2)    /* no RTF output */
  235.           {
  236.         if (cLast == '\n')
  237.           cThis = '\n';
  238.         else
  239.           cThis = ' ';
  240.           }
  241.           break;
  242.           }
  243.     case '%': IgnoreTo('\n');
  244.           cThis = ' ';
  245.           break;
  246.     case '{':
  247.           Push(RecursLevel,BracketLevel);
  248.           ++BracketLevel;
  249.           break;
  250.     case '}':
  251.           BracketLevel--;
  252.           PPopLevel = RecursLevel;
  253.           PPopBrack = BracketLevel;
  254.           size = Pop(&PopLevel, &PopBrack);
  255.           while ( (size = Pop(&PopLevel, &PopBrack)) >= 0 )
  256.           {
  257.         if ( PopBrack < BracketLevel )
  258.         {
  259.           break;
  260.         }
  261.         PPopLevel = PopLevel;
  262.         PPopBrack = PopBrack;
  263.           } /* while */
  264.           Push(PopLevel,PopBrack);    /* push back */
  265.           retlevel = PPopLevel;
  266.           ret = RecursLevel-retlevel;
  267.           Push(retlevel,BracketLevel);
  268.  
  269.           if (ret > 0)
  270.           {
  271.         ret--;
  272.         RecursLevel--;
  273.         return TRUE;
  274.           }
  275.           else
  276.         break;
  277.     case '\r':fprintf(stderr,"\n%s: ERROR: error in input file: %s at linenumber: %ld\n",progname,latexname,linenumber);
  278.           fprintf(stderr,"\nprogram aborted\n");
  279.           exit(-1);
  280.           break;
  281.     case ' ': if (!bInDocument) continue;
  282.           if ( (cLast != ' ') && (cLast != '\n'))
  283.           {
  284.         if (mbox == FALSE)
  285.            /*   if (bNewPar == FALSE)*/
  286.             fprintf(fRtf," ");
  287.         else
  288.           fprintf(fRtf,"\\~");
  289.           }
  290.           break;
  291.     case '~': if (!bInDocument) numerror(ERR_WRONG_COMMAND);
  292.           fprintf(fRtf,"\\~");
  293.           break;
  294.     case '\n':
  295.           tabcounter=0;
  296.           linenumber++;
  297.  
  298.           if (!bInDocument) continue;
  299.           if (cLast != '\n')
  300.           {
  301.         if (bNewPar == TRUE)
  302.         { bNewPar = FALSE; cThis = ' '; break; }
  303.         if (cLast != ' ')
  304.           fprintf(fRtf," ",cLast);     /* treat as 1 space */
  305.           }
  306.           else
  307.           {
  308.         if (NoNewLine) break;
  309.         if (cLast2 != '\n')
  310.         {
  311.           fprintf(fRtf,"\n\r\\par ");
  312.           if (bPard)
  313.           {
  314.             fprintf(fRtf,"\\pard\\q%c ",alignment);
  315.             bPard = FALSE;
  316.           }
  317.         }
  318.           }
  319.           break;
  320.     case '^': if (!bInDocument) numerror(ERR_WRONG_COMMAND);
  321.           fprintf(fRtf,"{\\up6 ");
  322.           Push(RecursLevel,BracketLevel);
  323.           Convert();
  324.           if (ret > 0)
  325.           {
  326.         --ret;
  327.         --RecursLevel;
  328.         return TRUE;
  329.           }
  330.           fprintf(fRtf,"}");
  331.           break;
  332.     case '_': if (!bInDocument) numerror(ERR_WRONG_COMMAND);
  333.           fprintf(fRtf,"{\\dn6 ");
  334.           Push(RecursLevel,BracketLevel);
  335.           Convert();
  336.           if (ret > 0)
  337.           {
  338.         --ret;
  339.         --RecursLevel;
  340.         return TRUE;
  341.           }
  342.           fprintf(fRtf,"}");
  343.           break;
  344.     case '$': CmdFormula(FORM_DOLLAR);
  345.           break;
  346.     case '-' : count++;
  347.            while ((fread(&cThishilf,1,1,fTex) >= 1) && (cThishilf == '-'))
  348.            count++;
  349.            switch (count)
  350.            {
  351.          case 1: fprintf(fRtf,"-");
  352.              break;
  353.          case 2: fprintf(fRtf,"\\endash ");
  354.              break;
  355.          case 3: fprintf(fRtf,"\\emdash ");
  356.              break;
  357.          default:
  358.          { for (i = count-1; i >= 0; i--)
  359.            fprintf(fRtf,"-");
  360.          }
  361.            }
  362.            fseek(fTex,-1L,SEEK_CUR); /* reread last character */
  363.            count = 0;
  364.         break;
  365.     case '\'' : count++;
  366.            while ((fread(&cThishilf,1,1,fTex) >= 1) && (cThishilf == '\''))
  367.            count++;
  368.            if (count != 2)
  369.          { for (i = count-1; i >= 0; i--)
  370.            fprintf(fRtf,"\\rquote ");
  371.          }
  372.            else
  373.            fprintf(fRtf,"\\rdblquote ");
  374.            fseek(fTex,-1L,SEEK_CUR); /* reread last character */
  375.            count = 0;
  376.            break;
  377.     case '`' : count++;
  378.            while ((fread(&cThishilf,1,1,fTex) >= 1) && (cThishilf == '`'))
  379.            count++;
  380.            if (count != 2)
  381.          { for (i = count-1; i >= 0; i--)
  382.            fprintf(fRtf,"\\lquote ");
  383.          }
  384.            else
  385.            fprintf(fRtf,"\\ldblquote ");
  386.            fseek(fTex,-1L,SEEK_CUR); /* reread last character */
  387.            count = 0;
  388.            break;
  389.     case '\"': if (GermanMode)
  390.          TranslateGerman();
  391.            else
  392.          fprintf(fRtf,"\"");
  393.            break;
  394.     case '\t': break;
  395.     default: if (bInDocument)
  396.          {
  397.           if ((isupper(cThis)) &&
  398.          ((cLast=='.') || (cLast=='!') || (cLast=='?') || (cLast==':')))
  399.         fprintf(fRtf," ");
  400.           fprintf(fRtf,"%c",cThis);
  401.           bNewPar = FALSE;
  402.         }
  403.       break;
  404.     }
  405.  
  406.   tabcounter++;
  407.   cLast2 = cLast;
  408.   cLast = cThis;
  409.   if (cThis != ' ')
  410.     cLastNoSpace = cThis;
  411.   }
  412.   RecursLevel--;
  413.   return TRUE;
  414. }
  415.  
  416.  
  417. /****************************************************************************/
  418. void error(char * text)
  419. /****************************************************************************
  420. purpose: writes error message
  421. globals: reads progname;
  422.  ****************************************************************************/
  423. {
  424.   fprintf(stderr,"\n%s: ERROR: %s",progname,text);
  425.   fprintf(stderr,"\nprogram aborted\n");
  426.   exit(-1);
  427. }
  428.  
  429.  
  430. /****************************************************************************/
  431. void numerror(int num)
  432. /****************************************************************************
  433. purpose: writes error message identified by number - for messages on many
  434.      places in code. Calls function error.
  435. globals: reads progname;
  436.  ****************************************************************************/
  437. {
  438.  
  439.   char text[1024];
  440.  
  441.   switch(num)
  442.   {
  443.     case ERR_EOF_INPUT:
  444.       sprintf(text,"%s%s%s%ld%s","unexpected end of input file in: ",latexname," at linenumber: ",linenumber,"\n");
  445.       error(text);
  446.       break;
  447.     case ERR_WRONG_COMMAND:
  448.       sprintf(text,"%s%s%s%ld%s","unexpected command or character in: ",latexname," at linenumber: ",linenumber,"\n");
  449.       error(text);
  450.       break;
  451.     case ERR_Param:
  452.       error("wrong number of parameters\n");
  453.       break;
  454.     case ERR_WRONG_COMMAND_IN_TABBING:
  455.       sprintf(text,"%s%s%s%ld%s","wrong command in Tabbing-kill-command-line in: ",latexname," at linenumber: ",linenumber,"\n");
  456.       error(text);
  457.       break;
  458.     default :
  459.       error("internal error");
  460.       break;
  461.   }
  462. }
  463.  
  464.  
  465. /****************************************************************************/
  466. BOOL PrepareRtf(char *filename, FILE **f)  /* creates file and writes */
  467.                        /* RTF header */
  468. /****************************************************************************
  469. purpose: creates output file an writes RTF-header.
  470. params: filename - name of outputfile
  471.     f - pointer to filepointer to store file ID
  472.  ****************************************************************************/
  473. {
  474.   if(filename != NULL)
  475.   {
  476.       if ((*f = fopen(filename,"wb")) == NULL)     /* open file */
  477.       {
  478.     error("Error opening RTF-file");
  479.     exit(1);
  480.       }
  481.   }
  482.   /* write header */
  483.   fprintf(*f,"{\\rtf1\\pc\\fs%d\\deff0\\deflang1024",fontsize);
  484.   fprintf(*f,"{\\stylesheet{\\fs%d\\lang1031\\snext0 Normal;}}",fontsize);
  485.   fprintf(*f,"{\\info{\\version1}}\\widowctrl\\ftnbj\\sectd\\linex0\\endnhere");
  486.   fprintf(*f,"\\qj \n");
  487.   return TRUE;
  488. }
  489.  
  490.  
  491. /****************************************************************************/
  492. BOOL PrepareTex(char *filename, FILE **f)  /* opens file for reading */
  493. /****************************************************************************
  494. purpose: opens input file.
  495. params: filename - name of inputfile
  496.     f - pointer to filepointer to store file ID
  497.  ****************************************************************************/
  498. {
  499.   if(filename != NULL)
  500.   {
  501.       if ((*f = fopen(filename,"r")) == NULL)    /* open file */
  502.       {
  503.     error("Error opening LATEX-file");
  504.     exit(1);
  505.       }
  506.   }
  507.   return TRUE;
  508. }
  509.  
  510.  
  511. /****************************************************************************/
  512. BOOL CloseTex(FILE **f)
  513. /****************************************************************************
  514. purpose: closes input file.
  515. params: f - pointer to filepointer to invalidate
  516.  ****************************************************************************/
  517. {
  518.   if(*f != stdin)
  519.       fclose(*f);
  520.   *f = NULL;
  521.   return TRUE;
  522. }
  523.  
  524.  
  525. /****************************************************************************/
  526. BOOL CloseRtf(FILE **f)
  527. /****************************************************************************
  528. purpose: closes output file.
  529. params: f - pointer to filepointer to invalidate
  530.  ****************************************************************************/
  531. {
  532.   fprintf(*f,"}");
  533.   if(*f != stdout)
  534.   {
  535.       if(fclose(*f) == EOF)
  536.       {
  537.     fprintf(stderr, "%s: Warning: Error closing RTF-File\n", progname);
  538.       }
  539.   }
  540.   *f = NULL;
  541.   return TRUE;
  542. }
  543.  
  544.  
  545. /****************************************************************************/
  546. BOOL TranslateCommand()
  547. /****************************************************************************
  548. purpose: The function is called on a backslash in input file and
  549.      tries to call the command-function for the following command.
  550. returns: sucess or not
  551. globals: fTex, fRtf, command-functions have side effects or recursive calls
  552.  ****************************************************************************/
  553. {
  554.   char cCommand[MAXCOMMANDLEN];
  555.   int i;
  556.   char cThis;
  557.   for (i = 0; ;i++)   /* get command from input stream */
  558.   {
  559.     if (fread(&cThis,1,1,fTex) < 1)
  560.        break;
  561.     if (i == 0) /* test for special characters */
  562.     {
  563.       switch(cThis)
  564.       {
  565.     case '}': fprintf(fRtf,"\\}"); return TRUE;
  566.     case '{': fprintf(fRtf,"\\{"); return TRUE;
  567.     case '#': fprintf(fRtf,"#"); return TRUE;
  568.     case '$': fprintf(fRtf,"$"); return TRUE;
  569.     case '&': fprintf(fRtf,"&"); return TRUE;
  570.     case '%': fprintf(fRtf,"%%"); return TRUE;
  571.     case '_': fprintf(fRtf,"_"); return TRUE;
  572.     case '\\':    /* produces a newline in output */
  573.               /*      no new paragraph    */
  574.           if (fread(&cThis,1,1,fTex) < 1)
  575.               cThis='a';
  576.  
  577.           if ((cThis == ' ') ||
  578.               (cThis == '*'))  /* ignore * after \\ -> it's the same command as \\ */
  579.             {
  580.             if (fread(&cThis,1,1,fTex) < 1)
  581.               cThis='a';
  582.             while(cThis == ' ')            /*space  ignore */
  583.                if (fread(&cThis,1,1,fTex) != 1)
  584.               break;
  585.             fseek(fTex,-1,SEEK_CUR);
  586.             }
  587.           else
  588.             {
  589.             fseek(fTex,-1,SEEK_CUR);
  590.             }
  591.  
  592.           fprintf(fRtf,"\\par ");
  593.           bNewPar = TRUE;
  594.           tabcounter = 0;
  595.           if (TABBING_ON)
  596.              fgetpos(fRtf,&pos_begin_kill);
  597.  
  598.           return TRUE;
  599.     case ' ': fprintf(fRtf," ");    /* ordinary interword space */
  600.           while (cThis == ' ')     /* all spaces after commands are ignored */
  601.           {
  602.              if (fread(&cThis,1,1,fTex) < 1)
  603.             numerror(ERR_EOF_INPUT);
  604.           }
  605.  
  606.           fseek(fTex,-1L,SEEK_CUR);
  607.           return TRUE;
  608.           break;
  609.     case '-': /* hyphen */
  610.           /* caution: this character has another effect in the tabbing-environment */
  611.           if (TABBING_ON);
  612.           else
  613.              fprintf(fRtf,"\\-");
  614.           return TRUE;
  615.           break;
  616.     case '+': /* see tabbing-environment */
  617.           /* no harm for RTF-output */
  618.           break;
  619.     case '<': /* see tabbing-environment */
  620.           /* no harm for RTF-output */
  621.           break;
  622.     case '~': CmdTildeChar(0);
  623.           return TRUE;
  624.     case '^': CmdSpitzeChar(0);
  625.           return TRUE;
  626.     case '\"':CmdUmlaute(0);
  627.           return TRUE;
  628.     case '`': if (TABBING_ON);
  629.           else
  630.             CmdLApostrophChar(0);
  631.           return TRUE;
  632.     case '\'':if (TABBING_ON);
  633.           else
  634.              CmdRApostrophChar(0);  /* char ' =?= \' */
  635.           return TRUE;
  636.     case '(': CmdFormula(FORM_RND_OPEN);
  637.           return TRUE;
  638.     case '[': CmdFormula(FORM_ECK_OPEN);
  639.           return TRUE;
  640.     case ')': CmdFormula(FORM_RND_CLOSE);
  641.           return TRUE;
  642.     case ']': CmdFormula(FORM_ECK_CLOSE);
  643.           return TRUE;
  644.     case '/': CmdIgnore(0);
  645.           return TRUE;
  646.     case ',': CmdIgnore(0);  /* \, produces a small space */
  647.           return TRUE;
  648.     case '@': CmdIgnore(0);  /* \@ produces an "end of sentence" space */
  649.           return TRUE;
  650.     case '>': CmdTabjump(0);
  651.           return TRUE;
  652.     case '=': CmdTabset(0);
  653.           return TRUE;
  654.     case '3': fprintf(fRtf, "\\ansi\\'df\\pc ");   /* german symbol 'ß' */
  655.           return TRUE;
  656.       }
  657.     }
  658.     /*if ( (cThis == ' ') || (cThis == '\\') || (cThis == '{') ||
  659.      (cThis == '\n') || (cThis == ',' ) || (cThis == '.') ||
  660.      (cThis == '}') || (cThis == '\"') || (cThis == '[') ||
  661.      (cThis == '$') || (cThis == '|') )*/
  662.     if (!isalpha(cThis))
  663.     {
  664.       int found_nl = FALSE;
  665.       /* all spaces after commands are ignored, a single \n may occur */
  666.       while (cThis == ' ' || cThis == '\t' || cThis == '\n' && !found_nl)
  667.     {
  668.     if(cThis == '\n')
  669.         found_nl = TRUE;
  670.     if (fread(&cThis,1,1,fTex) < 1)
  671.         break;
  672.     }
  673.  
  674.       fseek(fTex,-1L,SEEK_CUR); /* position of next character after command
  675.                    except space */
  676.       break;
  677.     }
  678.     cCommand[i] = cThis;
  679.   }
  680.  
  681.   cCommand[i] = '\0';  /* mark end of string with zero */
  682.  
  683.   if ( i == 0)
  684.     return FALSE;
  685.   if (CallCommandFunc(cCommand)==TRUE) /*call handling function for command*/
  686.     return TRUE;
  687.   else
  688.   {
  689.     if (TryDirectConvert(cCommand, fRtf) == TRUE)
  690.       return TRUE;
  691.     else
  692.       {
  693.     if (TryVariableIgnore(cCommand, fTex) == TRUE)
  694.       return TRUE;
  695.     else
  696.     {
  697.       fprintf(stderr,"\n%s: WARNING: command: %s not found - ignored\n",progname,cCommand);
  698.       return FALSE;
  699.     }
  700.       }
  701.   }
  702.   return TRUE;
  703. }
  704. /****************************************************************************/
  705.  
  706. /****************************************************************************/
  707. void IgnoreTo(char cEnd)
  708. /****************************************************************************
  709. purpose: ignores anything from inputfile till character cEnd
  710. params:  charcter to stop ignoring
  711. globals: changes inputfile fTex
  712.  ****************************************************************************/
  713. {
  714.   char c;
  715.   while (fread(&c, 1,1,fTex) >= 1)
  716.   {
  717.     if (c == cEnd)
  718.     {
  719.       if (cEnd == '\n')
  720.     fseek(fTex,-1L,SEEK_CUR);   /*linenumber is set in convert-routine */
  721.     /*linenumber++;*/
  722.       return;
  723.     }
  724.     else
  725.     {
  726.      if (c == '\n')
  727.        linenumber++;
  728.     }
  729.   }
  730.   numerror(ERR_EOF_INPUT);
  731. }
  732.  
  733. FILE *open_cfg(const char *name)
  734. {
  735.     char *cfg_path = getenv("RTFPATH");
  736.     static char *path = NULL;
  737.     static int size = 1024;
  738.     int len;
  739.     FILE *fp;
  740.  
  741.     if(path == NULL && (path = malloc(size)) == NULL)
  742.     {
  743.     fprintf(stderr, "%s: Fatal Error: Cannot allocate memory\n", progname);
  744.     exit(23);
  745.     }
  746.     if(cfg_path != NULL)
  747.     {
  748.     char *s, *t;
  749.     s = cfg_path;
  750.     while(s && *s)
  751.     {
  752.         t = s;
  753.         s = strchr(s, ':');
  754.         if(s)
  755.         {
  756.         *s = '\0';
  757.         s++;
  758.         }
  759.         if((len = (strlen(t) + strlen(name) + 2)) > size)
  760.         {
  761.         size = len;
  762.         if((path = realloc(path, size)) == NULL)
  763.         {
  764.             fprintf(stderr, "%s: Fatal Error: Cannot allocate memory\n",
  765.             progname);
  766.             exit(23);
  767.         }
  768.         }
  769.         strcpy(path, t);
  770.         strcat(path, "/");
  771.         strcat(path, name);
  772.         if((fp = fopen(path,"r")) != NULL)
  773.         return(fp);
  774.     }
  775.     }
  776.     if((len = (strlen(LIBDIR) + strlen(name) + 2)) > size)
  777.     {
  778.     size = len;
  779.     if((path = realloc(path, size)) == NULL)
  780.     {
  781.         fprintf(stderr, "%s: Fatal Error: Cannot allocate memory\n",
  782.         progname);
  783.         exit(23);
  784.     }
  785.     }
  786.     strcpy(path, LIBDIR);
  787.     strcat(path, "/");
  788.     strcat(path, name);
  789.     if((fp = fopen(path,"r")) == NULL)
  790.     {
  791.     fprintf(stderr, "\n%s: ERROR: cannot open file '%s'.",progname,name);
  792.     fprintf(stderr,"\nprogram aborted\n");
  793.     fclose(fp);
  794.     exit(1);
  795.     }
  796.     return(fp);
  797. }
  798.