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]