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/tr.c |
Initial commit
Diffstat (limited to 'support/tr2latex/tr.c')
-rw-r--r-- | support/tr2latex/tr.c | 1361 |
1 files changed, 1361 insertions, 0 deletions
diff --git a/support/tr2latex/tr.c b/support/tr2latex/tr.c new file mode 100644 index 0000000000..ec2d97845d --- /dev/null +++ b/support/tr2latex/tr.c @@ -0,0 +1,1361 @@ +/* -*- mode: C; c-basic-offset: 2; tab-width: 2 -*- */ +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: tr.c +** +** This module contains the HARD-WIRED rules of the translator. +** It should be handled with care. +*/ + +#include "setups.h" +#include "protos.h" + +int def_count = 0; +int mydef_count = 0; + +extern int man; /* man flag */ + +void troff_tex (char *pin, char *pout, int mid, int rec) +{ + char eqn_no[MAXWORD], w[MAXWORD], ww[MAXLINE], tmp[MAXWORD], tmp2[MAXWORD]; + char *p, **pw; + int len,c,c1,c2,i,j; + int ref = 0; + int put_brace = 0; + int first_word = 1; + int no_word = 1; + int arg = 0; + int par = 0; + int illegal = 0; + int floating = 0; + static int delim_defd = 0; /* whether math delimiter has been defined */ + static char DELIM [] = "$"; + float flen; + int N; + int EXEE = 0; /* example indentation */ + int NTNE = 0; /* note indentation */ + int thisfont = 1; /* default font is roman */ + int lastfont = 1; /* default last font is roman */ + int offset = 0; /* amount to offset pin */ + + *pout = EOS; + w[0] = EOS; + ww[0] = EOS; + tmp[0] = EOS; + tmp2[0] = EOS; + while (*pin != EOS) { + len = getword(pin,w); + c1 = (first_word? '\n': pin[-1]); + c2 = pin[0]; + pin += len; + if (!isspace(w[0])) + no_word = 0; + /* first check if we are in math mode */ + if (math_mode) { + len = get_till_space(pin,ww); + snprintf(tmp,sizeof(tmp),"%s%s",w,ww); + if (strcmp(w,"delim") == 0) { + delim_defd = 1; + pin += skip_white(pin); + DELIM[0] = *pin; + pin = skip_line(pin); + } + /* check if it is a math delimiter; switch to non-math mode if so*/ + else if (delim_defd && strcmp(w,DELIM) == 0) { + math_mode = 0; + *pout++ = '$'; + } + /* check for illegal macros here */ + else if (len > 0 && def_count > 0 && (i=is_def(tmp)) >= 0) { + pin += len; + pout = strapp(pout,def[i].replace); + } + /* See if it is a (legally) defined macro */ + else if (def_count > 0 && (i=is_def(w)) >= 0) { + if (def[i].illegal) + pout = strapp(pout,def[i].replace); + else { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + } + /* Search for commands in some order; + start with non-alphanumeric symbols */ + else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 + || strcmp(w,"%") == 0 || strcmp(w,"_") == 0) { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + else if (strcmp(w,"=") == 0) { + if (*pin == '=') { + pin++; + pout = strapp(pout,"\\equiv"); + } + else + pout = strapp(pout,"="); + } + else if (strcmp(w,"<") == 0 || strcmp(w,">") == 0) { + if (*pin == '=') { + pin++; + if (strcmp(w,"<") == 0) + pout = strapp(pout,"\\le"); + else + pout = strapp(pout,"\\ge"); + } + else { + *pout++ = *w; + } + } + else if (strcmp(w,"-") == 0) { + if (*pin == '>') { + pin++; + pout = strapp(pout,"\\to"); + } + else if (*pin == '+') { + pin++; + pout = strapp(pout,"\\mp"); + } + else + *pout++ = '-'; + } + else if (strcmp(w,"+") == 0) { + if (*pin == '-') { + pin++; + pout = strapp(pout,"\\pm"); + } + else + *pout++ = '+'; + } + else if (strcmp(w,"\"") == 0) { + len = get_no_math(pin,ww); + pin += len+1; + if (len > 1) { + snprintf(tmp,sizeof(tmp),"\\ \\it\\hbox{%s}",ww); + pout = strapp(pout,tmp); + } + else if (len == 1) + *pout++ = ww[0]; + } + /* Now search for symbols that start with a captial */ + else if (strcmp(w,".EN") == 0) { + math_mode = 0; + if ((len=strlen(eqn_no)) > 0) + { + snprintf(tmp,sizeof(tmp),"\\eqno %s",eqn_no); + pout = strapp(pout,tmp); + } + eqn_no[0] = EOS; + c1 = *--pout; + c2 = *--pout; + if (c1 == '\n' && c2 == '$') + *--pout = EOS; + else { + pout += 2; + pout = strapp(pout,"$$"); + } + } + /* Now search for symbols that start with a small letter */ + else if (strcmp(w,"bold") == 0 || strcmp(w,"roman") == 0 || + strcmp(w,"italic") == 0) { + pin += get_arg(pin,ww,1); + if (strcmp(w,"bold") == 0) { + snprintf(tmp,sizeof(tmp),"{\\bf %s}",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w,"roman") == 0) { + snprintf(tmp,sizeof(tmp),"{\\rm %s}",ww); + pout = strapp(pout,tmp); + } + else { + snprintf(tmp,sizeof(tmp),"{\\it %s}",ww); + pout = strapp(pout,tmp); + } + } + else if (strcmp(w, "define") == 0) { + if (def_count >= MAXDEF) { + fprintf(stderr, "Too many defines. MAXDEF=%d\n",MAXDEF); + exit(-1); + } + for (i=0; *--pout != '$' && (unsigned)i < MAXLEN; i++) + tmp[i] = *pout; + tmp[i] = EOS; + strcat(tmp,"$$"); + *--pout = EOS; + pin += skip_white(pin); + pin += get_defword(pin, w, &illegal); + pin += skip_white(pin); + pin += getdef(pin,ww); + if (illegal) { + def[def_count].illegal = 1; + fprintf(stderr, "illegal TeX macro, %s, replacing it\n",w); + def[def_count].replace = strdup(ww); + } + else { + def[def_count].illegal = 0; + snprintf(tmp2, sizeof(tmp2), "\\def\\%s{%s}\n", w, ww); + pout = strapp(pout,tmp2); + } + def[def_count++].def_macro = strdup(w); + pin = skip_line(pin); + for (j=i+1; j >= 0; j--) + *pout++ = tmp[j]; + tmp[0] = EOS; + } + else if (strcmp(w,"gsize") == 0 || strcmp(w,"gfont") == 0) + pin = skip_line(pin); + else if (strcmp(w,"left") == 0 || strcmp(w,"right") == 0) { + snprintf(tmp,sizeof(tmp),"\\%s",w); + pout = strapp(pout,tmp); + pin += skip_white(pin); + len = getword(pin,ww); + if (strcmp(ww,"floor") == 0) { + pin += len; + if (strcmp(w,"left") == 0) + pout = strapp(pout,"\\lfloor"); + else + pout = strapp(pout,"\\rfloor"); + } + else if (strcmp(ww,"nothing") == 0 || ww[0] == '\"') { + pin += len; + *pout++ = '.'; + if (ww[0] == '\"') pin++; + } + else if (*pin == '{' || *pin == '}') + *pout++ = '\\'; + } + else if (strcmp(w,"over") == 0) { + if (!first_word) { + pout--; + for (i=0; isspace (*pout); i++) + tmp[i] = *pout--; + if (*pout == '}' && put_brace == 0) + *pout = ' '; + else { + for (; !isspace(*pout) && *pout != '$'; i++) + tmp[i] = *pout--; + put_brace = 0; + *++pout = '{'; + } + for (j=i-1; j >= 0; j--) + *++pout = tmp[j]; + *++pout = EOS; + } + pout = strapp(pout,"\\over"); + pin += skip_white(pin); + *pout++ = ' '; + if (*pin == '{') + pin++; + else { + pin = get_over_arg(pin,ww); + pout = strapp(pout,ww); + if (*pin != EOS || !first_word) + *pout++ = '}'; + } + } + else if (strcmp(w,"size") == 0) + pin += get_arg(pin,ww,0); + else if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0 || + strcmp(w,"sub") == 0 || strcmp(w,"from") == 0) { + while ((c = *--pout) == ' ' || c == '\t' || c == '\n') + /* EMPTY */; + *++pout = EOS; + if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0) + pout = strapp(pout,"^"); + else + pout = strapp(pout,"_"); + pin += skip_white(pin); + len = get_sub_arg(pin,ww); + pin += len; + if (len > 1) { + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + len = skip_white(pin); + pin += len; + (void) getword(pin,ww); + if (strcmp(ww,"over") == 0) + put_brace = 1; + pin -= len; + } + else + pout = strapp(pout,ww); + } + else if (strcmp(w,"up") == 0 || strcmp(w,"down") == 0 + || strcmp(w,"fwd") == 0 || strcmp(w,"back") == 0) { + if (strcmp(w,"up") == 0) { + pout = strapp(pout,"\\raise"); + strcpy(tmp,"ex"); + } + else if (strcmp(w,"down") == 0) { + pout = strapp(pout,"\\lower"); + strcpy(tmp,"ex"); + } + else if (strcmp(w,"fwd") == 0) { + pout = strapp(pout,"\\kern"); + strcpy(tmp,"em"); + } + else if (strcmp(w,"back") == 0) { + pout = strapp(pout,"\\kern-"); + strcpy(tmp,"em"); + } + pin += skip_white(pin); + pin += getword(pin,ww); + len = atoi(ww); flen = len/100.; + ww[0] = EOS; + snprintf(tmp2, sizeof(tmp2), "%4.2f%s", flen, tmp); + pout = strapp(pout,tmp2); + } + /* Now check if the word is a member of a group */ + else if (CAP_GREEK(w) > 0) { + GR_to_Greek(w,ww); + pout = strapp(pout,ww); + } + else if (is_flip(w) >= 0) { + if (!first_word) { + len = skip_white(pin); + pin += len; + (void) getword(pin,ww); + if (is_flip(ww) >= 0) { + pin += strlen(ww); + pout = flip_twice(pout,w,ww); + } + else { + pin -= len; + pout = flip(pout,w); + } + } + else { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + } + else if (is_mathcom (w, ww) >= 0) + pout = strapp (pout, ww); + else if (similar(w) > 0) { + pout = strapp (pout, "\\"); + pout = strapp (pout, w); + } + + /* if none of the above math commands matched, it is an ordinary + symbol; just copy it */ + + else + pout = strapp(pout,w); + } + + /* check if it is a math delimiter; switch to math mode if so */ + + else if (strcmp(w,"$") == 0 && de_arg > 0) { + de_arg++; + *pout++ = '#'; + } + else if (delim_defd && strcmp(w,DELIM) == 0) { + math_mode = 1; + *pout++ = '$'; + } + else if (strcmp(w,"$") == 0) + pout = strapp(pout,"\\$"); + + /* check if it is a non-math troff command */ + + else if (c2=='.' && !mid && (c1=='\n' || c1==EOS || first_word)) { + /* Search in some order; start with non-alphanumeric characters */ + if (strcmp(w, ".") == 0) { + c1 = *pin; + c2 = *++pin; + if (c1 == '\\' && c2 == '\"') { + /* Comment starts with .\" */ + ++pin; + pin += get_line(pin,ww,0); + pout = strapp(pout,"%"); + pout = strapp(pout,ww); + } + else if (c1 == '\n') { + pout = strapp(pout, "\n"); + } + else { + fprintf(stderr, + "I cannot translate troff macro .%c%c\n",c1,c2); + pin += get_line(pin,ww,0); + snprintf(tmp, sizeof(tmp), "%%.%c%c%s", c1, c2, ww); + pout = strapp(pout,tmp); + if (*pin == EOS) + *pout++ = '\n'; + } + } + /* Now search for commads that start with a capital */ + else if (strcmp(w,".AB") == 0) { + pin += get_arg(pin,ww,0); + if (strcmp(ww,"no") == 0) + pout = strapp(pout,"\\bigskip"); + else + pout = strapp(pout,"\\begin{abstract}"); + } + else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0 || + strcmp(w,".I") == 0 || strcmp(w,".it") == 0 || + strcmp(w,".R") == 0 || strcmp(w,".rm") == 0 || + strcmp(w,".P") == 0) { + if (strcmp(w,".R") == 0 || strcmp(w,".rm") == 0) + strcpy(w, "rm"); + else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0) + strcpy(w, "bf"); + else if (strcmp(w,".I") == 0 || strcmp(w,".it") == 0) + strcpy(w, "it"); + else { + switch(lastfont) { + case 1: + strcpy (w, "rm"); + thisfont = 1; + break; + case 2: + strcpy (w, "it"); + thisfont = 2; + break; + case 3: + strcpy (w, "bf"); + thisfont = 3; + break; + default: + strcpy (w, "rm"); + thisfont = 1; + break; + } + } + pin += get_arg(pin, ww, 1); + if (ww[0] == EOS) { + pout = strapp(pout,"\\"); + pout = strapp(pout, w); + } + else { + snprintf(tmp,sizeof(tmp),"{\\%s %s",w,ww); + pout = strapp(pout,tmp); + while (1) { + pin += get_arg(pin, ww, 1); + if (ww[0] == EOS) + break; + snprintf(tmp,sizeof(tmp)," %s",ww); + pout = strapp(pout,tmp); + } + pout = strapp(pout, "}"); + } + } + else if (man && (strcmp(w,".BR") == 0 || strcmp(w,".BI") == 0 + || strcmp(w,".IR") == 0 || strcmp(w,".IB") == 0 + || strcmp(w,".RI") == 0 || strcmp(w,".RB") == 0)){ + pout = alternate(pin,pout,w); + pin = skip_line(pin); + *pout++ = '\n'; + } + else if (strcmp(w,".BX") == 0) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"\\fbox{%s}",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, ".DA") == 0) { + pin += get_arg(pin, ww, 0); + if (ww[0] != EOS) { + snprintf(tmp, sizeof(tmp), "\\def\\today{%s}%%\n", ww); + pout = strapp(pout, tmp); + } + pout = strapp(pout, "\\centerfoot{\\today}"); + } + else if (strcmp(w, ".DS") == 0) { + /*pout = end_env(pout);*/ + pout = strapp(pout, "\\begin{display}*"); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + snprintf(tmp, sizeof(tmp), "[%s]", ww); + pout = strapp(pout, tmp); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + (void) get_size(ww, &indent); + snprintf(tmp, sizeof(tmp), "[%3.1f%s]", indent.value, indent.units); + pout = strapp(pout, tmp); + } + } + } + else if (strcmp(w,".EH") == 0 || strcmp(w,".EF") == 0 || + strcmp(w,".OH") == 0 || strcmp(w,".OF") == 0) { + if (strcmp(w,".EH") == 0 || strcmp(w,".EF")) + fprintf(stderr, "%s works only in towside style\n", w); + if (strcmp(w,".EH") == 0) + pout = strapp(pout, "\\EvenHeader"); + else if (strcmp(w,".EF") == 0) + pout = strapp(pout, "\\EvenFooter"); + else if (strcmp(w,".OH") == 0) + pout = strapp(pout, "\\OddHeader"); + else if (strcmp(w,".OF") == 0) + pout = strapp(pout, "\\OddFooter"); + pin += skip_white(pin); + pin += getdef(pin, w) - 1; + pin += getdef(pin, ww) - 1; + pin += getdef(pin, tmp); + snprintf(tmp2, sizeof(tmp2), "{%s}{%s}{%s}", w, ww, tmp); + pout = strapp(pout, tmp2); + } + else if (strcmp(w,".EQ") == 0) { + math_mode = 1; + put_brace = 0; + pout = strapp(pout,"$$"); + len = get_arg(pin,eqn_no,0); + if (strcmp(eqn_no,"I") == 0 || strcmp(eqn_no,"L") == 0) { + fprintf(stderr,"lineups are ignored\n"); + pin += len; + len = get_arg(pin,eqn_no,0); + } + if ((strlen(eqn_no)) > 0) + pin += len; + len = get_arg(pin,tmp,0); + if (strcmp(tmp, "I") == 0 || strcmp(tmp, "L") == 0) { + fprintf(stderr,"lineups are ignored\n"); + pin += len; + } + } + else if (strcmp (w, ".ID") == 0) { + pout = end_env(pout); + pout = strapp(pout, "\\begin{display}[I]"); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + (void) get_size(ww, &indent); + snprintf(tmp, sizeof(tmp), "[%3.1f%s]", indent.value, indent.units); + pout = strapp(pout, tmp); + } + *pout++ = '\n'; + pin = skip_line(pin); + } + else if (strcmp (w, ".IP") == 0) { + pin += get_arg(pin, ww, 1); + strcpy(w, ""); + pin += get_arg(pin, w, 0); + pin = skip_line(pin); + if (IP_stat[RSRE] == 0) { + pout = strapp(pout, "\\begin{IPlist}"); + if (w[0]) { + snprintf(tmp, sizeof(tmp), "[%s]", w); + pout = strapp(pout, tmp); + } + pout = strapp(pout, "\n"); + } + snprintf(tmp, sizeof(tmp), "\\IPitem{{%s}}\n", ww); + pout = strapp(pout,tmp); + if (de_arg > 0) mydef[mydef_count].par = 2; + else IP_stat[RSRE] = 1; + } + else if (strcmp(w, ".KE") == 0) { + if (floating) + pout = strapp(pout, "\\end{figure}"); + else { + if (IP_stat[RSRE] > 1) + IP_stat[RSRE]--; + else + pout = end_env(pout); + pout = strapp(pout, "}"); + } + floating = 0; + } + else if (strcmp(w, ".KS") == 0) { + pout = strapp(pout, "{\\par\\nobreak"); + if (IP_stat[RSRE]) + IP_stat[RSRE]++; + } + else if (strcmp(w, ".KF") == 0) { + floating = 1; + pout = strapp(pout,"\\begin{figure}"); + } + else if (strcmp(w, ".NH") == 0) { + pout = end_env(pout); + pin += get_arg(pin, ww, 0); + pin = skip_line(pin); + switch(ww[0]) { + case '1': + pout = strapp(pout, "\\section{"); + break; + case '2': + pout = strapp(pout, "\\subsection{"); + break; + case '3': + pout = strapp(pout, "\\subsubsection{"); + break; + case '4': + pout = strapp(pout, "\\paragraph{"); + break; + case '5': + pout = strapp(pout, "\\subparagraph{"); + break; + default: + pout = strapp(pout, "\\section{"); + break; + } + len = get_line(pin, ww, 0); + while (ww[0] != '.') { + troff_tex (ww, tmp, 0, 1); + pout = strapp(pout, tmp); + pin += len+1; + len = get_line(pin, ww, 0); + } + //fprintf(stderr, "NH:|%s|\n", tmp); + pout = strapp(pout, "}"); + if (strcmp(ww, ".") != 0) + pout = strapp(pout, "\n"); + //fprintf(stderr, "NH:|%10.20s|\n", pin); + } + else if (strcmp(w,".QP") == 0) { + if (de_arg > 0) + mydef[mydef_count].par = 4; + else + QP_stat = 1; + pout = strapp(pout,"\\begin{quotation}"); + } + else if (strcmp(w,".RE") == 0) { + pout = end_env(pout); + RSRE--; + if (RSRE < 0) + fprintf(stderr,".RE with no matching .RS\n"); + if (man) { + snprintf(tmp, sizeof(tmp), "\\ind{%d\\parindent}", RSRE); + pout = strapp(pout,tmp); + } + pin = skip_line(pin); + } + else if (strcmp(w,".RS") == 0) { + RSRE++; + if (man) { + pin += get_arg (pin, ww, 1); + snprintf(tmp, sizeof(tmp), "\\ind{%d\\parindent}", RSRE); + pout = strapp(pout,tmp); + } + pin = skip_line (pin); + } + else if (strcmp(w,".Re") == 0) { + if (ref == 0) + pout = strapp(pout,"\\REF\n"); + ref++; + pin = skip_line(pin); + pin += get_ref(pin,ww); + snprintf(tmp,sizeof(tmp),"\\reference{%s}",ww); + pout = strapp(pout,tmp); + } + else if (man && (strcmp(w,".TP") == 0 || strcmp(w,".HP") == 0)) { + if (IP_stat[RSRE] && TP_stat) { + pout = strapp(pout,"\\end{IPlist}%\n"); + IP_stat[RSRE] = 0; + } + if (QP_stat && TP_stat) { + pout = strapp(pout,"\\end{quotation}%\n"); + QP_stat = 0; + } + pin = skip_line(pin); + pin += get_line(pin,ww,1); + if (TP_stat == 0) { + snprintf(tmp,sizeof(tmp),"\\begin{TPlist}{%s}\n",ww); + pout = strapp(pout,tmp); + } + snprintf(tmp,sizeof(tmp),"\\item[{%s}]",ww); + pout = strapp(pout,tmp); + if (de_arg > 0) + mydef[mydef_count].par = 3; + else + TP_stat = 1; + } + else if (man && (strcmp(w,".TH") == 0)) { + /* expect something like .TH LS 1 "September 4, 1985"*/ + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL || pw [1] == NULL) + fprintf (stderr, "Missing argument in troff macro .TH\n"); + else { + for (j = 2; j <= 5; j++) + if (pw [j] == NULL) + break; + for (; j <= 5; j++) + pw[j] = ""; + snprintf(tmp, sizeof(tmp), "\\phead{%s}{%s}{%s}{%s}{%s}", + pw[0], pw[1], pw[2], pw[3], pw[4]); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".PN") == 0) { + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL) + fprintf (stderr, "Missing argument in troff macro .PN\n"); + else { + snprintf(tmp, sizeof(tmp), "{\\tt{}%s}%s ", + pw [0], pw [1]? pw [1]: ""); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".CW") == 0) + pout = strapp (pout, "\\tt{}"); + else if (man && strcmp (w, ".MS") == 0) { + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL || pw [1] == NULL) + fprintf (stderr, "Missing arguments in troff macro .MS\n"); + else { + snprintf(tmp, sizeof(tmp), "{\\tt{}%s}(%s)%s ", + pw [0], pw [1], pw [2]? pw [2]: ""); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".EX") == 0) { + pin += get_arg (pin, ww, 1); + pin = skip_line (pin); + snprintf(tmp,sizeof(tmp), "\\nofill\\ind{%d\\parindent}\\tt{}", ++EXEE); + pout = strapp(pout,tmp); + } + else if (man && strcmp (w, ".EE") == 0) { + if (EXEE == 0) + fprintf(stderr,".EE with no matching .EX\n"); + else { + --EXEE; + pout = strapp(pout, "\\fill "); + } + } + else if (man && strcmp (w, ".NT") == 0) { + ++NTNE; + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL) + pout = strapp (pout, "\\beginnotec{NOTE}"); + else { + if (strcmp (pw [0], "C") == 0) { + if (pw [1]) { + snprintf (tmp, sizeof(tmp), "\\beginnotec{%s}", pw [1]); + pout = strapp (pout, tmp); + } else { + pout = strapp (pout, "\\beginnotec{NOTE}"); + } + } + else { + snprintf(tmp, sizeof(tmp), "\\beginnote{%s}", pw [0]); + pout = strapp (pout, tmp); + } + } + } + else if (man && strcmp (w, ".NE") == 0) { + if (NTNE == 0) + fprintf(stderr,".NE with no matching .NT\n"); + else { + --NTNE; + pout = strapp(pout, "\n\\end{quote}\n"); + } + } + else if (strcmp(w,".TS") == 0) + { + fprintf(stderr, "I am not very good at tables.\n" + "I can only do very simple ones. " + "You may need to check what I've done.\n"); + pin = skip_line(pin); + pout = do_table(pin,pout,&offset); + pin += offset; + offset = 0; /* reset */ + } + /* Now search for commands that start with small letters */ + else if (strcmp(w,".TE") == 0) { + fprintf(stderr, + "Oops! I goofed. I told you I am not very good at tables.\n" + "I have encountered a table end but I am not in table mode.\n"); + }/* + else if (strcmp(w, ".ad") == 0) { + pin += get_arg(pin, w, 0); + pin += skip_white(pin); + snprintf(tmp, sizeof(tmp), "\\adjust{%s}\n", w); + pout = strapp(pout,tmp); + }*/ + else if (strcmp(w, ".de") == 0) { + de_arg = 1; + if (mydef_count >= MAXDEF) { + fprintf(stderr, + "Too many .de's. MAXDEF=%d\n", MAXDEF); + exit(-1); + } + pin += skip_white(pin); + pin += get_defword(pin, w, &illegal); + pin += skip_white(pin); + pin += get_mydef(pin, ww); + mydef[mydef_count].arg_no = de_arg; + if (illegal) { + mydef[mydef_count].illegal = 1; + fprintf(stderr, + "illegal TeX macro, %s, replacing it\n",w); + mydef[mydef_count].replace = strdup(ww); + } + else { + mydef[mydef_count].illegal = 0; + snprintf(tmp,sizeof(tmp),"\\def\\%s",w); + pout = strapp(pout,tmp); + for (j=1; j<de_arg; j++) { + snprintf(tmp,sizeof(tmp),"#%d",j); + pout = strapp(pout,tmp); + } + snprintf(tmp,sizeof(tmp),"{%s}\n",ww); + pout = strapp(pout,tmp); + } + p = (char *)malloc((unsigned)(strlen(w)+2)); + sprintf(p,".%s",w); + mydef[mydef_count++].def_macro = p; + pin = skip_line(pin); + de_arg = 0; + } + else if (strcmp(w, ".ds") == 0) { + pin += get_arg(pin, w, 0); + pin += skip_white(pin); + pin += get_line(pin, ww, 1); + if ((p = strchr(ww, '%')) != NULL) { + *(p-1) = EOS; + p++; + snprintf(tmp, sizeof(tmp), "%s\\rm\\thepage %s", ww, p); + strcpy(ww, tmp); + } + if (strcmp(w, "LH") == 0) { + snprintf(tmp, sizeof(tmp),"\\lefthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "CH") == 0) { + snprintf(tmp, sizeof(tmp),"\\centerthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "RH") == 0) { + snprintf(tmp, sizeof(tmp),"\\righthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "LF") == 0) { + snprintf(tmp, sizeof(tmp),"\\leftfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "CF") == 0) { + snprintf(tmp, sizeof(tmp),"\\centerfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "RF") == 0) { + snprintf(tmp, sizeof(tmp),"\\rightfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else { + fprintf(stderr, "Define troff string '%s'\n", w); + snprintf(tmp, sizeof(tmp), "\\defTroffString{%s}{%s}", w, ww); + pout = strapp(pout,tmp); + } + } + else if (strcmp(w, ".ft") == 0) { + pin += get_arg(pin, ww, 0); + if (ww[0] == EOS) c1 = 'P'; else c1 = ww[0]; + switch(c1) { + case 'R': + lastfont = thisfont; + thisfont = 1; + pout = strapp(pout, "\\rm%"); + break; + case 'I': + lastfont = thisfont; + thisfont = 2; + pout = strapp(pout, "\\it%"); + break; + case 'B': + lastfont = thisfont; + thisfont = 3; + pout = strapp(pout, "\\bf%"); + break; + case 'P': + default: + switch(lastfont) { + case 1: + pout = strapp(pout,"\\rm%"); + thisfont = 1; + break; + case 2: + pout = strapp(pout,"\\it%"); + thisfont = 2; + break; + case 3: + pout = strapp(pout,"\\bf%"); + thisfont = 3; + break; + default: + pout = strapp(pout,"\\rm%"); + thisfont = 1; + break; + } + break; + } + } + else if (strcmp(w,".sp") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&space); + snprintf(tmp,sizeof(tmp),"\\par\\vspace{%3.1f%s}",space.value,space.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".in") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&indent); + snprintf(tmp,sizeof(tmp),"\\ind{%3.1f%s}",indent.value,indent.units); + pout = strapp(pout, tmp); + } + else if (strcmp(w,".ls") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&linespacing); + snprintf(tmp,sizeof(tmp),"\\baselineskip=%3.1f%s",linespacing.value, + linespacing.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".so") == 0) { + pin += get_arg(pin,ww,0); + snprintf(tmp,sizeof(tmp),"\\input %s",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, ".sp") == 0) { + pin += get_arg(pin, ww, 0); + (void) get_size(ww, &space); + snprintf(tmp, sizeof(tmp), "\\par\\noindent\\vspace{%3.1f%s}%%", space.value, space.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".ti") == 0) { + pin += get_arg(pin,ww,0); + tmpind.value = indent.value; + strcpy(tmpind.units,indent.units); + (void) get_size(ww,&tmpind); + snprintf(tmp,sizeof(tmp),"\\tmpind{%3.1f%s}", tmpind.value,tmpind.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".vs") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&vspace); + snprintf(tmp,sizeof(tmp),"\\par\\vspace{%3.1f%s}", vspace.value,vspace.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".nr") == 0) { + pin += get_arg(pin, ww, 0); + if (strcmp(ww, "VS") == 0) { + pin += get_arg(pin, tmp, 0); + (void) get_size(tmp, &linespacing); + snprintf(tmp, sizeof(tmp), "\\defTroffNr{%s}{%3.1f%s}\n", ww, + linespacing.value, linespacing.units); + pout = strapp(pout,tmp); + snprintf(tmp, sizeof(tmp), "\\baselineskip=%3.1f%s\n", linespacing.value, + linespacing.units); + pout = strapp(pout,tmp); + } + else + fprintf(stderr, "I do not understand .nr %s yet.\n", ww); + pin = skip_line(pin); + } + /* check if it is a member of a group */ + else if (mydef_count > 0 && (i=is_mydef(w)) >= 0) { + if (mydef[i].par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = mydef[i].par; + else { + pout = end_env(pout); + pout = strapp(pout,"\n"); + } + } + if (mydef[i].illegal) + pout = strapp(pout,mydef[i].replace); + else { + w[0] = '\\'; /* replace dot by backslash */ + pout = strapp(pout,w); + } + for (j=1; j <mydef[i].arg_no; j++) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + } + if (de_arg == 0) + envoke_stat(mydef[i].par); + } + else if ((i=is_troff_mac(w, ww, &arg, &par)) >= 0) { + if (par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = par; + else + pout = end_env(pout); + } + pout = strapp(pout,ww); + if (ww[0] == EOS) + pin = skip_line(pin); + if (ww[0] != EOS && arg == 0) { + pin = skip_line(pin); + *pout++ = '\n'; + } + if (arg > 0) { + if (arg == 1) { + pin += skip_white(pin); + if (*(pin-1) == '\n') + ww[0] = EOS; + else + pin += get_string(pin,ww,1); + } + else { + if (isupper(w[1])) { + pin = skip_line(pin); + pin += get_multi_line(pin, ww); + } + else { + pin += get_arg(pin, tmp, 0); + pin = skip_line(pin); + if (tmp[0] == EOS) + N = 1; + else + N = atoi(tmp); + pin += get_N_lines(pin, ww, N); + } + } + snprintf(tmp2, sizeof(tmp2), "{%s}", ww); + pout = strapp(pout,tmp2); + } + } + /* if none of the above commands matched, it is either + an illegal macro or an unknown command */ + else { + len = get_till_space(pin,ww); + snprintf(tmp,sizeof(tmp),"%s%s",w,ww); + if (mydef_count > 0 && (i=is_mydef(tmp)) >= 0) { + pin += len; + if (mydef[i].par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = mydef[i].par; + else { + pout = end_env(pout); + pout = strapp(pout,"\n"); + } + } + pout = strapp(pout,mydef[i].replace); + for (j=1; j <mydef[i].arg_no; j++) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + } + if (de_arg == 0) + envoke_stat(mydef[i].par); + } + else { + fprintf(stderr, "I cannot translate troff macro %s\n",w); + pin += get_line(pin,ww,0); + pout = strapp(pout,"%"); + pout = strapp(pout,w); + pout = strapp(pout,ww); + if (*pin == EOS) + *pout++ = '\n'; + } + } + } + + /* some manuals have commented lines beginning with ''' */ + else if (c2=='\'' && !mid && (c1=='\n' || c1==EOS || first_word)) { + if (*pin == '\'') { + pin++; + if (*pin == '\'') { + pin++; + pout = strapp(pout,"%"); + } + else + pout = strapp(pout,"''"); + } + else + pout = strapp(pout,"'"); + } + + /* See if it is one of these symbols */ + + else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 || + strcmp(w,"{") == 0 || strcmp(w,"}") == 0 || + strcmp(w,"%") == 0 || strcmp(w,"_") == 0 || + strcmp(w,"~") == 0 || strcmp(w,"^") == 0 ) { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + if (strcmp(w,"~") == 0 || strcmp(w,"^") == 0) + pout = strapp(pout,"{}"); + } + + else if (strcmp(w,">") == 0 || strcmp(w,"<") == 0 + || strcmp(w,"|") == 0) { + snprintf(tmp,sizeof(tmp),"$%s$",w); + pout = strapp(pout,tmp); + } + + /* check for backslash commands */ + + else if (strcmp(w, "\\") == 0) { + switch (*pin) { + case ' ': + case '\t': + case '\n': + pout = strapp(pout,"\\"); + *pout++ = *pin++; + break; + case ',': + pin++; + pout = strapp(pout, "{}"); + break; + case '/': + pin++; + pout = strapp(pout, "\\thinspace "); + break; + case EOS: + break; + case '-': + pin++; + pout = strapp(pout,"--"); + break; + case '~': + case '^': + pin++; + pout = strapp(pout,"\\/"); + break; + case '0': + pin++; + pout = strapp(pout,"\\ "); + break; + case 'e': + pin++; + pout = strapp(pout,"\\textbackslash "); + break; + case '$': + pin++; + if (rec && de_arg > 0) { + de_arg++; + *pout++ = '#'; + } else + pout = strapp(pout, "$"); + break; + case '\\': + pin++; + if (*pin == '$' && de_arg > 0) { + pin++; + de_arg++; + *pout++ = '#'; + } + else + pout = strapp(pout,"\\textbackslash "); + break; + case '`': + case '\'': + break; /* do nothing */ + case '"': + pin++; + if (rec == 1) + pout = strapp(pout, "\""); + else { + pin += get_line(pin, ww, 0); + pout = strapp(pout, "%"); + pout = strapp(pout, ww); + } + break; + case '|': + pin++; + pout = strapp(pout, "\\,"); + break; + case '&': + pin++; + pout = strapp(pout, "{}"); + break; + case '%': + pin++; + pout = strapp(pout,"\\-"); + break; + case '(': + pin++; + w[0] = *pin++; w[1] = *pin++; w[2] = EOS; + if (is_special(w, ww) > -1) { + if (ww[0] == '\\') + snprintf(tmp, sizeof(tmp), "\\hbox{%s}", ww); + else + strcpy(tmp, ww); + pout = strapp(pout, tmp); + } + else if (w[0] == '*') + *pout++ = w[1]; + else + fprintf(stderr, + "I am not prepared to handle \\(%s\n", w); + break; + case '[': /* groff string definition */ + pin++; + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + if (len == 2 && is_special(tmp, ww) > -1) { + snprintf(tmp2, sizeof(tmp2), "\\hbox{%s}", ww); + pout = strapp(pout, tmp2); + } else { + snprintf(tmp2, sizeof(tmp2), "\\useTroffString{%s}", tmp); + fprintf(stderr, "Please define TroffString@%s\n", tmp); + pout = strapp(pout, tmp2); + } + pin += (len+1); + } + break; + case 's': + pin +=3; + break; + case '*': + c1 = *++pin; + pin++; + switch (c1) { + case ':': + pout = strapp(pout,"\\\""); + break; + case 'C': + pout = strapp(pout,"\\v"); + break; + case ',': + pout = strapp(pout,"\\c"); + break; + case '`': + case '\'': + case '^': + case '~': + snprintf(tmp, sizeof(tmp), "\\%c", c1); + pout = strapp(pout, tmp); + break; + case '(': + pout = strapp(pout, "\\useTroffString"); + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + fprintf(stderr, "Check definition of TroffString@%s\n", ww); + break; + case '[': /*GNU troff string reference*/ + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + //fprintf(stderr, "Found: \\[%s] len:%d\n", tmp, len); + if (len == 2 && is_special(tmp, ww) > -1) { + snprintf(tmp2, sizeof(tmp2), "\\hbox{%s}", ww); + pout = strapp(pout, tmp2); + } else { + snprintf(tmp2, sizeof(tmp2), "\\useTroffString{%s}", tmp); + fprintf(stderr, "Please define TroffString@%s\n", tmp); + pout = strapp(pout, tmp2); + } + pin += (len+1); + } + break; + default: + fprintf(stderr, "TeX should understand \\%c\n", c1); + snprintf(tmp, sizeof(tmp), "\\%c", c1); + pout = strapp(pout, tmp); + break; + } + if (c1 == '(') { + snprintf(tmp, sizeof(tmp), "{%s}", ww); + pout = strapp(pout, tmp); + } else if (c1 != '[') { + c1 = *pin++; + snprintf(tmp,sizeof(tmp),"{%c}",c1); + pout = strapp(pout,tmp); + } + break; + case 'f': + c1 = *++pin; + pin++; + switch (c1) { + case '1': + case 'R': + lastfont = thisfont; + thisfont = 1; + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + pout = strapp(pout,"%\n\\rm "); + break; + case '2': + case 'I': + lastfont = thisfont; + thisfont = 2; + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + pout = strapp(pout,"%\n\\it "); + break; + case '3': + case 'B': + lastfont = thisfont; + thisfont = 3; + if (*pin == ' ' || *pin == '\t' || + *pin == '\n' || *pin == '\f') { + *pout++ = ' '; pin++; + } + pout = strapp(pout,"%\n\\bf "); + break; + case 'P': + /* preserve white space - from Nelson Beebe */ + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + switch(lastfont) { + case 1: + pout = strapp(pout,"\\rm%\n"); + thisfont = 1; + break; + case 2: + pout = strapp(pout,"\\it%\n"); + thisfont = 2; + break; + case 3: + pout = strapp(pout,"\\bf%\n"); + thisfont = 3; + break; + default: + pout = strapp(pout,"\\rm%\n"); + thisfont = 1; + break; + } + break; + case '(': + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + snprintf(tmp, sizeof(tmp), "\\useTroffFont{%s}", ww); + pout = strapp(pout, tmp); + fprintf(stderr, "Please define '\\TroffFont@%s' command\n", ww); + break; + default: + fprintf(stderr, "I do not understand \\f%c yet\n",c1); + break; + } + break; + case 'n': + c1 = *++pin; + pin++; + if (c1 == '(') { + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + snprintf(tmp, sizeof(tmp), "\\useTroffNr[%s]", ww); + fprintf(stderr, "Please define TroffRegister@%s\n", tmp); + pout = strapp(pout, tmp); + } else if (c1 == '[') { + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + snprintf(tmp2, sizeof(tmp2), "\\useTroffNr{%s}", tmp); + fprintf(stderr, "Please define TroffRegister@%s\n", tmp); + pout = strapp(pout, tmp2); + pin += (len+1); + //fprintf(stderr, "Found: \\n[%s] len:%d, next:%c\n", tmp, len,*pin); + } + } + break; + default: + fprintf(stderr,"I am not prepared to handle \\%c\n",*pin++); + break; + } + } + + /* if non of the above checks, its a dull word; copy it */ + + else + pout = strapp(pout,w); + *pout = EOS; + ww[0] = EOS; + tmp[0] = EOS; + tmp2[0] = EOS; + if (!no_word) + first_word = 0; + } + /* if file end, close opened environments and delimitters */ + if (rec == 0) { + pout = end_env(pout); + } + + *pout = EOS; +} |