[fa.info-mac] macwrite to dvi conversion program

info-mac@uw-beaver.UUCP (11/02/84)

From: ihnp4!umich!doug@uw-beaver.arpa (Doug Orr)

The following is a program that converts from macwrite format to TeX dvi
format.  This allows you to print (typeset?!) macwrite documents on a
variety of electronic printers that support printing of TeX output.

It currently doesn't handle pictures (other than to ignore them),
page number, date, or time icons, special characters or accent marks.
Macwrite printing options are ignored.

I am planning to add these features, but I thought that people would
find this much useful in the mean time.

Support for interfacing to IMAGEN software on 4.1 and 4.2 is provided.
This can just be commented out if not applicable.

Thanks to the gentleman that posted the description of macwrite internal
format.  

If anyone knows anything about the legalities of using Mac fonts on
an imagen or has access to higher density versions of the mac fonts,
I would just love to talk to you.  Currently this program substitutes
TeX fonts for mac fonts.

	-Doug Orr
	ihnp4!uovm-cv!umich!doug


#----------------- cut here --------------------


#  mwdvi  -  douglas orr | University of Michigan  Mon Oct 29 10:34:46 EST 1984
#
#  execute this shell (sh) script on a clean directory to
#  install this version of mwdvi sources
#
#  don't forget to read the makefile and modify the 
#  appropriate parameters


#  File Makefile:
#  ----------------------------------------------------------------------------
echo extracting: Makefile
cat << "eof-Makefile" > Makefile

#
##
#	mwdvi  <->  macwrite to dvi translation program.
#
#	10/11/84  douglas orr


#
#   Installation Options:
#
###
#   version can be  BSD_41
#		or  BSD_42
VERSION=BSD_42

###
#   directory where TeX tfm information can be found
#
TFM_PATH=/usr/lib/font/imagen/tfm


###
#    directory and group for installation of binaries
#
BINDIR	=/usr/local/bin
BINGRP	=bin
BINMODE	=711

INSTALL=install
INSOPTS=-g $(BINGRP) -m $(BINMODE) -s

#
#
CFLAGS= -O

SOURCES	= main.c dvi.c fonts.c md.c
INCLUDES= gen.h option.h md.h dvi.h fonts.h
OBJECTS	= main.o dvi.o fonts.o md.o

mwdvi:	$(OBJECTS)
	cc -o mwdvi $(OBJECTS)

site.h: Makefile
	echo "#define $(VERSION)=1" > site.new.h
	echo "#define TFM_PATH=\"$(TFM_PATH)\"" >> site.new.h
	-if( cmp -s site.h site.new.h );  \
	then \
		$(RM) -f site.new.h; \
	else \
		$(RM) -f site.h; \
		mv site.new.h site.h; \
	fi
		


main.o:		gen.h site.h option.h md.h
md.o:		gen.h site.h option.h md.h dvi.h
dvi.o:		gen.h site.h option.h md.h dvi.h fonts.h
fonts.o:	gen.h site.h option.h md.h dvi.h fonts.h


#
#	administrative stuff
#
install:
	$(INSTALL) $(INSOPTS) mwdvi $(BINDIR)



clean:
	rm $(OBJECTS)

clobber:
	rm -f $(SOURCES) $(INCLUDES) site.h

sources:
	@echo $(SOURCES) $(INCLUDES)

mdump:	mdump.o
	cc -o mdump mdump.o


eof-Makefile

#  File main.c:
#  ----------------------------------------------------------------------------
echo extracting: main.c
cat << "eof-main.c" > main.c
#include	<stdio.h>
#include	<signal.h>

#include	"site.h"
#include	"gen.h"
#include	"option.h"
#include	"md.h"

LOCAL	char	* program;
LOCAL	char	* outfile	= NULL;
LOCAL	char	tmpfile[] = "/tmp/mwXXXXXX";
LOCAL	bool	temp = FALSE;

#ifdef	BSD_42
LOCAL	char	pr_opts[BUFSIZ]	= "";
#endif	BSD_42
LOCAL	void	sig();


/*
 *	global variables
 */
FILE	* infd;
FILE	* outfd = NULL;



/*
 *	options
 */
bool	verbose	= FALSE;
bool	spool = FALSE;
bool	debflg	= FALSE;
char	* font_sub_file	= NULL;


extern	char	* getenv();


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

	bool	first_time = TRUE;

	program = argv[0];

	/*
	 *	signals, signals, signals!
	 */
	signal( SIGINT, sig );
	signal( SIGQUIT, sig );
	signal( SIGHUP, sig );

	/*
	 *	take a shot at some environment variables
	 */
	font_sub_file = getenv( "MACFONTS" );


	/*
	 *	process command line options
	 */
	while( (++argv, --argc) && (*argv)[0] == '-' )
	switch( (*argv)[1] )
		{

		/*	be noisy	*/
		case 'v':
			verbose = TRUE;
			break;

		/*	spool resultant output	*/
		case 'p':
			spool = TRUE;
			break;
		
#ifdef	BSD_42
		case 'P':
			strcat( pr_opts, " " );
			strcat( pr_opts, *argv );
			spool = TRUE;
			break;
#endif	BSD_42
		

		/*	debug output	*/
		case 'D':
			debflg = TRUE;
			break;

		/*	font substitution file	*/
		case 's':
			if( --argc == 0 )
				fatal( "must specify output file" );

			font_sub_file = *(++argv);
			break;
			

		/*	put mah output here	*/
		case 'o':
			if( --argc == 0 )
				fatal( "must specify output file" );

			outfile = *(++argv);
			break;
		
		default:
			fatal( "unknown option %c", (*argv)[1] );

		}
	

	/*
	 *	do it
	 */
	if( argc == 0 )
		fatal( "no input file" );
	

	/*	all output goes to a file 	*/
	if( outfile == NULL )
		{
		if( !spool )
			fatal( "no output file" );
		else
			{
			mktemp( tmpfile );
			temp = TRUE;
			outfile = tmpfile;
			}
		}
	

	if( (outfd = fopen( outfile, "w" )) == NULL )
		fatal( "couldn't open %s", outfile );


	

	while( argc-- )
		{

		if( (infd = fopen( *(argv++), "r" )) == NULL )
			fatal( "couldn't open macwrite file %s", *argv );
		
		if( verbose && argc > 0 )
			fprintf( stderr, "%s:\n", *argv );

		if( first_time )
			{
			init();
			first_time = FALSE;
			}

		read_globals();
		body();

		fclose( infd );

		}
	
	finish();

	fclose( outfd );
	if( verbose )
		fprintf( stderr, "%d page(s) produced\n", page_cnt );

	if( spool )
		spool_file();

	Exit( 0 );

	}


Exit( rc )
int	rc;
	{

	if( temp && outfd )
		unlink( tmpfile );
	
	exit( rc );

	}



/*
 *	SYSTEM DEPENDENT!
 */


