[comp.sources.unix] v10i032: Translate troff to LaTex

rs@uunet.UU.NET (Rich Salz) (07/02/87)

Mod.Sources: Volume 10, Number 32
Submitted by: Kamal Al-Yahya <kamal@hanauma.stanford.edu>
Archive-name: tr2latex

This program translates troff documents to latex.  You will notice that the
translation is not always 100%, but it relieves one from manual translation,
where the user might need to touch up on the translated document to customize
the translation.

There is a testfile and a manual page in the package that can be used
to test the translator.  Try some UNIX manual pages too.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	tr2tex.c
#	tr.c
#	subs.c
#	setups.h
#	simil.h
#	greek.h
#	flip.h
#	forbid.h
#	macros.h
#	maths.h
#	makefile
#	makefile.msc
#	troffms.sty
#	troffman.sty
#	tr2tex.9
#	tr2tex.9-tex-orig
#	README
#	testfile
#	testfile.tex-orig
#	diffs.tex
# This archive created: Sun Mar  8 12:05:26 1987
export PATH; PATH=/bin:$PATH
if test -f 'tr2tex.c'
then
	echo shar: will not over-write existing file "'tr2tex.c'"
else
cat << \SHAR_EOF > 'tr2tex.c'
/* COPYRIGHT (C) 1987 Kamal Al-Yahya */

/* tr2tex: troff to tex translator */
/* Author: Kamal Al-Yahya, Stanford University,		9/4/86 */
/* Last modified:					1/1/87 */
/* Keyword: convert translate tex troff */

char *documentation[] = {
" SYNTAX",
"        tr2tex [-m] file1 file2 ...",
"or",
"        tr2tex [-m] < file1 file2 ...",
"",
" Use the -m flag for manual",
"",
};

int	doclength = { sizeof documentation/sizeof documentation[0] };

#include        "setups.h"

#ifdef tops20
#define TEMPFILE "texXXXXXX"
#else
#define TEMPFILE "/tmp/texXXXXXX"
#endif

FILE *out_file;

#if HAVE_SGTTY
struct sgttyb ttystat;
#endif
extern char *mktemp();
char scratch_file[MAXWORD];

int man;
int xargc;
char **xargv;

