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