/*	write dvi output directly to imagen	*/
spool_file()
	{
	char	buf[300];
	bool	temp = FALSE;

	if( verbose )
		fprintf( stderr, "spooling dvi output\n" );

	/*
	 *	must use less precise -a setting because of common bug in
	 *  dviimp  ->  fixptrsuconv calculated using 2E20 fix/pt, 
	 *  not 2^20 fix/pt
	 */

#ifdef	BSD_41
	sprintf( buf, "dviimp -a %s | ipr -Limpress", outfile );
#endif	BSD_41

#ifdef	BSD_42
	sprintf( buf, "TERMCAP=/etc/printcap; export TERMCAP; dviimp -a -p %s %s", pr_opts, outfile );
#endif	BSD_42

	if( system( buf ) != 0 )
		fatal( "error in spooling" );


	}


LOCAL	void
sig()
	{
	fprintf( stderr, "%s aborted\n", program );
	Exit( 1 );
	}


fatal( fmt, a1, a2, a3, a4 )
char	* fmt;
int	a1, a2, a3, a4;
	{

	fprintf( stderr, "%s: fatal - ", program );
	fprintf( stderr, fmt, a1, a2, a3, a4 );
	putc( '\n', stderr );

	Exit( 1 );

	}

warning( fmt, a1, a2, a3, a4 )
char	* fmt;
int	a1, a2, a3, a4;
	{

	fprintf( stderr, "%s: warning - ", program );
	fprintf( stderr, fmt, a1, a2, a3, a4 );
	putc( '\n', stderr );

	}

eof-main.c

#  File dvi.c:
#  ----------------------------------------------------------------------------
echo extracting: dvi.c
cat << "eof-dvi.c" > dvi.c
#include	<stdio.h>
#include	<ctype.h>

#include	"gen.h"
#include	"option.h"
#include	"md.h"
#include	"dvi.h"
#include	"fonts.h"


LOCAL	SP	indent		= min_to_sp(   500 );
LOCAL	SP	lmargin_h	= min_to_sp(   500 );
LOCAL	SP	lmargin_v	= min_to_sp(  1000 );
LOCAL	SP	rmargin_v	= min_to_sp( 10500 );
LOCAL	SP	rmargin_h	= min_to_sp(  6500 );
LOCAL	SP	tabs[TABMAX]	= { 0, };
LOCAL	int	tabcnt		= 0;
LOCAL	double	spacing	= 1.0;
LOCAL	int	adjust = JST_LEFT;


LOCAL	int	cur_font;
LOCAL	int	pushmax		= 0;
LOCAL	POS	stack[20];
LOCAL	POS	* cur;

LOCAL	FILEPTR	last_page = -1;


LOCAL	bool	silent = FALSE;


init()
	{
	int	i;

	for( i=0; i<MAX_FONTS; i++ )
		{
		fonts[i].f_active = FALSE;
		fonts[i].f_number = -1;
		}
	

	preamble();

	page_no = 0;
	page();

	}

finish()
	{
	outcmd( EOP );
	postamble();
	}

preamble()
	{
	outcmd( TEX_ID );		/* tek version 2 */
	out4( scale_num );		/* num */
	out4( scale_denom );		/* denom  */
	out4( 1000 );			/* mag */
	out1( 0 );
	}

postamble()
	{
	long	postptr;
	int	i;


	postptr = ftell( outfd );
	outcmd( POST );
	out4( last_page );
	out4( scale_num );		/* num */
	out4( scale_denom );		/* denom  */
	out4( 1000 );			/* mag */
	out4( min_to_sp( 11000 ) );	/* max height (fix this) */
	out4( min_to_sp( 8500 ) );	/* max width (fix this) */
	out2( pushmax );		/* max stack depth  */
	out2( page_no );

	/*	font definitions	*/
	for( i=0; i<MAX_FONTS; i++ )
		{
		if( fonts[i].f_number == -1 )
			break;
		else
			def_font( i );
		}
	
	outcmd( POSTPOST );
	out4( postptr );
	out1( TEX_ID );

	/* output a signature	*/
	for( i=0; i<4; i++ )
		out1( 223 );
	
	postptr = ftell(outfd);
	
	for( i=0; i< (postptr % 4); i++ )
		out1( 223 );

	}



/*
 *	do a page eject
 */
LOCAL	in_page = FALSE;
LOCAL	in_footer = FALSE;

page()
	{

	SP	bottom_margin;

	if( in_page )
		{

		if( in_footer )
			{
			warning( "footer extends off the bottom of the page" );
			return;
			}

		bottom_margin = rmargin_v;

		cur->p_v = rmargin_v;
		rmargin_v = min_to_sp( 11500 );
		in_footer = TRUE;

		footer();

		in_footer = FALSE;
		rmargin_v = bottom_margin;

		outcmd( EOP );

		}

	bop( ++page_no );
	in_page = TRUE;

	/*	potentially, don't print header on title page  */
	if( page_cnt++ || !title_page )
		header();

	}



bop( page )
int	page;
	{
	long	lastp;
	int	i;

	lastp = ftell(outfd);

	outcmd( BOP );
	out4( page );
	for( i=0; i<9; i++ )
		out4( 0 );
	out4( last_page );

	last_page = lastp;

	cur = stack;
	cur->p_v = cur->p_h = cur->p_w = 
	cur->p_x = cur->p_y = cur->p_z = 0;
	cur_font = -1;

	/*	start us out someplace reasonable	*/
	out_pos( 0L, lmargin_v );

	}


push()
	{
	if( cur - stack >= 19 )
		fatal( "botch: stack overflow" );
	
	outcmd( PUSH );

	*(cur+1) = *cur;
	++cur;

	pushmax = max( pushmax, cur - stack );
	}

pop()
	{
	if( cur <= stack )
		fatal( "botch: stack underflow" );
	
	outcmd( POP );

	--cur;
	}



/*
 *	format another line, dvi style
 */