int
main(argc,argv)
int argc; 
char *argv[];
{

char *inbuf, *outbuf;

FILE *temp,*scr;
register char *cptr;
int piped_in;
int i;
long timeval;		/* clock value from time() for ctime()	*/
char *document = "article";			/* document type */
char *options = "[troffms,11pt]";		/* style options */

/* Allocate large arrays dynamically to conserve stack space */

if (((inbuf = (char *)malloc(MAXLEN*sizeof(char))) == (char *)NULL) ||
    ((outbuf = (char *)malloc(MAXLEN*sizeof(char))) == (char *)NULL))
	{
    	fprintf(stderr,"tr2tex: Cannot malloc() internal buffer space\n\
Need two arrays of %d characters each\n",MAXLEN);
	exit(-1);
	}

/* If no arguments, and not in a pipeline, self document */
#if HAVE_SGTTY
piped_in = ioctl ((fileno (stdin)), TIOCGETP, &ttystat);
#else	/* if no sggty, it cannot distinguish piped input from no input */
piped_in = (argc == 1);
#endif

if (argc == 1 && !piped_in)
	{
	for( i=0; i<doclength; i++)
		printf("%s\n",documentation[i]);
	exit (0);
	}

/* initialize spacing and indentation parameters */
strcpy(linespacing.def_units,"\\normalbaselineskip");
strcpy(linespacing.old_units,"\\normalbaselineskip");
strcpy(indent.def_units,"em");		strcpy(indent.old_units,"em");
strcpy(tmpind.def_units,"em");		strcpy(tmpind.old_units,"em");
strcpy(space.def_units,"\\baselineskip");
strcpy(space.old_units,"\\baselineskip");
strcpy(vspace.def_units,"pt");		strcpy(vspace.old_units,"pt");
linespacing.value = 1.;			linespacing.old_value = 1.;
indent.value = 0.;			indent.old_value = 0.;
tmpind.value = 0.;			tmpind.old_value = 0.;
space.value = 1.;			space.old_value = 1.;
vspace.value = 1.;			vspace.old_value = 1.;
linespacing.def_value = 0;
indent.def_value = 0;
tmpind.def_value = 0;
space.def_value = 1;
vspace.def_value = 1;

out_file = stdout;		/* default output */
math_mode = 0;			/* start with non-math mode */
de_arg = 0;			/* not a .de argument */

/* process option flags */
xargc = argc;
xargv = argv;
for (xargc--,xargv++; xargc; xargc--,xargv++)
	{
	cptr = *xargv; 
	if( *cptr=='-' )
		{
		while( *(++cptr))
			{
			switch( *cptr )
				{
				case 'm':
					man = 1;
					strcpy(options,"[troffman]");
					break;
				default:
			     		fprintf(stderr,
						"tr2tex: unknown flag -%c\n",*cptr);
					break;
				}
			}
		}
	}
/* start of translated document */

timeval = time(0);
fprintf(out_file,"%% -*-LaTeX-*-\n\
%% Converted automatically from troff to LaTeX by tr2tex on %s",ctime(&timeval));
fprintf(out_file,"%% tr2tex was written by Kamal Al-Yahya at Stanford University\n\
%% (Kamal%%Hanauma@SU-SCORE.ARPA)\n\n\n");

/* document style and options */
fprintf(out_file,"\\documentstyle%s{%s}\n\\begin{document}\n",options,document);

/* first process pipe input */
if(piped_in)
	{
/* need to buffer; can't seek in pipes */
/* make a temporary and volatile file */
	strcpy(scratch_file,TEMPFILE);
	mktemp(scratch_file);
	if ((scr=fopen(scratch_file,"w")) == (FILE *)NULL)
		{
		fprintf(stderr,
	        "tr2tex: Cannot open scratch file [%s]\n",scratch_file);
		exit(-1);
		}
	scrbuf(stdin,scr);
	fclose(scr);
	scr=fopen(scratch_file,"r");
	unlink(scratch_file);
	tmpbuf(scr,inbuf);
	fclose(scr);
	troff_tex(inbuf,outbuf,0,0);
	fprintf(out_file,"%%\n%% input file: stdin\n%%\n");
	fputs(outbuf,out_file);
	}

/* then process input line for arguments and assume they are input files */
xargc = argc;
xargv = argv;

for (xargc--,xargv++; xargc; xargc--,xargv++)
	{
	cptr = *xargv; 
	if( *cptr=='-' ) continue; /* this is a flag */
	if((temp=fopen(cptr,"r")) != (FILE *)NULL)
		{
		tmpbuf(temp,inbuf);
		fclose(temp);
		troff_tex(inbuf,outbuf,0,0);
		fprintf(out_file,"%%\n%% input file: %s\n%%\n",cptr);
		fputs(outbuf,out_file);
		}
	else
		fprintf(stderr,"tr2tex: Cannot open %s\n",cptr);
	}
/* close translated document */
fputs("\\end{document}\n",out_file);

exit(0);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'tr.c'
then
	echo shar: will not over-write existing file "'tr.c'"
else
cat << \SHAR_EOF > 'tr.c'
/* COPYRIGHT (C) 1987 Kamal Al-Yahya */

/*
This program has the HARD-WIRED rules of the translator.
It should handled with care.
*/

#define IN_TR  1
#include        "setups.h"
int def_count = 0;
int mydef_count = 0;

void
troff_tex(inbuf,outbuf,mid,rec)
char *inbuf,*outbuf;
int mid,rec;
{
char eqn_no[MAXWORD], w[MAXWORD], ww[MAXLINE], tmp[MAXWORD], tmp2[MAXWORD];
char *p;
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 RSRE = 0;			/* block indentation */
int thisfont = 1;		/* default font is roman */
int lastfont = 1;		/* default last font is roman */
int offset = 0;			/* amount to offset inbuf */
extern man;			/* man flag */

*outbuf = NULL;		w[0] = NULL;	ww[0] = NULL;
tmp[0] = NULL;		tmp2[0] = NULL;
while (*inbuf != NULL)
	{
	len = getword(inbuf,w);
	c1 = *--inbuf;
	c2 = *++inbuf;
	inbuf += len;
	if (isspace(w[0]) == 0)		no_word = 0;
/* first check if we are in math mode */
	if (math_mode)
		{
		len = get_till_space(inbuf,ww);
		sprintf(tmp,"%s%s",w,ww);
		if (strcmp(w,"delim") == 0)
			{
			delim_defd = 1;
			inbuf += skip_white(inbuf);
			DELIM[0] = *inbuf;
			inbuf = skip_line(inbuf);
			}
/* 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;
			*outbuf++ = '$';
			}
/* check for illegal macros here */
		else if (len > 0 && def_count > 0 && (i=is_def(tmp)) >= 0)
			{
			inbuf += len;
			outbuf = strapp(outbuf,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)
				outbuf = strapp(outbuf,def[i].replace);
			else
				{
				outbuf = strapp(outbuf,"\\");
				outbuf = strapp(outbuf,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)
			{
			outbuf = strapp(outbuf,"\\");
			outbuf = strapp(outbuf,w);
			}
		else if (strcmp(w,"=") == 0)
			{
			if (*inbuf == '=')
				{
				inbuf++;
				outbuf = strapp(outbuf,"\\equiv");
				}
			else
				outbuf = strapp(outbuf,"=");
			}
		else if (strcmp(w,"<") == 0 || strcmp(w,">") == 0)
			{
			if (*inbuf == '=')
				{
				inbuf++;
				if (strcmp(w,"<") == 0)
					outbuf = strapp(outbuf,"\\le");
				else
					outbuf = strapp(outbuf,"\\ge");
				}
			}
		else if (strcmp(w,"-") == 0)
			{
			if (*inbuf == '>')
				{
				inbuf++;
				outbuf = strapp(outbuf,"\\to");
				}
			else if (*inbuf == '+')
				{
				inbuf++;
				outbuf = strapp(outbuf,"\\mp");
				}
			else
				*outbuf++ = '-';
			}
		else if (strcmp(w,"+") == 0)
			{
			if (*inbuf == '-')
				{
				inbuf++;
				outbuf = strapp(outbuf,"\\pm");
				}
			else
				*outbuf++ = '+';
			}
		else if (strcmp(w,"\"") == 0)
			{
			len = get_no_math(inbuf,ww);
			inbuf += len+1;
			if (len > 1)
				{
				sprintf(tmp,"\\ \\it\\hbox{%s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			else if (len == 1)
				*outbuf++ = 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)
				{
				sprintf(tmp,"\\eqno %s",eqn_no);
				outbuf = strapp(outbuf,tmp);
				}
			eqn_no[0] = NULL;
			c1 = *--outbuf;
			c2 = *--outbuf;
			if (c1 == '\n' && c2 == '$')
				*--outbuf = NULL;
			else
				{
				outbuf += 2;
				outbuf = strapp(outbuf,"$$");
				}
			}
/* Now search for symbols that start with a small letter */
		else if (strcmp(w,"bold") == 0 || strcmp(w,"roman") == 0 ||
			 strcmp(w,"italic") == 0)
			{
			inbuf += get_arg(inbuf,ww,1);
			if (strcmp(w,"bold") == 0)
				{
				sprintf(tmp,"{\\bf %s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			else if (strcmp(w,"roman") == 0)
				{
				sprintf(tmp,"{\\rm %s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			else
				{
				sprintf(tmp,"{\\it %s}",ww);
				outbuf = strapp(outbuf,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; *--outbuf != '$' && i < MAXLEN; i++)
				tmp[i] = *outbuf;
			tmp[i] = NULL;
			strcat(tmp,"$$");
			*--outbuf = NULL;
			inbuf += skip_white(inbuf);
			inbuf += get_defword(inbuf,w,&illegal);
			inbuf += skip_white(inbuf);
			inbuf += getdef(inbuf,ww);
			if (illegal)
				{
				def[def_count].illegal = 1;
				fprintf(stderr,
					"illegal TeX macro, %s, replacing it\n",w);
				p = (char *)malloc((unsigned)(strlen(ww)+1)*
					sizeof(char));
				strcpy(p,ww);
				def[def_count].replace = p;
				}
			else
				{
				def[def_count].illegal = 0;
				sprintf(tmp2,"\\def\\%s{%s}\n",w,ww);
				outbuf = strapp(outbuf,tmp2);
				}
			p = (char *)malloc((unsigned)(strlen(w)+1)*sizeof(char));
			strcpy(p,w);
			def[def_count++].def_macro = p;
			inbuf += skip_white(inbuf);
			for (j=i+1; j >= 0; j--)
				*outbuf++ = tmp[j];
			tmp[0] = NULL;
			}
		else if (strcmp(w,"gsize") == 0 || strcmp(w,"gfont") == 0)
			inbuf = skip_line(inbuf);
		else if (strcmp(w,"left") == 0 || strcmp(w,"right") == 0)
			{
			sprintf(tmp,"\\%s",w);
			outbuf = strapp(outbuf,tmp);
			inbuf += skip_white(inbuf);
			len = getword(inbuf,ww);
			if (strcmp(ww,"floor") == 0)
				{
				inbuf += len;
				if (strcmp(w,"left") == 0)
					outbuf = strapp(outbuf,"\\lfloor");
				else
					outbuf = strapp(outbuf,"\\rfloor");
				}
			else if (strcmp(ww,"nothing") == 0 || ww[0] == '\"')
				{
				inbuf += len;
				*outbuf++ = '.';
				if (ww[0] == '\"')	inbuf++;
				}
			else if (*inbuf == '{' || *inbuf == '}')
				*outbuf++ = '\\';
			}
		else if (strcmp(w,"over") == 0)
			{
			if (!first_word)
				{
				outbuf--;
				for (i=0; *outbuf == ' ' || *outbuf == '\t' ||
						*outbuf =='\n'; i++)
					tmp[i] = *outbuf--;
				if (*outbuf == '}' && put_brace == 0)
					*outbuf = ' ';
				else
					{
					for (; !(*outbuf == ' ' || *outbuf == '\t'
					|| *outbuf =='\n' || *outbuf == '$'); i++)
						tmp[i] = *outbuf--;
					put_brace = 0;
				*++outbuf = '{';
					}
				for (j=i-1; j >= 0; j--)
					*++outbuf = tmp[j];
			*++outbuf = NULL;
				}
			outbuf = strapp(outbuf,"\\over");
			inbuf += skip_white(inbuf);
			*outbuf++ = ' ';
			if (*inbuf == '{')
				inbuf++;
			else
				{
				inbuf = get_over_arg(inbuf,ww);
				outbuf = strapp(outbuf,ww);
				if (*inbuf != NULL || !first_word)
					*outbuf++ = '}';
				}
			}
		else if (strcmp(w,"size") == 0)
			inbuf += get_arg(inbuf,ww,0);
		else if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0 ||
			 strcmp(w,"sub") == 0 || strcmp(w,"from") == 0)
			{
			while ((c = *--outbuf) == ' ' || c == '\t' || c == '\n') ;
			*++outbuf = NULL;
			if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0)
				outbuf = strapp(outbuf,"^");
			else
				outbuf = strapp(outbuf,"_");
			inbuf += skip_white(inbuf);
			len = get_sub_arg(inbuf,ww);
			inbuf += len;
			if (len > 1)
				{
				sprintf(tmp,"{%s}",ww);
				outbuf = strapp(outbuf,tmp);
				len = skip_white(inbuf);
				inbuf += len;
				(void) getword(inbuf,ww);
				if (strcmp(ww,"over") == 0)
					put_brace = 1;
				inbuf -= len;
				}
			else
				outbuf = strapp(outbuf,ww);
			}
		else if (strcmp(w,"up") == 0 || strcmp(w,"down") == 0
			 || strcmp(w,"fwd") == 0 || strcmp(w,"back") == 0)
			{
			if (strcmp(w,"up") == 0)
				{
				outbuf = strapp(outbuf,"\\raise");
				strcpy(tmp,"ex");
				}
			else if (strcmp(w,"down") == 0)
				{
				outbuf = strapp(outbuf,"\\lower");
				strcpy(tmp,"ex");
				}
			else if (strcmp(w,"fwd") == 0)
				{
				outbuf = strapp(outbuf,"\\kern");
				strcpy(tmp,"em");
				}
			else if (strcmp(w,"back") == 0)
				{
				outbuf = strapp(outbuf,"\\kern-");
				strcpy(tmp,"em");
				}
			inbuf += skip_white(inbuf);
			inbuf += getword(inbuf,ww);
			len = atoi(ww);		flen = len/100.;
			ww[0] = NULL;
			sprintf(tmp2,"%4.2f%s",flen,tmp);
			outbuf = strapp(outbuf,tmp2);
			}
/* Now check if the word is a member of a group */
		else if (CAP_GREEK(w) > 0)
			{
			GR_to_Greek(w,ww);
			outbuf = strapp(outbuf,ww);
			}
		else if (is_flip(w) >= 0)
			{
			if (!first_word)
				{
				len = skip_white(inbuf);
				inbuf += len;
				(void) getword(inbuf,ww);
				if (is_flip(ww) >= 0)
					{
					inbuf += strlen(ww);
					outbuf = flip_twice(outbuf,w,ww);
					}
				else
					{
					inbuf -= len;
					outbuf = flip(outbuf,w);
					}
				}
			else
				{
				outbuf = strapp(outbuf,"\\");
				outbuf = strapp(outbuf,w);
				}
			}
		else if (is_mathcom(w,ww) >=0 )
			outbuf = strapp(outbuf,ww);
		else if (similar(w) > 0)
			{
			outbuf = strapp(outbuf,"\\");
			outbuf = strapp(outbuf,w);
			}

/* if none of the above math commands matched, it is an ordinary symbol;
   just copy it */

		else	outbuf = strapp(outbuf,w);
		}

/* check if it is a math delimiter; switch to math mode if so */

	else if (strcmp(w,"$") == 0 && de_arg > 0)
		{
		de_arg++;
		*outbuf++ = '#';
		}
	else if (delim_defd && strcmp(w,DELIM) == 0)
		{
		math_mode = 1;
		*outbuf++ = '$';
		}
	else if (strcmp(w,"$") == 0)
		outbuf = strapp(outbuf,"\\$");

/* check if it is a non-math troff command */

	else if ((c2 == '.') && !(mid) && (c1 == '\n' || (first_word)))
		{
/* Search in some order; start with non-alphanumeric characters */
		if (strcmp(w,".") == 0)
			{
			c1 = *inbuf;
			c2 = *++inbuf;
			if (c1 == '\\' && c2 == '\"')
				{
				++inbuf;
				inbuf += get_line(inbuf,ww,0);
				outbuf = strapp(outbuf,"%");
				outbuf = strapp(outbuf,ww);
				}
			else
				{
				fprintf(stderr,
				"I cannot translate troff macro .%c%c\n",c1,c2);
				inbuf += get_line(inbuf,ww,0);
				sprintf(tmp,"%%.%c%c",c1,c2);
				outbuf = strapp(outbuf,tmp);
				outbuf = strapp(outbuf,ww);
				if (*inbuf == NULL)	*outbuf++ = '\n';
				}
			}
/* Now search for commads that start with a capital */
		else if (strcmp(w,".AB") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			if (strcmp(ww,"no") == 0)
				outbuf = strapp(outbuf,"\\bigskip");
			else
				outbuf = strapp(outbuf,"\\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)
			{
			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
				strcpy(w,"it");
			inbuf += get_arg(inbuf,ww,1);
			if (ww[0] == NULL)
				{
				outbuf = strapp(outbuf,"\\");
				outbuf = strapp(outbuf,w);
				}
			else
				{
				sprintf(tmp,"{\\%s %s}",w,ww);
				outbuf = strapp(outbuf,tmp);
				}
			}
		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))
			{
			outbuf = alternate(inbuf,outbuf,w);
			inbuf = skip_line(inbuf);
			*outbuf++ = '\n';
			}
		else if (strcmp(w,".BX") == 0)
			{
			inbuf += get_arg(inbuf,ww,1);
			sprintf(tmp,"\\fbox{%s}",ww);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".EQ") == 0)
			{
			math_mode = 1;
			put_brace = 0;
			outbuf = strapp(outbuf,"$$");
			len = get_arg(inbuf,eqn_no,0);
			if (strcmp(eqn_no,"I") == 0 || strcmp(eqn_no,"L") == 0)
				{
				fprintf(stderr,"lineups are ignored\n");
				inbuf += len;
				len = get_arg(inbuf,eqn_no,0);
				}
			if ((strlen(eqn_no)) > 0)
				inbuf += len;
			len = get_arg(inbuf,tmp,0);
			if (strcmp(tmp,"I") == 0 || strcmp(tmp,"L") == 0)
				{
				fprintf(stderr,"lineups are ignored\n");
				inbuf += len;
				}
			}
		else if (strcmp(w,".IP") == 0)
			{
			inbuf += get_arg(inbuf,ww,1);
			inbuf = skip_line(inbuf);
			if (IP_stat == 0)
				outbuf = strapp(outbuf,"\\begin{itemize}\n");
			sprintf(tmp,"\\item[{%s}]\n",ww);
			outbuf = strapp(outbuf,tmp);
			if (de_arg > 0)		mydef[mydef_count].par = 2;
			else			IP_stat = 1;
			}
		else if (strcmp(w,".KE") == 0)
			{
			if (floating)
				outbuf = strapp(outbuf,"\\end{figure}");
			else
				outbuf = strapp(outbuf,"}");
			floating = 0;
			}
		else if (strcmp(w,".KF") == 0)
			{
			floating = 1;
			outbuf = strapp(outbuf,"\\begin{figure}");
			}
		else if (strcmp(w,".QP") == 0)
			{
			if (de_arg > 0)		mydef[mydef_count].par = 4;
			else			QP_stat = 1;
			outbuf = strapp(outbuf,"\\begin{quotation}");
			}
		else if (strcmp(w,".RE") == 0)
			{
			RSRE--;
			if (RSRE < 0)
				fprintf(stderr,".RS with no matching .RE\n");
			sprintf(tmp,"\\ind{%d\\parindent}",RSRE);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".RS") == 0)
			{
			RSRE++;
			sprintf(tmp,"\\ind{%d\\parindent}",RSRE);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".Re") == 0)
			{
			if (ref == 0)
				outbuf = strapp(outbuf,"\\REF\n");
			ref++;
			inbuf = skip_line(inbuf);
			inbuf += get_ref(inbuf,ww);
			sprintf(tmp,"\\reference{%s}",ww);
			outbuf = strapp(outbuf,tmp);
			}
		else if (man && (strcmp(w,".TP") == 0 || strcmp(w,".HP") == 0))
			{
			if (IP_stat && TP_stat)
				{
				outbuf = strapp(outbuf,"\\end{itemize}%\n");
				IP_stat = 0;
				}
			if (QP_stat && TP_stat)
				{
				outbuf = strapp(outbuf,"\\end{quotation}%\n");
				QP_stat = 0;
				}
			inbuf = skip_line(inbuf);
			inbuf += get_line(inbuf,ww,1);
			if (TP_stat == 0)
				{
				sprintf(tmp,"\\begin{TPlist}{%s}\n",ww);
				outbuf = strapp(outbuf,tmp);
				}
			sprintf(tmp,"\\item[{%s}]",ww);
			outbuf = strapp(outbuf,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"*/
			outbuf = strapp(outbuf,"\\phead");
			for (j = 1; j <= 3; ++j)
				{
				inbuf += get_arg(inbuf,ww,0);
				sprintf(tmp,"{%s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			*outbuf++ = '\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");
			inbuf = skip_line(inbuf);
			outbuf = do_table(inbuf,outbuf,&offset);
			inbuf += 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.\nI have encountered a table end but I am not in table mode\n");
			}
		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);
				}
			inbuf += skip_white(inbuf);
			inbuf += get_defword(inbuf,w,&illegal);
			inbuf += skip_white(inbuf);
			inbuf += get_mydef(inbuf,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);
				p = (char *)malloc((unsigned)(strlen(ww)+2)*
					sizeof(char));
				sprintf(p,"%s",ww);
				mydef[mydef_count].replace = p;
				}
			else
				{
				mydef[mydef_count].illegal = 0;
				sprintf(tmp,"\\def\\%s",w);
				outbuf = strapp(outbuf,tmp);
				for (j=1; j<de_arg; j++)
					{
					sprintf(tmp,"#%d",j);
					outbuf = strapp(outbuf,tmp);
					}
				sprintf(tmp,"{%s}\n",ww);
				outbuf = strapp(outbuf,tmp);
				}
			p = (char *)malloc((unsigned)(strlen(w)+2)*sizeof(char));
			sprintf(p,".%s",w);
			mydef[mydef_count++].def_macro = p;
			inbuf = skip_line(inbuf);
			de_arg = 0;
			}
		else if (strcmp(w,".ds") == 0)
			{
			inbuf += get_arg(inbuf,w,0);
			inbuf += skip_white(inbuf);
			inbuf += get_line(inbuf,ww,1);
			if (strcmp(w,"LH") == 0)
				{
				sprintf(tmp,"\\lefthead{%s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			else if (strcmp(w,"RH") == 0)
				{
				sprintf(tmp,"\\righthead{%s}",ww);
				outbuf = strapp(outbuf,tmp);
				}
			else if (strcmp(w,"CF") == 0)
				{
				if (index(ww,'%') == 0)
					{
					sprintf(tmp,"\\footer{%s}",ww);
					outbuf = strapp(outbuf,tmp);
					}
				else
					outbuf = strapp(outbuf,
							"\\footer{\\rm\\thepage}");
				}
			else
				{
				fprintf(stderr,"I do not understand .ds %s\n",w);
				sprintf(tmp,"%%.ds %s %s",w,ww);
				outbuf = strapp(outbuf,tmp);
				}
			}
		else if (strcmp(w,".sp") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			(void) get_size(ww,&space);
			sprintf(tmp,"\\par\\vspace{%3.1f%s}",
				space.value,space.units);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".in") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			(void) get_size(ww,&indent);
			sprintf(tmp,"\\ind{%3.1f%s}",indent.value,indent.units);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".ls") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			(void) get_size(ww,&linespacing);
			sprintf(tmp,"\\baselineskip=%3.1f%s",linespacing.value,
					linespacing.units);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".so") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			sprintf(tmp,"\\input %s",ww);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".ti") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			tmpind.value = indent.value;
			strcpy(tmpind.units,indent.units);
			(void) get_size(ww,&tmpind);
			sprintf(tmp,"\\tmpind{%3.1f%s}",
				tmpind.value,tmpind.units);
			outbuf = strapp(outbuf,tmp);
			}
		else if (strcmp(w,".vs") == 0)
			{
			inbuf += get_arg(inbuf,ww,0);
			(void) get_size(ww,&vspace);
			sprintf(tmp,"\\par\\vspace{%3.1f%s}",
				vspace.value,vspace.units);
			outbuf = strapp(outbuf,tmp);
			}
/* 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
					{
					outbuf = end_env(outbuf);
					outbuf = strapp(outbuf,"\n");
					}
				}
			if (mydef[i].illegal)
				outbuf = strapp(outbuf,mydef[i].replace);
			else
				{
				w[0] = '\\';	/* replace dot by backslash */
				outbuf = strapp(outbuf,w);
				}
			for (j=1; j <mydef[i].arg_no; j++)
				{
				inbuf += get_arg(inbuf,ww,1);
				sprintf(tmp,"{%s}",ww);
				outbuf = strapp(outbuf,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		outbuf = end_env(outbuf);
				}
			outbuf = strapp(outbuf,ww);
			if (ww[0] == NULL)
				inbuf = skip_line(inbuf);
			if (ww[0] != NULL && arg == 0)
				{
				inbuf = skip_line(inbuf);
				*outbuf++ = '\n';
				}
			if (arg > 0) 
				{
				if (arg == 1)
					{
					inbuf += skip_white(inbuf);
					inbuf += get_string(inbuf,ww,1);
					}
				else
					{
					if (isupper(w[1]))
						{
						inbuf = skip_line(inbuf);
						inbuf += get_multi_line(inbuf,ww);
						}
					else
						{
						inbuf += get_arg(inbuf,tmp,0);
						inbuf = skip_line(inbuf);
						if (tmp[0] == NULL)	N = 1;
						else		N = atoi(tmp);
						inbuf += get_N_lines(inbuf,ww,N);
						}
					}
				sprintf(tmp2,"{%s}",ww);
				outbuf = strapp(outbuf,tmp2);
				}
			}
/* if none of the above commands matched, it is either
   an illegal macro or an unknown command */
		else
			{
			len = get_till_space(inbuf,ww);
			sprintf(tmp,"%s%s",w,ww);
			if (mydef_count > 0 && (i=is_mydef(tmp)) >= 0)
				{
				inbuf += len;
				if (mydef[i].par > 0)
					{
					if (de_arg > 0)
						mydef[mydef_count].par=mydef[i].par;
					else
						{
						outbuf = end_env(outbuf);
						outbuf = strapp(outbuf,"\n");
						}
					}
				outbuf = strapp(outbuf,mydef[i].replace);
				for (j=1; j <mydef[i].arg_no; j++)
					{
					inbuf += get_arg(inbuf,ww,1);
					sprintf(tmp,"{%s}",ww);
					outbuf = strapp(outbuf,tmp);
					}
				if (de_arg == 0)	envoke_stat(mydef[i].par);
				}
			else
				{
				fprintf(stderr,
				"I cannot translate troff macro %s\n",w);
				inbuf += get_line(inbuf,ww,0);
				outbuf = strapp(outbuf,"%");
				outbuf = strapp(outbuf,w);
				outbuf = strapp(outbuf,ww);
				if (*inbuf == NULL)	*outbuf++ = '\n';
				}
			}
		}

/* some manuals have commented lines beginning with ''' */
	else if ((c2 == '\'') && !(mid) && (c1 == '\n' || (first_word)))
		{
		if (*inbuf == '\'')
			{
			inbuf++;
			if (*inbuf == '\'')
				{
				inbuf++;
				outbuf = strapp(outbuf,"%");
				}
			else	outbuf = strapp(outbuf,"''");
			}
		else	outbuf = strapp(outbuf,"'");
		}

/* 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 )
		{
		outbuf = strapp(outbuf,"\\");
		outbuf = strapp(outbuf,w);
		if (strcmp(w,"~") == 0 || strcmp(w,"^") == 0)
			outbuf = strapp(outbuf,"{}");
		}

	else if (strcmp(w,">") == 0 || strcmp(w,"<") == 0 || strcmp(w,"|") == 0)
		{
		sprintf(tmp,"$%s$",w);
		outbuf = strapp(outbuf,tmp);
		}

/* check for backslash commands */

	else if (strcmp(w,"\\") == 0)
		{
		if (*inbuf == ' ' || *inbuf == '\t' || *inbuf == '\n')
			{
			outbuf = strapp(outbuf,"\\");
			*outbuf++ = *inbuf++;
			}
		else if (*inbuf == NULL)	;
		else if (*inbuf == '-')
			{
			inbuf++;
			outbuf = strapp(outbuf,"--");
			}
		else if (*inbuf == '~' || *inbuf == '^')
			{
			inbuf++;
			outbuf = strapp(outbuf,"\\/");
			}
		else if (*inbuf == '0')
			{
			inbuf++;
			outbuf = strapp(outbuf,"\\ ");
			}
		else if (*inbuf == 'e')
			{
			inbuf++;
			outbuf = strapp(outbuf,"\\bs ");
			}
		else if (*inbuf == '\\')
			{
			inbuf++;
			if (*inbuf == '$' && de_arg > 0)
				{
				inbuf++;
				de_arg++;
				*outbuf++ = '#';
				}
			else
				outbuf = strapp(outbuf,"\\bs ");
			}
		else if (*inbuf == '`' || *inbuf == '\'')
			;				/* do nothing */
		else if (*inbuf == '"')
			{
			inbuf++;
			inbuf += get_line(inbuf,ww,0);
			outbuf = strapp(outbuf,"%");
			outbuf = strapp(outbuf,ww);
			}
		else if (*inbuf == '|')
			{
			inbuf++;
			outbuf = strapp(outbuf,"\\,");
			}
		else if (*inbuf == '&')
			inbuf++;
		else if (*inbuf == '(')
			{
			c1 = *++inbuf;
			c2 = *++inbuf;
			inbuf++;
			if (c1 == 'e' && c2 == 'm')
				outbuf = strapp(outbuf,"---");
			else if (c1 == 'd' && c2 == 'e')
				outbuf = strapp(outbuf,"$^\\circ$");
			else fprintf(stderr,
				"I am not prepared to handle \\(%c%c\n",c1,c2);
			}
		else if (*inbuf == 's')
			inbuf +=3;
		else if (*inbuf == '*')
			{
			c1 = *++inbuf;
			inbuf++;
			if (c1 == ':')
				outbuf = strapp(outbuf,"\\\"");
			else if (c1 == 'C')
				outbuf = strapp(outbuf,"\\v");
			else if (c1 == ',')
				outbuf = strapp(outbuf,"\\c");
			else if (c1 != '(')
				{
				sprintf(tmp,"\\%c",c1);
				outbuf = strapp(outbuf,tmp);
				}
			else
				{
				fprintf(stderr,
				"I am not prepared to handle \\*( cases\n");
				inbuf += 2;
				}
			if (c1 != '(')
				{
				c1 = *inbuf++;
				sprintf(tmp,"{%c}",c1);
				outbuf = strapp(outbuf,tmp);
				}
			}
		else if (*inbuf == 'f')
			{
			c1 = *++inbuf;
			inbuf++;
			if (c1 == '1' || c1 == 'R')
				{
				lastfont = thisfont;
				thisfont = 1;
				if (*inbuf == ' ' || *inbuf == '\t' ||
				    *inbuf == '\n' || *inbuf == '\f')
					{*outbuf++ = ' ';	inbuf++;}
				outbuf = strapp(outbuf,"%\n\\rm ");
				}
			else if (c1 == '2' || c1 == 'I')
				{
				lastfont = thisfont;
				thisfont = 2;
				if (*inbuf == ' ' || *inbuf == '\t' ||
				    *inbuf == '\n' || *inbuf == '\f')
					{*outbuf++ = ' ';	inbuf++;}
				outbuf = strapp(outbuf,"%\n\\it ");
				}
			else if (c1 == '3' || c1 == 'B')
				{
				lastfont = thisfont;
				thisfont = 3;
				if (*inbuf == ' ' || *inbuf == '\t' ||
				    *inbuf == '\n' || *inbuf == '\f')
					{*outbuf++ = ' ';	inbuf++;}
				outbuf = strapp(outbuf,"%\n\\bf ");
				}
			else if (c1 == 'P')
				{
/* preserve white space - from Nelson Beebe  */
				if (*inbuf == ' ' || *inbuf == '\t' ||
				    *inbuf == '\n' || *inbuf == '\f')
					{*outbuf++ = ' ';	inbuf++;}
				switch(lastfont)
					{
					case 1:
						outbuf = strapp(outbuf,"\\rm%\n");
						thisfont = 1;
						break;
					case 2:
						outbuf = strapp(outbuf,"\\it%\n");
						thisfont = 2;
						break;
					case 3:
						outbuf = strapp(outbuf,"\\bf%\n");
						thisfont = 3;
						break;
					default:
						outbuf = strapp(outbuf,"\\rm%\n");
						thisfont = 1;
						break;
					}
				}
			else fprintf(stderr,
				"I do not understand \\f%c yet\n",c1);
			}
		else
			{
			fprintf(stderr,"I am not prepared to handle \\%c\n",*inbuf);
			inbuf++;
			}
		}

/* if non of the above checks, its a dull word; copy it */

	else
		outbuf = strapp(outbuf,w);
	*outbuf = NULL;	ww[0] = NULL;  tmp[0] = NULL;	tmp2[0] = NULL;
	if (!no_word)	first_word = 0;
	}
