diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tr2latex/subs.c |
Initial commit
Diffstat (limited to 'support/tr2latex/subs.c')
-rw-r--r-- | support/tr2latex/subs.c | 1375 |
1 files changed, 1375 insertions, 0 deletions
diff --git a/support/tr2latex/subs.c b/support/tr2latex/subs.c new file mode 100644 index 0000000000..c6a2db3b6e --- /dev/null +++ b/support/tr2latex/subs.c @@ -0,0 +1,1375 @@ +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: subs.c +** +** These subroutines do (in general) small things for the translator. +** They appear in alphabetical order and their names are unique in the +** first six characters. +*/ + +#include "setups.h" +#include "protos.h" +#include "simil.h" +#include "greek.h" +#include "flip.h" +#include "forbid.h" +#include "maths.h" +#include "macros.h" +#include "special.h" + +int get_tbl_txt_entry(char *pin, char *w); + +extern int def_count; +extern int mydef_count; + +/* compile-time counting of elements */ +const int GRK_count = (sizeof(GRK_list) / sizeof(GRK_list[0])); +const int sim_count = (sizeof(sim_list) / sizeof(sim_list[0])); +const int flip_count = (sizeof(flip_list) / sizeof(flip_list[0])); +const int forbd_count = (sizeof(forbid) / sizeof(forbid[0])); +const int mathcom_count = (sizeof(math) / sizeof(struct math_equiv)); +const int macro_count = (sizeof(macro) / sizeof(struct macro_table)); +const int special_count = (sizeof(special) / sizeof(struct special_table)); + +/* +** alternate fonts (manual macro) +*/ +char *alternate(char *pin, char *pout, char *w) +{ + int which = 1; + char font[MAXWORD + 1], font1[MAXWORD + 1], font2[MAXWORD + 1], ww[MAXWORD + 1], tmp[MAXWORD + 1]; + + tmp[0] = EOS; + switch (w[1]) { + case 'R': strcpy(font1, "\\rm"); break; + case 'I': strcpy(font1, "\\it"); break; + case 'B': strcpy(font1, "\\bf"); break; + } + switch (w[2]) { + case 'R': strcpy(font2, "\\rm"); break; + case 'I': strcpy(font2, "\\it"); break; + case 'B': strcpy(font2, "\\bf"); break; + } + + strcpy(font, font1); + while (*pin != '\n' && *pin != EOS) { + pin += get_arg(pin, ww, 1); + if (which == 1) { + snprintf(tmp,sizeof(tmp),"{%s %s}", font1, ww); + which = 2; + } + else { + snprintf(tmp,sizeof(tmp),"{%s %s}", font2, ww); + which = 1; + } + pout = strapp(pout, tmp); + while (*pin == ' ' || *pin == '\t') + pin++; + } + return (pout); +} + + + +/* +** check if w is in the GREEK list +*/ +int CAP_GREEK(char *w) +{ + int i; + + for (i = 0; i < GRK_count; i++) { + if (strcmp(GRK_list[i], w) == 0) + return (1); + } + return (-1); +} + +int prefix(char *small, char *big) +{ + char c; + while ((c = *small++) == *big++) + if (c == EOS) + return (1); + return (c == EOS); +} + +int expflag, ctrflag, boxflag, dboxflag, tab, linsize, allflag, DELIM1, DELIM2; + +struct optstr { + char *optnam; + int *optadd; +}; +struct optstr options[] = { + { "tab", &tab }, + { "TAB", &tab }, + { "allbox", &allflag }, + { "ALLBOX", &allflag }, + { "box", &boxflag }, + { "BOX", &boxflag }, + { "center", &ctrflag }, + { "CENTER", &ctrflag }, + { "delim", &DELIM1 }, + { "DELIM", &DELIM1 }, + { "doublebox", &dboxflag }, + { "DOUBLEBOX", &dboxflag }, + { "expand", &expflag }, + { "EXPAND", &expflag }, + { "linesize", &linsize }, + { "LINESIZE", &linsize }, + { EOS, 0 } +}; + +/* +** get single option +*/ +int get_option(char *pin, char *w) { + char c; + int i, j; + for (j=0; *pin == ',' || *pin == ' ' || *pin == '\t'; j++, pin++); + for (i = 0; (c = *pin++) != EOS && + (c != ' ' && c != '\t' && c != ',' && c != ';' && c != '(') && i < MAXWORD; i++) { + w[i] = c; + } + w[i] = EOS; + return (j+i); +} + +/* +** get table options until ';' +*/ +int get_tbl_options(char *pin, struct optstr *options) +{ + char line[MAXLINE], *cp, nb[25], *t; + struct optstr *lp; + int c, ci, len = 0, found; + char opt[MAXWORD]; + + //tmp[0] = EOS; + for (lp = options; lp->optnam; lp++) + *(lp->optadd) = 0; + tab = '\t'; /* default is tab char */ + len = get_line(pin, line, 0); + if (strchr(line, ';') == 0) + return(0); + cp = line; + while ((c = *cp) != ';') { + cp += get_option(cp, opt); + found = 0; + for (lp = options; lp->optadd; lp++) { + if (strcmp(lp->optnam, opt) == 0) { + *(lp->optadd) = 1; + while (*cp == ' ') cp++; + t = nb; + if (*cp == '(') { + while ((ci = *++cp) != ')') + *t++ = ci; + cp++; + } + *t++ = 0; *t = 0; + if (lp->optadd == &tab) { + if (nb[0]) + *(lp->optadd) = nb[0]; + } else + if (lp->optadd == &linsize) { + *(lp->optadd) = atoi(nb); + } else + if (lp->optadd == &DELIM1) { + DELIM1 = nb[0]; + DELIM2 = nb[1]; + } + found = 1; + break; + } + } + if (!found) + fprintf(stderr, "Illigel option in table definition: %s\n", opt); + } + return(len); +} + + +/* +** translate table +** arguments: +** pin +** pout +** offset amount to offset pin +*/ +char *do_table (char *pin, char *pout, int *offset) +{ + char w[MAXLINE+1], ww[MAXLINE+1], format[MAXWORD+1], tmp[MAXLINE+1]; + char *ptr; + int i, fc = 0, columns = 0; + + tmp[0] = EOS; + ptr = pin; /* remember where we started */ + + pin += get_tbl_options(pin, options); + if (boxflag || dboxflag || allflag) + format[fc++] = '|'; + if (dboxflag) + format[fc++] = '|'; + pin = skip_line(pin); + while (*pin != EOS) { /* get the LAST format line */ + pin += get_line(pin, w, 0); + if (w[strlen(w) - 1] == '.') + break; + else /* not a format line */ + pin = skip_line(pin); + } + for (i = 0; w[i] != '.'; i++) { + switch (w[i]) { + case ' ': + case '\t': + continue; + case 'l': + case 'L': + case 'n': + case 'N': + case 'a': + case 'A': + format[fc++] = 'l'; + break; + case 'r': + case 'R': + format[fc++] = 'r'; + break; + case 'c': + case 'C': + case 's': + case 'S': + format[fc++] = 'c'; + break; + case '|': + format[fc++] = '|'; + break; + case ',': + fc = 0; /* use only last format */ + columns = 0; + continue; + default: + continue; + } + if (allflag) + format[fc++] = '|'; + columns++; + } + if ((boxflag || dboxflag) && !allflag) + format[fc++] = '|'; + if (dboxflag) + format[fc++] = '|'; + if (columns == 0) { + fprintf (stderr, "Sorry, I cannot do tables without a format line\n" + "Doing plain translation of table, lines will be commented\n" + "You need to fix it yourself\n"); + while (*pin != EOS) { + (void) getword (pin, w); + if (strcmp (w,".TE") == 0) { + pin += 4; + break; + } + pin += get_line (pin, w, 1); + *pout++ = '%'; + pout = strapp (pout, w); + pout = strapp (pout, "\n"); + pin++; /* skip the \n */ + } + *offset = pin - ptr; + return (pout); + } + format[fc] = EOS; + pin = skip_line(pin); + pout = strapp(pout, "\\par\\noindent\n"); + if (linsize > 0) { + snprintf(tmp, sizeof(tmp), "{\\arrayrulewidth=%dpt\n", linsize); + pout = strapp(pout, tmp); + } + if (ctrflag) + pout = strapp(pout, "\\begin{center}\n"); + snprintf(tmp, sizeof(tmp), "\\begin{tabular}{%s}\n", format); + pout = strapp (pout, tmp); + if (boxflag || dboxflag || allflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + while (*pin != EOS) { + (void)getword(pin, w); + if (strcmp(w, ".sp") == 0) { + pin += get_line(pin, ww, 1); + snprintf(tmp, sizeof(tmp), "%s\n\\\\ ", ww); + pout = strapp(pout, tmp); + continue; + } else if (strcmp(w, "_") == 0) { + pout = strapp(pout, "\\hline\n"); + pin = skip_line(pin); + continue; + } else if (strcmp(w, "=") == 0) { + pout = strapp(pout, "\\hline\n\\hline\n"); + pin = skip_line(pin); + continue; + } else if (strcmp(w, "\n") == 0) { + pin++; + continue; + } + for (i = 0; i < columns - 1; i++) { + (void) getword (pin, w); + if (strcmp (w, ".TE") == 0) { + pin += 4; + if (i == 0 && !boxflag && !dboxflag && !allflag) { + pout -= 3; /* take back the \\ and the \n */ + pout = strapp(pout, "\n"); + } + if (boxflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + pout = strapp(pout,"\\end{tabular}\n"); + if (ctrflag) + pout = strapp(pout, "\\end{center}\n"); + if (linsize > 0) + pout = strapp(pout, "}\n"); + pout = strapp(pout, "\\par\n"); + *offset = pin - ptr; + return (pout); + } + (void)get_line(pin, w, 0); + if (strncmp(w, "T{", 2) == 0) { + pin = skip_line(pin); + pin += get_tbl_txt_entry(pin, w); + troff_tex(w, ww, 0, 0); + snprintf(tmp, sizeof(tmp), "\\parbox[t]{%5.4f\\hsize}{\n%s} & ", 1.0 / columns, ww); + pin += get_table_entry(pin, w, tab); + } + else { + pin += get_table_entry(pin, w, tab); + troff_tex(w, ww, 0, 1); + snprintf(tmp, sizeof(tmp), "%s & ", ww); + } + pin++; /* skip tab */ + pout = strapp(pout,tmp); + } /* end for */ + pin += skip_white(pin); + (void) getword (pin, w); + if (strcmp(w, ".TE") == 0) { + fprintf(stderr, "Oops! I goofed. I told I you I am not very good at tables\n" + "I've encountered an unexpected end for the table\n" + "You need to fix it yourself\n"); + pin = skip_line(pin); + if (boxflag || allflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + pout = strapp(pout,"\\end{tabular}\n"); + if (ctrflag) + pout = strapp(pout, "\\end{center}\n"); + if (linsize > 0) + pout = strapp(pout, "}\n"); + pout = strapp(pout, "\\par\n"); + *offset = pin - ptr; + return(pout); + } + //pin += skip_white(pin); + (void)get_line(pin, w, 0); + if (strncmp(w, "T{", 2) == 0) { + pin = skip_line(pin); + pin += get_tbl_txt_entry(pin, w); + troff_tex(w, ww, 0, 0); + snprintf(tmp, sizeof(tmp), "\\parbox[t]{%5.4f\\hsize}{\n%s} \\\\\n", 1.0 / columns, ww); + //pin += get_table_entry(pin, w, tab); + } + else { + pin += get_table_entry(pin, w, '\n'); + troff_tex(w, ww, 0, 1); + snprintf(tmp, sizeof(tmp), "%s \\\\\n", ww); + } + pin++; /* skip tab */ + pout = strapp (pout, tmp); + if (allflag) + pout = strapp(pout, "\\hline\n"); + } + fprintf (stderr, "Oops! I goofed. I told I you I am not very good at tables\n" + "File ended and I haven't finished the table!\n" + "You need to fix it yourself\n"); + *offset = pin - ptr; + pout = strapp (pout, "\\end{tabular}\n\\par\n"); + return (pout); +} + + +/* +** end current environment +*/ +char *end_env (char *pout) +{ + if (IP_stat[RSRE]) { + IP_stat[RSRE] = 0; + pout = strapp (pout, "\\end{IPlist}"); + } + if (QP_stat) { + QP_stat = 0; + pout = strapp (pout, "\\end{quotation}"); + } + if (TP_stat) { + TP_stat = 0; + pout = strapp (pout, "\\end{TPlist}"); + } + return(pout); +} + + +/* +** set flag for current environment +*/ +void envoke_stat (int par) +{ + + switch(par) { + case 2: + IP_stat[RSRE] = 1; + break; + case 3: + TP_stat = 1; + break; + case 4: + QP_stat = 1; + break; + default: + break; + } +} + + + +/* +** do the flipping +*/ +char * flip (char *pout, char *w) +{ + int lb=0, rb=0; + char ww[MAXWORD+1], tmp[MAXWORD+1]; + + ww[0] = EOS; + tmp[0] = EOS; + pout--; + while (isspace (*pout)) + pout--; + while (1) { + if (*pout == '{') { + lb++; + if (lb > rb) + break; + } + if (*pout == '}') + rb++; + if (rb == 0) { + if (! isspace (*pout) && *pout != '$') { + pout--; + continue; + } + else + break; + } + pout--; + if (lb == rb && lb != 0) + break; + } + pout++; + if (*pout == '\\') { + pout++; + (void) getword (pout, tmp); + snprintf(ww, sizeof(ww), "\\%s", tmp); + pout--; + } + else if (*pout == '{') + (void) get_brace_arg (pout, ww); + else + (void) getword (pout, ww); + *pout = EOS; + snprintf(tmp,sizeof(tmp),"\\%s %s", w, ww); + pout = strapp (pout, tmp); + return (pout); +} + + + +/* +** take care of things like x hat under +*/ +char * flip_twice (char *pout, char *w, char *ww) +{ + int lb=0, rb=0; + char tmp1[MAXWORD+1], tmp2[MAXWORD+1]; + + tmp1[0] = EOS; tmp2[0] = EOS; + pout--; + while (*pout == ' ' || *pout == '\t' || *pout == '\n') + pout--; + while (1) { + if (*pout == '{') { + lb++; + if (lb > rb) + break; + } + if (*pout == '}') + rb++; + if (rb == 0) { + if (! isspace (*pout) && *pout != '$') { + pout--; + continue; + } + else + break; + } + pout--; + if (lb == rb && lb != 0) + break; + } + pout++; + if (*pout == '\\') { + pout++; + (void) getword(pout,tmp2); + snprintf(tmp1, sizeof(tmp1), "\\%s", tmp2); + pout--; + } + else if (*pout == '{') + (void) get_brace_arg(pout,tmp1); + else + (void) getword(pout,tmp1); + *pout = EOS; + snprintf(tmp2, sizeof(tmp2), "\\%s{\\%s %s}", w, ww, tmp1); + pout = strapp(pout,tmp2); + return(pout); +} + + + +/* +** get argument +** arguments: +** rec=1 means recursive +*/ +int get_arg (register char *pin, char *w, int rec) +{ + int c,len,i; + char ww[MAXWORD+1]; + int delim; + int escape = 0; + + len=0; + while ((c = *pin) == ' ' || c == '\t') { /* skip spaces and tabs */ + pin++; + len++; + } + i = 0; + if (*pin == '{' || *pin == '\"') { + if (*pin == '{') + delim = '}'; + else + delim = '\"'; + pin++; + len++; + while ((c = *pin++) != EOS && (escape || c != delim) && i < MAXWORD) { + /*if (c == ' ' && delim == '\"') + ww[i++] = '\\';*/ + if (escape && c == 't') + ww[i++] = '\t'; + else + ww[i++] = (char)c; + if (c == '\\' && !escape) + escape = 1; + else { + escape = 0; + } + len++; + } + len++; + } + else { + while ((c = *pin++) != EOS && !isspace(c) + /* && c != '$' && c != '}' */ && i < MAXWORD) { + if (math_mode && c == '~') + break; + ww[i++] = (char)c; + len++; + } + } + ww[i] = EOS; + if (rec == 1) /* check if recursion is required */ + troff_tex(ww, w, 1, 1); + else + strcpy(w, ww); + return(len); +} + + +/* +** get all arguments +** arguments: +** rec=1 means recursive +*/ +int get_allargs (register char *pin, char ***ppw, int rec) +{ + int c, i; + static char *ww [MAXARGS]; + char w[MAXWORD+1], *instart; + int nww; + int delim; + + instart = pin; + for (nww = 0; ; nww++) { + while ((c = *pin) == ' ' || c == '\t') /* skip spaces and tabs */ + pin++; + if (c == '\n') { + pin++; + ww [nww] = EOS; + break; + } + ww [nww] = pin; + i=0; + if (*pin == '{' || *pin == '\"') { + if (*pin == '{') + delim = '}'; + else + delim = '\"'; + ww [nww] = ++pin; + while ((c = *pin++) != EOS && c != delim && i < MAXWORD) + /* EMPTY */ + ; + pin [-1] = EOS; + } + else { + while ((c = *pin++) != EOS && !isspace(c) + /* && c != '$' && c != '}' */ && i < MAXWORD) { + if (math_mode && c == '~') + break; + } + pin [-1] = EOS; + if (c == '\n') { + ww [nww + 1] = EOS; + break; + } + } + } + if (rec == 1) { /* check if recursion is required */ + for (i = 0; ww [i]; i++) { + if (ww [i] && *ww [i]) { + troff_tex (ww [i], w, 1, 1); + if (strcmp (ww [i], w) != 0) + ww [i] = strdup(w); + } + } + } + *ppw = ww; + return (pin - instart); +} + + + + +/* +** get argument surrounded by braces +*/ +void get_brace_arg (char *buf, char *w) +{ + int c,i, lb=0, rb=0; + + i=0; + while ((c = *buf++) != EOS) { + w[i++] = (char)c; + if (c == '{') lb++; + if (c == '}') rb++; + if (lb == rb) break; + } + w[i] = EOS; +} + +/* +** get "define" or .de word +** arguments: +** pin delimited by space only +** w delimited by space only +*/ +int get_defword (char *pin, char *w, int *illegal) +{ + int c,i; + + *illegal = 0; + for (i=0; (c = *pin++) != EOS && !isspace (c) && i < MAXWORD; i++) { + w[i] = (char)c; + if (isalpha(c) == 0) + *illegal = 1; /* illegal TeX macro */ + } + w[i] = EOS; + if (*illegal == 0 && is_forbid(w) >= 0) + *illegal=1; + return(i); +} + + +/* +** get the rest of the line +** arguments: +** rec=1 means recursion is required +*/ +int get_line (char *pin, char *w, int rec) +{ + int c,i,len; + int escape=0; + char ww[MAXLINE+1]; + + i=0; + len=0; + c = *pin; + while ((c = *pin++) != EOS && c != '\n' && len < MAXLINE) { + if (de_arg > 0 && !rec && c == '\\' && !escape) + escape = 1; + else { + escape = 0; + ww[i++] = (char)c; + } + len++; + } + ww[i] = EOS; + if (de_arg>0 && ww[0] == '.') { + /* skip blanks */ + for (i=1; ww[i] == ' '; i++); + strcpy(ww+1, ww+i); + } + //fprintf(stderr, "get_line:%s\n", ww); + if (rec == 1) + troff_tex(ww, w, 0, 1); + else + strcpy(w, ww); + //fprintf(stderr, "get_line out:%s\n", w); + return(len); +} + + +/* +** get multi-line argument +*/ +int get_multi_line (char *pin, char *w) +{ + int len=0,l=0,lines=0; + char tmp[MAXWORD+1]; + int c1,c2; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS) { + c1 = *pin; + c2 = *++pin; + --pin; + if (c1 == '.' && isupper(c2)) + break; + lines++; + if (lines > 1) + strcat(w," \\\\\n"); + l = get_line(pin,tmp,1); + strcat(w,tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return(len); +} + + +/* +** get the macro substitution +*/ +int get_mydef (char *pin, char *w) +{ + int c1,c2,l,len; + char tmp[MAXLINE+1]; + char ww[MAXLINE*20+1]; + + tmp[0] = EOS; + ww[0] = EOS; + len=1; + while (*pin != EOS) { + c1 = *pin; + c2 = *++pin; + --pin; + if (c1 == '.' && c2 == '.') + break; + l = get_line(pin, tmp, 0); + if (len+l+1 < MAXLINE*20) { + strcat(ww, tmp); + strcat(ww, "\n"); + len += l+1; + pin += l+1; + } else break; + } + troff_tex(ww, w, 0, 1); + return(len); +} + + +/* +** get N lines +*/ +int get_N_lines (char *pin, char *w, int N) +{ + int len=0,l=0,lines=0; + char tmp[MAXWORD+1]; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS && lines < N) { + lines++; + if (lines > 1) + strcat(w," \\\\\n"); + l = get_line(pin, tmp, 1); + strcat(w,tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return(len); +} + + +/* +** get text surrounded by quotes in math mode +*/ +int get_no_math (char *pin, char *w) +{ + int c,i,len; + + len = 0; + for (i=0; (c = *pin++) != EOS && c != '\"' && i < MAXWORD; i++) { + if (c == '{' || c == '}') { + w[i] = '\\'; + w[++i] = (char)c; + } + else + w[i] = (char)c; + len++; + } + w[i] = EOS; + return(len); +} + + +/* +** get the denominator of over +*/ +char *get_over_arg (char *pin, char *ww) +{ + char w[MAXWORD+1], tmp1[MAXWORD+1], tmp2[MAXWORD+1]; + int len; + + w[0] = EOS; + tmp1[0] = EOS; + tmp2[0] = EOS; + pin += getword (pin,tmp1); /* read first word */ + pin += skip_white (pin); + len = getword (pin, tmp2); /* read second word */ + strcat(w,tmp1); strcat(w," "); + + /* as long as there is a sup or sub read the next two words */ + while (strcmp (tmp2, "sub") == 0 || strcmp (tmp2, "sup") == 0) { + pin += len; + strcat (w, tmp2); + strcat (w, " "); + pin += skip_white (pin); + pin += getword (pin, tmp1); + strcat (w, tmp1); + strcat (w, " "); + pin += skip_white (pin); + len = getword (pin, tmp2); + } + troff_tex (w, ww, 0, 1); + return (pin); +} + + + +/* +** get reference +*/ +int get_ref (char *pin, char *w) +{ + int len=0, l=0, lines=0; + char tmp[MAXWORD+1]; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS) { + if (*pin == '\n') + break; + (void) getword(pin,tmp); + if (tmp[0] == '.' && isupper(tmp[1])) { + /* these commands don't cause a break in reference */ + if (strcmp (tmp, ".R") != 0 && strcmp (tmp, ".I") != 0 + && strcmp(tmp,".B") != 0) + break; + } + else if (tmp[0] == '.' && !(isupper(tmp[1]))) { + /* these commands don't cause a break in reference */ + if (strcmp (tmp, ".br") != 0 && strcmp (tmp, ".bp") != 0) + break; + } + l = get_line (pin, tmp, 1); + lines++; + if (lines > 1) + strcat (w, " "); + strcat (w, tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return (len); +} + + +/* +** +*/ +void get_size (char *ww, struct measure *PARAMETER) +{ + int sign=0, units=0; + float value; + + if (ww[0] == EOS) { + if (PARAMETER->def_value == 0) { + PARAMETER->value = PARAMETER->old_value; + strcpy(PARAMETER->units,PARAMETER->old_units); + } + else { + PARAMETER->value = PARAMETER->def_value; + strcpy(PARAMETER->units,PARAMETER->def_units); + } + } + else { + PARAMETER->old_value = PARAMETER->value; + strcpy (PARAMETER->old_units, PARAMETER->units); + + parse_units (ww, &sign, &units, &value); + + if (units == 'p') + strcpy (PARAMETER->units, "pt"); + else if (units == 'i') + strcpy (PARAMETER->units, "in"); + else if (units == 'c') + strcpy (PARAMETER->units, "cm"); + else if (units == 'm') + strcpy (PARAMETER->units, "em"); + else if (units == 'n') { + value = .5*value; /* n is about half the width of m */ + strcpy (PARAMETER->units, "em"); + } + else if (units == 'v') + strcpy(PARAMETER->units,"ex"); + else if (units == 0) { + if (sign == 0 || PARAMETER->old_units[0] == EOS) + strcpy(PARAMETER->units,PARAMETER->def_units); + else + strcpy(PARAMETER->units,PARAMETER->old_units); + } + else { + fprintf(stderr,"unknown units %c, using default units\n", units); + strcpy(PARAMETER->units,PARAMETER->def_units); + } + if (sign == 0) + PARAMETER->value = value; + else + PARAMETER->value = PARAMETER->old_value + sign*value; + } +} + + + +/* +** get the rest of the line -- Nelson Beebe +** arguments: +** rec=1 means recursion is required +*/ +int get_string (char *pin, char *w, int rec) +{ + int c,i,len; + char ww[MAXLINE+1]; + char *start; + + if (*pin != '\"') + return(get_line(pin,w,rec)); + start = pin; /* remember start so we can find len */ + i=0; + pin++; /* point past initial quote */ + while ((c = *pin++) != EOS && c != '\"' && c != '\n' && i < MAXLINE) + ww[i++] = (char)c; + ww[i] = EOS; + if (c != '\n') /* flush remainder of line */ + while ((c = *pin++) != '\n') + /* EMPTY */ + ; + len = pin - start - 1; /* count only up to NL, not past */ + if (rec == 1) + troff_tex(ww,w,0,1); + else + strcpy(w,ww); + return(len); +} + + + +/* +** get the argument for sub and sup +*/ +int get_sub_arg (char *pin, char *w) +{ + int c,len,i; + char ww[MAXWORD+1], tmp[MAXWORD+1]; + + len=0; tmp[0] = EOS; + while ((c = *pin) == ' ' || c == '\t') { + pin++; + len++; + } + i=0; + while ((c = *pin++) != EOS && c != ' ' && c != '\t' && c != '\n' + && c != '$' && c != '}' && c != '~' && i < MAXWORD) { + ww[i++] = (char)c; + len++; + } + ww[i] = EOS; + if (strcmp(ww,"roman") == 0 || strcmp(ww,"bold") == 0 + || strcmp(w,"italic") == 0) { + (void) get_arg(pin,tmp,0); + snprintf(ww, sizeof(ww), "%s%c%s", ww, c, tmp); + len += strlen(tmp)+1; + } + troff_tex(ww,w,0,1); /* recursive */ + return(len); +} + + +/* +** +*/ +int get_table_entry (char *pin, char *w, int tab) +{ + int i=0, escape=0; + char c; + + while ((c = *pin++) != EOS && (escape || (c != tab && c != '\n')) && i < MAXLINE) { + if (escape && c != '\n') + w[i++] = '\\'; + if (c == '&') + w[i++] = '\\'; + if (c == '\\' && !escape) + escape = 1; + else { + w[i++] = c; + escape = 0; + } + } + w[i] = EOS; + return(i); +} + +int get_tbl_txt_entry(char *pin, char *w) { + int i; + char c, tmp[MAXWORD+1]; + + for (i = 0; (c = *pin++) != EOS && i < MAXLINE; i++) { + w[i] = c; + if (c == '\n') { + (void)get_line(pin, tmp, 0); + if (strncmp(tmp, "T}", 2) == 0) { + w[++i] = EOS; + return (i + 2); + } + } + } + w[i] = EOS; + return (i); +} + + +/* +** get characters till the next space +*/ +int get_till_space (char *pin, char *w) +{ + int c,i; + + for (i=0; (c = *pin++) != EOS && c != ' ' && c != '\n' + && c != '\t' && i < MAXWORD; i++) + w[i] = (char)c; + w[i] = EOS; + return(i); +} + + + +/* +** get the define substitution +*/ +int getdef (char *pin, char *ww) +{ + int c,i,len; + int def_delim; + char w[MAXWORD+1]; + + def_delim = *pin++; /* take first character as delimiter */ + len=1; + i=0; + while ((c = *pin++) != EOS && c != def_delim && i < MAXWORD) { + len++; + w[i++] = (char)c; + } + w[i] = EOS; + len++; + if (c != def_delim) { + fprintf(stderr, + "WARNING: missing right delimiter in define, define=%s\n",w); + len--; + } + troff_tex(w,ww,0,1); /* now translate the substitution */ + return(len); +} + + + +/* +** get an alphanumeric word (dot also) +*/ +int getword (char *pin, char *w) +{ + int c,i; + + for (i=0; (c = *pin++) != EOS + && (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++) + w[i] = (char)c; + if (i == 0 && c != EOS) + w[i++] = (char)c; + w[i] = EOS; + return(i); +} + + + +/* +** change GREEK to Greek +*/ +void GR_to_Greek (char *w, char *ww) +{ + *ww++ = '\\'; + *ww++ = *w; + while(*++w != EOS) + *ww++ = tolower(*w); + *ww = EOS; +} + + + +/* +** check if w was defined by the user +*/ +int is_def (char *w) +{ + int i; + + for (i=0; i < def_count; i++) { + if (strcmp(def[i].def_macro,w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is in the flip list +*/ +int is_flip (char *w) +{ + int i; + + for (i=0; i < flip_count; i++) { + if (strcmp(flip_list[i],w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is one of those sacred macros +*/ +int is_forbid (char *w) +{ + int i; + + for (i=0; i < forbd_count; i++) { + if (strcmp(forbid[i],w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w has a simple correspondence in TeX +*/ +int is_mathcom (char *w, char *ww) +{ + int i; + + for (i = 0; i < mathcom_count; i++) + if (strcmp (math[i].troff_symb, w) == 0) { + strcpy (ww, math[i].tex_symb); + return (i); + } + return (-1); +} + +/* +** +*/ +int is_special (char *w, char *ww) +{ + int i; + //fprintf(stderr, "special_count:%d\n", special_count); + for (i = 0; i < special_count; i++) + if (strcmp (special[i].troff_char, w) == 0) { + strcpy (ww, special[i].tex_char); + //fprintf(stderr, "Special: %d, %s -> %s\n", i, w, ww); + return (i); + } + return (-1); +} + + +/* +** check if w is user-defined macro +*/ +int is_mydef (char *w) +{ + int i; + + for (i=0; i < mydef_count; i++) { + if (strcmp(mydef[i].def_macro,w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is a macro or plain troff command +*/ +int is_troff_mac (char *w, char *ww, int *arg, int *par) +{ + int i; + + for (i=0; i < macro_count; i++) + if (strcmp(macro[i].troff_mac,w) == 0) { + strcpy(ww,macro[i].tex_mac); + *arg = macro[i].arg; + *par = macro[i].macpar; + return(i); + } + return(-1); +} + + +/* +** +*/ +void parse_units (char *ww, int *sign, int *units, float *value) +{ + int len, k=0, i; + char tmp[MAXWORD+1]; + + len = strlen(ww); + if (ww[0] == '-') + *sign = -1; + else if (ww[0] == '+') + *sign = 1; + if (*sign != 0) + k++; + + i=0; + while (k < len) { + if (isdigit(ww[k]) || ww[k] == '.') + tmp[i++] = ww[k++]; + else + break; + } + tmp[i] = EOS; + sscanf(tmp,"%f",value); + i=0; + if (k < len) { + *units = ww[k++]; + if (k < len) + fprintf(stderr, "Suspect problem in parsing %s, unit used is %c\n", + ww, *units); + } +} + + + +/* +** check if w is in the similar list +*/ +int similar (char *w) +{ + int i; + + for (i=0; i < sim_count ; i++) { + if (strcmp(sim_list[i],w) == 0) + return(1); + } + return(-1); +} + + + +/* +** ignore the rest of the line +*/ +char * skip_line (char *pin) +{ + while (*pin != '\n' && *pin != EOS) + pin++; + if (*pin == EOS) + return(pin); + else + return(++pin); +} + + + +/* +** skip white space +*/ +int skip_white (char *pin) +{ + int c,len=0; + + while ((c = *pin++) == ' ' || c == '\t') /* || c == '\n') */ + len++; + return(len); +} + + + +/* +** copy tail[] to s[], return ptr to terminal EOS in s[] +*/ +char * strapp (char *s, char *tail) +{ + while ((*s++ = *tail++) != 0) + if (debug_o) + fputc(s[-1], stderr); + return (s-1); /* pointer to EOS at end of s[] */ +} |