out_line( len, line )
int	len;
Char	* line;
	{
	WORD	words[MAX_WORDS];

	int	wordpos;
	int	cpos;

	int	i;
	int	j;

	int	cur_font;
	int	this_font;

	SP	line_length;
	SP	line_height;
	SP	word_length;
	SP	word_space;
	SP	ss_space;
	SP	margin;

	/*
	 *	initial indent
	 */
	margin = indent;

	/*
	 *	break this paragraph into words
	 */
	for( cpos=0; cpos < len; ) {

	/*
	 *	skip leading spaces
	 */
	for( ; cpos < len; cpos++ )
		if( line[cpos].c_char != ' ' )
			break;

	cur_font = this_font = fontno( &line[cpos] );
	word_space = font_ws( cur_font );
	ss_space = font_ss( cur_font );
	line_height = font_height( cur_font );

	wordpos = 0;
	line_length = 0;

	/* leave yourself an initial null space */
	words[wordpos].wd_length = 0;
	words[wordpos++].wd_flags = 0;

	while( cpos < len && line_length < (rmargin_h - margin) )
		{

		if( wordpos >= MAX_WORDS )
			fatal( "(botch) too many words in this paragraph" );

		if( !isspace( line[cpos].c_char ) )
			{
			/*
			 *	non space characters
			 */
			words[wordpos].wd_flags = WD_WORD;
			words[wordpos].wd_pos = cpos;

			
			word_length = 0;
			while( cpos < len 
			&&     !isspace( line[cpos].c_char ) )
				{
				word_length += ch_wid( &line[cpos] );

				this_font = fontno( &line[cpos] );
				line_height = max( line_height,
					font_height( this_font ) );

				cpos++;
				}
			
			/*
			 *	this_font is guaranteed to be set
			 */
			if( this_font != cur_font )
				{
				cur_font = this_font;
				word_space = font_ws( cur_font );
				ss_space = font_ss( cur_font );
				}
			
			words[wordpos].wd_length = word_length;
			words[wordpos++].wd_end = cpos;

			Debug {
			fprintf( stderr, "line_out: -" );
			for( i=words[wordpos-1].wd_pos; i<cpos; i++ )
				fprintf( stderr, "%c", line[i].c_char );
			fprintf( stderr, "- (%2.2f)\n", sp_to_in(word_length),
				sp_to_in(line_length) );
			}

			/*
			 *	will this word overflow the line? 
			 */
			if(line_length + word_length > (rmargin_h - margin))
				{
				cpos = words[--wordpos].wd_pos;
				break;
				}
			}
		else
			{

			SP	space;

			/*
			 *	process the word gap
			 */
			words[wordpos].wd_flags = 0;
			words[wordpos].wd_tabcnt = 0;
			word_length = words[wordpos].wd_length = 0;


			/* 
			 *	is this an inter-word or inter-sentence gap?
			 */
			if( wordpos > 0 
			&&  (words[wordpos-1].wd_flags & WD_WORD)
			&&  ispunct(line[words[wordpos-1].wd_end-1].c_char ) )
				space = ss_space;
			else
				space = word_space;
				

			/* 
			 *	eat up those spaces.  count those tabs
			 */
			while( cpos < len 
			&&     isspace( line[cpos].c_char ) )
				{
				if( line[cpos].c_char == '\t' )
					{
					words[wordpos].wd_flags |= WD_TAB;
					words[wordpos].wd_length = word_space;
					words[wordpos].wd_tabcnt++;
					}
				else
				if( line[cpos].c_char == ' ')
					{
					word_length = 
					words[wordpos].wd_length = space;
					}
				
				if( line[cpos].c_style & ST_UL )
					words[wordpos].wd_flags |= WD_UL;

				cpos++;
				}
				
			wordpos++;
				
			}
		
		line_length += word_length;

		}

	/*

	 *	print out the words in this line
	 */


	/* 	move to the next line */

	down( (SP)((line_height * 1.4) * spacing) );


	push();		/* save the margin coordinates */

	if( cur->p_v > rmargin_v )
		{
		page();	/* you get an implicit pop when you page */
		push();
		}
	right( margin );

	
	/*
	 *	remove trailing white space
	 */
	while( wordpos > 0 )
		{
		if( words[wordpos-1].wd_flags & WD_WORD )
			break;
		else
			wordpos--;
		}

	/*
	 *	center, justify, or whatever
	 */
	justify( words, &wordpos, &cpos, margin, (cpos >= len) );


	/*
	 *	print that suckah
	 */
	for( i=0; i < wordpos; i++ )
		{
		if( words[i].wd_flags & WD_WORD )
			{
			for( j=words[i].wd_pos; j < words[i].wd_end; j++)
				set_ch( &line[j] );
			}
		else
			right( words[i].wd_length );
		}
	
	Debug {
	fprintf( stderr, "line %2.2f, %2.2f\n", sp_to_in(cur->p_h ),
		sp_to_in(cur->p_v) );
	}

	pop();		/* restore the margin coordinates */


	/*	do any underlining that might be appropriate	*/
	underline( words, wordpos, line, margin );
	

	margin = lmargin_h;	/* undo the indent */

	}

	}


/*
 *	justify the line.  add some tabs
 */
justify( words, word_count, cur_pos, margin, last_line )
WORD	* words;
int	* word_count;
int	* cur_pos;
SP	margin;
int	last_line;
	{

	SP	spacelen;
	SP	extra_space;
	SP	line_len;
	SP	line_wid;
	REG	WORD	* cw;
	REG	double	ratio;
	REG	int	i;
	int	lasttab;
	int	wdcnt;

	wdcnt	= *word_count;

	/*
	 *	take care of tabs
	 */
	lasttab = 0;

	if( adjust == JST_LEFT || adjust == JST_ADJ )
		{
		REG	SP cpos = margin;
		int	tb;

		/*  modify tab width to justify next word */
		for( cw=words; cw < &words[wdcnt]; cw++ )
			{
			if( cw->wd_flags & WD_TAB )
				{
				lasttab = (cw-words) + 1;

				for( tb=0; tb < cw->wd_tabcnt; tb++ )
					{

					for( i=0; i<tabcnt; i++ )
						if( cpos < tabs[i] )
							break;

					if( i < tabcnt )
						cw->wd_length = tabs[i] - cpos;

					}
				
				}
			
			/*  is the line now too large to fit? */
			if( cpos + cw->wd_length > rmargin_h )
				break;
				
			cpos += cw->wd_length;

			}
		
		/*	shorten this line.  tabs expanded it too much */
		if( cw != &words[wdcnt] )
			{
			*cur_pos = cw->wd_pos;
			wdcnt = *word_count = cw - words;
			}
		
		/*	don't justify words before a tab stop	*/
		for( cw=words; cw < &words[lasttab]; cw++ )
			margin += cw->wd_length;

		}
	
	/* figure out the current length of this line */
	for  ( line_len = 0, cw = &words[lasttab]; cw < &words[wdcnt]; cw++ )
		line_len += cw->wd_length;
	
	line_wid = rmargin_h - margin;


	switch( adjust )
		{
		case JST_LEFT:
			break;

		case JST_ADJ:
			
			if( last_line || line_len <= 0 )
				break;

			spacelen = 0;

			for( cw = &words[lasttab]; cw < &words[wdcnt]; cw++ )
				{
				if( !(cw->wd_flags & WD_WORD) )
					spacelen += cw->wd_length;
				}
				
			extra_space = (line_wid-line_len) + spacelen;
			ratio = ((double)extra_space) / spacelen;


			for( cw = &words[lasttab]; cw < &words[wdcnt]; cw++ )
				if( !(cw->wd_flags & WD_WORD) )
					cw->wd_length = cw->wd_length * ratio; 
			break;


		case JST_RIGHT:
			words[0].wd_length = line_wid - line_len;
			break;

		case JST_CENTER:
			words[0].wd_length = (line_wid - line_len) / 2;
			break;
		}
	}


underline( words, length, line, margin )
WORD	* words;
int	length;
Char	* line;
SP	margin;
	{

	SP	cpos;
	SP	ul_start;
	REG	int	chpos;
	REG	WORD	* wd;

	bool	ul	= FALSE;

	if( silent )
		return;

	for( cpos = 0, wd = words; wd < &words[length]; wd++  )
		{

		if( wd->wd_flags & WD_WORD )
			{

			for( chpos = wd->wd_pos; chpos < wd->wd_end; chpos++ )
				{
				if( line[chpos].c_style & ST_UL && !ul )
					{
					ul_start = cpos;
					ul = TRUE;
					}
				else
				if( !(line[chpos].c_style & ST_UL) && ul )
					{
					ul = FALSE;

					t_rule( margin+ul_start, mpt_to_sp(250),
						cpos-ul_start );
					}
				
				cpos += ch_wid( &line[chpos] );
				}
			}
		else
			{

			if( (wd->wd_flags & WD_UL) &&  !ul )
				{
				ul = TRUE;
				ul_start = cpos;
				}
			else
			if( !(wd->wd_flags & WD_UL) &&  ul )
				{
				ul = FALSE;

				t_rule( margin+ul_start, mpt_to_sp(250), 
					cpos-ul_start );
				}

			cpos += wd->wd_length;
			}
		
		}
	if( ul )
		t_rule( margin+ul_start, mpt_to_sp(250), cpos-ul_start );

	}