/* if file end, close opened environments and delimitters */
if (rec == 0)
	{
	if (IP_stat)	outbuf = strapp(outbuf,"\\end{itemize}\n");
	if (QP_stat)	outbuf = strapp(outbuf,"\\end{quotation}\n");
	if (TP_stat)	outbuf = strapp(outbuf,"\\end{TPlist}\n");
	}

*outbuf = NULL;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'subs.c'
then
	echo shar: will not over-write existing file "'subs.c'"
else
cat << \SHAR_EOF > 'subs.c'
/* COPYRIGHT (C) 1987 Kamal Al-Yahya */
/* 
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        "simil.h"
#include        "greek.h"
#include        "flip.h"
#include        "forbid.h"
#include        "maths.h"
#include        "macros.h"

extern def_count;
extern mydef_count;

/* compile-time counting of elements */
int GRK_count = (sizeof(GRK_list)/sizeof(GRK_list[0]));
int sim_count = (sizeof(sim_list)/sizeof(sim_list[0]));
int flip_count = (sizeof(flip_list)/sizeof(flip_list[0]));
int forbd_count = (sizeof(forbid)/sizeof(forbid[0]));
int mathcom_count = (sizeof(math)/sizeof(struct math_equiv));
int macro_count = (sizeof(macro)/sizeof(struct macro_table));

char *
alternate(inbuf,outbuf,w)		/* alternate fonts (manual macro) */
char *inbuf, *outbuf, *w;
{
int f1,f2;
int which=1;
char font[MAXWORD], font1[MAXWORD], font2[MAXWORD],
     ww[MAXWORD], tmp[MAXWORD];

tmp[0] = NULL;
f1 = w[1];	f2 = w[2];
if (f1 == 'R')	strcpy(font1,"\\rm");
if (f1 == 'I')	strcpy(font1,"\\it");
if (f1 == 'B')	strcpy(font1,"\\bf");
if (f2 == 'R')	strcpy(font2,"\\rm");
if (f2 == 'I')	strcpy(font2,"\\it");
if (f2 == 'B')	strcpy(font2,"\\bf");

strcpy(font,font1);
while (*inbuf != '\n' && *inbuf != NULL)
	{
	inbuf += get_arg(inbuf,ww,1);
	sprintf(tmp,"{%s %s}",font,ww);
	outbuf = strapp(outbuf,tmp);
	if (which == 1)
		{
		which = 2;
		strcpy(font,font2);
		}
	else
		{
		which = 1;
		strcpy(font,font1);
		}
	while (*inbuf == ' ' || *inbuf == '\t')
		inbuf++;
	}

return(outbuf);
}

int
CAP_GREEK(w)			/* check if w is in the GREEK list */
char *w;
{
int i;

for (i=0; i < GRK_count ; i++)
	{
	if (strcmp(GRK_list[i],w) == 0)
		return(1);
	}
return(-1);
}

