home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / tr2latex / subs.c < prev    next >
C/C++ Source or Header  |  1987-06-30  |  18KB  |  959 lines

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