/*
 *	gimme a transparent rule (assume you are at left margin to start)
 */
t_rule( start, h, w )
SP	start;
SP	h;
SP	w;
	{

	push();

	right( start );

	down( (SP)(h + mpt_to_sp(400)) );

	outcmd( PUTRULE );
	out4( h );
	out4( w );

	pop();

	}


/*
 *	put a character at the current position and advance
 */
set_ch( lptr )
Char	* lptr;
	{
	int	font;

	if( silent )
		return;

	if( (font = fontno(lptr)) != cur_font )
		{

		cur_font = font;
		if( !fonts[font].f_active )
			def_font( font );

		outcmd( FONT0 + font );

		}

	outcmd( SET0 + lptr->c_char );

	cur->p_h += ch_wid( lptr );

	}



/*
 *	measure the size of the footer
 */
init_footer()
	{

	SP	top;

	push();
	silent = TRUE;

	top = cur->p_v = min_to_sp( 500 );

	footer();

	rmargin_v = min_to_sp( 10500 ) - (cur->p_v - top);

	if( verbose )
		fprintf( stderr, "footer length %3.2f in.\n", 
			sp_to_in( cur->p_v - top ) );

	silent = FALSE;
	pop();

	}
	

set_ruler( lmargin, rmargin, indnt, space, just )
PIX	lmargin;
PIX	rmargin;
PIX	indnt;
int	space;
int	just;
	{

	lmargin_h = pix_to_sp( lmargin ) + min_to_sp( 1000 );;
	rmargin_h = pix_to_sp( rmargin ) + min_to_sp( 1000 );;
	indent = pix_to_sp( indnt ) + min_to_sp( 1000 );
	adjust = just;

	switch( space )
		{
		case S_SINGLE:
			spacing = 1.0;
			break;

		case S_ONEANDHALF:
			spacing = 1.5;
			break;

		case S_DOUBLE:
			spacing = 2.0;
			break;

		default:
			warning( "unknown line spacing" );
			spacing = 1.0;
			break;
		}

	}


/*	single level save	*/
LOCAL	SP	o_rmargin_h;
LOCAL	SP	o_lmargin_h;
LOCAL	SP	o_indent;
LOCAL	double	o_spacing;
LOCAL	int	o_adjust;
LOCAL	SP	o_tabs[TABMAX];
LOCAL	int	o_tabcnt;

save_ruler()
	{
	int	i;

	o_rmargin_h = rmargin_h;
	o_lmargin_h = lmargin_h;
	o_indent = indent;
	o_spacing = spacing;
	o_adjust = adjust;

	for( o_tabcnt = tabcnt, i=0; i<o_tabcnt; i++ )
		o_tabs[i] = tabs[i];

	}

restore_ruler()
	{
	int	i;

	rmargin_h = o_rmargin_h;
	lmargin_h = o_lmargin_h;
	indent = o_indent;
	spacing = o_spacing;
	adjust = o_adjust;

	for( tabcnt = o_tabcnt, i=0; i<tabcnt; i++ )
		tabs[i] = o_tabs[i];

	}




clr_tabs()
	{
	tabcnt = 0;
	}

set_tab( tab )
PIX	tab;
	{
	tabs[tabcnt++] = pix_to_sp( tab ) + min_to_sp( 1000 );
	}


cr()
	{
	out_pos( lmargin_h, cur->p_v );
	}


right( h )
SP	h;
	{

	if( h == 0 )
		return;

	outcmd( RIGHT4 );
	out4( h );

	cur->p_h += h;

	}

down( v )
SP	v;
	{

	outcmd( DOWN4 );
	out4( v );

	cur->p_v += v;

	}


/*
 *	go to the indicated position
 */
out_pos( h, v)
long	h;
long	v;
	{

	if( h != cur->p_h )
		{
		outcmd( X4 );
		out4( h - cur->p_h );
		}
	if( v != cur->p_v )
		{
		outcmd( Y4 );
		out4( v - cur->p_v );
		}

	cur->p_h = h;
	cur->p_v = v;

	}

out( outfd, length, value )
FILE	* outfd;
int	length;
long	value;
	{
	REG	int	i;
	int	v;

	for( i=0; i<length; i++ )
		{
		v = value >> (((length-1) - i) * 8);
		putc( v & 0xff, outfd );
		}
	
	}
eof-dvi.c

#  File fonts.c:
#  ----------------------------------------------------------------------------
echo extracting: fonts.c
cat << "eof-fonts.c" > fonts.c
#include	<stdio.h>
#include	<ctype.h>

#include	"site.h"
#include	"gen.h"
#include	"option.h"
#include	"md.h"
#include	"dvi.h"
#include	"fonts.h"

LOCAL	char	* get_tok();
LOCAL	char	* mac_font();

/*
 *	translate apple font numbers into something more reasonable
 */