char *
do_table(inbuf,outbuf,offset)
char *inbuf, *outbuf;
int *offset;				/* amount to offset inbuf */
{
char w[MAXWORD], ww[MAXWORD], format[MAXWORD], tmp[MAXWORD];
char *ptr;
int i,j,len,columns=0;
int tab = '\t';				/* default tab */

tmp[0] = NULL;
ptr = inbuf;				/* remember where we started */
len = get_line(inbuf,w,0);
if (w[strlen(w)-1] == ';')		/* options */
	{
	inbuf += len;
	if (strncmp(w,"tab",3) == 0)	/* get the tab charecter */
		tab = w[4];		/* expect something like tab(&); */
	inbuf = skip_line(inbuf);
	}
while (*inbuf != NULL)			/* get the LAST format line */
	{
	len = get_line(inbuf,w,0);
	if (w[strlen(w)-1] != '.')	break;	/* not a fromat line */
	inbuf += len;
	for (i=0, j=0; i<len-1; i++)
		{
		if (isspace(w[i]))	continue;
		columns++;
		if (w[i] == 'l')	format[j] = 'l';
		else if (w[i] == 'r')	format[j] = 'r';
		else			format[j] = 'c';
		j++;
		}
	}
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 (*inbuf != NULL)
		{
		(void) getword(inbuf,w);
		if (strcmp(w,".TE") ==  0)	{inbuf += 4;	break;}
		inbuf += get_line(inbuf,w,1);
		*outbuf++ = '%';
		outbuf = strapp(outbuf,w);
		outbuf = strapp(outbuf,"\n");
		inbuf++;		/* skip the \n */
		}
	*offset = inbuf - ptr;
	return(outbuf);
	}
format[j] = NULL;
sprintf(tmp,"\\par\n\\begin{tabular}{%s}\n",format);
outbuf = strapp(outbuf,tmp);

while (*inbuf != NULL)
	{
	for (i=0; i<columns-1; i++)
		{
		(void) getword(inbuf,w);
		if (i == 0 && (strcmp(w,"\n") == 0 || strcmp(w,"_") == 0))
			{inbuf++;	i--;	continue;}
		if (strcmp(w,".TE") == 0)
			{
			inbuf += 4;
			if (i == 0)
				{
				outbuf -= 3;	/* take back the \\ and the \n */
				*outbuf = NULL;
				}
			outbuf = strapp(outbuf,"\n\\end{tabular}\n\\par\n");
			*offset = inbuf - ptr;
			return(outbuf);
			}
		inbuf += get_table_entry(inbuf,w,tab);
		inbuf ++;		/* skip tab */
		troff_tex(w,ww,0,1);
		sprintf(tmp,"%s & ",ww);
		outbuf = strapp(outbuf,tmp);
		}
	(void) getword(inbuf,w);
	if (strcmp(w,".TE") == 0)
		{
		fprintf(stderr,"Oops! I goofed. I told I you I am not very good at tables\nI've encountered an unexpected end for the table\n\
You need to fix it yourself\n");
		inbuf += 4;
		outbuf = strapp(outbuf,"\\end{tabular}\n\\par\n");
		*offset = inbuf - ptr;
		return(outbuf);
		}
	inbuf += get_table_entry(inbuf,w,'\n');
	inbuf++;		/* skip tab */
	troff_tex(w,ww,0,1);
	outbuf = strapp(outbuf,ww);
	outbuf = strapp(outbuf,"\\\\\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 = inbuf - ptr;
outbuf = strapp(outbuf,"\\end{tabular}\n\\par\n");
return(outbuf);
}

char *
end_env(outbuf)
char *outbuf;
{
if (IP_stat)
	{
	IP_stat = 0;
	outbuf = strapp(outbuf,"\\end{itemize}");
	}
if (QP_stat)
	{
	QP_stat = 0;
	outbuf = strapp(outbuf,"\\end{quotation}");
	}
if (TP_stat)
	{
	TP_stat = 0;
	outbuf = strapp(outbuf,"\\end{TPlist}");
	}
return(outbuf);
}

void
envoke_stat(par)
int par;
{

switch(par)
	{
	case 2:
		IP_stat = 1;
		break;
	case 3:
		TP_stat = 1;
		break;
	case 4:
		QP_stat = 1;
		break;
	default:
		break;
	}
}

char *
flip(outbuf,w)			/* do the flipping */
char *outbuf, *w;
{
int lb=0, rb=0;
char ww[MAXWORD], tmp[MAXWORD];

ww[0] = NULL;	tmp[0] = NULL;
outbuf--;
while (*outbuf == ' ' || *outbuf == '\t' || *outbuf == '\n')
	outbuf--;
while (1)
	{
	if (*outbuf == '{')
		{
		lb++;
		if (lb > rb)	break;
		}
	if (*outbuf == '}')	rb++;
	if (rb == 0)
		{
		if (*outbuf != ' ' && *outbuf != '\t' && *outbuf != '\n'
			&& *outbuf != '$')
			{
			outbuf--;
			continue;
			}
		else	break;
		}
	outbuf--;
	if (lb == rb && lb != 0)	break;
	}
outbuf++;
if (*outbuf == '\\')
	{
	outbuf++;
	(void) getword(outbuf,tmp);
	sprintf(ww,"\\%s",tmp);
	outbuf--;
	}
else if (*outbuf == '{')
	(void) get_brace_arg(outbuf,ww);
else
	(void) getword(outbuf,ww);
*outbuf = NULL;
sprintf(tmp,"\\%s %s",w,ww);
outbuf = strapp(outbuf,tmp);
return(outbuf);
}

char *
flip_twice(outbuf,w,ww)		/* take care of things like x hat under */
char *outbuf, *w, *ww;
{
int lb=0, rb=0;
char tmp1[MAXWORD], tmp2[MAXWORD];

tmp1[0] = NULL;		tmp2[0] = NULL;
outbuf--;
while (*outbuf == ' ' || *outbuf == '\t' || *outbuf == '\n')
	outbuf--;
while (1)
	{
	if (*outbuf == '{')
		{
		lb++;
		if (lb > rb)	break;
		}
	if (*outbuf == '}')	rb++;
	if (rb == 0)
		{
		if (*outbuf != ' ' && *outbuf != '\t' && *outbuf != '\n'
			&& *outbuf != '$')
			{
			outbuf--;
			continue;
			}
		else	break;
		}
	outbuf--;
	if (lb == rb && lb != 0)	break;
	}
outbuf++;
if (*outbuf == '\\')
	{
	outbuf++;
	(void) getword(outbuf,tmp2);
	sprintf(tmp1,"\\%s",tmp2);
	outbuf--;
	}
else if (*outbuf == '{')
	(void) get_brace_arg(outbuf,tmp1);
else
	(void) getword(outbuf,tmp1);
*outbuf = NULL;
sprintf(tmp2,"\\%s{\\%s %s}",w,ww,tmp1);
outbuf = strapp(outbuf,tmp2);
return(outbuf);
}

int
get_arg(inbuf,w,rec)		/* get argumnet */
char *inbuf, *w;
int rec;		/* rec=1 means recursive */
{
int c,len,i;
char ww[MAXWORD];
int delim;

len=0;
while ((c = *inbuf) == ' ' || c == '\t')	/* skip spaces and tabs */
		{inbuf++;	len++;}
i=0;
if (*inbuf == '{' || *inbuf == '\"')
	{
	if (*inbuf == '{')	delim = '}';
	else			delim = '\"';
	inbuf++;	len++;
	while ((c = *inbuf++) != NULL && c != delim && i < MAXWORD)
		{
		if (c == ' ' && delim == '\"')	ww[i++] = '\\';
		ww[i++] = (char)c;	len++;
		}
	len++;
	}
else
	{
	while ((c = *inbuf++) != NULL && c != ' ' && c != '\t' && c != '\n'
		&& c != '$' && c != '}' && i < MAXWORD)
		{
		if (math_mode && c == '~')	break;
		ww[i++] = (char)c;	len++;
		}
	}
ww[i] = NULL;
if (rec == 1)				/* check if recursion is rquired */
	troff_tex(ww,w,1,1);
else
	strcpy(w,ww);
return(len);
}

void
get_brace_arg(buf,w)		/* get argumnet surrounded by braces */
char *buf, *w;
{
int c,i, lb=0, rb=0;

i=0;
while ((c = *buf++) != NULL)
	{
	w[i++] = (char)c;
	if (c == '{')	lb++;
	if (c == '}')	rb++;
	if (lb == rb)	break;
	}
w[i] = NULL;
}

int
get_defword(inbuf,w,illegal)		/* get "define" or .de word */
char *inbuf, *w;			/* delimited by space only */
int *illegal;
{
int c,i;

*illegal = 0;
for (i=0; (c = *inbuf++) != NULL && c != ' ' && c != '\n'
		&& c != '\t' && i < MAXWORD; i++)
	{
	w[i] = (char)c;
	if (isalpha(c) == 0)	*illegal = 1;	/* illegal TeX macro */ 
	}
w[i] = NULL;
if (*illegal == 0)
	if (is_forbid(w) >= 0)		*illegal=1;
return(i);
}

int
get_line(inbuf,w,rec)		/* get the rest of the line */
char *inbuf, *w;
int rec;			/* rec=1 means recursion is required */
{
int c,i,len;
char ww[MAXLINE];

i=0;	len=0;
while ((c = *inbuf++) != NULL && c != '\n' && len < MAXLINE)
		{ww[i++] = (char)c;	len++;}
ww[i] = NULL;
if (rec == 1)
	troff_tex(ww,w,0,1);
else
	strcpy(w,ww);
return(len);
}

int
get_multi_line(inbuf,w)		/* get multi-line argument */
char *inbuf, *w;
{
int len=0,l=0,lines=0;
char tmp[MAXWORD];
int c1,c2;

w[0] = NULL;	tmp[0] = NULL;
while (*inbuf != NULL)
	{
	c1 = *inbuf;	c2 = *++inbuf;		--inbuf;
	if (c1 == '.' && isupper(c2))		break; 
	lines++;
	if (lines > 1)
		strcat(w," \\\\\n");
	l = get_line(inbuf,tmp,1);
	strcat(w,tmp);
	len += l+1;	inbuf += l+1;
	}
len--;		inbuf--;
return(len);
}

int
get_mydef(inbuf,w)		/* get the macro substitution */
char *inbuf, *w;
{
int c1,c2,l,len;
char tmp[MAXWORD];

tmp[0] = NULL;
len=1;
while (*inbuf != NULL)
	{
	c1 = *inbuf;	c2 = *++inbuf;		--inbuf;
	if (c1 == '.' && c2 == '.')		break; 
	l = get_line(inbuf,tmp,1);
	strcat(w,tmp);
	len += l+1;	inbuf += l+1;
	}
return(len);
}
int
get_N_lines(inbuf,w,N)		/* get N lines */
char *inbuf, *w;
int N;
{
int len=0,l=0,lines=0;
char tmp[MAXWORD];

w[0] = NULL;	tmp[0] = NULL;
while (*inbuf != NULL && lines < N)
	{
	lines++;
	if (lines > 1)
		strcat(w," \\\\\n");
	l = get_line(inbuf,tmp,1);
	strcat(w,tmp);
	len += l+1;	inbuf += l+1;
	}
len--;		inbuf--;
return(len);
}

int
get_no_math(inbuf,w)		/* get text surrounded by quotes in math mode */
char *inbuf, *w;
{
int c,i,len;

len = 0;
for (i=0; (c = *inbuf++) != NULL && c != '\"' && i < MAXWORD; i++)
	{
	if (c == '{' || c == '}')
		{w[i] = '\\';	w[++i] = (char)c;}
	else
		w[i] = (char)c;
	len++;
	}
w[i] = NULL;
return(len);
}

char *
get_over_arg(inbuf,ww)		/* get the denominator of over */
char *inbuf, *ww;
{
char w[MAXWORD], tmp1[MAXWORD], tmp2[MAXWORD];
int len;

w[0] = NULL;	tmp1[0] = NULL;		tmp2[0] = NULL;
inbuf += getword(inbuf,tmp1);		/* read first word */
inbuf += skip_white(inbuf);
len = getword(inbuf,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)
	{
	inbuf += len;
	strcat(w,tmp2); strcat(w," ");
	inbuf += skip_white(inbuf);
	inbuf += getword(inbuf,tmp1);
	strcat(w,tmp1); strcat(w," ");
	inbuf += skip_white(inbuf);
	len = getword(inbuf,tmp2);
	}
troff_tex(w,ww,0,1);
return(inbuf);
}

int
get_ref(inbuf,w)		/* get reference */
char *inbuf, *w;
{
int len=0, l=0, lines=0;
char tmp[MAXWORD];

w[0] = NULL;	tmp[0] = NULL;
while (*inbuf != NULL)
	{
	if (*inbuf == '\n')		break;
	(void) getword(inbuf,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(inbuf,tmp,1);
	lines++;
	if (lines > 1)		strcat(w," ");
	strcat(w,tmp);
	len += l+1;	inbuf += l+1;
	}
len--;		inbuf--;
return(len);
}

void
get_size(ww,PARAMETER)
char *ww;
struct measure *PARAMETER;
{
int sign=0, units=0;
float value;

if (ww[0] == NULL)
	{
	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,&value,&units);
	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] == NULL)
			strcpy(PARAMETER->units,PARAMETER->def_units);
		else
			strcpy(PARAMETER->units,PARAMETER->old_units);
		}
	else
		{
		fprintf(stderr,"unknown units %c, using default units\n");
		strcpy(PARAMETER->units,PARAMETER->def_units);
		}
	if (sign == 0)	PARAMETER->value = value;
	else		PARAMETER->value = PARAMETER->old_value + sign*value;
	}
}

