summaryrefslogtreecommitdiff
path: root/support/tr2latex/subs.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tr2latex/subs.c
Initial commit
Diffstat (limited to 'support/tr2latex/subs.c')
-rw-r--r--support/tr2latex/subs.c1375
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[] */
+}