[net.sources.mac] macwrite to troff

sean@oddjob.UUCP (Sean Casey) (05/07/85)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***
Here is a macwrite to troff filter that was posted ealier this year.
It was writen by Michael Caplinger of Rice University. If anyone
has something better let me know.


Sean Casey	...ihnp4!oddjob!sean

---------------------------(cut here)------------------------------



echo 'Start of distribution file w2t.sh:'
echo 'Extracting Makefile...'
sed 's/^X//' > Makefile << '/'
Xw2t: w2t.o
X	cc w2t.o -o w2t
X
Xw2t.o: write.h
X
Xbackup:
X	tar cvf w2t.tar *.c *.h
X	rcp w2t.tar iap:sunsave
/
echo 'Extracting w2t.1...'
sed 's/^X//' > w2t.1 << '/'
X.TH W2T 1-local
X.SH NAME
Xw2t \- convert MacWrite files to troff input files
X.SH SYNOPSIS
X.B w2t
X[
X.B \-d
X] [
X.B \-w
X] [
X.B \-sPointSize
X] [
X.B \-r
X]
Xfile ...
X.br
X.SH DESCRIPTION
X.I W2t
Xreads the
X.I files
Xand produces a
X.I troff
Xinput file on the standard output.  The files should be .data files as
Xtransferred by
X.I macget(1).
X.PP
XBy default, the output file will contain enough
X.I -me
Xmacro commands to cause the output to ``strongly resemble'' the MacWrite
Xoutput.  Currently, this means that justification, spacing, tabs,
Xparagraphing, and certain kinds of text attributes will be the same.  See
XBUGS for a list of things that don't work.
X.PP
XThe
X.B -r
Xoption causes the output to have far fewer
X.I troff
Xcommands inserted.  Essentially, null paragraphs will be converted into .pp
Xmacros, and text attributes will be converted.  This is useful because the
X.I troff
Xto do a verbatim formatting job is rather ugly; this option can be used when
Xthe Mac is just being used to draft the text prior to a more rigorous
Xformatting.
X.PP
XThe
X.B -s
X.I pointsize
Xoption is used to change the ``base point size''.  This is the
X.I troff
Xpoint size that corresponds to MacWrite 12 point.  By default, this value is
X10, as 12 point output is usually too large, but 10 point on the Mac is hard
Xto read.
X.PP
XThe
X.I -w
Xoption turns intraparagraph wrapping off.  A MacWrite paragraph is a single
Xline of text with no newlines.
X.I W2t
Xwill wrap these lines at about 80 columns by default.  I have never seen an
Xapplication where this wrapping was undesirable, but...
X.PP
XThe
X.I -d
Xoption causes an immense amount of debugging information to appear
Xinterspersed with the output on stdout.
X.PP
X.SH "SEE ALSO"
Xmacget(1)
X.SH BUGS
X.PP
XBecause of byte ordering dependencies, this program only runs on machines
Xwhose byte order is the same as the 68000's (thus, no VAXen or PDP-11s)
X.PP
XPictures are not supported in any way.
X.PP
XHeaders and footers are ignored.
X.PP
XDecimal tabs are not handled correctly.
X.PP
XThe output is heavily -me macro dependent.
X.PP
XMost of the text attributes are not supported.  Bold, italic, subscript, and
Xsuperscript are.  Because of brain damage in troff, underlining is
Xdifficult.  Mixing attributes is difficult.  Shadow is hard due to font
Xlimitations; plus, it's ugly.
X.PP
XOnly a very small number of special characters are supported.  Unrecognized
Xones are ignored.  (Currently, only !=, +-, <=, and >= are recognized.)
X.SH AUTHOR
XMichael Caplinger, Rice University (mike@rice)
/
echo 'Extracting w2t.c...'
sed 's/^X//' > w2t.c << '/'
X/*
X    MacWrite to troff input converter.
X
X    version 0.1, Michael Caplinger (mike@rice.arpa), October 1984.
X*/
X
X/*
X    copyright (c) 1984, Michael Caplinger.
X    May be freely redistributed, but this comment must remain in the
X    program or any derivative.
X*/
X
X#define VERSION "0.1"
X
X#include <stdio.h>
X#include "write.h"
X
Xint verbose, wrap = 1;
Xint basePoint = 10;
Xint raw;
X
Xmain(argc, argv)
Xchar **argv;
X{
X    int f;
X
X    setFlags(argc, argv);
X    argv++;
X    while(*argv) {
X    	if(argv[0][0] != '-') {
X	    f = open(argv[0], 0);
X	    if(f >= 0) processFile(f);
X	}
X	argv++;
X    }
X}
X
XprocessFile(f)
Xint f;
X{
X    struct global global;
X    struct document text, header, footer;
X    struct infoArrayElem *textInfo, *headerInfo, *footerInfo;
X    char *data;
X    struct textHeader *textHeader;
X    struct paraHeader paraHeader;
X    short formatRunLength;
X    char *cp;
X    int i, j, k, col;
X    struct format *fp, *startfp, *endfp;
X    struct ruler *ruler;
X    int lastParaNull = 1;
X    int skipBlanks = 0;
X    int lastWasFormat;
X
X    read(f, &global, 140);
X    read(f, &text, 34);
X    read(f, &header, 34);
X    read(f, &footer, 34);
X    debug("version %d\n", global.versionNumber);
X    debug("%d paragraphs in main text\n", global.paraCount);
X    
X    textInfo = (struct infoArrayElem *) malloc(global.paraCount * 8);
X    headerInfo = (struct infoArrayElem *) malloc(global.headerParaCount * 8);
X    footerInfo = (struct infoArrayElem *) malloc(global.footerParaCount * 8);
X    read(f, textInfo, global.paraCount * 8);
X    read(f, headerInfo, global.headerParaCount * 8);
X    read(f, footerInfo, global.footerParaCount * 8);
X
X    doPrelude();
X    for(j = 0; j < global.paraCount; j++) {
X	read(f, &paraHeader, 4);
X	debug("type %d paragraph\n", paraHeader.type);
X	debug("%d bytes in paragraph data\n", paraHeader.dataLength);
X	data = (char *) malloc(paraHeader.dataLength);
X	read(f, data, paraHeader.dataLength);
X	debug("height %d, position %d, page #%d\n", textInfo[j].paraHeight,
X	    textInfo[j].position, textInfo[i].pageNum);
X	switch(paraHeader.type) {
X	    case TEXTPARA:
X		textHeader = (struct textHeader *) data;
X		debug("%d bytes of text\n", textHeader->textLength);
X		if(textHeader->textLength == 1) {
X		    /* null paragraph */
X		    if(!raw) printf(".sp\n");
X		    lastParaNull = 1;
X		    break;
X		}
X		cp = data + 2 + textHeader->textLength;
X		if((int) cp & 0x1) cp++; /* even byte boundary */
X		formatRunLength = *(short *)cp;
X		formatRunLength /= 6;
X		debug("%d format items\n", formatRunLength);
X		startfp = (struct format *) (cp + 2);
X		fp = startfp;
X		for(k = 0; k < formatRunLength; k++) {
X		    debug("pos %d, pointsize %d, style 0x%0x, font %d\n",
X			fp->charPos, fp->pointSize, fp->style, fp->fontNumber);
X		    fp++;
X		}
X		cp = data + 2;
X		fp = startfp;
X		endfp = fp + (formatRunLength - 1);
X		if(*cp == '.' || (*cp == '\\' && *(cp + 1) == '*'))
X		    lastWasFormat = 1;
X		else {
X		    if(!lastWasFormat) printf(".pp\n");
X		    lastWasFormat = 0;
X		}
X		col = 0;
X		for(i = 0; i < textHeader->textLength; i++) {
X		    if(i == fp->charPos) {
X			col += doFormat(fp, 
X			    lastWasFormat == 0 && fp == startfp);
X			if(fp != endfp) fp++;
X		    }
X		    if(wrap && *cp == ' ' && col > 65) {
X			skipBlanks = 1;
X			putchar('\n');
X			col = -1;
X			cp++;
X			continue;
X		    }
X		    if(skipBlanks && *cp == ' ');
X		    else if(*cp != '\r') {
X			col++;
X			putcharExtended(*cp);
X			skipBlanks = 0;
X		    }
X		    cp++;
X		}
X		printf("\n");
X		lastParaNull = 0;
X		break;
X	    case RULERPARA:
X		ruler = (struct ruler *) data;
X		debug("leftMargin %d, right %d\n", 
X		    ruler->leftMargin, ruler->rightMargin);
X		debug("just %d, %d tabs, paraIndent %d\n",
X		    ruler->justify, ruler->numTabs, ruler->paraIndent);
X		doRuler(ruler);
X		break;
X	} /* switch */
X	free(data);
X    } /* for */
X    free(textInfo);
X    free(headerInfo);
X    free(footerInfo);
X}
X
Xint curPoint, curStyle, curFont;
Xint curJust = -1, curRight, curLeft;
X
XdoFormat(fp, force)
Xstruct format *fp;
X{
X    static int isRaised;
X
X    if(force || fp->pointSize != curPoint) {
X	if(!raw) printf(".sz %d\n", fp->pointSize - (12 - basePoint));
X	curPoint = fp->pointSize;
X    }
X    if(fp->style != curStyle) {
X	curStyle = fp->style;
X	if(curStyle == 0) printf("\\fR");
X	if(curStyle & BOLD) printf("\\fB");
X	if(curStyle & ITALIC) printf("\\fI");
X	if(curStyle & RAISE) {
X	    printf("\\u");
X	    isRaised = 1;
X	}
X	else if(isRaised) {
X	    printf("\\d");
X	    isRaised = 0;
X	}
X    }
X    /* this should be the number of chars taken up by the format
X    string, but I'm lazy. */
X    return 4;
X}
X
Xdebug(f, a1, a2, a3, a4, a5, a6, a7, a8, a9)
Xchar *f;
X{
X    if(verbose) fprintf(stdout, f, a1, a2, a3, a4, a5, a6, a7, a8, a9);
X}
X
XsetFlags(argc, argv)
Xchar **argv;
X{
X
X    if(argc == 1) {
X    	printf("usage: %s [-r] [-d] [-w] [-s<pointsize>] files...\n", argv[0]);
X	exit(1);
X    }
X    while(*argv) {
X	if(argv[0][0] == '-') {
X	    switch(argv[0][1]) {
X		case 'd':
X		    verbose = 1;
X		    break;
X		case 'w':
X		    wrap = 0;
X		    break;
X		case 's':
X		    basePoint = atoi(*argv + 2);
X		    break;
X		case 'r':
X		    raw = 1;
X		    break;
X	    }
X	}
X	argv++;
X    }
X}
X
XdoRuler(ruler)
Xstruct ruler *ruler;
X{
X    double linelength, indent;
X    int i;
X
X    if(curJust != ruler->justify) {
X    	curJust = ruler->justify;
X	printf(".br\n"); /* need to put out a break or the last bit of text
X			    gets munged into the new formatting rules. */
X	switch(curJust) {
X	    case LEFTJUST:
X		printf(".ad l\n");
X		break;
X	    case CENTERJUST:
X		printf(".ad c\n");
X		break;
X	    case RIGHTJUST:
X		printf(".ad r\n");
X		break;
X	    case BOTHJUST:
X		printf(".ad b\n");
X		break;
X	}
X    }
X    if(curLeft != ruler->leftMargin || curRight != ruler->rightMargin) {
X    	curLeft = ruler->leftMargin;
X	curRight = ruler->rightMargin;
X	/* set indent and line length */
X	indent = curLeft / 10.0 / 8.0;
X	linelength = curRight / 10.0 / 8.0;
X	printf(".in %.1fi\n", indent);
X	printf(".nr $i %.1fi\n", indent);
X	printf(".ll %.1fi\n", linelength);
X	printf(".nr pi %.1fi\n", ruler->paraIndent / 10.0 / 8.0 - indent);
X    }
X    printf(".ta ");
X    for(i = 0; i < ruler->numTabs; i++) {
X    	printf("%.1fi ", ruler->tabs[i] / 10.0 / 8.0);
X    }
X    putchar('\n');
X}
X
X/* standard troff prelude */
XdoPrelude() {
X    printf(".\" this file automatically generated by WtoT version %s\n", 
X	VERSION);
X    printf(".po 1i\n");
X    printf(".nr ps 0\n"); /* kill .pp's interpara spacing */
X    printf(".nr pi 0\n");
X#ifdef no
X    printf(".de pp\n"); /* redefine the .pp macro */
X    printf(".br\n.ti \\(pi\n");
X    printf("..\n");
X#endif
X}
X
XputcharExtended(c)
Xunsigned char c;
X{
X    if(c & 0200)
X	switch(c) {
X	    case 0xad: /* not equal */
X		printf("\\(!=");
X		break;
X	    case 0xb1: /* plus or minus */
X		printf("\\(+-");
X		break;
X	    case 0xb2: /* <= */
X		printf("\\(<=");
X		break;
X	    case 0xb3: /* >= */
X		printf("\\(>=");
X		break;
X	    default:
X		debug("unknown meta 0x%x\n", c);
X		break;
X	}
X    else putchar(c);
X}
/
echo 'Extracting write.h...'
sed 's/^X//' > write.h << '/'
Xtypedef unsigned char byte;
X
Xstruct global { /* should be 140 bytes */
X    short versionNumber;
X    short paraOffset;
X    short paraCount;
X    short headerParaCount;
X    short footerParaCount;
X    byte titlePage;
X    byte scrapShow;
X    byte footerDisplayed;
X    byte headerDisplayed;
X    byte rulersShowing;
X    byte spare;
X    short activeDoc; /* 0 = main, 1 = header, 2 = footer */
X    short startPageNum;
X    byte printingVars[120]; /* ??? */
X};
X
X#define MAINDOC 0
X#define HEADERDOC 1
X#define FOOTERDOC 2
X
Xstruct endpoint {
X    short paraNumber;
X    short charPos;
X};
X
Xstruct position {
X    short vert;
X    short hor;
X};
X
Xstruct document { /* should be 34 bytes */
X    struct endpoint start;
X    struct endpoint end;
X    short vertOffset; /* always <= 0 */
X    short needToRedraw;
X    struct position pageNumberPos;
X    struct position datePos;
X    struct position timePos;
X    struct position timeStringPos;
X    byte iconRedraw;
X    byte iconFlag;
X    short activeFont;
X    short activeStyle;
X};
X
Xstruct infoArrayElem { /* should be 8 bytes */
X    short paraHeight;
X    short position;
X    byte pageNum; /* 0-based */
X    byte unused[3];
X};
X
X/*
X    paragraph data
X*/
X
Xstruct paraHeader {
X    short type; /* 0=ruler, 1=text, 2=picture */
X    short dataLength;
X};
X
X#define RULERPARA 0
X#define TEXTPARA 1
X#define PICTUREPARA 2
X
Xstruct textHeader {
X    short textLength;
X};
X
X/*
X    ASCII data follows.  On the even word boundary following text there is
X    a word for the format run length.  Each format consists of six bytes:
X*/
X
Xstruct format {
X    short charPos;
X    byte pointSize;
X    byte style;
X    byte unused;
X    byte fontNumber;
X};
X
Xstruct ruler {
X    short leftMargin;
X    short rightMargin;
X    byte justify;
X    byte numTabs;
X    byte filler; /* ??? */
X    byte spacing;
X    short paraIndent;
X    short tabs[12];
X};
X
X#define LEFTJUST 0
X#define CENTERJUST 1
X#define RIGHTJUST 2
X#define BOTHJUST 3
X
X#define SINGLESPACE 0
X#define DOUBLESPACE 1
X#define TRIPLESPACE 2
X
X/* bits for text styles */
X#define BOLD 0x1
X#define ITALIC 0x2
X#define RAISE 0x20
X#define LOWER 0x10
/
echo 'Distribution file w2t.sh complete.'

sean@oddjob.UUCP (Sean Casey) (05/09/85)

Oopps! I forgot to mention that w2t only works with 2.X versions of
macwrite. (2.X means that I cann't remember the macwrite version number.)

Sean Casey	...ihnp4!oddjob!sean