int
get_string(inbuf,w,rec)		/* get the rest of the line -- Nelson Beebe */
char *inbuf, *w;
int rec;			/* rec=1 means recursion is required */
{
register int c,i,len;
char ww[MAXLINE];
register char *start;

if (*inbuf != '\"')
    return(get_line(inbuf,w,rec));
start = inbuf;				/* remember start so we can find len */
i=0;
inbuf++;				/* point past initial quote */
while ((c = *inbuf++) != NULL && c != '\"' && c != '\n' && i < MAXLINE)
    ww[i++] = (char)c;
ww[i] = NULL;
if (c != '\n')				/* flush remainder of line */
    while ((c = *inbuf++) != '\n')
	/* NO-OP */;
len = inbuf - start - 1;		/* count only up to NL, not past */
if (rec == 1)
	troff_tex(ww,w,0,1);
else
	strcpy(w,ww);
return(len);
}

int
get_sub_arg(inbuf,w)		/* get the argument for sub and sup */
char *inbuf, *w;
{
int c,len,i;
char ww[MAXWORD], tmp[MAXWORD];

len=0;	tmp[0] = NULL;
while ((c = *inbuf) == ' ' || c == '\t')
		{inbuf++;	len++;}
i=0;
while ((c = *inbuf++) != NULL && c != ' ' && c != '\t' && c != '\n'
		&& c != '$' && c != '}' && c != '~' && i < MAXWORD)
		{ww[i++] = (char)c;	len++;}
ww[i] = NULL;
if (strcmp(ww,"roman") == 0  || strcmp(ww,"bold") == 0 || strcmp(w,"italic") == 0)
	{
	(void) get_arg(inbuf,tmp,0);
	sprintf(ww,"%s%c%s",ww,c,tmp);
	len += strlen(tmp)+1;
	}
troff_tex(ww,w,0,1);		/* recursive */
return(len);
}

int
get_table_entry(inbuf,w,tab)
char *inbuf, *w;
int tab;
{
int c, i=0;

for (i=0; (c = *inbuf++) != NULL && c != tab && i < MAXWORD; i++)
		w[i] = (char)c;
w[i] = NULL;

return(i);
}

int
get_till_space(inbuf,w)			/* get characters till the next space */
char *inbuf, *w;
{
int c,i;

for (i=0; (c = *inbuf++) != NULL && c != ' ' && c != '\n'
		&& c != '\t' && i < MAXWORD; i++)
	w[i] = (char)c;
w[i] = NULL;
return(i);
}

int
getdef(inbuf,ww)		/* get the define substitution */
char *inbuf, *ww;
{
int c,i,len;
int def_delim;
char w[MAXWORD];

def_delim = *inbuf++;		/* take first character as delimiter */
len=1;		i=0;
while ((c = *inbuf++) != NULL && c != def_delim && i < MAXWORD)
	{len++;		w[i++] = (char)c;}
w[i] = NULL;
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);
}

int
getword(inbuf,w)		/* get an alphanumeric word (dot also) */
char *inbuf, *w;
{
int c,i;

for (i=0; (c = *inbuf++) != NULL
	&& (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++)
		w[i] = (char)c;
if (i == 0 && c != NULL)
	w[i++] = (char)c;
w[i] = NULL;
return(i);
}

void
GR_to_Greek(w,ww)			/* change GREEK to Greek */
char *w, *ww;
{
*ww++ = '\\';		*ww++ = *w;
while(*++w != NULL)
	*ww++ = tolower(*w);
*ww = NULL;
}

int
is_def(w)		/* check if w was defined by the user */
char *w;
{
int i;

for (i=0; i < def_count; i++)
	{
	if (strcmp(def[i].def_macro,w) == 0)
		return(i);
	}
return(-1);
}

int
is_flip(w)		/* check if w is in the flip list */
char *w;
{
int i;

for (i=0; i < flip_count; i++)
	{
	if (strcmp(flip_list[i],w) == 0)
		return(i);
	}
return(-1);
}

int
is_forbid(w)		/* check if w is one of those sacred macros */
char *w;
{
int i;

for (i=0; i < forbd_count; i++)
	{
	if (strcmp(forbid[i],w) == 0)
		return(i);
	}
return(-1);
}

int
is_mathcom(w,ww)	/* check if w has a simple correspondence in TeX */
char *w,*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_mydef(w)		/* check if w is user-defined macro */
char *w;
{
int i;

for (i=0; i < mydef_count; i++)
	{
	if (strcmp(mydef[i].def_macro,w) == 0)
		return(i);
	}
return(-1);
}

int
is_troff_mac(w,ww,arg,par)/* check if w is a macro or plain troff command */
char *w,*ww;
int *arg,*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(ww,sign,value,units)
char *ww;
int *sign, *units;
float *value;
{
int len, k=0, i;
char tmp[MAXWORD];

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] = NULL;
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);
	}
}

void
scrbuf(in,out)			/* copy input to output */
FILE *in,*out;
{
int c;
while ((c =getc(in)) != EOF)	putc(c,out);
}

int
similar(w)			/* check if w is in the similar list */
char *w;
{
int i;

for (i=0; i < sim_count ; i++)
	{
	if (strcmp(sim_list[i],w) == 0)
		return(1);
	}
return(-1);
}

char *
skip_line(inbuf)		/* ignore the rest of the line */
char *inbuf;
{
while (*inbuf != '\n' && *inbuf != NULL)
	inbuf++;
if (*inbuf == NULL)	return(inbuf);
else			return(++inbuf);
}

int
skip_white(inbuf)		/* skip white space */
char *inbuf;
{
int c,len=0;

while ((c = *inbuf++) == ' ' || c == '\t' || c == '\n')
	len++;	
return(len);
}

char *
strapp(s,tail)  /* copy tail[] to s[], return ptr to terminal NULL in s[] */
register char *s;	/* Nelson Beebe */
register char *tail;
{
while (*s++ = *tail++)
	/*NO-OP*/;
return (s-1);			/* pointer to NULL at end of s[] */
}