fontno( lptr )
Char	* lptr;
	{
	REG	int	i;
	REG	int	j;
	REG	FONT	* fnt;

	char	buf[200];
	char	obuf[200];
	FILE	* fd;
	int	bc, ec;
	int	hlength;
	int	wlength;
	int	dlength;
	int	extra_length;
	int	hdlength;

	int	at_size;
	double	ratio;


	for( i=0; i<MAX_FONTS; i++ )
		{
		if( fonts[i].f_number == -1 )
			break;
		else
		if( fonts[i].f_number == lptr->c_font
		&&  fonts[i].f_size == lptr->c_size
		&&  ( (fonts[i].f_style & ~(ST_UL|ST_SHADOW)) == 
		      (lptr->c_style & ~(ST_UL|ST_SHADOW)) )  )
			return( i );
		}
	
	if( i == MAX_FONTS )
		fatal( "too many fonts" );

	fnt = &fonts[i];
	

	/*
	 *	no such font - load one up
	 */

	at_size = lptr->c_size;

	/*	default font is a scaled 10pt font	*/
	sprintf( buf, "cm%s10", Style(lptr->c_style) );
	substitute_font( buf, lptr, &at_size );

	if( verbose )
		fprintf( stderr, "using font %s at %dpt for MAC font %s\n", 
			buf, at_size, mac_font(lptr) );

	strcat( buf, ".tfm" );

	fnt->f_number = lptr->c_font;
	fnt->f_size = lptr->c_size;
	fnt->f_style = lptr->c_style;

	sprintf( obuf, "%s/%s", TFM_PATH, buf );

	buf[strlen(buf)-4] = '\0';
	fnt->f_name = (char *)(strcpy( (char *)malloc(strlen(buf)+1),buf));


	/*
	 *	read in the tfm file
	 */
	if( (fd = fopen(obuf, "r")) == NULL )
		fatal( "couldn't open font tfm file %s", obuf );
	
	get_int(fd);			/* lf */
	hdlength = get_int(fd);		/* header data */
	bc = get_int(fd);		/* first character */
	ec = get_int(fd);		/* last character */
	wlength = get_int(fd);		/* lengths of sections */
	hlength = get_int(fd);
	dlength = get_int(fd);

	extra_length = get_int(fd) + get_int(fd) +
		get_int(fd) + get_int(fd);	/* length of the rest */

	fnt->f_info = (CH_INFO *)malloc( (ec-bc+1) * sizeof(CH_INFO) );
	fnt->f_width = (long *)malloc( wlength * 4 );
	fnt->f_height = (long *)malloc( hlength * 4 );
	fnt->f_depth = (long *)malloc( dlength * 4 );

	set( fd, 6 * sizeof(long) );

	fnt->f_csum = get_long(fd);
	fnt->f_dsize = fix_to_sp(get_long(fd));
	fnt->f_at_size = pt_to_sp(at_size);

	set( fd, (6 + hdlength) * 4 );

	for( j=0; j<(ec-bc+1); j++ )
		{
		fnt->f_info[j].ch_windex = get_byte(fd);
		fnt->f_info[j].ch_hindex = get_byte(fd);
		fnt->f_info[j].ch_itindex = get_byte(fd);
		fnt->f_info[j].ch_remainder = get_byte(fd);
		}
	
	for( j=0; j<wlength; j++ )
		fnt->f_width[j] = fix_to_sp(get_long(fd) * at_size);

	for( j=0; j<hlength; j++ )
		fnt->f_height[j] = fix_to_sp(get_long(fd) * at_size);

	for( j=0; j<dlength; j++ )
		fnt->f_depth[j] = fix_to_sp(get_long(fd) * at_size);
	
	/*
	 *	(fix this right) - grab a big character to set the pace
	 */
	fnt->f_maxheight = 
		fnt->f_height[(fnt->f_info['['].ch_hindex>>4) & 0xf];

	skip( fd, extra_length * 4 );

	/*	parameter words	*/
	(void)get_long(fd);					/* slant */
	fnt->f_ws = fix_to_sp(get_long(fd) * at_size);		/* space */
	fnt->f_stretch = fix_to_sp(get_long(fd) * at_size);	/* stretch */
	fnt->f_shrink = fix_to_sp(get_long(fd) * at_size);	/* shrink */
	fnt->f_accent = fix_to_sp(get_long(fd) * at_size);	/* accent */
	(void)get_long(fd);					/* quad */
	fnt->f_ss = fnt->f_ws + fix_to_sp(get_long(fd) * at_size); /*sentence*/
	
	fclose(fd);

	return( i );

	}

/*
 *	perform font substitutions from a file with the format:
 *
 *	font pointsize style  -> newfont atsize
 */

LOCAL	char	*
get_tok( ptr )
REG	char	* * ptr;
	{

	char	* pstart = *ptr;

	while( **ptr && !isspace( **ptr ) )
		(*ptr)++;
	
	if( **ptr )
		*((*ptr)++) = '\0';
	
	return( pstart );

	}


LOCAL
skip_blank( ptr )
REG	char	* * ptr;
	{

	while( **ptr && isspace( **ptr ) )
		(*ptr)++;
	
	return( **ptr != '\0' );

	}



substitute_font( buf, cptr, at_size )
char	* buf;
Char	* cptr;
int	* at_size;
	{
	FILE	* fd;
	char	tbuf[200];
	char	* font;
	char	* ptr;
	REG	char	* tok;
	char	*	rc;
	int	fno;
	int	style;
	int	pt;
	int	st;
	int	line_no;

	if( !font_sub_file )
		return;

	if( (fd = fopen( font_sub_file, "r" )) == NULL )
		{
		warning( "couldn't open substitution file %s", font_sub_file );
		return;
		}
	
	/*	substitute only the rational fonts	*/
	style = cptr->c_style & (ST_PLAIN|ST_BOLD|ST_ITALIC);
	
	for( line_no=1; (rc = fgets( tbuf, 200, fd )) != NULL; line_no++ )
		{

		if( *tbuf == '#' )
			continue;

		st = pt = -1;
		ptr = tbuf;


		/*
		 *	font name or number
		 */
		if( !skip_blank( &ptr ) )
			break;
		
		font = get_tok( &ptr );
		if( isdigit( *font ) )
			fno = atoi( font );
		else
			{
			if( (fno = f_ord( font )) < 0 )
				break;
			}

		/*
		 *	style or pt size or ->
		 */
		if( !skip_blank( &ptr ) )
			break;

		tok =  get_tok( &ptr );

		/*	could have default style, pt, or both at this point */
		if( strcmp( "->", tok ) != 0 && !isdigit( *tok ) )
			{
			if( (st = st_ord( tok )) < 0 )
				break;
			

			if( !skip_blank( &ptr ) )
				break;
			
			tok =  get_tok( &ptr );
			}
		
		if( isdigit( *tok ) )
			{
			pt = atoi( tok );


			if( !skip_blank( &ptr ) )
				break;

			tok = get_tok( &ptr );
			}

		/*	gots to have that arrow	*/
		if( strcmp( "->", tok ) != 0 )
			break;
		

		if( fno == cptr->c_font
		&&  (st == -1 || st == style)
		&&  (pt == -1 || pt == cptr->c_size) )
			{
			/*	match!		*/

			if( !skip_blank( &ptr ) )
				break;
			
			strcpy( buf, get_tok( &ptr ) );

			if( skip_blank( &ptr ) )
				*at_size = atoi( get_tok( &ptr ) );

			return;

			}
		

		}
	
	if( rc != NULL )
		warning( "syntax error in font substitution file at line %d",
			line_no );
	
	fclose( fd );

	}

/*	macintosh predefined fonts */
LOCAL	
char	* macfonts[] =
	{
	"system",
	"application",
	"new_york",
	"geneva",
	"monaco",
	"venice",
	"london",
	"athens",
	"san_fran",
	"toronto",
	};

f_ord( font )
char	* font;
	{

	char	* * fptr;

	for( 
	     fptr = macfonts;
	     fptr < &macfonts[sizeof(macfonts)/sizeof(char *)];
	     fptr++
	   )
		if( strcmp( font, *fptr ) == 0 )
			return( fptr - macfonts );
	
	return( -1 );
	
	}

st_ord( style )
char	* style;
	{

	if( strcmp( "plain", style ) == 0 )
		return( ST_PLAIN );
	
	else
	if( strcmp( "bold", style ) == 0 )
		return( ST_BOLD );
	else
	if( strcmp( "italics", style ) == 0 )
		return( ST_ITALIC );
	else
	if( strcmp( "bold_italics", style ) == 0 )
		return( ST_BOLD | ST_ITALIC );
	
	return( -1 );

	}


