home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / tr2latex_2 / c / subs next >
Encoding:
Text File  |  1992-04-27  |  19.8 KB  |  1,146 lines

  1. /*
  2. ** tr2latex - troff to LaTeX converter
  3. ** $Id: subs.c,v 2.2 1992/04/27 15:13:26 Christian_Engel Dist krischan $
  4. ** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel
  5. ** 
  6. ** Module: subs.c
  7. ** 
  8. ** These subroutines do (in general) small things for the translator.
  9. ** They appear in alphabetical order and their names are unique in the
  10. ** first six characters.
  11. */
  12.  
  13. #include    "setups.h"
  14. #include    "protos.h"
  15. #include    "simil.h"
  16. #include    "greek.h"
  17. #include    "flip.h"
  18. #include    "forbid.h"
  19. #include    "maths.h"
  20. #include    "macros.h"
  21.  
  22. extern def_count;
  23. extern mydef_count;
  24.  
  25. /* compile-time counting of elements */
  26. int GRK_count = (sizeof(GRK_list)/sizeof(GRK_list[0]));
  27. int sim_count = (sizeof(sim_list)/sizeof(sim_list[0]));
  28. int flip_count = (sizeof(flip_list)/sizeof(flip_list[0]));
  29. int forbd_count = (sizeof(forbid)/sizeof(forbid[0]));
  30. int mathcom_count = (sizeof(math)/sizeof(struct math_equiv));
  31. int macro_count = (sizeof(macro)/sizeof(struct macro_table));
  32.     
  33. /*
  34. ** alternate fonts (manual macro)
  35. */
  36. char *alternate (char *pin, char *pout, char *w)
  37. {
  38.     int which = 1;
  39.     char font[MAXWORD], font1[MAXWORD], font2[MAXWORD],
  40.          ww[MAXWORD], tmp[MAXWORD];
  41.     
  42.     tmp[0] = EOS;
  43.     switch (w[1]) {
  44.     case 'R':    strcpy (font1,"\\rm"); break;
  45.     case 'I':    strcpy (font1,"\\it"); break;
  46.     case 'B':    strcpy (font1,"\\bf"); break;
  47.     }
  48.     switch (w[2]) {
  49.     case 'R':    strcpy (font2,"\\rm"); break;
  50.     case 'I':    strcpy (font2,"\\it"); break;
  51.     case 'B':    strcpy (font2,"\\bf"); break;
  52.     }
  53.     
  54.     strcpy (font, font1);
  55.     while (*pin != '\n' && *pin != EOS) {
  56.         pin += get_arg (pin, ww, 1);
  57.         if (which == 1) {
  58.             sprintf(tmp,"{%s %s}", font1, ww);
  59.             which = 2;
  60.         }
  61.         else {
  62.             sprintf (tmp,"{%s %s}", font2, ww);
  63.             which = 1;
  64.         }
  65.         pout = strapp (pout, tmp);
  66.         while (*pin == ' ' || *pin == '\t')
  67.             pin++;
  68.     }
  69.     return (pout);
  70. }
  71.  
  72.  
  73.  
  74. /*
  75. ** check if w is in the GREEK list
  76. */
  77. int CAP_GREEK (char *w)
  78. {
  79.     int i;
  80.     
  81.     for (i = 0; i < GRK_count; i++) {
  82.         if (strcmp (GRK_list[i], w) == 0)
  83.             return (1);
  84.     }
  85.     return (-1);
  86. }
  87.  
  88.  
  89. /*
  90. ** translate table
  91. ** arguments:
  92. **  pin
  93. **  pout
  94. **    offset    amount to offset pin
  95. */
  96. char *do_table (char *pin, char *pout, int *offset)
  97. {
  98.     char w [MAXWORD], ww [MAXWORD], format [MAXWORD], tmp [MAXWORD];
  99.     char *ptr;
  100.     int i, len, columns=0;
  101.     int tab = '\t';                        /* default tab */
  102.     
  103.     tmp[0] = EOS;
  104.     ptr = pin;                            /* remember where we started */
  105.     len = get_line (pin, w, 0);
  106.     if (w [strlen (w) - 1] == ';') {    /* options */
  107.         pin += len;
  108.         if (strncmp (w, "tab", 3) == 0)    /* get the tab charecter */
  109.             tab = w[4];        /* expect something like tab(&); */
  110.         pin = skip_line(pin);
  111.     }
  112.     while (*pin != EOS) {                /* get the LAST format line */
  113.         len = get_line (pin, w, 0);
  114.         if (w[strlen (w) - 1] != '.')    /* not a format line */
  115.             break;
  116.         pin += len;
  117.         for (i = 0; i < len - 1; i++) {
  118.             if (isspace (w[i]))
  119.                 continue;
  120.             if (w[i] == 'l')
  121.                 format[columns] = 'l';
  122.             else if (w[i] == 'r')
  123.                 format[columns] = 'r';
  124.             else
  125.                 format[columns] = 'c';
  126.             columns++;
  127.         }
  128.     }
  129.     if (columns == 0) {
  130.         fprintf (stderr, "Sorry, I cannot do tables without a format line\n\
  131. Doing plain translation of table, lines will be commented\n\
  132. You need to fix it yourself\n");
  133.         while (*pin != EOS) {
  134.             (void) getword (pin, w);
  135.             if (strcmp (w,".TE") ==  0) {
  136.                 pin += 4;
  137.                 break;
  138.             }
  139.             pin += get_line (pin, w, 1);
  140.             *pout++ = '%';
  141.             pout = strapp (pout, w);
  142.             pout = strapp (pout, "\n");
  143.             pin++;        /* skip the \n */
  144.         }
  145.         *offset = pin - ptr;
  146.         return (pout);
  147.     }
  148.     format[columns] = EOS;
  149.     sprintf (tmp, "\\par\n\\begin{tabular}{%s}\n",format);
  150.     pout = strapp (pout, tmp);
  151.     
  152.     while (*pin != EOS) {
  153.         for (i = 0; i < columns - 1; i++) {
  154.             (void) getword (pin, w);
  155.             if (i == 0 && (strcmp (w, "\n") == 0 || strcmp (w, "_") == 0)) {
  156.                 pin++;
  157.                 i--;
  158.                 continue;
  159.             }
  160.             if (strcmp (w, ".TE") == 0) {
  161.                 pin += 4;
  162.                 if (i == 0) {
  163.                     pout -= 3;    /* take back the \\ and the \n */
  164.                     *pout = EOS;
  165.                 }
  166.                 pout = strapp(pout,"\n\\end{tabular}\n\\par\n");
  167.                 *offset = pin - ptr;
  168.                 return (pout);
  169.             }
  170.             pin += get_table_entry(pin,w,tab);
  171.             pin ++;        /* skip tab */
  172.             troff_tex(w,ww,0,1);
  173.             sprintf(tmp,"%s & ",ww);
  174.             pout = strapp(pout,tmp);
  175.         }
  176.         (void) getword (pin,w);
  177.         if (strcmp(w,".TE") == 0) {
  178.             fprintf(stderr,"Oops! I goofed. I told I you I am not very good at tables\nI've encountered an unexpected end for the table\n\
  179. You need to fix it yourself\n");
  180.             pin += 4;
  181.             pout = strapp(pout,"\\end{tabular}\n\\par\n");
  182.             *offset = pin - ptr;
  183.             return(pout);
  184.         }
  185.         pin += get_table_entry(pin,w,'\n');
  186.         pin++;        /* skip tab */
  187.         troff_tex(w,ww,0,1);
  188.         pout = strapp (pout, ww);
  189.         pout = strapp (pout, "\\\\\n");
  190.     }
  191.     fprintf (stderr, "Oops! I goofed. I told I you I am not very good at tables\n\
  192. File ended and I haven't finished the table!\n\
  193. You need to fix it yourself\n");
  194.     *offset = pin - ptr;
  195.     pout = strapp (pout, "\\end{tabular}\n\\par\n");
  196.     return (pout);
  197. }
  198.  
  199.  
  200.  
  201. /*
  202. ** end current environment
  203. */
  204. char *end_env (char *pout)
  205. {
  206.     if (IP_stat) {
  207.         IP_stat = 0;
  208.         pout = strapp (pout, "\\end{IPlist}");
  209.     }
  210.     if (QP_stat) {
  211.         QP_stat = 0;
  212.         pout = strapp (pout, "\\end{quotation}");
  213.     }
  214.     if (TP_stat) {
  215.         TP_stat = 0;
  216.         pout = strapp (pout, "\\end{TPlist}");
  217.     }
  218.     return(pout);
  219. }
  220.  
  221.  
  222. /*
  223. ** set flag for current environment
  224. */
  225. void envoke_stat (int par)
  226. {
  227.     
  228.     switch(par) {
  229.     case 2:
  230.         IP_stat = 1;
  231.         break;
  232.     case 3:
  233.         TP_stat = 1;
  234.         break;
  235.     case 4:
  236.         QP_stat = 1;
  237.         break;
  238.     default:
  239.         break;
  240.     }
  241. }
  242.  
  243.  
  244.  
  245. /*
  246. ** do the flipping
  247. */
  248. char * flip (char *pout, char *w)
  249. {
  250.     int lb=0, rb=0;
  251.     char ww[MAXWORD], tmp[MAXWORD];
  252.     
  253.     ww[0] = EOS;
  254.     tmp[0] = EOS;
  255.     pout--;
  256.     while (isspace (*pout))
  257.         pout--;
  258.     while (1) {
  259.         if (*pout == '{') {
  260.             lb++;
  261.             if (lb > rb)
  262.                 break;
  263.         }
  264.         if (*pout == '}')
  265.             rb++;
  266.         if (rb == 0) {
  267.             if (! isspace (*pout) && *pout != '$') {
  268.                 pout--;
  269.                 continue;
  270.             }
  271.             else
  272.                 break;
  273.         }
  274.         pout--;
  275.         if (lb == rb && lb != 0)
  276.             break;
  277.     }
  278.     pout++;
  279.     if (*pout == '\\') {
  280.         pout++;
  281.         (void) getword (pout, tmp);
  282.         sprintf (ww, "\\%s", tmp);
  283.         pout--;
  284.     }
  285.     else if (*pout == '{')
  286.         (void) get_brace_arg (pout, ww);
  287.     else
  288.         (void) getword (pout, ww);
  289.     *pout = EOS;
  290.     sprintf (tmp,"\\%s %s", w, ww);
  291.     pout = strapp (pout, tmp);
  292.     return (pout);
  293. }
  294.  
  295.  
  296.  
  297. /*
  298. ** take care of things like x hat under
  299. */
  300. char * flip_twice (char *pout, char *w, char *ww)
  301. {
  302.     int lb=0, rb=0;
  303.     char tmp1[MAXWORD], tmp2[MAXWORD];
  304.     
  305.     tmp1[0] = EOS;        tmp2[0] = EOS;
  306.     pout--;
  307.     while (*pout == ' ' || *pout == '\t' || *pout == '\n')
  308.         pout--;
  309.     while (1) {
  310.         if (*pout == '{') {
  311.             lb++;
  312.             if (lb > rb)
  313.                 break;
  314.         }
  315.         if (*pout == '}')
  316.             rb++;
  317.         if (rb == 0) {
  318.             if (! isspace (*pout) && *pout != '$') {
  319.                 pout--;
  320.                 continue;
  321.             }
  322.             else
  323.                 break;
  324.         }
  325.         pout--;
  326.         if (lb == rb && lb != 0)
  327.             break;
  328.     }
  329.     pout++;
  330.     if (*pout == '\\') {
  331.         pout++;
  332.         (void) getword(pout,tmp2);
  333.         sprintf(tmp1,"\\%s",tmp2);
  334.         pout--;
  335.     }
  336.     else if (*pout == '{')
  337.         (void) get_brace_arg(pout,tmp1);
  338.     else
  339.         (void) getword(pout,tmp1);
  340.     *pout = EOS;
  341.     sprintf(tmp2,"\\%s{\\%s %s}",w,ww,tmp1);
  342.     pout = strapp(pout,tmp2);
  343.     return(pout);
  344. }
  345.  
  346.  
  347.  
  348. /*
  349. ** get argument
  350. ** arguments:
  351. **  rec=1 means recursive 
  352. */
  353. int    get_arg (register char *pin, char *w, int rec)
  354. {
  355.     int c,len,i;
  356.     char ww[MAXWORD];
  357.     int delim;
  358.     
  359.     len=0;
  360.     while ((c = *pin) == ' ' || c == '\t') {    /* skip spaces and tabs */
  361.         pin++;
  362.         len++;
  363.     }
  364.     i=0;
  365.     if (*pin == '{' || *pin == '\"') {
  366.         if (*pin == '{')
  367.             delim = '}';
  368.         else
  369.             delim = '\"';
  370.         pin++;
  371.         len++;
  372.         while ((c = *pin++) != EOS && c != delim && i < MAXWORD) {
  373.             if (c == ' ' && delim == '\"')
  374.                 ww[i++] = '\\';
  375.             ww[i++] = (char)c;
  376.             len++;
  377.         }
  378.         len++;
  379.     }
  380.     else {
  381.         while ((c = *pin++) != EOS && !isspace(c)
  382.                /* && c != '$' && c != '}' */ && i < MAXWORD) {
  383.             if (math_mode && c == '~')
  384.                 break;
  385.             ww[i++] = (char)c;
  386.             len++;
  387.         }
  388.     }
  389.     ww[i] = EOS;
  390.     if (rec == 1)                /* check if recursion is required */
  391.         troff_tex(ww,w,1,1);
  392.     else
  393.         strcpy(w,ww);
  394.     return(len);
  395. }
  396.  
  397.  
  398. /*
  399. ** get all arguments
  400. ** arguments:
  401. **  rec=1 means recursive
  402. */
  403. int    get_allargs (register char *pin, char ***ppw, int rec)
  404. {
  405.     int c, i;
  406.     static char *ww [MAXARGS];
  407.     char w [MAXWORD], *instart;
  408.     int nww;
  409.     int delim;
  410.  
  411.     instart = pin;
  412.     for (nww = 0; ; nww++) {
  413.         while ((c = *pin) == ' ' || c == '\t')    /* skip spaces and tabs */
  414.             pin++;
  415.         if (c == '\n') {
  416.             pin++;
  417.             ww [nww] = EOS;
  418.             break;
  419.         }
  420.         ww [nww] = pin;
  421.         i=0;
  422.         if (*pin == '{' || *pin == '\"') {
  423.             if (*pin == '{')
  424.                 delim = '}';
  425.             else
  426.                 delim = '\"';
  427.             ww [nww] = ++pin;
  428.             while ((c = *pin++) != EOS && c != delim && i < MAXWORD)
  429.                 /* EMPTY */
  430.                 ;
  431.             pin [-1] = EOS;
  432.         }
  433.         else {
  434.             while ((c = *pin++) != EOS && !isspace(c)
  435.                    /* && c != '$' && c != '}' */ && i < MAXWORD) {
  436.                 if (math_mode && c == '~')
  437.                     break;
  438.             }
  439.             pin [-1] = EOS;
  440.             if (c == '\n') {
  441.                 ww [nww + 1] = EOS;
  442.                 break;
  443.             }
  444.         }
  445.     }
  446.     if (rec == 1) {                /* check if recursion is required */
  447.         for (i = 0; ww [i]; i++) {
  448.             if (ww [i] && *ww [i]) {
  449.                 troff_tex (ww [i], w, 1, 1);
  450.                 if (strcmp (ww [i], w) != 0)
  451.                     ww [i] = strsave (w);
  452.             }
  453.         }
  454.     }
  455.     *ppw = ww;
  456.     return (pin - instart);
  457. }
  458.  
  459.  
  460.  
  461.  
  462. /*
  463. ** get argument surrounded by braces
  464. */
  465. void get_brace_arg (char *buf, char *w)
  466. {
  467.     int c,i, lb=0, rb=0;
  468.     
  469.     i=0;
  470.     while ((c = *buf++) != EOS) {
  471.         w[i++] = (char)c;
  472.         if (c == '{')    lb++;
  473.         if (c == '}')    rb++;
  474.         if (lb == rb)    break;
  475.     }
  476.     w[i] = EOS;
  477. }
  478.  
  479. /*
  480. ** get "define" or .de word
  481. ** arguments:
  482. **  pin    delimited by space only
  483. **  w      delimited by space only
  484. */
  485. int get_defword (char *pin, char *w, int *illegal)
  486. {
  487.     int c,i;
  488.     
  489.     *illegal = 0;
  490.     for (i=0; (c = *pin++) != EOS && !isspace (c) && i < MAXWORD; i++) {
  491.         w[i] = (char)c;
  492.         if (isalpha(c) == 0)
  493.             *illegal = 1;    /* illegal TeX macro */ 
  494.     }
  495.     w[i] = EOS;
  496.     if (*illegal == 0 && is_forbid(w) >= 0)
  497.         *illegal=1;
  498.     return(i);
  499. }
  500.  
  501.  
  502. /*
  503. ** get the rest of the line
  504. ** arguments:
  505. **  rec=1 means recursion is required
  506. */
  507. int get_line (char *pin, char *w, int rec)
  508. {
  509.     int c,i,len;
  510.     char ww[MAXLINE];
  511.     
  512.     i=0;
  513.     len=0;
  514.     while ((c = *pin++) != EOS && c != '\n' && len < MAXLINE) {
  515.         ww[i++] = (char)c;
  516.         len++;
  517.     }
  518.     ww[i] = EOS;
  519.     if (rec == 1)
  520.         troff_tex(ww,w,0,1);
  521.     else
  522.         strcpy(w,ww);
  523.     return(len);
  524. }
  525.  
  526.  
  527. /*
  528. ** get multi-line argument
  529. */
  530. int get_multi_line (char *pin, char *w)
  531. {
  532.     int len=0,l=0,lines=0;
  533.     char tmp[MAXWORD];
  534.     int c1,c2;
  535.     
  536.     w[0] = EOS;    tmp[0] = EOS;
  537.     while (*pin != EOS) {
  538.         c1 = *pin;
  539.         c2 = *++pin;
  540.         --pin;
  541.         if (c1 == '.' && isupper(c2))
  542.             break; 
  543.         lines++;
  544.         if (lines > 1)
  545.             strcat(w," \\\\\n");
  546.         l = get_line(pin,tmp,1);
  547.         strcat(w,tmp);
  548.         len += l+1;
  549.         pin += l+1;
  550.     }
  551.     len--;
  552.     pin--;
  553.     return(len);
  554. }
  555.  
  556.  
  557. /*
  558. ** get the macro substitution
  559. */
  560. int get_mydef (char *pin, char *w)
  561. {
  562.     int c1,c2,l,len;
  563.     char tmp[MAXWORD];
  564.     
  565.     tmp[0] = EOS;
  566.     len=1;
  567.     while (*pin != EOS) {
  568.         c1 = *pin;
  569.         c2 = *++pin;
  570.         --pin;
  571.         if (c1 == '.' && c2 == '.')
  572.             break; 
  573.         l = get_line(pin,tmp,1);
  574.         strcat(w,tmp);
  575.         len += l+1;
  576.         pin += l+1;
  577.     }
  578.     return(len);
  579. }
  580.  
  581.  
  582. /*
  583. ** get N lines
  584. */
  585. int get_N_lines (char *pin, char *w, int N)
  586. {
  587.     int len=0,l=0,lines=0;
  588.     char tmp[MAXWORD];
  589.     
  590.     w[0] = EOS;    tmp[0] = EOS;
  591.     while (*pin != EOS && lines < N) {
  592.         lines++;
  593.         if (lines > 1)
  594.             strcat(w," \\\\\n");
  595.         l = get_line(pin,tmp,1);
  596.         strcat(w,tmp);
  597.         len += l+1;
  598.         pin += l+1;
  599.     }
  600.     len--;
  601.     pin--;
  602.     return(len);
  603. }
  604.  
  605.  
  606. /*
  607. ** get text surrounded by quotes in math mode
  608. */
  609. int get_no_math (char *pin, char *w)
  610. {
  611.     int c,i,len;
  612.     
  613.     len = 0;
  614.     for (i=0; (c = *pin++) != EOS && c != '\"' && i < MAXWORD; i++) {
  615.         if (c == '{' || c == '}') {
  616.             w[i] = '\\';
  617.             w[++i] = (char)c;
  618.         }
  619.         else
  620.             w[i] = (char)c;
  621.         len++;
  622.     }
  623.     w[i] = EOS;
  624.     return(len);
  625. }
  626.  
  627.  
  628. /*
  629. ** get the denominator of over
  630. */
  631. char *get_over_arg (char *pin, char *ww)
  632. {
  633.     char w[MAXWORD], tmp1[MAXWORD], tmp2[MAXWORD];
  634.     int len;
  635.     
  636.     w[0] = EOS;
  637.     tmp1[0] = EOS;
  638.     tmp2[0] = EOS;
  639.     pin += getword (pin,tmp1);        /* read first word */
  640.     pin += skip_white (pin);
  641.     len = getword (pin, tmp2);        /* read second word */
  642.     strcat(w,tmp1);    strcat(w," ");
  643.     
  644.     /* as long as there is a sup or sub read the next two words */
  645.     while (strcmp (tmp2, "sub") == 0 || strcmp (tmp2, "sup") == 0) {
  646.         pin += len;
  647.         strcat (w, tmp2);
  648.         strcat (w, " ");
  649.         pin += skip_white (pin);
  650.         pin += getword (pin, tmp1);
  651.         strcat (w, tmp1);
  652.         strcat (w, " ");
  653.         pin += skip_white (pin);
  654.         len = getword (pin, tmp2);
  655.     }
  656.     troff_tex (w, ww, 0, 1);
  657.     return (pin);
  658. }
  659.  
  660.  
  661.  
  662. /*
  663. ** get reference
  664. */
  665. int get_ref (char *pin, char *w)
  666. {
  667.     int len=0, l=0, lines=0;
  668.     char tmp[MAXWORD];
  669.     
  670.     w[0] = EOS;    tmp[0] = EOS;
  671.     while (*pin != EOS) {
  672.         if (*pin == '\n')
  673.             break;
  674.         (void) getword(pin,tmp);
  675.         if (tmp[0] == '.' && isupper(tmp[1])) {
  676.             /* these commands don't cause a break in reference */
  677.             if (strcmp (tmp, ".R") != 0 && strcmp (tmp, ".I") != 0
  678.                 && strcmp(tmp,".B") != 0)
  679.                 break; 
  680.         }
  681.         else if (tmp[0] == '.' && !(isupper(tmp[1]))) {
  682.             /* these commands don't cause a break in reference */
  683.             if (strcmp (tmp, ".br") != 0 && strcmp (tmp, ".bp") != 0)
  684.                 break; 
  685.         }
  686.         l = get_line (pin, tmp, 1);
  687.         lines++;
  688.         if (lines > 1)
  689.             strcat (w, " ");
  690.         strcat (w, tmp);
  691.         len += l+1;
  692.         pin += l+1;
  693.     }
  694.     len--;
  695.     pin--;
  696.     return (len);
  697. }
  698.  
  699.  
  700. /*
  701. **
  702. */
  703. void get_size (char *ww, struct measure *PARAMETER)
  704. {
  705.     int sign=0, units=0;
  706.     float value;
  707.     
  708.     if (ww[0] == EOS) {
  709.         if (PARAMETER->def_value == 0) {
  710.             PARAMETER->value = PARAMETER->old_value;
  711.             strcpy(PARAMETER->units,PARAMETER->old_units);
  712.         }
  713.         else {
  714.             PARAMETER->value = PARAMETER->def_value;
  715.             strcpy(PARAMETER->units,PARAMETER->def_units);
  716.         }
  717.     }
  718.     else {
  719.         PARAMETER->old_value = PARAMETER->value;
  720.         strcpy (PARAMETER->old_units, PARAMETER->units);
  721.  
  722.         parse_units (ww, &sign, &units, &value);
  723.  
  724.         if (units == 'p')
  725.             strcpy (PARAMETER->units, "pt");
  726.         else if (units == 'i')
  727.             strcpy (PARAMETER->units, "in");
  728.         else if (units == 'c')
  729.             strcpy (PARAMETER->units, "cm");
  730.         else if (units == 'm')
  731.             strcpy (PARAMETER->units, "em");
  732.         else if (units == 'n') {
  733.             value = .5*value;    /* n is about half the width of m */
  734.             strcpy (PARAMETER->units, "em");
  735.         }
  736.         else if (units == 'v')
  737.             strcpy(PARAMETER->units,"ex");
  738.         else if (units == 0) {
  739.             if (sign == 0 || PARAMETER->old_units[0] == EOS)
  740.                 strcpy(PARAMETER->units,PARAMETER->def_units);
  741.             else
  742.                 strcpy(PARAMETER->units,PARAMETER->old_units);
  743.         }
  744.         else {
  745.             fprintf(stderr,"unknown units %c, using default units\n", units);
  746.             strcpy(PARAMETER->units,PARAMETER->def_units);
  747.         }
  748.         if (sign == 0)
  749.             PARAMETER->value = value;
  750.         else
  751.             PARAMETER->value = PARAMETER->old_value + sign*value;
  752.     }
  753. }
  754.  
  755.  
  756.  
  757. /*
  758. ** get the rest of the line -- Nelson Beebe
  759. ** arguments:
  760. **  rec=1 means recursion is required
  761. */
  762. int get_string (char *pin, char *w, int rec)
  763. {
  764.     register int c,i,len;
  765.     char ww[MAXLINE];
  766.     register char *start;
  767.     
  768.     if (*pin != '\"')
  769.         return(get_line(pin,w,rec));
  770.     start = pin;                /* remember start so we can find len */
  771.     i=0;
  772.     pin++;                        /* point past initial quote */
  773.     while ((c = *pin++) != EOS && c != '\"' && c != '\n' && i < MAXLINE)
  774.         ww[i++] = (char)c;
  775.     ww[i] = EOS;
  776.     if (c != '\n')                /* flush remainder of line */
  777.         while ((c = *pin++) != '\n')
  778.         /* EMPTY */
  779.             ;
  780.     len = pin - start - 1;        /* count only up to NL, not past */
  781.     if (rec == 1)
  782.         troff_tex(ww,w,0,1);
  783.     else
  784.         strcpy(w,ww);
  785.     return(len);
  786. }
  787.  
  788.  
  789.  
  790. /*
  791. ** get the argument for sub and sup
  792. */
  793. int get_sub_arg (char *pin, char *w)
  794. {
  795.     int c,len,i;
  796.     char ww[MAXWORD], tmp[MAXWORD];
  797.     
  798.     len=0;    tmp[0] = EOS;
  799.     while ((c = *pin) == ' ' || c == '\t') {
  800.         pin++;
  801.         len++;
  802.     }
  803.     i=0;
  804.     while ((c = *pin++) != EOS && c != ' ' && c != '\t' && c != '\n'
  805.            && c != '$' && c != '}' && c != '~' && i < MAXWORD) {
  806.         ww[i++] = (char)c;
  807.         len++;
  808.     }
  809.     ww[i] = EOS;
  810.     if (strcmp(ww,"roman") == 0  || strcmp(ww,"bold") == 0
  811.         || strcmp(w,"italic") == 0) {
  812.         (void) get_arg(pin,tmp,0);
  813.         sprintf(ww,"%s%c%s",ww,c,tmp);
  814.         len += strlen(tmp)+1;
  815.     }
  816.     troff_tex(ww,w,0,1);        /* recursive */
  817.     return(len);
  818. }
  819.  
  820.  
  821. /*
  822. **
  823. */
  824. int    get_table_entry (char *pin, char *w, int tab)
  825. {
  826.     int c, i=0;
  827.     
  828.     for (i=0; (c = *pin++) != EOS && c != tab && i < MAXWORD; i++)
  829.         w[i] = (char)c;
  830.     w[i] = EOS;
  831.     
  832.     return(i);
  833. }
  834.  
  835.  
  836.  
  837. /*
  838. ** get characters till the next space
  839. */
  840. int get_till_space (char *pin, char *w)
  841. {
  842.     int c,i;
  843.     
  844.     for (i=0; (c = *pin++) != EOS && c != ' ' && c != '\n'
  845.          && c != '\t' && i < MAXWORD; i++)
  846.         w[i] = (char)c;
  847.     w[i] = EOS;
  848.     return(i);
  849. }
  850.  
  851.  
  852.  
  853. /*
  854. ** get the define substitution
  855. */
  856. int getdef (char *pin, char *ww)
  857. {
  858.     int c,i,len;
  859.     int def_delim;
  860.     char w[MAXWORD];
  861.     
  862.     def_delim = *pin++;        /* take first character as delimiter */
  863.     len=1;
  864.     i=0;
  865.     while ((c = *pin++) != EOS && c != def_delim && i < MAXWORD) {
  866.         len++;
  867.         w[i++] = (char)c;
  868.     }
  869.     w[i] = EOS;
  870.     len++;
  871.     if (c != def_delim) {
  872.         fprintf(stderr,
  873.                 "WARNING: missing right delimiter in define, define=%s\n",w);
  874.         len--;
  875.     }
  876.     troff_tex(w,ww,0,1);        /* now translate the substitution */
  877.     return(len);
  878. }
  879.  
  880.  
  881.  
  882. /*
  883. ** get an alphanumeric word (dot also)
  884. */
  885. int getword (char *pin, char *w)
  886. {
  887.     int c,i;
  888.     
  889.     for (i=0; (c = *pin++) != EOS
  890.          && (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++)
  891.         w[i] = (char)c;
  892.     if (i == 0 && c != EOS)
  893.         w[i++] = (char)c;
  894.     w[i] = EOS;
  895.     return(i);
  896. }
  897.  
  898.  
  899.  
  900. /*
  901. ** change GREEK to Greek
  902. */
  903. void GR_to_Greek (char *w, char *ww)
  904. {
  905.     *ww++ = '\\';
  906.     *ww++ = *w;
  907.     while(*++w != EOS)
  908.         *ww++ = tolower(*w);
  909.     *ww = EOS;
  910. }
  911.  
  912.  
  913.  
  914. /*
  915. ** check if w was defined by the user
  916. */
  917. int is_def (char *w)
  918. {
  919.     int i;
  920.     
  921.     for (i=0; i < def_count; i++) {
  922.         if (strcmp(def[i].def_macro,w) == 0)
  923.             return(i);
  924.     }
  925.     return(-1);
  926. }
  927.  
  928.  
  929.  
  930. /*
  931. ** check if w is in the flip list
  932. */
  933. int is_flip (char *w)
  934. {
  935.     int i;
  936.     
  937.     for (i=0; i < flip_count; i++) {
  938.         if (strcmp(flip_list[i],w) == 0)
  939.             return(i);
  940.     }
  941.     return(-1);
  942. }
  943.  
  944.  
  945.  
  946. /*
  947. ** check if w is one of those sacred macros
  948. */
  949. int is_forbid (char *w)
  950. {
  951.     int i;
  952.     
  953.     for (i=0; i < forbd_count; i++) {
  954.         if (strcmp(forbid[i],w) == 0)
  955.             return(i);
  956.     }
  957.     return(-1);
  958. }
  959.  
  960.  
  961.  
  962. /*
  963. ** check if w has a simple correspondence in TeX
  964. */
  965. int is_mathcom (char *w, char *ww)
  966. {
  967.     int i;
  968.     
  969.     for (i = 0; i < mathcom_count; i++)
  970.         if (strcmp (math[i].troff_symb, w) == 0) {
  971.             strcpy (ww, math[i].tex_symb);
  972.             return (i);
  973.         }
  974.     return (-1);
  975. }
  976.  
  977.  
  978.  
  979. /*
  980. ** check if w is user-defined macro
  981. */
  982. int is_mydef (char *w)
  983. {
  984.     int i;
  985.     
  986.     for (i=0; i < mydef_count; i++) {
  987.         if (strcmp(mydef[i].def_macro,w) == 0)
  988.             return(i);
  989.     }
  990.     return(-1);
  991. }
  992.  
  993.  
  994.  
  995. /*
  996. ** check if w is a macro or plain troff command
  997. */
  998. int is_troff_mac (char *w, char *ww, int *arg, int *par)
  999. {
  1000.     int i;
  1001.     
  1002.     for (i=0; i < macro_count; i++)
  1003.         if (strcmp(macro[i].troff_mac,w) == 0) {
  1004.             strcpy(ww,macro[i].tex_mac);
  1005.             *arg = macro[i].arg;
  1006.             *par = macro[i].macpar;
  1007.             return(i);
  1008.         }
  1009.     return(-1);
  1010. }
  1011.  
  1012.  
  1013. /*
  1014. **
  1015. */
  1016. void parse_units (char *ww, int *sign, int *units, float *value)
  1017. {
  1018.     int len, k=0, i;
  1019.     char tmp[MAXWORD];
  1020.     
  1021.     len = strlen(ww);
  1022.     if (ww[0] == '-')
  1023.         *sign = -1;
  1024.     else if (ww[0] == '+')
  1025.         *sign = 1;
  1026.     if (*sign != 0)
  1027.         k++;
  1028.     
  1029.     i=0;
  1030.     while (k < len) {
  1031.         if (isdigit(ww[k]) || ww[k] == '.')
  1032.             tmp[i++] = ww[k++];
  1033.         else
  1034.             break;
  1035.     }
  1036.     tmp[i] = EOS;
  1037.     sscanf(tmp,"%f",value);
  1038.     i=0;
  1039.     if (k < len) {
  1040.         *units = ww[k++];
  1041.         if (k < len)
  1042.             fprintf(stderr, "Suspect problem in parsing %s, unit used is %c\n",
  1043.                     ww, *units);
  1044.     }
  1045. }
  1046.  
  1047.  
  1048.  
  1049. /*
  1050. ** check if w is in the similar list
  1051. */
  1052. int similar (char *w)
  1053. {
  1054.     int i;
  1055.     
  1056.     for (i=0; i < sim_count ; i++) {
  1057.         if (strcmp(sim_list[i],w) == 0)
  1058.             return(1);
  1059.     }
  1060.     return(-1);
  1061. }
  1062.  
  1063.  
  1064.  
  1065. /*
  1066. ** ignore the rest of the line
  1067. */
  1068. char * skip_line (char *pin)
  1069. {
  1070.     while (*pin != '\n' && *pin != EOS)
  1071.         pin++;
  1072.     if (*pin == EOS)
  1073.         return(pin);
  1074.     else
  1075.         return(++pin);
  1076. }
  1077.  
  1078.  
  1079.  
  1080. /*
  1081. ** skip white space
  1082. */
  1083. int skip_white (char *pin)
  1084. {
  1085.     int c,len=0;
  1086.     
  1087.     while ((c = *pin++) == ' ' || c == '\t' || c == '\n')
  1088.         len++;    
  1089.     return(len);
  1090. }
  1091.  
  1092.  
  1093.  
  1094. /*
  1095. ** copy tail[] to s[], return ptr to terminal EOS in s[]
  1096. */
  1097. char * strapp (register char *s, register char *tail)
  1098. {
  1099.     while ((*s++ = *tail++) != 0)
  1100. #ifdef DEBUG
  1101.         if (debug_o)
  1102.             putchar (s[-1]);
  1103. #else
  1104.         /*EMPTY*/
  1105.         ;
  1106. #endif
  1107.     return (s-1);            /* pointer to EOS at end of s[] */
  1108. }
  1109.  
  1110.  
  1111.  
  1112. /*
  1113. ** copy input to buffer, buffer holds only MAXLEN characters
  1114. */
  1115. void tmpbuf (FILE *in, char *buffer)
  1116. {
  1117.     int c;
  1118.     unsigned int l=0;
  1119.     
  1120.     while (l++ < MAXLEN && (c = getc(in)) != EOF)
  1121.         *buffer++ = (char) c;
  1122.     if (l >= MAXLEN) {
  1123.         fprintf (stderr,"Sorry: document is too large\n");
  1124.         exit(-1);
  1125.     }
  1126.     *buffer = EOS;
  1127. }
  1128.  
  1129.  
  1130.  
  1131. /*
  1132. ** save a string by allocating space
  1133. */
  1134. char *strsave (char *s)
  1135. {
  1136.     char *res;
  1137.     
  1138.     if ((res = malloc (strlen (s) + 1)) == NULL) {
  1139.         fprintf (stderr, "strsave: Can't allocate %d bytes\n", strlen(s) + 1);
  1140.         errexit (errno);
  1141.     }
  1142.     strcpy (res, s);
  1143.     return (res);
  1144. }
  1145.  
  1146.