void
tmpbuf(in,buffer)
/* copy input to buffer, buffer holds only MAXLEN characters */
FILE *in;
char *buffer;
{
int c;
unsigned int l=0;

while (l++ < MAXLEN && (c = getc(in)) != EOF)
	*buffer++ = (char)c;
if (l >= MAXLEN)
	{
	fprintf(stderr,"Sorry: document is too large\n");
	exit(-1);
	}
*buffer = NULL;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'setups.h'
then
	echo shar: will not over-write existing file "'setups.h'"
else
cat << \SHAR_EOF > 'setups.h'
/* setup file */

#ifndef NO_SGTTY
#define HAVE_SGTTY 1			/* host has sgtty.h and ioctl.h */
#endif

#include        <stdio.h>
#include        <ctype.h>
#ifdef MSC
#include        <string.h>
#include	<stdlib.h>	/* for type declarations */
#include	<io.h>		/* for type declarations */
#else
#include        <strings.h>
#endif

#if HAVE_SGTTY
#include        <sys/ioctl.h>
#include        <sgtty.h>
#endif

#define	MAXLEN	65535		/* maximum length of document */
#define	MAXWORD	250		/* maximum word length */
#define	MAXLINE	500		/* maximum line length */
#define	MAXDEF	200		/* maximum number of defines */

extern char *malloc();
#ifdef IN_TR		/* can only declare globals once */
#else
extern
#endif
int math_mode,		/* math mode status */
    de_arg,		/* .de argument */
    IP_stat,		/* IP status */
    QP_stat,		/* QP status */
    TP_stat;		/* TP status */

#ifdef IN_TR		/* can only declare globals once */
#else
extern
#endif
struct defs {
	char *def_macro;
	char *replace;
	int illegal;
} def[MAXDEF];

#ifdef IN_TR		/* can only declare globals once */
#else
extern
#endif
struct mydefs {
	char *def_macro;
	char *replace;
	int illegal;
	int arg_no;
	int par;		/* if it impiles (or contains) a par break */
} mydef[MAXDEF];

#ifdef IN_TR		/* can only declare globals once */
#else
extern
#endif
struct measure {
	char old_units[MAXWORD];	float old_value;
	char units[MAXWORD];		float value;
	char def_units[MAXWORD];	/* default units */
	int def_value;			/* default value: 0 means take last one */
} linespacing, indent, tmpind, space, vspace;

#ifdef ANSI
char*	alternate(char*, char*, char*);
int	CAP_GREEK(char*);
char*	do_table(char*,char*,int);
char*	end_env(char*);
void	envoke_stat(int);
char*	flip(char*,char*);
char*	flip_twice(char*,char*,char*);
int	get_arg(char*,char*,int ,int );
void	get_brace_arg(char*,char*);
int	get_defword(char*,char*,int*);
int	get_line(char*,char*,int );
int	get_multi_line(char*,char*);
int	get_mydef(char*,char*);
int	get_N_lines(char *,char *,int);
int	get_no_math(char*,char*);
char*	get_over_arg(char*,char*);
int	get_ref(char*,char*);
int	get_string(char*,char*,int );
void	get_size(char*,char*,char*);
int	get_sub_arg(char*,char*);
int	get_till_space(char*,char*);
int	getdef(char*,char*);
int	getword(char*,char*);
void	GR_to_Greek(char*,char*);
int	is_def(char*);
int	is_flip(char*);
int	is_forbid(char*);
int	is_mathcom(char*,char*);
int	is_mydef(char *);
int	is_troff_mac(char*,char*,int*);
int	main(int ,char **);
void	parse_units(char*,int,int,int);
void	scrbuf(FILE*,FILE*);
int	similar(char*);
char*	skip_line(char*);
int	skip_white(char*);
char*	strapp(char*,char*);
void	tmpbuf(FILE*,char*);
void	troff_tex(char *,char *,int );
#else
char*	alternate();
int	CAP_GREEK();
char*	do_table();
char*	end_env();
void	envoke_stat();
char*	flip();
char*	flip_twice();
int	get_arg();
void	get_brace_arg();
int	get_defword();
int	get_line();
int	get_multi_line();
int	get_mydef();
int	get_N_lines();
int	get_no_math();
char*	get_over_arg();
int	get_ref();
int	get_string();
void	get_size();
int	get_till_space();
int	get_sub_arg();
int	getdef();
int	getword();
void	GR_to_Greek();
int	is_def();
int	is_flip();
int	is_forbid();
int	is_mathcom();
int	is_mydef();
int	is_troff_mac();
int	main();
void	parse_units();
void	scrbuf();
int	similar();
char*	skip_line();
int	skip_white();
char*	strapp();
void	tmpbuf();
void	troff_tex();
#endif
SHAR_EOF
fi # end of overwriting check
if test -f 'simil.h'
then
	echo shar: will not over-write existing file "'simil.h'"
else
cat << \SHAR_EOF > 'simil.h'
/*
This file contains a list of math words that are similar in the
two languages (in fact identical except for TeX's backslah).
If I overlooked anything out, it can be put here
Do NOT put here words that are similar but require some action (like over)
*/
char *sim_list[] =
{
"alpha",    "approx",    "beta",     "cdot",     "chi",      "cos",
"cosh",     "cot",       "coth",     "delta",    "epsilon",  "eta",
"exp",      "gamma",     "int",      "kappa",    "lambda",   "lim",
"log",      "matrix",    "mu",       "nu",       "omega",    "partial",
"phi",      "pi",        "prime",    "prod",     "psi",      "rho",
"sigma",    "sin",       "sinh",     "sqrt",     "sum",      "tan",
"tanh",     "tau",       "theta",    "times",    "xi",       "zeta"
};
SHAR_EOF
fi # end of overwriting check
if test -f 'greek.h'
then
	echo shar: will not over-write existing file "'greek.h'"
else
cat << \SHAR_EOF > 'greek.h'
/*
This file contains the list of the upper-case Greek letters.
In case I overlooked any, it can be added here.
*/
char *GRK_list[] =
{
"ALPHA",    "BETA",    "CHI",    "DELTA",   "EPSILON",
"ETA",      "GAMMA",   "KAPPA",  "LAMDA",   "MU",
"NU",       "OMEGA",   "PHI",    "PI",      "PSI",
"RHO",      "SIGMA",   "TAU",    "THETA",   "XI",    "ZETA"
};
SHAR_EOF
fi # end of overwriting check
if test -f 'flip.h'
then
	echo shar: will not over-write existing file "'flip.h'"
else
cat << \SHAR_EOF > 'flip.h'
/*
This file contains the words that are placed the opposite way
in troff and TeX. Is there any more?
*/
char *flip_list[] =
{
"bar",  "dot",   "dotdot",   "hat",    "tilde",   "under",     "vec"
};
SHAR_EOF
fi # end of overwriting check
if test -f 'forbid.h'
then
	echo shar: will not over-write existing file "'forbid.h'"
else
cat << \SHAR_EOF > 'forbid.h'
/*
This file contains TeX commands that cannot be re-defined.
Re-defining them is not permitted by TeX (or they may produce
unpredictable consequences).
If the troff user happens to re-define one of these, it will be replaced.
This list is extracted from the starred entries in the index of the TeXBook.
They are entered here in alphabetical order.
If the macro has non-alphabetical characters, it will be trapped
somewhere else; it needn't be put here.
This list is added to make the program more robust.
Note that the backslash is omitted.
*/
char *forbid[] =
{
"atop",     "char",    "copy",     "count",    "cr",      "crcr",
"day",      "def",     "divide",   "dp",       "dump",    "edef",
"else",     "end",     "eqno",     "fam",      "fi",      "font",
"gdef",     "global",  "halign",   "hbox",     "hfil",    "hfill",
"hfuzz",    "hoffset", "hrule",    "hsize",    "hskip",   "hss",
"ht",       "if",      "ifcase",   "ifcat",    "ifnum",   "ifodd",
"iftrue",   "ifx",     "indent",   "input",    "insert",  "kern",
"left",     "leqno",   "let",      "limits",   "long",    "lower",
"mag",      "mark",    "mkern",    "month",    "mskip",   "multiply",
"muskip",   "omit",    "or",       "outer",    "output",  "over",
"overline", "par",     "raise",    "read",     "right",   "show",
"span",     "special", "string",   "the",      "time",    "toks",
"topmark",  "topskip", "unkern",   "unskip",   "vbox",    "vfil",
"vfill",    "vfuzz",   "voffset",  "vrule",    "vsize",   "vskip",
"vsplit",   "vss",     "vtop",     "wd",       "write",   "xdef"
};
SHAR_EOF
fi # end of overwriting check
if test -f 'macros.h'
then
	echo shar: will not over-write existing file "'macros.h'"
else
cat << \SHAR_EOF > 'macros.h'
/*
This file contains the list of non-math macros and plain troff macros.
Do NOT forget to put the dot for the troff macros, and the backslash
for TeX macros (two backslashes, one for escape).
The third column in the list is 0 for macros that have no arguments
and either 1 or 2 for those that do. If it is 1, then only one line
will be read as an argument. If it is 2, then lines will be read until
properly terminated. Arguments for ms macros are terminated by an ms macro
(e.g. .PP). Plain troff macros are terminated after reading the desired number
of lines specified by the macro (e.g. .ce 5   will centerline 5 lines).
The fourth column specifies whether the macro implies a paragraph break
(par > 1) or not (par = 0). This is needed to terminate some environments.
If .LP, or .PP, par=1; if .IP, par=2; if .TP, par=3; if .QP, par=4.
*/
struct macro_table {
	char *troff_mac, *tex_mac;
	int arg, macpar;
} macro[] = {

/*  troff macro		TeX macro		   argument	par	*/
	".1C",		 "\\onecolumn",			0,	1,
	".2C",		 "\\twocolumn",			0,	1,
	".AE",		 "\\end{abstract}",		0,	1,
	".AI",		 "\\authoraff",			2,	1,
	".AU",		 "\\author",			2,	1,
	".Ac",		 "\\ACK",		  	0,	1,
	".B1",		 "\\boxit{",			0,	0,
	".B2",		 "}",				0,	0,
	".DE",		 "\\displayend",		0,	1,
	".DS",		 "\\displaybegin",		0,	1,
	".FE",		 "}",				0,	0,
	".FS",		 "\\footnote{",			0,	0,
	".Ic",		 "\\caption{",			0,	1,
	".Ie",		 "}\\end{figure}",		0,	1,
	".Is",		 "\\begin{figure}",		0,	1,
	".KS",		 "{\\nobreak",			0,	0,
	".LP",		 "\\par\\noindent",		0,	1,
	".MH",		 "\\mhead",			2,	1,
	".NH",		 "\\section",			1,	1,
	".PP",		 "\\par",			0,	1,
	".QE",		 "\\end{quotation}",		0,	1,
	".QS",		 "\\begin{quotation}",		0,	1,
	".SH",		 "\\shead",			1,	1,
	".TH",		 "\\phead",			1,	0,
	".TL",		 "\\title",			2,	1,
	".UC",		 "",				0,	0,
	".UL",		 "\\undertext",			1,	0,
	".bp",		 "\\newpage",			0,	1,
	".br",		 "\\nwl",			0,	0,
	".ce",		 "\\cntr",			2,	0,
	".cu",		 "\\undertext",			2,	0,
	".fi",		 "\\fill",			0,	0,
	".na",		 "\\raggedright",		0,	0,
	".nf",		 "\\nofill",			0,	0,
	".ns",		 "",				0,	0,
	".ul",		 "\\undertext",			2,	0
};
SHAR_EOF
fi # end of overwriting check
if test -f 'maths.h'
then
	echo shar: will not over-write existing file "'maths.h'"
else
cat << \SHAR_EOF > 'maths.h'
/*
This file contains a list of the words that have simple
correspondence in the two languages.
Do not put here words that require action (like sub).
If the word is identical in the two languages (except for TeX's backslash),
put it in simil.h
*/

struct math_equiv {
	char *troff_symb, *tex_symb;
} math[] = {
/*	troff name		TeX name		*/

	"~",			"\\ ",
	"^",			"\\,",
	"above",		"\\cr",
	"ccol",			"\\matrix",
	"cpile",		"\\matrix",
	"fat",			"",
	"grad",			"\\nabla",
	"half",			"{1\\over 2}",
	"inf",			"\\infty",
	"inter",		"\\cap",
	"lcol",			"\\matrix",
	"lineup",		"",
	"lpile",		"\\matrix",
	"mark",			"",
	"nothing",		"",
	"pile",			"\\matrix",
	"rcol",			"\\matrix",
	"rpile",		"\\matrix",
	"union",		"\\cup"
};
SHAR_EOF
fi # end of overwriting check
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
# Use makefile.msc if you are compiling with MS-DOS

# add -Dtops20 to CFLAGS if you're running it under tops20
# and add -DANSI if you're using ANSI C
CFLAGS =
LINTFLAGS = -abchnpux
CFILES = tr2tex.c tr.c subs.c
HFILES = setups.h simil.h greek.h macros.h maths.h flip.h forbid.h
B =

default: tr2tex

tr2tex: tr2tex.o tr.o subs.o
	cc $(CFLAGS) tr2tex.o tr.o subs.o -o $(B)tr2tex

tr2tex.o: tr2tex.c setups.h
	cc $(CFLAGS) -c tr2tex.c
tr.o: tr.c setups.h
	cc $(CFLAGS) -c tr.c
subs.o: subs.c $(HFILES)
	cc $(CFLAGS) -c subs.c

lint:
	lint $(LINTFLAGS) $(CFILES) > lint.lst

clean:
	\rm -f *.o core *junk* tr2tex lint.lst

SHAR_EOF
fi # end of overwriting check
if test -f 'makefile.msc'
then
	echo shar: will not over-write existing file "'makefile.msc'"
else
cat << \SHAR_EOF > 'makefile.msc'
#-----------------------------------------------------------------------
# Makefile for troff-to-TeX translator using MS-DOS
# Make targets:
#	(none)	same as tr2tex
#	tr2tex	build translator
#	lint	run lint on sources
#	clean	remove object and executable files
#	share	make ../ttr.sh for mailing
#
# Author: Nelson H.F. Beebe	 25-Oct-86

CFLAGS = -O -DMSC -DNO_SGTTY
CFILES = tr2tex.c tr.c subs.c
LINTFLAGS = -abchnpux
B =

tr2tex:	tr2tex.o tr.o subs.o
	cc $(CFLAGS) tr2tex.o tr.o subs.o -o $(B)tr2tex

share:
	make clean
	makescript ../ttr.sh *

tr2tex.o:	tr2tex.c setups.h
	cc $(CFLAGS) -c tr2tex.c

tr.o:	tr.c setups.h
	cc $(CFLAGS) -c tr.c

subs.o:	subs.c setups.h similar.h greek.h flip.h troff_mac.h mathcom.h
	cc $(CFLAGS) -c subs.c

lint:
	lint $(LINTFLAGS) $(CFILES) > lint.lst

clean:
	\rm -f *.o core *junk* tr2tex lint.lst
SHAR_EOF
fi # end of overwriting check
if test -f 'troffms.sty'
then
	echo shar: will not over-write existing file "'troffms.sty'"
else
cat << \SHAR_EOF > 'troffms.sty'
% You need these macros since they are refered to by the translator.
% You can modify them if you want.
% I would very much want better macros for the headers and footers.
% Please pass your suggestions to me.		-Kamal

\def\ps@sepone{%
\def\@oddhead{}
\def\@evenhead{}
\def\@oddfoot{\hfil\it\sepfoot\hfil}
\def\@evenfoot{\hfil\it\sepfoot\hfil}}
\def\ps@sep{%
\def\@oddhead{\hbox{}\it\seprhead\hfil\it\seplhead}
\def\@evenhead{\it\seprhead\hfil\it\seplhead\hbox{}}
\def\@oddfoot{\hfil\it\sepfoot\hfil}
\def\@evenfoot{\hfil\it\sepfoot\hfil}}
\pagestyle{sep}
\def\righthead#1{\def\seplhead{#1}}
\def\lefthead#1{\def\seprhead{#1}}
\def\footer#1{\def\sepfoot{#1}}
\footer{}
\lefthead{}
\righthead{}
\thispagestyle{sepone}
\def\makefootline{\baselineskip24\p@\line{\the\footline}}
\def\makeheadline{\vbox to 0pt{\vskip-22.5pt \line{vbox to 8.5pt{}\the\headline}\vss}\nointerlineskip}

\newfont{\bigbf}{ambx10 scaled\magstep 3}
\newfont{\bigit}{amti10 scaled\magstep 2}
\newfont{\bigrm}{amr10 scaled\magstep 2}

\textheight=9in
\textwidth=6.4in
\textfloatsep 30pt plus 3pt minus 6pt
\parskip=5pt
\oddsidemargin=-.2in
\voffset=-.1in
\newdimen\singlespacing
\singlespacing=11pt     % single line spacing
\normalbaselineskip=15pt     % 1.5 line spacing
\baselineskip=\normalbaselineskip

% multi-line title
\newenvironment{SEPtitle}{\begin{center}\bigbf}{\end{center}}
\def\title#1{
	\begin{SEPtitle}
	\vbox{\baselineskip=1.5\normalbaselineskip
	\vskip1in #1\vskip.3in}
	\end{SEPtitle}}
% multi-line author
\newenvironment{SEPauthor}{\begin{center}\bigit}{\end{center}}
\def\author#1{
	\begin{SEPauthor}
	\vbox{#1 \vskip.3cm}
	\end{SEPauthor}}
\newenvironment{SEPauthoraff}{\begin{center}\bigrm}{\end{center}}
\def\authoraff#1{
	\begin{SEPauthoraff}
	\vbox{#1 \vskip.2in}
	\end{SEPauthoraff}}
% multi-line centered section heading
\newenvironment{SEPmhead}{\begin{center}\bf}{\end{center}}
\def\mhead#1{\pagebreak[3]
	\begin{SEPmhead}\pagebreak[3]
	\vbox{\vskip.3in #1}\nopagebreak
	\end{SEPmhead}\nopagebreak}
% multi-line left-justified subheading
\newenvironment{SEPshead}{\begin{flushleft}\bf}{\end{flushleft}}
\def\shead#1{\pagebreak[3]
	\begin{SEPshead}\pagebreak[3]
	\vbox{\vskip.2in #1}\nopagebreak
	\end{SEPshead}\nopagebreak}

% define ABSTRACT, INTRODUCTION, DISCUSSION, CONCLUSIONS, REFERENCES,
% and APPENDIX as the first three letters
\def\ABS{\mhead{ABSTRACT}}
\def\INT{\mhead{INTRODUCTION}}
\def\DIS{\mhead{DISCUSSION}}
\def\CON{\mhead{CONCLUSIONS}}
\def\ACK{\mhead{ACKNOWLEDGMENT}}
\def\REF{\mhead{REFERENCES}}
\def\APP{\mhead{APPENDIX}}

% reference macro, second ... lines are indented
\newdimen\dtmp     % temporary dimension variable
\def\reference#1{ \baselineskip=\singlespacing \dtmp=\hsize
		\advance\dtmp by-\parindent \parshape 2 0in \hsize \parindent
		\dtmp \noindent #1 \endgraf \baselineskip=\normalbaselineskip
		\vskip4pt
		}

\newcommand{\bs}{$\backslash$}
\def\under{\underline}
\def\dotdot{\ddot}
\def\nwl{\hfill\break}		% similar to latex's \newline but does not
				% complain if there is no line to break