/*	print out the name of the macintosh font indicated	*/
LOCAL	char *
mac_font( cptr )
Char	* cptr;
	{
	LOCAL	char	buf[40];

	if( cptr->c_font >= 0 
	&&  cptr->c_font < (sizeof(macfonts)/sizeof(char *)) )
		strcpy( buf, macfonts[ cptr->c_font ] );
	else
		sprintf( buf, "#%d", cptr->c_font );
	
	if( cptr->c_style & ST_BOLD )
		strcat( buf, " bold" );
	
	if( cptr->c_style & ST_ITALIC )
		strcat( buf, " italic" );
	
	return( buf );
	
	}


		

/*
 *	put a definition of the indicated font into the dvi file
 */
	
def_font( fno )
int	fno;
	{
	REG	int	i;

	if( fno < 0 || fno > MAX_FONTS ||
	    fonts[fno].f_number < 0 )
		fatal( "unknown font: %d\n", fno );


	outcmd( DFONT1 );
	out1( fno );
	out4( fonts[fno].f_csum );		/* checksum */
	out4( fonts[fno].f_at_size  );		/* num */
	out4( fonts[fno].f_dsize );		/* denom */
	out1( 0 );				/* use the system fonts */
	out1( strlen( fonts[fno].f_name ) );
	for( i=0; i<strlen(fonts[fno].f_name ); i++ )
		out1( fonts[fno].f_name[i] );

	fonts[fno].f_active = TRUE;
	
	}


SP
font_height( fontno )
int	fontno;
	{

	return( fonts[fontno].f_maxheight );

	}

SP
font_ws( fontno )
int	fontno;
	{

	return( fonts[fontno].f_ws );

	}

SP
font_ss( fontno )
	{

	return( fonts[fontno].f_ss );

	}


SP
ch_wid( cptr )
Char	* cptr;
	{
	REG	FONT	* fno;

	fno = &fonts[fontno(cptr)];

	return(fno->f_width [ (fno->f_info[cptr->c_char]).ch_windex ]);

	}

SP
ch_height( cptr )
Char	* cptr;
	{
	REG	FONT	* fno;

	fno = &fonts[fontno(cptr)];

	return( fno->f_height[(fno->f_info[cptr->c_char].ch_hindex>>4) & 0xf] );

	}

SP
ch_depth( cptr )
Char	* cptr;
	{
	REG	FONT	* fno;

	fno = &fonts[fontno(cptr)];

	return( fno->f_depth[fno->f_info[cptr->c_char].ch_hindex & 0xf] );

	}
eof-fonts.c

#  File md.c:
#  ----------------------------------------------------------------------------
echo extracting: md.c
cat << "eof-md.c" > md.c
#include	<stdio.h>
#include	<ctype.h>

#include	"gen.h"
#include	"option.h"
#include	"md.h"

LOCAL	FILEPTR	p_offset	= -1;
LOCAL	FILEPTR	h_offset	= -1;
LOCAL	FILEPTR	f_offset	= -1;

LOCAL	bool	display_header	= TRUE;
LOCAL	bool	display_footer	= TRUE;

LOCAL	int	document_count;
LOCAL	int	header_count;
LOCAL	int	footer_count;

int	page_cnt		= 0;
int	page_no			= 0;
bool	title_page		= FALSE;

read_globals()
	{

	int	version;
	REG	int	i;
	int	length;

	if( (version = get_int(infd)) != MW_ID )
		warning( "Unknown Macwrite version %d", version );

	p_offset = get_int(infd);
	document_count = get_int(infd);
	header_count = get_int(infd);
	footer_count = get_int(infd);

	title_page = get_byte(infd);
	(void)get_byte(infd);			/* display scrap */
	display_footer =  get_byte(infd);
	display_header =  get_byte(infd);
	(void)get_byte(infd);			/* rulers showing */
	(void)get_byte(infd);			/* spare byte (?) */
	(void)get_byte(infd);			/* active document */
	page_no = get_int(infd) - 1;

	/*  get the seek locations of the header and footer info  */
	set( infd, p_offset );
	for( i=0; i<document_count; i++ )
		{
		(void)get_int(infd);	/* paragraph type */
		length = get_int(infd);	/* paragraph length */

		skip( infd, length );
		}
	
	h_offset = pos(infd);


	for( i=0; i<header_count; i++ )
		{
		(void)get_int(infd);	/* paragraph type */
		length = get_int(infd);	/* paragraph length */

		skip( infd, length );
		}
	
	/*	set the bottom margin, based on the footer length */
	f_offset = pos(infd);
	init_footer();

	if( verbose )
		{
		fprintf( stderr, "Macwrite(%d) %d header, %d body, %d footer paragraghs\n", 
		version, header_count, document_count,  footer_count );
		fprintf( stderr, "footers %s headers %s\n", 
			display_footer ? "displayed" : "hidden",
			display_footer ? "displayed" : "hidden" );
		}
	}


read_paragraphs( off, count )
FILEPTR	off;
int	count;
	{
	int	i;

	set(infd, off);

	for( i=0; i<count; i++ )
		paragraph();
	
	}

body()
	{
	read_paragraphs( p_offset, document_count );
	}

header()
	{
	FILEPTR	save_pos;

	if( !display_header )
		return;

	save_pos = pos(infd);
	save_ruler();

	read_paragraphs( h_offset, header_count );

	restore_ruler();
	set( infd, save_pos );
	}


footer()
	{
	FILEPTR	save_pos;

	if( !display_footer )
		return;

	save_pos = pos(infd);
	save_ruler();

	read_paragraphs( f_offset, footer_count );

	restore_ruler();
	set( infd, save_pos );
	}


paragraph()
	{
	int	type;
	int	length;
	int	line_length;
	int	flength;
	FILEPTR	paragraph_end;
	REG	int	i;

	byte	cur_style;
	byte	cur_size;
	short	cur_font;

	Char	buf[200];
	bool	freeline = FALSE;
	Char	* line = buf;

	int	chpos;
	int	end_pos;


	if( (type = get_int(infd)) != RULER 
	&&  type != TEXT
	&&  type != PICTURE )
		fatal( "botch - invalid paragraph type %d in macwrite file",
			type );
	
	length = get_int(infd);
	paragraph_end = pos(infd) + length;

	if( type == TEXT )
		{

		line_length = get_int(infd);
		if( line_length > 200 )
			{
			line = (Char *)malloc( sizeof(Char) * line_length );
			if( line == NULL )
				fatal( "fatal - out of space\n" );
			freeline = TRUE;
			}


		for( i=0; i<line_length; i++ )
			line[i].c_char = get_byte(infd);

		if( line_length % 2 )
			skip(infd,1);

		/*	get font info	*/
		if( (flength = get_int(infd)) % 6 != 0 )
			{
			fatal( "invalid font length (%d) in macwrite file\n",
			flength );
			}

		for( chpos = get_int(infd); flength; chpos = end_pos )
			{
			cur_size = get_byte(infd);
			cur_style = get_byte(infd);
			cur_font = get_int(infd);

			flength -= 6;
			if( flength )
				end_pos = get_int(infd);
			else
				end_pos = line_length;

			
			for( i=chpos; i<end_pos; i++ )
				{
				line[i].c_size = cur_size;
				line[i].c_style = cur_style;
				line[i].c_font = cur_font;
				}
			}
		
		/*
		 *	mystery bytes 
		 */
		set( infd, paragraph_end );

		out_line( line_length, line );

		if( freeline )
			free( line );
		}
	else
	if( type == PICTURE )
		{

		/*	page breaks are pictures	*/
		if( (length = get_int(infd)) == 0 )
			page();
		else
			warning( "pictures not yet supported" );
		set( infd, paragraph_end );

		}
	else
	if( type == RULER )
		{
		PIX	lmargin;
		PIX	rmargin;
		PIX	indent;
		PIX	tab;
		int	tablen;
		int	spacing;
		int	justify;

		lmargin = get_int(infd);
		rmargin = get_int(infd);

		justify = get_byte(infd);
		
		tablen = get_byte(infd);
		get_byte(infd);		/* ??? mystery byte */

		spacing = get_byte(infd);
		indent = get_int(infd);

		set_ruler( lmargin, rmargin, indent, spacing, justify );

		/*
		 *	pick up the tab stops
		 */
		clr_tabs();

		for( i=0; i<tablen; i++ )
			{
			set_tab( get_int(infd) );
			}
		
		for( i=0; i < 10-flength; i++ )
			get_int(infd);
		
		/*
		 *	more mystery bytes
		 */
		get_int(infd);
		get_int(infd);

		set( infd, paragraph_end );

		}

	}


