/* ** 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[] */ }