\def\ind#1{\par\everypar{\hangindent=#1\hangafter=0\hskip-\parindent}}
\def\tmpind#1{\par\hskip#1}
\newenvironment{SEPcntr}{\begin{center}}{\end{center}}
\def\cntr#1{\begin{SEPcntr} #1 \end{SEPcntr}}
% displayed text, indented, justification off
\def\displaybegin{\par\begingroup\medskip\narrower\narrower\noindent
		  \obeylines\obeyspaces}
\def\displayend{\endgroup\smallskip\noindent}
% fill and nofill
\def\nofill{\par\begingroup\noindent\obeylines
    \frenchspacing\@vobeyspaces\linepenalty10000}
{\catcode`\ =\active\gdef\@vobeyspaces{\catcode`\ \active \let \@xobeysp}}
\def\@xobeysp{\leavevmode{} }
\def\fill{\endgroup\noindent}

% define a boxing macro
\def\boxit#1{\vbox{\hrule\hbox{\vrule\kern10pt\vbox{\medskip\kern5pt#1\bigskip
\kern5pt}\kern10pt\vrule}\hrule}}
SHAR_EOF
fi # end of overwriting check
if test -f 'troffman.sty'
then
	echo shar: will not over-write existing file "'troffman.sty'"
else
cat << \SHAR_EOF > 'troffman.sty'
% -*-LaTeX-*-
% <BEEBE.TR2TEX>TROFFMAN.STY.6, 24-Feb-87 09:53:53, Edit by BEEBE
% These macros are intended to be referenced by a LaTeX
% \documentstyle[troffman]{article}
% command.  You can insert an 11pt or 12pt option if you like larger
% type--sizes set here are computed from the LaTeX point size setting.
% Size values have been chosen to closely match Unix manual page
% documents, which are actually too wide and too high for good
% typographic taste and readability.
%
\hbadness=10000                 % do not want underfull box messages--there are
                                % usually lots in man pages
\hfuzz=\maxdimen                % no overfull box messages either
\voffset=-0.8in                 % man pages start high on page
\textheight=9in                 % and are long
\textwidth=6.5in                % troff man pages have very wide text
\parindent=0pt
\oddsidemargin=-.2in
\newdimen\singlespacing
\singlespacing=10pt                     % LaTeX has (10+\@ptsize)pt
\addtolength{\singlespacing}{\@ptsize pt} % get size from \documentstyle[??pt]{}

% Use conventional typesetting baselineskip spacing for 10pt type
\normalbaselineskip=1.2\singlespacing
\newlength{\parmargin}  % whole paragraphs indented this much on man pages
\parmargin=3\normalbaselineskip 
\baselineskip=\normalbaselineskip

% page heading/footing
% NB: we need \hfill, not \hfil, here; otherwise box is filled only to current
%     paragraph width
\newcommand{\phead}[3]{%
   \renewcommand{\@oddhead}{%\@setpar{\hangindent=0pt\hangafter=0\@@par}
     {\makebox[\textwidth]{#1(#2) \hfill \rm UNIX Programmer's Manual%
         \hfill #1(#2)}}}%
   \renewcommand{\@oddfoot}{%\@setpar{\hangindent=0pt\hangafter=0\@@par}
      {\makebox[\textwidth]{4th Berkeley distribution \hfill #3%
         \hfill \rm\thepage}}}%
   \renewcommand{\@evenfoot}{\@oddfoot}%
   \renewcommand{\@evenhead}{\@oddhead}%
}
% multi-line left-justified subheading
\def\shead#1{
        \par % force out previous paragraph with its \hangindent values
        \@setpar{\hangindent=0pt\hangafter=0\@@par}
        \typeout{[#1]}  % maybe temporary, but nice for progress report
        \subsubsection*{#1}
        \@setpar{\hangindent=\parmargin\hangafter=0\@@par}
}

\newcommand{\bs}{$\backslash$}
\def\under{\underline}
\def\dotdot{\ddot}
\def\nwl{\hfill\break}          % similar to LaTex's \newline but does not
                                % complain if there is no line to break
\def\ind#1{\par\everypar{\hangindent=#1\hangafter=0\hskip-\parindent}}
\def\tmpind#1{\par\hskip#1}
\newenvironment{SEPcntr}{\begin{center}}{\end{center}}
\def\cntr#1{\begin{SEPcntr} #1 \end{SEPcntr}}
% displayed text, indented, justification off
\def\displaybegin{\par\begingroup\medskip\narrower\narrower\noindent
                  \obeylines\obeyspaces}
\def\displayend{\endgroup\smallskip\noindent}
% fill and nofill
\def\nofill{\par\begingroup\noindent\obeylines
    \frenchspacing\@vobeyspaces\linepenalty10000}
{\catcode`\ =\active\gdef\@vobeyspaces{\catcode`\ \active \let \@xobeysp}}
\def\@xobeysp{\leavevmode{} }
\def\fill{\endgroup\noindent}

% define a boxing macro
\def\boxit#1{\vbox{\hrule\hbox{\vrule\kern10pt\vbox{\medskip\kern5pt#1\bigskip
\kern5pt}\kern10pt\vrule}\hrule}}