get_int(fd)
FILE	* fd;
	{
	int	ch;

	ch = get_byte(fd);
	ch = ch << 8 | get_byte(fd);

	return( ch );
	}

long
get_long(fd)
FILE	* fd;
	{
	long	val;
	int	i;

	for( val=0, i=0; i<4; i++ )
		{
		val <<= 8;
		val |= get_byte(fd);
		}
	
	return( val );
	}

int
get_byte(fd)
FILE	* fd;
	{
	int	ch;

	if( (ch = getc(fd)) == EOF )
		fatal( "unexpected EOF" );

	return( ch & 0xff );
	}


char	* 
Style( style_no )
byte	style_no;
	{

	style_no &= (ST_PLAIN|ST_BOLD|ST_ITALIC);

	switch( style_no )
		{
		case ST_PLAIN:
			return( "r" );

		case ST_BOLD:
			return( "b" );

		case ST_ITALIC:
			return( "ti" );

		default:
			fprintf( stderr, "unknown style %d\n", style_no );
			break;
		}
	return( "??" );

	}
eof-md.c

#  File gen.h:
#  ----------------------------------------------------------------------------
echo extracting: gen.h
cat << "eof-gen.h" > gen.h


#define	FALSE	(0)
#define	TRUE	(!FALSE)

#define	L_SET	0
#define	L_CURR	1
#define	L_EOF	2

#define	REG	register
#define	LOCAL	static


#define	Debug		if( debflg )
#define	skip(fd,count)	(fseek(fd, (FILEPTR)(count), L_CURR))
#define	set(fd,pos)	(fseek(fd, (FILEPTR)(pos), L_SET))
#define	pos(fd)		(ftell(fd))
#define	align(fd)	if( pos(fd) % 2 ) Skip( 1 )

#define	Skip(count)	(skip(stdin,count))
#define	Set(pos)	set(stdin,pos)
#define	Get_int()	get_int(stdin)
#define	Get_byte()	get_byte(stdin)
#define	Pos()		(pos(stdin))
#define	Align()		align(stdin)

#define	max(a,b)	( (a) > (b) ? (a) : (b) )


typedef	unsigned char	byte;
typedef	byte	bool;

typedef	long	RSU, FIX, SP;		/* tex units */
typedef	long	FILEPTR;

typedef	struct
	{
	short	c_char;
	short	c_font;
	byte	c_size;
	byte	c_style;
	} Char;


extern	long	get_long();
extern	int	get_int();
extern	int	get_byte();

extern	char	* Style();

extern	bool	debflg;
eof-gen.h

#  File option.h:
#  ----------------------------------------------------------------------------
echo extracting: option.h
cat << "eof-option.h" > option.h
/*
 *	program options
 */

extern	bool	verbose;

extern	FILE	* outfd;
extern	FILE	* infd;

extern	char	* font_sub_file;
eof-option.h

#  File md.h:
#  ----------------------------------------------------------------------------
echo extracting: md.h
cat << "eof-md.h" > md.h

#define	MW_ID	3		/* macwrite version */

#define	RULER	0		/* paragraph type */
#define	TEXT	1
#define	PICTURE	2

#define	ST_PLAIN (0)		/* style */
#define	ST_BOLD	(0x1)
#define	ST_ITALIC (0x2)
#define	ST_UL (0x4)
#define	ST_SHADOW (0x8)

#define	JST_LEFT (0)		/* line justification	*/
#define	JST_CENTER (1)
#define	JST_RIGHT (2)
#define	JST_ADJ (3)

#define	S_SINGLE (0)		/* line spacing */
#define	S_ONEANDHALF (1)
#define	S_DOUBLE (2)


typedef	long	PIX;


extern	int	page_no;	/* current page number */
extern	int	page_cnt;	/* how many pages we got? */
extern	bool	title_page;	/* first page is title page */
eof-md.h

#  File dvi.h:
#  ----------------------------------------------------------------------------
echo extracting: dvi.h
cat << "eof-dvi.h" > dvi.h
#define	MAX_WORDS	(200)		/* 200 words per paragraph */

/*
 *	dvi specific definitions
 */
#define	pt_per_in	(72)
#define	sp_per_pt	(1<<16)

#define	scale_num	(25400000)	/* scaling factor - sp to 10e-7 m. */
#define	scale_denom	(473628672)

#define	TEX_ID		(2)		/* TeX version 2 */


#define	WD_WORD	(0x01)
#define	WD_TAB	(0x02)
#define	WD_DTAB (0x04)
#define	WD_UL	(0x08)

#define	TABMAX	10			/* can you believe this? */



#define	SET0	0
#define	PUT1	133
#define	PUTRULE	137
#define	NOP	138
#define	BOP	139
#define	EOP	140
#define	PUSH	141
#define	POP	142
#define	RIGHT1	143
#define	RIGHT2	144
#define	RIGHT3	145
#define	RIGHT4	146
#define	W0	147
#define	W1	148
#define	X0	152
#define	X1	153
#define	X2	154
#define	X3	155
#define	X4	156
#define	DOWN1	157
#define	DOWN2	158
#define	DOWN3	159
#define	DOWN4	160
#define	Y0	161
#define	Y1	162
#define	Y2	163
#define	Y3	164
#define	Y4	165
#define	Z0	166
#define	Z1	167
#define	FONT0	171
#define	FONT1	235
#define	XXX1	239
#define	DFONT1	243
#define	PRE	247
#define	POST	248
#define	POSTPOST 249


#define	pt_to_sp(x)	((x) * sp_per_pt)
#define	mpt_to_sp(x)	(pt_to_sp(x)/1000)
#define	min_to_sp(x)	(pt_to_sp( (((x) * pt_per_in) / 1000) ))
#define	fix_to_sp(x)	(((x>>3)+1)>>1)
#define	pix_to_sp(x)	pt_to_sp((((double)x) / 80) * pt_per_in)

