home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / tr2latex / tr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-30  |  24.3 KB  |  1,057 lines

  1. /* COPYRIGHT (C) 1987 Kamal Al-Yahya */
  2.  
  3. /*
  4. This program has the HARD-WIRED rules of the translator.
  5. It should handled with care.
  6. */
  7.  
  8. #define IN_TR  1
  9. #include        "setups.h"
  10. int def_count = 0;
  11. int mydef_count = 0;
  12.  
  13. void
  14. troff_tex(inbuf,outbuf,mid,rec)
  15. char *inbuf,*outbuf;
  16. int mid,rec;
  17. {
  18. char eqn_no[MAXWORD], w[MAXWORD], ww[MAXLINE], tmp[MAXWORD], tmp2[MAXWORD];
  19. char *p;
  20. int len,c,c1,c2,i,j;
  21. int ref = 0;
  22. int put_brace = 0;
  23. int first_word = 1;
  24. int no_word = 1;
  25. int arg = 0;
  26. int par = 0;
  27. int illegal = 0;
  28. int floating = 0;
  29. static int delim_defd = 0;    /* whether math delimiter has been defined */
  30. static char *DELIM = "$";
  31. float flen;
  32. int N;
  33. int RSRE = 0;            /* block indentation */
  34. int thisfont = 1;        /* default font is roman */
  35. int lastfont = 1;        /* default last font is roman */
  36. int offset = 0;            /* amount to offset inbuf */
  37. extern man;            /* man flag */
  38.  
  39. *outbuf = NULL;        w[0] = NULL;    ww[0] = NULL;
  40. tmp[0] = NULL;        tmp2[0] = NULL;
  41. while (*inbuf != NULL)
  42.     {
  43.     len = getword(inbuf,w);
  44.     c1 = *--inbuf;
  45.     c2 = *++inbuf;
  46.     inbuf += len;
  47.     if (isspace(w[0]) == 0)        no_word = 0;
  48. /* first check if we are in math mode */
  49.     if (math_mode)
  50.         {
  51.         len = get_till_space(inbuf,ww);
  52.         sprintf(tmp,"%s%s",w,ww);
  53.         if (strcmp(w,"delim") == 0)
  54.             {
  55.             delim_defd = 1;
  56.             inbuf += skip_white(inbuf);
  57.             DELIM[0] = *inbuf;
  58.             inbuf = skip_line(inbuf);
  59.             }
  60. /* check if it is a math delimiter; switch to non-math mode if so */
  61.         else if (delim_defd && strcmp(w,DELIM) == 0)
  62.             {
  63.             math_mode = 0;
  64.             *outbuf++ = '$';
  65.             }
  66. /* check for illegal macros here */
  67.         else if (len > 0 && def_count > 0 && (i=is_def(tmp)) >= 0)
  68.             {
  69.             inbuf += len;
  70.             outbuf = strapp(outbuf,def[i].replace);
  71.             }
  72. /* See if it is a (legally) defined macro */
  73.         else if (def_count > 0 && (i=is_def(w)) >= 0)
  74.             {
  75.             if (def[i].illegal)
  76.                 outbuf = strapp(outbuf,def[i].replace);
  77.             else
  78.                 {
  79.                 outbuf = strapp(outbuf,"\\");
  80.                 outbuf = strapp(outbuf,w);
  81.                 }
  82.             }
  83. /* Search for commands in some order; start with non-alphanumeric symbols */
  84.         else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0
  85.              || strcmp(w,"%") == 0 || strcmp(w,"_") == 0)
  86.             {
  87.             outbuf = strapp(outbuf,"\\");
  88.             outbuf = strapp(outbuf,w);
  89.             }
  90.         else if (strcmp(w,"=") == 0)
  91.             {
  92.             if (*inbuf == '=')
  93.                 {
  94.                 inbuf++;
  95.                 outbuf = strapp(outbuf,"\\equiv");
  96.                 }
  97.             else
  98.                 outbuf = strapp(outbuf,"=");
  99.             }
  100.         else if (strcmp(w,"<") == 0 || strcmp(w,">") == 0)
  101.             {
  102.             if (*inbuf == '=')
  103.                 {
  104.                 inbuf++;
  105.                 if (strcmp(w,"<") == 0)
  106.                     outbuf = strapp(outbuf,"\\le");
  107.                 else
  108.                     outbuf = strapp(outbuf,"\\ge");
  109.                 }
  110.             }
  111.         else if (strcmp(w,"-") == 0)
  112.             {
  113.             if (*inbuf == '>')
  114.                 {
  115.                 inbuf++;
  116.                 outbuf = strapp(outbuf,"\\to");
  117.                 }
  118.             else if (*inbuf == '+')
  119.                 {
  120.                 inbuf++;
  121.                 outbuf = strapp(outbuf,"\\mp");
  122.                 }
  123.             else
  124.                 *outbuf++ = '-';
  125.             }
  126.         else if (strcmp(w,"+") == 0)
  127.             {
  128.             if (*inbuf == '-')
  129.                 {
  130.                 inbuf++;
  131.                 outbuf = strapp(outbuf,"\\pm");
  132.                 }
  133.             else
  134.                 *outbuf++ = '+';
  135.             }
  136.         else if (strcmp(w,"\"") == 0)
  137.             {
  138.             len = get_no_math(inbuf,ww);
  139.             inbuf += len+1;
  140.             if (len > 1)
  141.                 {
  142.                 sprintf(tmp,"\\ \\it\\hbox{%s}",ww);
  143.                 outbuf = strapp(outbuf,tmp);
  144.                 }
  145.             else if (len == 1)
  146.                 *outbuf++ = ww[0];
  147.             }
  148. /* Now search for symbols that start with a captial */
  149.         else if (strcmp(w,".EN") == 0)
  150.             {
  151.             math_mode = 0;
  152.             if ((len=strlen(eqn_no)) > 0)
  153.                 {
  154.                 sprintf(tmp,"\\eqno %s",eqn_no);
  155.                 outbuf = strapp(outbuf,tmp);
  156.                 }
  157.             eqn_no[0] = NULL;
  158.             c1 = *--outbuf;
  159.             c2 = *--outbuf;
  160.             if (c1 == '\n' && c2 == '$')
  161.                 *--outbuf = NULL;
  162.             else
  163.                 {
  164.                 outbuf += 2;
  165.                 outbuf = strapp(outbuf,"$$");
  166.                 }
  167.             }
  168. /* Now search for symbols that start with a small letter */
  169.         else if (strcmp(w,"bold") == 0 || strcmp(w,"roman") == 0 ||
  170.              strcmp(w,"italic") == 0)
  171.             {
  172.             inbuf += get_arg(inbuf,ww,1);
  173.             if (strcmp(w,"bold") == 0)
  174.                 {
  175.                 sprintf(tmp,"{\\bf %s}",ww);
  176.                 outbuf = strapp(outbuf,tmp);
  177.                 }
  178.             else if (strcmp(w,"roman") == 0)
  179.                 {
  180.                 sprintf(tmp,"{\\rm %s}",ww);
  181.                 outbuf = strapp(outbuf,tmp);
  182.                 }
  183.             else
  184.                 {
  185.                 sprintf(tmp,"{\\it %s}",ww);
  186.                 outbuf = strapp(outbuf,tmp);
  187.                 }
  188.             }
  189.         else if (strcmp(w,"define") == 0)
  190.             {
  191.             if (def_count >= MAXDEF)
  192.                 {
  193.                 fprintf(stderr,
  194.                     "Too many defines. MAXDEF=%d\n",MAXDEF);
  195.                 exit(-1);
  196.                 }
  197.             for (i=0; *--outbuf != '$' && i < MAXLEN; i++)
  198.                 tmp[i] = *outbuf;
  199.             tmp[i] = NULL;
  200.             strcat(tmp,"$$");
  201.             *--outbuf = NULL;
  202.             inbuf += skip_white(inbuf);
  203.             inbuf += get_defword(inbuf,w,&illegal);
  204.             inbuf += skip_white(inbuf);
  205.             inbuf += getdef(inbuf,ww);
  206.             if (illegal)
  207.                 {
  208.                 def[def_count].illegal = 1;
  209.                 fprintf(stderr,
  210.                     "illegal TeX macro, %s, replacing it\n",w);
  211.                 p = (char *)malloc((unsigned)(strlen(ww)+1)*
  212.                     sizeof(char));
  213.                 strcpy(p,ww);
  214.                 def[def_count].replace = p;
  215.                 }
  216.             else
  217.                 {
  218.                 def[def_count].illegal = 0;
  219.                 sprintf(tmp2,"\\def\\%s{%s}\n",w,ww);
  220.                 outbuf = strapp(outbuf,tmp2);
  221.                 }
  222.             p = (char *)malloc((unsigned)(strlen(w)+1)*sizeof(char));
  223.             strcpy(p,w);
  224.             def[def_count++].def_macro = p;
  225.             inbuf += skip_white(inbuf);
  226.             for (j=i+1; j >= 0; j--)
  227.                 *outbuf++ = tmp[j];
  228.             tmp[0] = NULL;
  229.             }
  230.         else if (strcmp(w,"gsize") == 0 || strcmp(w,"gfont") == 0)
  231.             inbuf = skip_line(inbuf);
  232.         else if (strcmp(w,"left") == 0 || strcmp(w,"right") == 0)
  233.             {
  234.             sprintf(tmp,"\\%s",w);
  235.             outbuf = strapp(outbuf,tmp);
  236.             inbuf += skip_white(inbuf);
  237.             len = getword(inbuf,ww);
  238.             if (strcmp(ww,"floor") == 0)
  239.                 {
  240.                 inbuf += len;
  241.                 if (strcmp(w,"left") == 0)
  242.                     outbuf = strapp(outbuf,"\\lfloor");
  243.                 else
  244.                     outbuf = strapp(outbuf,"\\rfloor");
  245.                 }
  246.             else if (strcmp(ww,"nothing") == 0 || ww[0] == '\"')
  247.                 {
  248.                 inbuf += len;
  249.                 *outbuf++ = '.';
  250.                 if (ww[0] == '\"')    inbuf++;
  251.                 }
  252.             else if (*inbuf == '{' || *inbuf == '}')
  253.                 *outbuf++ = '\\';
  254.             }
  255.         else if (strcmp(w,"over") == 0)
  256.             {
  257.             if (!first_word)
  258.                 {
  259.                 outbuf--;
  260.                 for (i=0; *outbuf == ' ' || *outbuf == '\t' ||
  261.                         *outbuf =='\n'; i++)
  262.                     tmp[i] = *outbuf--;
  263.                 if (*outbuf == '}' && put_brace == 0)
  264.                     *outbuf = ' ';
  265.                 else
  266.                     {
  267.                     for (; !(*outbuf == ' ' || *outbuf == '\t'
  268.                     || *outbuf =='\n' || *outbuf == '$'); i++)
  269.                         tmp[i] = *outbuf--;
  270.                     put_brace = 0;
  271.                 *++outbuf = '{';
  272.                     }
  273.                 for (j=i-1; j >= 0; j--)
  274.                     *++outbuf = tmp[j];
  275.             *++outbuf = NULL;
  276.                 }
  277.             outbuf = strapp(outbuf,"\\over");
  278.             inbuf += skip_white(inbuf);
  279.             *outbuf++ = ' ';
  280.             if (*inbuf == '{')
  281.                 inbuf++;
  282.             else
  283.                 {
  284.                 inbuf = get_over_arg(inbuf,ww);
  285.                 outbuf = strapp(outbuf,ww);
  286.                 if (*inbuf != NULL || !first_word)
  287.                     *outbuf++ = '}';
  288.                 }
  289.             }
  290.         else if (strcmp(w,"size") == 0)
  291.             inbuf += get_arg(inbuf,ww,0);
  292.         else if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0 ||
  293.              strcmp(w,"sub") == 0 || strcmp(w,"from") == 0)
  294.             {
  295.             while ((c = *--outbuf) == ' ' || c == '\t' || c == '\n') ;
  296.             *++outbuf = NULL;
  297.             if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0)
  298.                 outbuf = strapp(outbuf,"^");
  299.             else
  300.                 outbuf = strapp(outbuf,"_");
  301.             inbuf += skip_white(inbuf);
  302.             len = get_sub_arg(inbuf,ww);
  303.             inbuf += len;
  304.             if (len > 1)
  305.                 {
  306.                 sprintf(tmp,"{%s}",ww);
  307.                 outbuf = strapp(outbuf,tmp);
  308.                 len = skip_white(inbuf);
  309.                 inbuf += len;
  310.                 (void) getword(inbuf,ww);
  311.                 if (strcmp(ww,"over") == 0)
  312.                     put_brace = 1;
  313.                 inbuf -= len;
  314.                 }
  315.             else
  316.                 outbuf = strapp(outbuf,ww);
  317.             }
  318.         else if (strcmp(w,"up") == 0 || strcmp(w,"down") == 0
  319.              || strcmp(w,"fwd") == 0 || strcmp(w,"back") == 0)
  320.             {
  321.             if (strcmp(w,"up") == 0)
  322.                 {
  323.                 outbuf = strapp(outbuf,"\\raise");
  324.                 strcpy(tmp,"ex");
  325.                 }
  326.             else if (strcmp(w,"down") == 0)
  327.                 {
  328.                 outbuf = strapp(outbuf,"\\lower");
  329.                 strcpy(tmp,"ex");
  330.                 }
  331.             else if (strcmp(w,"fwd") == 0)
  332.                 {
  333.                 outbuf = strapp(outbuf,"\\kern");
  334.                 strcpy(tmp,"em");
  335.                 }
  336.             else if (strcmp(w,"back") == 0)
  337.                 {
  338.                 outbuf = strapp(outbuf,"\\kern-");
  339.                 strcpy(tmp,"em");
  340.                 }
  341.             inbuf += skip_white(inbuf);
  342.             inbuf += getword(inbuf,ww);
  343.             len = atoi(ww);        flen = len/100.;
  344.             ww[0] = NULL;
  345.             sprintf(tmp2,"%4.2f%s",flen,tmp);
  346.             outbuf = strapp(outbuf,tmp2);
  347.             }
  348. /* Now check if the word is a member of a group */
  349.         else if (CAP_GREEK(w) > 0)
  350.             {
  351.             GR_to_Greek(w,ww);
  352.             outbuf = strapp(outbuf,ww);
  353.             }
  354.         else if (is_flip(w) >= 0)
  355.             {
  356.             if (!first_word)
  357.                 {
  358.                 len = skip_white(inbuf);
  359.                 inbuf += len;
  360.                 (void) getword(inbuf,ww);
  361.                 if (is_flip(ww) >= 0)
  362.                     {
  363.                     inbuf += strlen(ww);
  364.                     outbuf = flip_twice(outbuf,w,ww);
  365.                     }
  366.                 else
  367.                     {
  368.                     inbuf -= len;
  369.                     outbuf = flip(outbuf,w);
  370.                     }
  371.                 }
  372.             else
  373.                 {
  374.                 outbuf = strapp(outbuf,"\\");
  375.                 outbuf = strapp(outbuf,w);
  376.                 }
  377.             }
  378.         else if (is_mathcom(w,ww) >=0 )
  379.             outbuf = strapp(outbuf,ww);
  380.         else if (similar(w) > 0)
  381.             {
  382.             outbuf = strapp(outbuf,"\\");
  383.             outbuf = strapp(outbuf,w);
  384.             }
  385.  
  386. /* if none of the above math commands matched, it is an ordinary symbol;
  387.    just copy it */
  388.  
  389.         else    outbuf = strapp(outbuf,w);
  390.         }
  391.  
  392. /* check if it is a math delimiter; switch to math mode if so */
  393.  
  394.     else if (strcmp(w,"$") == 0 && de_arg > 0)
  395.         {
  396.         de_arg++;
  397.         *outbuf++ = '#';
  398.         }
  399.     else if (delim_defd && strcmp(w,DELIM) == 0)
  400.         {
  401.         math_mode = 1;
  402.         *outbuf++ = '$';
  403.         }
  404.     else if (strcmp(w,"$") == 0)
  405.         outbuf = strapp(outbuf,"\\$");
  406.  
  407. /* check if it is a non-math troff command */
  408.  
  409.     else if ((c2 == '.') && !(mid) && (c1 == '\n' || (first_word)))
  410.         {
  411. /* Search in some order; start with non-alphanumeric characters */
  412.         if (strcmp(w,".") == 0)
  413.             {
  414.             c1 = *inbuf;
  415.             c2 = *++inbuf;
  416.             if (c1 == '\\' && c2 == '\"')
  417.                 {
  418.                 ++inbuf;
  419.                 inbuf += get_line(inbuf,ww,0);
  420.                 outbuf = strapp(outbuf,"%");
  421.                 outbuf = strapp(outbuf,ww);
  422.                 }
  423.             else
  424.                 {
  425.                 fprintf(stderr,
  426.                 "I cannot translate troff macro .%c%c\n",c1,c2);
  427.                 inbuf += get_line(inbuf,ww,0);
  428.                 sprintf(tmp,"%%.%c%c",c1,c2);
  429.                 outbuf = strapp(outbuf,tmp);
  430.                 outbuf = strapp(outbuf,ww);
  431.                 if (*inbuf == NULL)    *outbuf++ = '\n';
  432.                 }
  433.             }
  434. /* Now search for commads that start with a capital */
  435.         else if (strcmp(w,".AB") == 0)
  436.             {
  437.             inbuf += get_arg(inbuf,ww,0);
  438.             if (strcmp(ww,"no") == 0)
  439.                 outbuf = strapp(outbuf,"\\bigskip");
  440.             else
  441.                 outbuf = strapp(outbuf,"\\begin{abstract}");
  442.             }
  443.         else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0 ||
  444.              strcmp(w,".I") == 0 || strcmp(w,".it") == 0 ||
  445.              strcmp(w,".R") == 0 || strcmp(w,".rm") == 0)
  446.             {
  447.             if (strcmp(w,".R") == 0 || strcmp(w,".rm") == 0)
  448.                 strcpy(w,"rm");
  449.             else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0)
  450.                 strcpy(w,"bf");
  451.             else
  452.                 strcpy(w,"it");
  453.             inbuf += get_arg(inbuf,ww,1);
  454.             if (ww[0] == NULL)
  455.                 {
  456.                 outbuf = strapp(outbuf,"\\");
  457.                 outbuf = strapp(outbuf,w);
  458.                 }
  459.             else
  460.                 {
  461.                 sprintf(tmp,"{\\%s %s}",w,ww);
  462.                 outbuf = strapp(outbuf,tmp);
  463.                 }
  464.             }
  465.         else if (man && (strcmp(w,".BR") == 0 || strcmp(w,".BI") == 0
  466.              || strcmp(w,".IR") == 0 || strcmp(w,".IB") == 0 ||
  467.              strcmp(w,".RI") == 0 || strcmp(w,".RB") == 0))
  468.             {
  469.             outbuf = alternate(inbuf,outbuf,w);
  470.             inbuf = skip_line(inbuf);
  471.             *outbuf++ = '\n';
  472.             }
  473.         else if (strcmp(w,".BX") == 0)
  474.             {
  475.             inbuf += get_arg(inbuf,ww,1);
  476.             sprintf(tmp,"\\fbox{%s}",ww);
  477.             outbuf = strapp(outbuf,tmp);
  478.             }
  479.         else if (strcmp(w,".EQ") == 0)
  480.             {
  481.             math_mode = 1;
  482.             put_brace = 0;
  483.             outbuf = strapp(outbuf,"$$");
  484.             len = get_arg(inbuf,eqn_no,0);
  485.             if (strcmp(eqn_no,"I") == 0 || strcmp(eqn_no,"L") == 0)
  486.                 {
  487.                 fprintf(stderr,"lineups are ignored\n");
  488.                 inbuf += len;
  489.                 len = get_arg(inbuf,eqn_no,0);
  490.                 }
  491.             if ((strlen(eqn_no)) > 0)
  492.                 inbuf += len;
  493.             len = get_arg(inbuf,tmp,0);
  494.             if (strcmp(tmp,"I") == 0 || strcmp(tmp,"L") == 0)
  495.                 {
  496.                 fprintf(stderr,"lineups are ignored\n");
  497.                 inbuf += len;
  498.                 }
  499.             }
  500.         else if (strcmp(w,".IP") == 0)
  501.             {
  502.             inbuf += get_arg(inbuf,ww,1);
  503.             inbuf = skip_line(inbuf);
  504.             if (IP_stat == 0)
  505.                 outbuf = strapp(outbuf,"\\begin{itemize}\n");
  506.             sprintf(tmp,"\\item[{%s}]\n",ww);
  507.             outbuf = strapp(outbuf,tmp);
  508.             if (de_arg > 0)        mydef[mydef_count].par = 2;
  509.             else            IP_stat = 1;
  510.             }
  511.         else if (strcmp(w,".KE") == 0)
  512.             {
  513.             if (floating)
  514.                 outbuf = strapp(outbuf,"\\end{figure}");
  515.             else
  516.                 outbuf = strapp(outbuf,"}");
  517.             floating = 0;
  518.             }
  519.         else if (strcmp(w,".KF") == 0)
  520.             {
  521.             floating = 1;
  522.             outbuf = strapp(outbuf,"\\begin{figure}");
  523.             }
  524.         else if (strcmp(w,".QP") == 0)
  525.             {
  526.             if (de_arg > 0)        mydef[mydef_count].par = 4;
  527.             else            QP_stat = 1;
  528.             outbuf = strapp(outbuf,"\\begin{quotation}");
  529.             }
  530.         else if (strcmp(w,".RE") == 0)
  531.             {
  532.             RSRE--;
  533.             if (RSRE < 0)
  534.                 fprintf(stderr,".RS with no matching .RE\n");
  535.             sprintf(tmp,"\\ind{%d\\parindent}",RSRE);
  536.             outbuf = strapp(outbuf,tmp);
  537.             }
  538.         else if (strcmp(w,".RS") == 0)
  539.             {
  540.             RSRE++;
  541.             sprintf(tmp,"\\ind{%d\\parindent}",RSRE);
  542.             outbuf = strapp(outbuf,tmp);
  543.             }
  544.         else if (strcmp(w,".Re") == 0)
  545.             {
  546.             if (ref == 0)
  547.                 outbuf = strapp(outbuf,"\\REF\n");
  548.             ref++;
  549.             inbuf = skip_line(inbuf);
  550.             inbuf += get_ref(inbuf,ww);
  551.             sprintf(tmp,"\\reference{%s}",ww);
  552.             outbuf = strapp(outbuf,tmp);
  553.             }
  554.         else if (man && (strcmp(w,".TP") == 0 || strcmp(w,".HP") == 0))
  555.             {
  556.             if (IP_stat && TP_stat)
  557.                 {
  558.                 outbuf = strapp(outbuf,"\\end{itemize}%\n");
  559.                 IP_stat = 0;
  560.                 }
  561.             if (QP_stat && TP_stat)
  562.                 {
  563.                 outbuf = strapp(outbuf,"\\end{quotation}%\n");
  564.                 QP_stat = 0;
  565.                 }
  566.             inbuf = skip_line(inbuf);
  567.             inbuf += get_line(inbuf,ww,1);
  568.             if (TP_stat == 0)
  569.                 {
  570.                 sprintf(tmp,"\\begin{TPlist}{%s}\n",ww);
  571.                 outbuf = strapp(outbuf,tmp);
  572.                 }
  573.             sprintf(tmp,"\\item[{%s}]",ww);
  574.             outbuf = strapp(outbuf,tmp);
  575.             if (de_arg > 0)        mydef[mydef_count].par = 3;
  576.             else            TP_stat = 1;
  577.             }
  578.         else if (man && (strcmp(w,".TH") == 0))
  579.             {
  580. /* expect something like .TH LS 1 "September 4, 1985"*/
  581.             outbuf = strapp(outbuf,"\\phead");
  582.             for (j = 1; j <= 3; ++j)
  583.                 {
  584.                 inbuf += get_arg(inbuf,ww,0);
  585.                 sprintf(tmp,"{%s}",ww);
  586.                 outbuf = strapp(outbuf,tmp);
  587.                 }
  588.             *outbuf++ = '\n';
  589.             }
  590.         else if (strcmp(w,".TS") == 0)
  591.             {
  592.             fprintf(stderr,"I am not very good at tables\n\
  593. I can only do very simple ones. You may need to check what I've done\n");
  594.             inbuf = skip_line(inbuf);
  595.             outbuf = do_table(inbuf,outbuf,&offset);
  596.             inbuf += offset;
  597.             offset = 0;        /* reset */
  598.             }
  599. /* Now search for commands that start with small letters */
  600.         else if (strcmp(w,".TE") == 0)
  601.             {
  602.             fprintf(stderr,"Oops! I goofed. I told you I am not very good at tables.\nI have encountered a table end but I am not in table mode\n");
  603.             }
  604.         else if (strcmp(w,".de") == 0)
  605.             {
  606.             de_arg = 1;
  607.             if (mydef_count >= MAXDEF)
  608.                 {
  609.                 fprintf(stderr,
  610.                     "Too many .de's. MAXDEF=%d\n",MAXDEF);
  611.                 exit(-1);
  612.                 }
  613.             inbuf += skip_white(inbuf);
  614.             inbuf += get_defword(inbuf,w,&illegal);
  615.             inbuf += skip_white(inbuf);
  616.             inbuf += get_mydef(inbuf,ww);
  617.             mydef[mydef_count].arg_no = de_arg;
  618.             if (illegal)
  619.                 {
  620.                 mydef[mydef_count].illegal = 1;
  621.                 fprintf(stderr,
  622.                     "illegal TeX macro, %s, replacing it\n",w);
  623.                 p = (char *)malloc((unsigned)(strlen(ww)+2)*
  624.                     sizeof(char));
  625.                 sprintf(p,"%s",ww);
  626.                 mydef[mydef_count].replace = p;
  627.                 }
  628.             else
  629.                 {
  630.                 mydef[mydef_count].illegal = 0;
  631.                 sprintf(tmp,"\\def\\%s",w);
  632.                 outbuf = strapp(outbuf,tmp);
  633.                 for (j=1; j<de_arg; j++)
  634.                     {
  635.                     sprintf(tmp,"#%d",j);
  636.                     outbuf = strapp(outbuf,tmp);
  637.                     }
  638.                 sprintf(tmp,"{%s}\n",ww);
  639.                 outbuf = strapp(outbuf,tmp);
  640.                 }
  641.             p = (char *)malloc((unsigned)(strlen(w)+2)*sizeof(char));
  642.             sprintf(p,".%s",w);
  643.             mydef[mydef_count++].def_macro = p;
  644.             inbuf = skip_line(inbuf);
  645.             de_arg = 0;
  646.             }
  647.         else if (strcmp(w,".ds") == 0)
  648.             {
  649.             inbuf += get_arg(inbuf,w,0);
  650.             inbuf += skip_white(inbuf);
  651.             inbuf += get_line(inbuf,ww,1);
  652.             if (strcmp(w,"LH") == 0)
  653.                 {
  654.                 sprintf(tmp,"\\lefthead{%s}",ww);
  655.                 outbuf = strapp(outbuf,tmp);
  656.                 }
  657.             else if (strcmp(w,"RH") == 0)
  658.                 {
  659.                 sprintf(tmp,"\\righthead{%s}",ww);
  660.                 outbuf = strapp(outbuf,tmp);
  661.                 }
  662.             else if (strcmp(w,"CF") == 0)
  663.                 {
  664.                 if (index(ww,'%') == 0)
  665.                     {
  666.                     sprintf(tmp,"\\footer{%s}",ww);
  667.                     outbuf = strapp(outbuf,tmp);
  668.                     }
  669.                 else
  670.                     outbuf = strapp(outbuf,
  671.                             "\\footer{\\rm\\thepage}");
  672.                 }
  673.             else
  674.                 {
  675.                 fprintf(stderr,"I do not understand .ds %s\n",w);
  676.                 sprintf(tmp,"%%.ds %s %s",w,ww);
  677.                 outbuf = strapp(outbuf,tmp);
  678.                 }
  679.             }
  680.         else if (strcmp(w,".sp") == 0)
  681.             {
  682.             inbuf += get_arg(inbuf,ww,0);
  683.             (void) get_size(ww,&space);
  684.             sprintf(tmp,"\\par\\vspace{%3.1f%s}",
  685.                 space.value,space.units);
  686.             outbuf = strapp(outbuf,tmp);
  687.             }
  688.         else if (strcmp(w,".in") == 0)
  689.             {
  690.             inbuf += get_arg(inbuf,ww,0);
  691.             (void) get_size(ww,&indent);
  692.             sprintf(tmp,"\\ind{%3.1f%s}",indent.value,indent.units);
  693.             outbuf = strapp(outbuf,tmp);
  694.             }
  695.         else if (strcmp(w,".ls") == 0)
  696.             {
  697.             inbuf += get_arg(inbuf,ww,0);
  698.             (void) get_size(ww,&linespacing);
  699.             sprintf(tmp,"\\baselineskip=%3.1f%s",linespacing.value,
  700.                     linespacing.units);
  701.             outbuf = strapp(outbuf,tmp);
  702.             }
  703.         else if (strcmp(w,".so") == 0)
  704.             {
  705.             inbuf += get_arg(inbuf,ww,0);
  706.             sprintf(tmp,"\\input %s",ww);
  707.             outbuf = strapp(outbuf,tmp);
  708.             }
  709.         else if (strcmp(w,".ti") == 0)
  710.             {
  711.             inbuf += get_arg(inbuf,ww,0);
  712.             tmpind.value = indent.value;
  713.             strcpy(tmpind.units,indent.units);
  714.             (void) get_size(ww,&tmpind);
  715.             sprintf(tmp,"\\tmpind{%3.1f%s}",
  716.                 tmpind.value,tmpind.units);
  717.             outbuf = strapp(outbuf,tmp);
  718.             }
  719.         else if (strcmp(w,".vs") == 0)
  720.             {
  721.             inbuf += get_arg(inbuf,ww,0);
  722.             (void) get_size(ww,&vspace);
  723.             sprintf(tmp,"\\par\\vspace{%3.1f%s}",
  724.                 vspace.value,vspace.units);
  725.             outbuf = strapp(outbuf,tmp);
  726.             }
  727. /* check if it is a member of a group */
  728.         else if (mydef_count > 0 && (i=is_mydef(w)) >= 0)
  729.             {
  730.             if (mydef[i].par > 0)
  731.                 {
  732.                 if (de_arg > 0)
  733.                     mydef[mydef_count].par = mydef[i].par;
  734.                 else
  735.                     {
  736.                     outbuf = end_env(outbuf);
  737.                     outbuf = strapp(outbuf,"\n");
  738.                     }
  739.                 }
  740.             if (mydef[i].illegal)
  741.                 outbuf = strapp(outbuf,mydef[i].replace);
  742.             else
  743.                 {
  744.                 w[0] = '\\';    /* replace dot by backslash */
  745.                 outbuf = strapp(outbuf,w);
  746.                 }
  747.             for (j=1; j <mydef[i].arg_no; j++)
  748.                 {
  749.                 inbuf += get_arg(inbuf,ww,1);
  750.                 sprintf(tmp,"{%s}",ww);
  751.                 outbuf = strapp(outbuf,tmp);
  752.                 }
  753.             if (de_arg == 0)    envoke_stat(mydef[i].par);
  754.             }
  755.         else if ((i=is_troff_mac(w,ww,&arg,&par)) >= 0)
  756.             {
  757.             if (par > 0)
  758.                 {
  759.                 if (de_arg > 0)    mydef[mydef_count].par = par;
  760.                 else        outbuf = end_env(outbuf);
  761.                 }
  762.             outbuf = strapp(outbuf,ww);
  763.             if (ww[0] == NULL)
  764.                 inbuf = skip_line(inbuf);
  765.             if (ww[0] != NULL && arg == 0)
  766.                 {
  767.                 inbuf = skip_line(inbuf);
  768.                 *outbuf++ = '\n';
  769.                 }
  770.             if (arg > 0) 
  771.                 {
  772.                 if (arg == 1)
  773.                     {
  774.                     inbuf += skip_white(inbuf);
  775.                     inbuf += get_string(inbuf,ww,1);
  776.                     }
  777.                 else
  778.                     {
  779.                     if (isupper(w[1]))
  780.                         {
  781.                         inbuf = skip_line(inbuf);
  782.                         inbuf += get_multi_line(inbuf,ww);
  783.                         }
  784.                     else
  785.                         {
  786.                         inbuf += get_arg(inbuf,tmp,0);
  787.                         inbuf = skip_line(inbuf);
  788.                         if (tmp[0] == NULL)    N = 1;
  789.                         else        N = atoi(tmp);
  790.                         inbuf += get_N_lines(inbuf,ww,N);
  791.                         }
  792.                     }
  793.                 sprintf(tmp2,"{%s}",ww);
  794.                 outbuf = strapp(outbuf,tmp2);
  795.                 }
  796.             }
  797. /* if none of the above commands matched, it is either
  798.    an illegal macro or an unknown command */
  799.         else
  800.             {
  801.             len = get_till_space(inbuf,ww);
  802.             sprintf(tmp,"%s%s",w,ww);
  803.             if (mydef_count > 0 && (i=is_mydef(tmp)) >= 0)
  804.                 {
  805.                 inbuf += len;
  806.                 if (mydef[i].par > 0)
  807.                     {
  808.                     if (de_arg > 0)
  809.                         mydef[mydef_count].par=mydef[i].par;
  810.                     else
  811.                         {
  812.                         outbuf = end_env(outbuf);
  813.                         outbuf = strapp(outbuf,"\n");
  814.                         }
  815.                     }
  816.                 outbuf = strapp(outbuf,mydef[i].replace);
  817.                 for (j=1; j <mydef[i].arg_no; j++)
  818.                     {
  819.                     inbuf += get_arg(inbuf,ww,1);
  820.                     sprintf(tmp,"{%s}",ww);
  821.                     outbuf = strapp(outbuf,tmp);
  822.                     }
  823.                 if (de_arg == 0)    envoke_stat(mydef[i].par);
  824.                 }
  825.             else
  826.                 {
  827.                 fprintf(stderr,
  828.                 "I cannot translate troff macro %s\n",w);
  829.                 inbuf += get_line(inbuf,ww,0);
  830.                 outbuf = strapp(outbuf,"%");
  831.                 outbuf = strapp(outbuf,w);
  832.                 outbuf = strapp(outbuf,ww);
  833.                 if (*inbuf == NULL)    *outbuf++ = '\n';
  834.                 }
  835.             }
  836.         }
  837.  
  838. /* some manuals have commented lines beginning with ''' */
  839.     else if ((c2 == '\'') && !(mid) && (c1 == '\n' || (first_word)))
  840.         {
  841.         if (*inbuf == '\'')
  842.             {
  843.             inbuf++;
  844.             if (*inbuf == '\'')
  845.                 {
  846.                 inbuf++;
  847.                 outbuf = strapp(outbuf,"%");
  848.                 }
  849.             else    outbuf = strapp(outbuf,"''");
  850.             }
  851.         else    outbuf = strapp(outbuf,"'");
  852.         }
  853.  
  854. /* See if it is one of these symbols */
  855.  
  856.     else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 ||
  857.          strcmp(w,"{") == 0 || strcmp(w,"}") == 0 ||
  858.          strcmp(w,"%") == 0 || strcmp(w,"_") == 0 ||
  859.          strcmp(w,"~") == 0 || strcmp(w,"^") == 0 )
  860.         {
  861.         outbuf = strapp(outbuf,"\\");
  862.         outbuf = strapp(outbuf,w);
  863.         if (strcmp(w,"~") == 0 || strcmp(w,"^") == 0)
  864.             outbuf = strapp(outbuf,"{}");
  865.         }
  866.  
  867.     else if (strcmp(w,">") == 0 || strcmp(w,"<") == 0 || strcmp(w,"|") == 0)
  868.         {
  869.         sprintf(tmp,"$%s$",w);
  870.         outbuf = strapp(outbuf,tmp);
  871.         }
  872.  
  873. /* check for backslash commands */
  874.  
  875.     else if (strcmp(w,"\\") == 0)
  876.         {
  877.         if (*inbuf == ' ' || *inbuf == '\t' || *inbuf == '\n')
  878.             {
  879.             outbuf = strapp(outbuf,"\\");
  880.             *outbuf++ = *inbuf++;
  881.             }
  882.         else if (*inbuf == NULL)    ;
  883.         else if (*inbuf == '-')
  884.             {
  885.             inbuf++;
  886.             outbuf = strapp(outbuf,"--");
  887.             }
  888.         else if (*inbuf == '~' || *inbuf == '^')
  889.             {
  890.             inbuf++;
  891.             outbuf = strapp(outbuf,"\\/");
  892.             }
  893.         else if (*inbuf == '0')
  894.             {
  895.             inbuf++;
  896.             outbuf = strapp(outbuf,"\\ ");
  897.             }
  898.         else if (*inbuf == 'e')
  899.             {
  900.             inbuf++;
  901.             outbuf = strapp(outbuf,"\\bs ");
  902.             }
  903.         else if (*inbuf == '\\')
  904.             {
  905.             inbuf++;
  906.             if (*inbuf == '$' && de_arg > 0)
  907.                 {
  908.                 inbuf++;
  909.                 de_arg++;
  910.                 *outbuf++ = '#';
  911.                 }
  912.             else
  913.                 outbuf = strapp(outbuf,"\\bs ");
  914.             }
  915.         else if (*inbuf == '`' || *inbuf == '\'')
  916.             ;                /* do nothing */
  917.         else if (*inbuf == '"')
  918.             {
  919.             inbuf++;
  920.             inbuf += get_line(inbuf,ww,0);
  921.             outbuf = strapp(outbuf,"%");
  922.             outbuf = strapp(outbuf,ww);
  923.             }
  924.         else if (*inbuf == '|')
  925.             {
  926.             inbuf++;
  927.             outbuf = strapp(outbuf,"\\,");
  928.             }
  929.         else if (*inbuf == '&')
  930.             inbuf++;
  931.         else if (*inbuf == '(')
  932.             {
  933.             c1 = *++inbuf;
  934.             c2 = *++inbuf;
  935.             inbuf++;
  936.             if (c1 == 'e' && c2 == 'm')
  937.                 outbuf = strapp(outbuf,"---");
  938.             else if (c1 == 'd' && c2 == 'e')
  939.                 outbuf = strapp(outbuf,"$^\\circ$");
  940.             else fprintf(stderr,
  941.                 "I am not prepared to handle \\(%c%c\n",c1,c2);
  942.             }
  943.         else if (*inbuf == 's')
  944.             inbuf +=3;
  945.         else if (*inbuf == '*')
  946.             {
  947.             c1 = *++inbuf;
  948.             inbuf++;
  949.             if (c1 == ':')
  950.                 outbuf = strapp(outbuf,"\\\"");
  951.             else if (c1 == 'C')
  952.                 outbuf = strapp(outbuf,"\\v");
  953.             else if (c1 == ',')
  954.                 outbuf = strapp(outbuf,"\\c");
  955.             else if (c1 != '(')
  956.                 {
  957.                 sprintf(tmp,"\\%c",c1);
  958.                 outbuf = strapp(outbuf,tmp);
  959.                 }
  960.             else
  961.                 {
  962.                 fprintf(stderr,
  963.                 "I am not prepared to handle \\*( cases\n");
  964.                 inbuf += 2;
  965.                 }
  966.             if (c1 != '(')
  967.                 {
  968.                 c1 = *inbuf++;
  969.                 sprintf(tmp,"{%c}",c1);
  970.                 outbuf = strapp(outbuf,tmp);
  971.                 }
  972.             }
  973.         else if (*inbuf == 'f')
  974.             {
  975.             c1 = *++inbuf;
  976.             inbuf++;
  977.             if (c1 == '1' || c1 == 'R')
  978.                 {
  979.                 lastfont = thisfont;
  980.                 thisfont = 1;
  981.                 if (*inbuf == ' ' || *inbuf == '\t' ||
  982.                     *inbuf == '\n' || *inbuf == '\f')
  983.                     {*outbuf++ = ' ';    inbuf++;}
  984.                 outbuf = strapp(outbuf,"%\n\\rm ");
  985.                 }
  986.             else if (c1 == '2' || c1 == 'I')
  987.                 {
  988.                 lastfont = thisfont;
  989.                 thisfont = 2;
  990.                 if (*inbuf == ' ' || *inbuf == '\t' ||
  991.                     *inbuf == '\n' || *inbuf == '\f')
  992.                     {*outbuf++ = ' ';    inbuf++;}
  993.                 outbuf = strapp(outbuf,"%\n\\it ");
  994.                 }
  995.             else if (c1 == '3' || c1 == 'B')
  996.                 {
  997.                 lastfont = thisfont;
  998.                 thisfont = 3;
  999.                 if (*inbuf == ' ' || *inbuf == '\t' ||
  1000.                     *inbuf == '\n' || *inbuf == '\f')
  1001.                     {*outbuf++ = ' ';    inbuf++;}
  1002.                 outbuf = strapp(outbuf,"%\n\\bf ");
  1003.                 }
  1004.             else if (c1 == 'P')
  1005.                 {
  1006. /* preserve white space - from Nelson Beebe  */
  1007.                 if (*inbuf == ' ' || *inbuf == '\t' ||
  1008.                     *inbuf == '\n' || *inbuf == '\f')
  1009.                     {*outbuf++ = ' ';    inbuf++;}
  1010.                 switch(lastfont)
  1011.                     {
  1012.                     case 1:
  1013.                         outbuf = strapp(outbuf,"\\rm%\n");
  1014.                         thisfont = 1;
  1015.                         break;
  1016.                     case 2:
  1017.                         outbuf = strapp(outbuf,"\\it%\n");
  1018.                         thisfont = 2;
  1019.                         break;
  1020.                     case 3:
  1021.                         outbuf = strapp(outbuf,"\\bf%\n");
  1022.                         thisfont = 3;
  1023.                         break;
  1024.                     default:
  1025.                         outbuf = strapp(outbuf,"\\rm%\n");
  1026.                         thisfont = 1;
  1027.                         break;
  1028.                     }
  1029.                 }
  1030.             else fprintf(stderr,
  1031.                 "I do not understand \\f%c yet\n",c1);
  1032.             }
  1033.         else
  1034.             {
  1035.             fprintf(stderr,"I am not prepared to handle \\%c\n",*inbuf);
  1036.             inbuf++;
  1037.             }
  1038.         }
  1039.  
  1040. /* if non of the above checks, its a dull word; copy it */
  1041.  
  1042.     else
  1043.         outbuf = strapp(outbuf,w);
  1044.     *outbuf = NULL;    ww[0] = NULL;  tmp[0] = NULL;    tmp2[0] = NULL;
  1045.     if (!no_word)    first_word = 0;
  1046.     }
  1047. /* if file end, close opened environments and delimitters */
  1048. if (rec == 0)
  1049.     {
  1050.     if (IP_stat)    outbuf = strapp(outbuf,"\\end{itemize}\n");
  1051.     if (QP_stat)    outbuf = strapp(outbuf,"\\end{quotation}\n");
  1052.     if (TP_stat)    outbuf = strapp(outbuf,"\\end{TPlist}\n");
  1053.     }
  1054.  
  1055. *outbuf = NULL;
  1056. }
  1057.