% try this TPlist environment
\newcommand{\TPlistlabel}[1]{\mbox{#1}\hfil}
\newenvironment{TPlist}[1]{
\begin{list}{}
    {
      \let\makelabel\TPlistlabel
      \settowidth{\labelwidth}{#1mm}
      \setlength{\leftmargin}{\parmargin}       % all paragraphs have this much
      \addtolength{\leftmargin}{\labelwidth}    % space for label
    }
  }{
\end{list}}
SHAR_EOF
fi # end of overwriting check
if test -f 'tr2tex.9'
then
	echo shar: will not over-write existing file "'tr2tex.9'"
else
cat << \SHAR_EOF > 'tr2tex.9'
.TH TR2TEX 9 "1 January 1987"
.UC 4
.SH NAME
tr2tex \- convert a document from troff to LaTeX
.SH SYNOPSIS
.B tr2tex
[
.B -m
]
.I filename
.SH DESCRIPTION
.B Tr2tex
converts a document typeset in
.B troff
to a
.B LaTeX
format.
It is intended to do the first pass of the conversion. The user
should then finish up the rest of the conversion and customize the
converted manuscript to his/her liking.
It can also serve as a tutor for those who want to convert from
troff to LaTeX.
.PP
Most of the converted document will be in LaTeX
but some of it may
be in plain
.B TeX.
It will also use some macros in
.B troffms.sty
or
.B troffman.sty
which are included in the package and must be available to the document
when processed with LaTeX.
.PP
If there is more than one input file, they will all be converted into
one LaTeX document.
.PP
.B Tr2tex
understands most of the
.B -ms
and
.B -man
macros and
.B eqn
preprocessor symbols. It also understands several plain
.B troff
commands. Few
.B tbl
preprocessor commands are understood to help convert very simple tables.
.PP
When converting manuals, use the
.B -m
flag.
.PP
If a troff command cannot be converted, the line that contain that
command will be commented out.
.PP
NOTE: if you have
.B eqn
symbols, you must have the in-line mathematics delimiter defined by
.B delim
in the file you are converting. If it is defined in another
setup file, that setup file has to be concatenated with the
file to be converted, otherwise
.B tr2tex
will regard the in-line math as ordinary text.
.SH BUGS
Many of these bugs are harmless. Most of them cause local errors
that can be fixed in the converted manuscript.
.PP
\- Some macros and macro arguments are not recognized.
.PP
\- Commands that are not separated from their argument by a space are
not properly parsed (e.g .sp3i).
.PP
\- When some operators (notably over, sub and sup) are renamed (via define),
then they are encountered in the text,
.B tr2tex
will treat them as
ordinary macros and will not apply their rules.
.PP
\- rpile, lpile and cpile are treated the same as cpile.
.PP
\- rcol, lcol are treated the same as ccol.
.PP
\- Math-mode size, gsize, fat, and gfont are ignored.
.PP
\- lineup and mark are ignored. The rules are so different.
.PP
\- Some troff commands are translated to commands that require
delimiters that have to be explicitly put. Since they are
sometimes not put in troff, they can create problems.
Example: .nf not closed by .fi.
.PP
\- When local motions are converted to \\raise or \\lower, an \\hbox
is needed, which has to be put manually after the conversion.
.PP
\- 'a sub i sub j' is converted to 'a_i_j' which TeX
parses as 'a_i{}_j}' with a complaint that it is vague. 'a sub {i sub j}'
is parsed correctly and converted to 'a_{i_j}'.
.PP
\- Line spacing is not changed within a paragraph in TeX
(which is a bad practice anyway).
TeX uses the last line spacing in effect in that paragraph.
.SH TODO
Access registers via
.B .nr
command.
.SH SEE ALSO
texmatch(9), trmatch(9).
.SH AUTHOR
Kamal Al-Yahya, Stanford University
SHAR_EOF
fi # end of overwriting check
if test -f 'tr2tex.9-tex-orig'
then
	echo shar: will not over-write existing file "'tr2tex.9-tex-orig'"
else
cat << \SHAR_EOF > 'tr2tex.9-tex-orig'
% -*-LaTeX-*-
% Converted automatically from troff to LaTeX by tr2tex on Fri Feb 20 12:05:23 1987
% tr2tex was written by Kamal Al-Yahya at Stanford University
% (Kamal%Hanauma@SU-SCORE.ARPA)


\documentstyle[troffman]{article}
\begin{document}
%
% input file: tr2tex.9
%
\phead{TR2TEX}{9}{1\ January\ 1987}

\shead{NAME}
tr2tex -- convert a document from troff to LaTeX
\shead{SYNOPSIS}
{\bf tr2tex}
[
{\bf -m}
]
{\it filename}
\shead{DESCRIPTION}
{\bf Tr2tex}
converts a document typeset in
{\bf troff}
to a
{\bf LaTeX}
format.
It is intended to do the first pass of the conversion. The user
should then finish up the rest of the conversion and customize the
converted manuscript to his/her liking.
It can also serve as a tutor for those who want to convert from
troff to LaTeX.
\par
Most of the converted document will be in LaTeX
but some of it may
be in plain
{\bf TeX.}
It will also use some macros in
{\bf troffms.sty}
or
{\bf troffman.sty}
which are included in the package and must be available to the document
when processed with LaTeX.
\par
If there is more than one input file, they will all be converted into
one LaTeX document.
\par
{\bf Tr2tex}
understands most of the
{\bf -ms}
and
{\bf -man}
macros and
{\bf eqn}
preprocessor symbols. It also understands several plain
{\bf troff}
commands. Few
{\bf tbl}
preprocessor commands are understood to help convert very simple tables.
\par
When converting manuals, use the
{\bf -m}
flag.
\par
If a troff command cannot be converted, the line that contain that
command will be commented out.
\par
NOTE: if you have
{\bf eqn}
symbols, you must have the in-line mathematics delimiter defined by
{\bf delim}
in the file you are converting. If it is defined in another
setup file, that setup file has to be concatenated with the
file to be converted, otherwise
{\bf tr2tex}
will regard the in-line math as ordinary text.
\shead{BUGS}
Many of these bugs are harmless. Most of them cause local errors
that can be fixed in the converted manuscript.
\par
-- Some macros and macro arguments are not recognized.
\par
-- Commands that are not separated from their argument by a space are
not properly parsed (e.g .sp3i).
\par
-- When some operators (notably over, sub and sup) are renamed (via define),
then they are encountered in the text,
{\bf tr2tex}
will treat them as
ordinary macros and will not apply their rules.
\par
-- rpile, lpile and cpile are treated the same as cpile.
\par
-- rcol, lcol are treated the same as ccol.
\par
-- Math-mode size, gsize, fat, and gfont are ignored.
\par
-- lineup and mark are ignored. The rules are so different.
\par
-- Some troff commands are translated to commands that require
delimiters that have to be explicitly put. Since they are
sometimes not put in troff, they can create problems.
Example: .nf not closed by .fi.
\par
-- When local motions are converted to \bs raise or \bs lower, an \bs hbox
is needed, which has to be put manually after the conversion.
\par
-- 'a sub i sub j' is converted to 'a\_i\_j' which TeX
parses as 'a\_i\{\}\_j\}' with a complaint that it is vague. 'a sub \{i sub j\}'
is parsed correctly and converted to 'a\_\{i\_j\}'.
\par
-- Line spacing is not changed within a paragraph in TeX
(which is a bad practice anyway).
TeX uses the last line spacing in effect in that paragraph.
\shead{TODO}
Access registers via
{\bf .nr}
command.
\shead{SEE ALSO}
texmatch(9), trmatch(9).
\shead{AUTHOR}
Kamal Al-Yahya, Stanford University
\end{document}
SHAR_EOF
fi # end of overwriting check
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
Please read this file before you install the program.

Troff-to-TeX translator version .93, March 4, 1987.
Copyright (C) by 1987 Kamal Al-Yahya.

This directory contains programs that were developed at the
Stanford Exploration Project, Geophysics Department, by Kamal Al-Yahya.
Copying them to any other machine is permitted without prior permission
provided that copyright messages are kept, no profit is made by copying
the files, and modifications are clearly documented.

I would very much appreciate any comments or suggestions. My e-net
address is
		kamal@hanauma.stanford.edu
If it doesn't work try
		kamal%hanauma@score.stanford.edu

			INSTALLATION INSTRUCTIONS

In short, type ``make'' and then run it on the document (try the testfile):
		tr2tex testfile > testfile.tex

In details:

- Use makefile.msc if you're running MS-DOS.
- In the makefile, define the destination of the executable (default is
  current directory). Also, add the -O flag if you want to (and the
  optimizer in your machine is not buggy). The -O flag causes long compilation
  time but experience has shown that it is unnecessary for this package;
  time saved in running time is extremely small in the computers I used.
- If the limit on your unsigned int is not 65535, change MAXLEN in
  setups.h accordingly.
- In tr2tex.c, change the document type if you want. The default is article.
  Also, change the style options to suit your taste. The default
  is [troffms,11pt] if no flag is used and [troffman] if the -m flag is used.
- Add necessary -D's to CFLAGS if you need them. The program recognizes the
  following compiler-time definitions:
	   -Dtops20, -DANSI, -DMSC, -DNO_SGTTY
- type ``make'' to produce the executable, called ``tr2tex''.
- Modify troffms.sty and troffman.sty to suit your taste but keep the
  necessary macro definitions as they will be needed when running latex.
  Make sure the font names exist on your site. Change them if necessary.
- Move troffms.sty and troffman.sty to your macros directory.
- Install and read the manual page.
- Run the translator on ``testfile'' and the manual page as follows
		tr2tex testfile > testfile.tex
		tr2tex -m tr2tex.9 > tr2tex.9.tex
  
  and compare ``testfile.tex'' with ``testfile.tex-orig'' and
  ``tr2tex.9.tex'' with ``tr2tex.9-tex-orig''.
  If they are not identical, you have not installed it properly.


			USING THE TRANSLATOR

You can run the program either by
		tr2tex < file  > file.tex
or
		tr2tex file  > file.tex
You are most likely to get messages on the standard error telling
you about things it encounters and cannot do.

Now you have the translated document. Look at it and see if you
can spot a major error. Run it through latex. If it runs and produces
the dvi file, then print it. If you get latex error messages modify
the translated document accordingly and repeat the latex run, and so on.
I usually get away with one or two iterations.

SHAR_EOF
fi # end of overwriting check
if test -f 'testfile'
then
	echo shar: will not over-write existing file "'testfile'"
else
cat << \SHAR_EOF > 'testfile'
.LP
.EQ
delim $$
gsize 11
define dC "delta C"
define xx 'x sup x'
define B 'bold B'
define (( 'left ('
define )) 'right )'
define ov 'over'
.EN
.ds CF %
.ds LH Al-Yahya
.ds RH troff to TeX translator
.TL  	
Testing the troff-to-tex translator
.AU  		
Kamal Al-Yahya
.AI
Stanford University
.AB
This file demonstrates the use of \fB tr2tex\fR which translates
documents written in troff to a LaTeX style.
Examples are given to show what the translator can do.
.AE
.PP
First let's test some equation written for the
.B eqn
preprocessor:
.EQ (1)
2 left ( 1 ~+~ sqrt{omega sub i+1 + zeta -{x+1} over {THETA +1} y + 1} right )
~~~=~~~ 1
.EN
.EQ
left [
matrix {
   ccol { e sub 1 above . above . above e sub i above . above . above e sub N }
}
right ] sub n+1 ~~=~~ y + 1
.EN
.EQ
bold X + roman a ~>=~
a under hat fwd 20 sum from i to N lim from {x -> k} dC
.EN
.EQ
(( "speed" times "time" = "distance travelled" ))
.EN
.EQ
beta tilde i >= zeta dC
.EN
.IP
In-line math like $beta +1$ which is surrounded by math delimiters, as
defined by
.I delim
is also translated.
.R
.PP
Only simple tables are translated. Translation of more complicated tables
is painful and I won't do it now. Here is an example:
.TS
tab(&);
l rc n.
name	& type		& color	& value
$alpha$	& real		& red	& 2.3
$x$	& imaginary	& green	& -1.2
$a + 2$	& real		& white	& 0.0
.TE
\" this is a commented text
.PP
Now we start a figure.
.Is
.sp 3i
.Ic 1
This is the caption of the figure.
.Ie
.PP
Try some floating objects.
.br
.KS
This text should be kept in one page. i.e. a page break is discouraged here.
.KE
.br
Now a floating text.
.KF
This text should be kept in one page even if we had to move it around,
since it is a
.I floating
object. This is a boxed
.BX word.
.KE
.br
These characters are special in TeX, so they need to be escaped
in the translation % & # _, while these characters have to be
printed in math mode < > |. 
.FS
This is a footnote
.FE
.PP
.Ac
Thanks to all of those who contributed by reporting bugs and suggesting
some improvements. Special thanks go to Nelson Beebe for all of his valuable
contributions and suggestions. He is responsible for making the translator
portable to other computers. He also made significant improvements to
the translation of manuals.
.Re
Knuth, D.E., 1984, The TeXBook, Addison-Wesley Publishing Company.
.Re
Lamprt, L., 1986, LaTeX: user's guide & reference manual, Addison-Wesley
Publishing Company.
.Re
Lesk, M.E., 1978, Typing documents on the UNIX
system: using the -ms macros
with troff and nroff, UNIX programmer's manual, v. 2B, sec. 3.
.Re
McGilton, H. and Morgan, R., 1983, Introducing the UNIX system, McGraw-Hill
Book Company.
SHAR_EOF
fi # end of overwriting check
if test -f 'testfile.tex-orig'
then
	echo shar: will not over-write existing file "'testfile.tex-orig'"
else
cat << \SHAR_EOF > 'testfile.tex-orig'
% -*-LaTeX-*-
% Converted automatically from troff to LaTeX by tr2tex on Tue Mar  3 23:25:31 1987
% tr2tex was written by Kamal Al-Yahya at Stanford University
% (Kamal%Hanauma@SU-SCORE.ARPA)


\documentstyle[troffms,11pt]{article}
\begin{document}
%
% input file: testfile
%
\par\noindent
\def\dC{\delta C}
\def\xx{x^x}
\def\B{{\bf B}}
\def\ov{\over  }

\footer{\rm\thepage}
\lefthead{Al-Yahya}
\righthead{troff to TeX translator}
\title{Testing the troff-to-tex translator}
\author{Kamal Al-Yahya}
\authoraff{Stanford University}
\begin{abstract}
This file demonstrates the use of  %
\bf tr2tex %
\rm which translates
documents written in troff to a LaTeX style.
Examples are given to show what the translator can do.
\end{abstract}
\par
First let's test some equation written for the
{\bf eqn}
preprocessor:
$$
2 \left( 1 \ +\  \sqrt{\omega_{i+1} + \zeta -{x+1  \over \Theta +1} y + 1} \right)
\ \ \ =\ \ \  1
\eqno (1)$$
$$
\left[
\matrix {
   \matrix { e_1 \cr . \cr . \cr e_i \cr . \cr . \cr e_N }
}
\right]_{n+1} \ \ =\ \  y + 1
$$
$$
{\bf X} + {\rm a} \ \ge\ 
\under{\hat a} \kern0.20em \sum_i^N \lim_{{x} \to k} \dC
$$
$$
\left( \ \it\hbox{speed} \times \ \it\hbox{time} = \ \it\hbox{distance travelled} \right)
$$
$$
\tilde \beta i \ge \zeta \dC
$$
\begin{itemize}
\item[{}]
In-line math like $\beta +1$ which is surrounded by math delimiters, as
defined by
{\it delim}
is also translated.
\rm
\end{itemize}\par
Only simple tables are translated. Translation of more complicated tables
is painful and I won't do it now. Here is an example:
\par
\begin{tabular}{lrcc}
name	 &  type		 &  color	 &  value\\
$\alpha$	 &  real		 &  red	 &  2.3\\
$x$	 &  imaginary	 &  green	 &  -1.2\\
$a + 2$	 &  real		 &  white	 &  0.0
\end{tabular}
\par
% this is a commented text
\par
Now we start a figure.
\begin{figure}
\par\vspace{3.0in}
\caption{
This is the caption of the figure.
}\end{figure}
\par
Try some floating objects.
\nwl
{\nobreak
This text should be kept in one page. i.e. a page break is discouraged here.
}
\nwl
Now a floating text.
\begin{figure}
This text should be kept in one page even if we had to move it around,
since it is a
{\it floating}
object. This is a boxed
\fbox{word.}
\end{figure}
\nwl
These characters are special in TeX, so they need to be escaped
in the translation \% \& \# \_, while these characters have to be
printed in math mode $<$ $>$ $|$. 
\footnote{
This is a footnote
}
\par
\ACK
Thanks to all of those who contributed by reporting bugs and suggesting
some improvements. Special thanks go to Nelson Beebe for all of his valuable
contributions and suggestions. He is responsible for making the translator
portable to other computers. He also made significant improvements to
the translation of manuals.
\REF
\reference{Knuth, D.E., 1984, The TeXBook, Addison-Wesley Publishing Company.}
\reference{Lamprt, L., 1986, LaTeX: user's guide \& reference manual, Addison-Wesley Publishing Company.}
\reference{Lesk, M.E., 1978, Typing documents on the UNIX system: using the -ms macros with troff and nroff, UNIX programmer's manual, v. 2B, sec. 3.}
\reference{McGilton, H. and Morgan, R., 1983, Introducing the UNIX system, McGraw-Hill Book Company.}
\end{document}
SHAR_EOF
fi # end of overwriting check
if test -f 'diffs.tex'
then
	echo shar: will not over-write existing file "'diffs.tex'"
else
cat << \SHAR_EOF > 'diffs.tex'
\documentstyle[tr2tex,11pt]{article}
\begin{document}
\def\troff{{\it troff}}
\def\Troff{{\it Troff}}
\def\ditroff{{\it ditroff}}
\def\Ditroff{{\it Ditroff}}

\title{Differences between \TeX\ and troff typesetters}

Outlined below are the differences between \TeX\ and \troff\/ that
I know from experience with the two languages most of which
obtained while writing {\bf tr2tex}.
Most of them are advantages \TeX\ has over \troff.

There are actually more than one type of \TeX, the most
used ones are \LaTeX and plain \TeX\
\Troff\/ can also be loaded with various macro packages to
produce variations to plain \troff. Also, \ditroff\/ (device independent \troff)
is becoming more and more the standard of \troff.
The following comparison is made mainly between \LaTeX\ and {\bf ms} \troff.
It will be mentioned if in a particular case \ditroff\/ makes a difference.

\begin{itemize}
\item \TeX\ is not system-dependent. \Troff\/ is a Unix tool.

\item In \Troff, tables and equations are handled by preprocessors
while in \TeX\ they are simultaneously processed with text.

\item \Troff\/'s commands have to start at the beginning of the line
and start with a dot. Equation symbols are recognized when delimited by space.
All \TeX\ commands, in math or non-math mode, start with a backslash
and they don't have to be placed at the beginning of the line.

\item \TeX\ and \LaTeX\ commands are more verbose than \troff\/'s.
This can be an advantage or disadvantage depending on the user.

\item \TeX\ processes {\it boxes} such as lines and paragraphs as one unit.
This means it can distribute {\it badness} over that box.
For example, when a spacing between two lines needs to be large, because
a line has large symbols, it will slightly stretch the
line spacing in other lines to make the large spacing not look
too bad. This also makes it avoid orphan lines.

\item The input to \LaTeX\ is a more structured document with scopes. It makes it
easier to proofread. \Troff\/'s input is less structured.

\item Some  \TeX\ drivers make it very easy to include prepared
graphs with the text. Including graphs with \troff\/'s text is more difficult.

\item Many fonts can be loaded in a \TeX\ document (up to 32); in \troff,
the limit is 4 (\ditroff\/ does not have this restriction).

\item Non-math macros are defined just like math macros in \TeX.
In \troff, {\bf define} is used for math definitions and {\bf .de} is
used for non-math macros.
\Troff\/'s macros can be made up from anything while
\TeX\ macros cannot have non-letters which is a nuisance sometimes.

\item There is no limit on the page size in \TeX. The size is limited only by
the output device. \Troff\/'s paper size is limited.

\item \TeX\ is interactive, while \troff\/ is not. However, not many people can
benefit from this feature since they have to be skillful in answering
its questions.

\item \TeX\ and \LaTeX\ give a {\bf l\,o\,n\,g} ambiguous log file that does not
exactly tell what the error is. \Troff\/ does not give error messages.

\item \LaTeX\ automatically numbers equations and figures, etc. A powerful
cross-referencing technique relieves the user from worrying about having
the right sequence of equations' and figures' numbers. This feature
is not available in \troff.

\item The documentation in the \LaTeX\ manual is excellent.
\Troff\/'s documentation is scattered over many references.
The documentation in the \TeX Book is very technical and the average reader
may find it unreadable.

\item At hanauma, we have a previewer for TeX on the SUN, but don't have it
for \troff.
\end{itemize}
\end{document}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0