#define	sp_to_in(x)	((((double)x) / sp_per_pt) / pt_per_in )

#define	out4(v)		(out( outfd, 4, (long)(v) ))
#define	out3(v)		(out( outfd, 3, (long)(v) ))
#define	out2(v)		(out( outfd, 2, (long)(v) ))
#define	out1(v)		(out( outfd, 1, (long)(v) ))

#define	outcmd(c)	(out1(c))

/*
 *	type defininitions
 */

typedef	struct
	{
	short	wd_flags;
	SP	wd_length;
	int	wd_pos;		
	int	wd_end;	
	} WORD;
#define	wd_tabcnt	wd_pos

typedef struct
	{
	SP	p_h;		/* current horizontal position */
	SP	p_v;		/* current vertical position */
	SP	p_w;		/* delta */
	SP	p_x;		/* delta */
	SP	p_y;		/* delta */
	SP	p_z;		/* delta */
	} POS;

/*
 *	external variables
 */

extern	FILE	* outfd;
eof-dvi.h

#  File fonts.h:
#  ----------------------------------------------------------------------------
echo extracting: fonts.h
cat << "eof-fonts.h" > fonts.h
#define	MAX_FONTS	64


/*	macintosh predefined font numbers */
#define	F_SYSTEM (0)
#define	F_APPL	(1)
#define	F_NEWYORK (2)
#define	F_GENEVA (3)
#define	F_MONACO (4)
#define	F_VENICE (5)
#define	F_LONDON (6)
#define	F_ATHENS (7)
#define	F_SANFRAN (8)
#define	F_TORONTO (9)


typedef	struct
	{
	byte	ch_windex;
	byte	ch_hindex;
	byte	ch_itindex;
	byte	ch_remainder;
	} CH_INFO;
	
typedef	struct
	{
	int	f_number;		/* mac font number */
	byte	f_size;
	byte	f_style;		/* bold, italic, etc. */
	bool	f_active;		/* does the driver know about me? */
	char	* f_name;		/* font name (cmr, etc.) */
	long	f_csum;	
	CH_INFO	* f_info;		/* tfm info */
	SP	* f_width;
	SP	* f_height;
	SP	f_maxheight;
	SP	* f_depth;
	SP	f_dsize;
	SP	f_at_size;
	SP	f_slant;
	SP	f_stretch;
	SP	f_shrink;
	SP	f_accent;
	SP	f_ss;
	SP	f_ws;
	} FONT;

FONT	fonts[MAX_FONTS];

SP	ch_wid();
SP	font_ws();
SP	font_depth();
SP	font_height();
eof-fonts.h

#  File mwdvi.1:
#  ----------------------------------------------------------------------------
echo extracting: mwdvi.1
cat << "eof-mwdvi.1" > mwdvi.1

.TH MWDVI 1 LOCAL
.SH NAME
mwdvi \- convert Macwrite files to dvi format
.SH SYNOPSIS
.B mwdvi
[ options ] file1 [file2 ...]
.SH DESCRIPTION
.I mwdvi
converts
.IR file s,
which should be in Macwrite format (version 3),
to TeX dvi format.  There are a several popular programs (such as
IMAGEN's 
.I dviimp(1)
program) that can be used to print files in this
format on a high quality electronic printer. 
.sp
In order to use mwdvi, the macwrite document must be saved with its
rulers and font information intact (not as TEXT ONLY) then transferred to
the host system (see macget(1)).
.sp
.I Mwdvi
will convert the macwrite document into dvi format and optionally submit
the resultant file to
.I dviimp(1) 
for printing on an electronic printer.
.sp
Mwdvi assumes that the file is to be printed using the TeX
cmr fonts and substitutes Computer Modern Roman for all plain
Macintosh fonts, Computer Modern Bold for all bold Macintosh fonts
and Computer Modern Italic for all italic Macintosh fonts, at the
appropriate point sizes.  Since the fonts used to print the
document are different from those used when viewing the 
document in macwrite, the spacing may come out somewhat differently.
The spacing will be proportional, but probably not quite the same.
.sp
If a different mapping is desired, a font
substitution file can be constructed using the following format:
.sp
.nf
	macfontname [style] [pt size] -> texfontname [targ pt]
.fi
.sp
Where
.I macfontname
can be any of \fBsystem, application, geneva, new_york, toronto, monaco, 
venice, london, athens, or san_fran,\fP or a decimal number indicating
the Macintosh internal number of the font to be substituted, 
.I style
can be any of \fBplain, bold, or italic,\fP
.I pt size
is the size to be replaced, 
.I texfontname
is the TeX font with which this font should be replaced,
and 
.I "targ pt"
is the point size at which the new font should be used.
.sp
For example:
.sp
.nf
	london bold 12 -> cmb10 12
.fi
.sp
The name of the substitution file can be specified 
in the environment variable "MACFONTS" or with a command line
option (that overrides any environment variable setting).
.sp
The options are:
.TP
.B \-p
Causes the output to be submitted to dviimp and spooled for printing
on an IMAGEN printer.
If no target printer is specified, the value of the PRINTER
environment variable is assumed to be the target printer.
.TP
.B \-Pprinter
Causes the indicated printer to be used for spooling of mwdvi output.
.TP
.B \-o
Causes the dvi file output by mwdvi to be put into the file named as
the next argument.
.TP
.B \-s
Causes the file named by the next argument to be used as the name of the file
that is to direct font substitutions.
.TP
.B \-v
Causes 
.I mwdvi
to operate in a verbose fashion, producing lots of interesting output.
.sp
If spooling is requested and no target file is indicated, 
.I mwdvi
will use a temporary file for the duration of the program.
.SH FILES
/usr/lib/font/imagen/tfm/*  -- description of host resident fonts.
.SH SEE ALSO
macget(1), dviimp(1), lpr(1)
.SH BUGS
Pictures, decimal tabs, and header/footer icons are not currently supported.
.SH AUTHOR
Douglas Orr - University of Michigan EECS dept.
eof-mwdvi.1

info-mac@uw-beaver (info-mac) (11/02/84)

From: ihnp4!umich!doug@uw-beaver.arpa (Doug Orr)

The following is a program that converts from macwrite format to TeX dvi
format.  This allows you to print (typeset?!) macwrite documents on a
variety of electronic printers that support printing of TeX output.

It currently doesn't handle pictures (other than to ignore them),
page number, date, or time icons, special characters or accent marks.
Macwrite printing options are ignored.

I am planning to add these features, but I thought that people would
find this much useful in the mean time.

Support for interfacing to IMAGEN software on 4.1 and 4.2 is provided.
This can just be commented out if not applicable.

Thanks to the gentleman that posted the description of macwrite internal
format.  

If anyone knows anything about the legalities of using Mac fonts on
an imagen or has access to higher density versions of the mac fonts,
I would just love to talk to you.  Currently this program substitutes
TeX fonts for mac fonts.

	-Doug Orr
	ihnp4!uovm-cv!umich!doug

[Ed. File is on [SUMEX]<INFO-MAC>MWDVI.C]