home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
unix
/
mwxlate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-02-06
|
93KB
|
2,265 lines
/*
**
** mwxlate
**
** This program interprets a MacWrite document and translates it to a batch
** document format like troff, script, tex or scribe, depending upon the backend
** functions
**
** Norman Meyrowitz
** IRIS (Institute for Research in Information and Scholarship)
** Brown University
** Box 1946
** Providence, RI 02912
**
** August, 1984
**
** (c) 1984 Brown University
**
**
** REVISION HISTORY
**
** Version Date Author Description
**
** 0.8 8/29/84 nkm Translates from MacWrite to WSCRIPT
** Headers and footers disabled
**
** 0.9 11/28/84 nkm TROFF enhancements added
** 12/4/84 tep added switch for imagen output for TROFF
**
** 0.95 1/2/85 nkm Cleaned up FilterText, fixed tabs, added Greek
**
** 0.97 1/26/85 nkm Fixed terminal .br bug, added TM sign in Script
**
** 1.00 1/29/85 nkm FIRST RELEASE
**
** 1.01 2/4/85 nkm Fixed Subscript/Superscript bug in SCRIPT
**
** KNOWN BUGS/FEATURES NOT IMPLEMENTED
**
** - Headers and footers (including date and time) not implemented
**
** - Tabs not guaranteed to work after first line of paragraph (TROFF
** only)
**
** - Decimal tabs are treated as right-aligned tabs (TROFF only, TROFF
** imposed limitation)
**
** - Tabs may not work on lines with font changes (TROFF only)
**
** - Pictures are always treated as a page advance
**
**
*/
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
/*
**
** C O N S T A N T D E F I N I T I O N S
**
*/
#define VALIDVERSION 3 /* ID of valid document from MacWrite 2.2 */
#define TEMPFILE "/tmp/#mwxXXXXXX" /* Template for filename of xlated file */
#define MAIN 0 /* Document Types */
#define HEADER 1
#define FOOTER 2
#define RULER 0 /* Paragraph Types */
#define TEXT 1
#define PICTURE 2
#ifdef WSCRIPT
# define SPOOLPATH "/a/mac/mwspool" /* Pathname of pgm that sends to 9700 */
# define SPOOLNAME "mwspool"
#endif
#ifdef TROFF
# define SPOOLPATH "/a/mac/mwtoip" /* Pathname of pgm to send to Imagen */
# define SPOOLNAME "mwtoip"
#endif
/* Error Codes */
#define TOOMANYARGS -1
#define CANTOPENINPUT -2
#define CANTOPENOUTPUT -3
#define CANTWRITETEMP -4
#define CANTFINDHEADER -5
#define INVALIDVERSION -6
/*
**
** T Y P E D E F I N I T I O N S
**
*/
typedef unsigned char BYTE; /* An 8-bit, unsigned quantity */
typedef short WORD; /* A 16-bit, unsigned quantity */
typedef struct { /* Holds paragraph number, character */
WORD paragraphNumber; /* num of one end of a selection */
WORD characterPosition;
} SELECTION;
typedef struct { /* Holds y,x QuickDraw coordinates */
WORD vertical;
WORD horizontal;
} POSITION;
typedef struct { /* Holds information pertaining to */
SELECTION startOfSelection; /* document state when document */
SELECTION endOfSelection; /* was last stored (not used) */
WORD verticalOffset;
WORD needToRedraw;
POSITION pageNumberPosition;
POSITION datePosition;
POSITION timePosition;
POSITION timeCoordinates;
BYTE iconRedraw;
BYTE iconFlag;
WORD activeFontNumber;
WORD activeStyleNumber;
} DOCUMENTVARIABLES;
typedef struct { /* One entry for each paragraph */
WORD height; /* the document to specify page */
WORD position; /* it falls on and its position on */
BYTE pageNumber; /* that page in QuickDraw coords */
BYTE unused[3]; /* (not used) */
} INFOARRAYELEMENT;
typedef struct { /* Each time an attribute (font, */
WORD characterPosition; /* type size, type style) changes */
BYTE pointSize; /* a format element is created. It */
BYTE style; /* contains the character position */
WORD fontNumber; /* in the paragraph where the */
} FORMATELEMENT; /* change occurs & the new attribs */
typedef struct { /* Created for each RULER in the doc */
WORD leftMargin; /* - In 1/80ths of an inch, with an */
WORD rightMargin; /* offset of 1", e.g. 30 => 1 3/8" */
BYTE justification; /* - 0=left, 1=ctr, 2=right, 3=full */
BYTE numberOfTabs; /* - Number between 1 and 10 */
BYTE unused1; /* - Unused */
BYTE spacing; /* - 0=single, 1 = 1 1/2, 2=double */
WORD indentMargin; /* - 1st line, same measures as abv */
WORD tabs[10]; /* - Up to 10, measured as above, */
WORD unused2[2]; /* negative for decimal tabs */
} RULERRECORD;
typedef struct { /* Variables used to hold status */
WORD versionNumber; /* info while MacWrite is running */
WORD paragraphOffset; /* (not used) */
WORD paragraphCount[3];
BYTE titlePageFlag;
BYTE scrapShowFlag;
BYTE footerDisplayedFlag;
BYTE headerDisplayedFlag;
BYTE rulersShowingFlag;
BYTE spareByte;
WORD activeDocumentNumber;
WORD startingPageNumber;
} GLOBALVARIABLES;
typedef struct { /* Precedes paras stored on disk */
WORD type; /* - 0=ruler, 1=text, 2=bitmap */
WORD length; /* - Number of bytes in entire para */
} PARAGRAPHDATAHEADER;
typedef struct { /* For text paragraphs... */
WORD length; /* - Number of bytes of text */
BYTE *ascii; /* -> To that text */
WORD formatRunLength; /* - Number of bytes of format info */
} PARAGRAPHTEXTRECORD;
typedef struct { /* Printing variables (not used) */
BYTE vars[120]
} PRINTINGVARIABLES;
/*
**
** G L O B A L V A R I A B L E S
**
*/
char *versionString = "1.01 2/4/85 15:50";/* Used by DocProlog for comment */
INFOARRAYELEMENT infoArray; /* Used to pass over info in data */
GLOBALVARIABLES globVar; /* Used to pass over global doc vars */
DOCUMENTVARIABLES docs[3]; /* 1 for main, 1 for hdr, 1 for foot */
PARAGRAPHDATAHEADER pDataHead; /* Holds current paragraph info */
PARAGRAPHTEXTRECORD pTextRec; /* Holds current info for text para */
PRINTINGVARIABLES printVar; /* Used to pass over print vars */
RULERRECORD rulerRec; /* Holds current ruler information */
BYTE buffer[2048]; /* Temporary buffer */
int bufferPtr; /* Index into buffer */
BYTE *textBuf; /* Pointer to buffer */
/*
**
** main(argc,argv)
**
*/
main(argc,argv)
int argc; /* Number of arguments */
char **argv; /* Array of pointers to arg strings */
{
register int j, k; /* Loop counters */
register int spool; /* True if -s option is used */
register int fdIn; /* Holds file desc of input file */
static char *tempFile = TEMPFILE; /* File to write xlated version to */
struct stat statBuf; /* Holds result of file status query */
char string[96]; /* Used to prepare "system" call */
/* In spooling mode, *arg[1] is the MacWrite file to be translated and */
/* *arg[2] is a header file containing filename and accounting info. In */
/* regular mode, if there is an arg[1] and arg[2] (i.e. if file */
/* indirection isn't being used), *arg[1] is the MacWrite file and */
/* *arg[2] is the name of the file to be written. */
/* If there are four args (including the command name) and the last is */
/* "-s", then turn spooling on. */
if (argc == 4) {
if (argv[3][0] == '-' && argv[3][1] == 's')
spool = 1;
}
else
spool = 0;
/* If more than four args, or four args but last isn't "-s", error */
if ((argc > 4) || (argc == 4 && !spool)) {
fprintf(stderr,
"Usage: mwxlate [file1 file2 [-s]]\n");
exit(TOOMANYARGS);
}
/* start out with std input and output coming from indirected files */
/* and change if arguments specify explicit files */
if (spool) {
/* if we're spooling, open temp file as std output in stream mode */
if (freopen(mktemp(tempFile),"w",stdout) == NULL) {
fprintf(stderr,"mwxlate: can't open temp file%s\n",tempFile);
exit(CANTWRITETEMP);
}
if (stat(argv[2],&statBuf)) {
fprintf(stderr,"mwxlate: cannot find spool header file %s\n",argv[2]);
exit(CANTFINDHEADER);
}
}
else if (argc == 3) { /* both in and out files have been specified */
/* open file2 as std output, in stream mode for printf */
if (freopen(argv[2],"w",stdout) == NULL) {
fprintf(stderr,"mwxlate: invalid output filename %s\n",argv[2]);
exit(CANTOPENOUTPUT);
}
}
if (argc >= 2) { /* the input file has been specified explictly */
/* open file1 as std input, in low-level read mode */
if ((fdIn = open(argv[1],O_RDONLY,0644)) < 0) {
fprintf(stderr,"mwxlate: invalid input filename %s\n",argv[1]);
exit(CANTOPENINPUT);
}
dup2(fdIn,0); /* force std input to point to this file */
close(fdIn);
}
GetGlobalVars();
GetPrintingVars();
GetDocumentVars(MAIN);
GetDocumentVars(HEADER);
GetDocumentVars(FOOTER);
GetInfoArray(MAIN);
GetInfoArray(HEADER);
GetInfoArray(FOOTER);
DocProlog(versionString); /* Put initial information in output file */
GetParagraphs(MAIN); /* Routine to read & process all para in main */
/* DocHeaderProlog();
GetParagraphs(HEADER);
DocHeaderEpilog();
*/
/* GetParagraphs(FOOTER); */
DocEpilog(); /* Put terminating information in output file */
/* Cleanup files, if spooling, send result on down the pipeline */
close(0);
fclose(stdout);
if (spool) {
/* remove MacWrite file */
if (unlink(argv[1]) != NULL)
fprintf(stderr,"mwxlate: Can't remove macwrite file %s\n",argv[1]);
/* send the translated file (tempfile) and the header file (argv[2]) */
/* to the spooler programe for printing */
execl(SPOOLPATH,SPOOLNAME,tempFile,argv[2],0);
_exit(1); /* exec failed */
}
}
/*
**
** U T I L I T Y R O U T I N E S
**
*/
/*
**
** BYTE getByte()
**
** getByte is a utility routine that maintains a current pointer into the
** global "buffer" array. When called, getByte returns the byte currently
** pointed at by bufferPtr and then increments that pointer.
**
*/
BYTE getByte()
{
return(buffer[bufferPtr++]);
}
/*
**
** WORD getWord()
**
** getWord is a utility routine that maintains a current pointer into the
** global "buffer" array and returns the 16-bit integer stored at that
** location. In MacWrite, these integers are stored with byte 0 (the left
** byte) holding the most significant bits and byte 1 (the right byte)
** holding the least significant bits. This routine reads byte 0,
** shifts it left 8 bits and masks it with 0xff00 to have it become
** the high-order byte and then takes byte one masked with 0xff and
** ors the two together to make a 16-bit integer. This process assures
** that regardless of the byte order of machine storage, the appropriate
** 16-bit value will be returned. The bufferPtr is moved past the word.
**
*/
WORD getWord()
{
WORD retVal;
retVal = (((buffer[bufferPtr]<<8)&0xFF00) | ((buffer[bufferPtr+1])&0xFF));
bufferPtr += 2;
return(retVal);
}
/*
**
** BYTE peekByte()
**
** Provides same functionality as getByte, but does not increment bufferPtr.
**
*/
BYTE peekByte()
{
return(buffer[bufferPtr]);
}
/*
**
** WORD peekWord()
**
** Provides same functionality as getWord, but does not increment bufferPtr.
**
*/
WORD peekWord()
{
return(((buffer[bufferPtr]<<8)&0xFF00) | ((buffer[bufferPtr+1])&0xFF));
}
/*
**
** readBuf(size)
**
** readBuf fills the global "buffer" array with size bytes read directly
** from the MacWrite document on disk. After reading, the master pointer
** to that buffer -- bufferPtr -- is set to point to the byte 0 of the buffer
**
*/
readBuf(size)
int size;
{
read(0,buffer,size);
bufferPtr = 0;
}
/*
**
** getNextType()
**
** A frequent necessity in the translation process is to determine the type
** of the next paragraph. getNextType fills the global buffer with the 16-bit
** integer that specifies the paragraph type.
**
*/
getNextType()
{
readBuf(2);
pDataHead.type = getWord();
}
/*
**
** getNextLength()
**
** A frequent necessity in the translation process is to determine the length
** of the data for the next paragraph. getNextLength fills the global buffer
** with the 16-bit integer that specifies that length.
**
*/
getNextLength()
{
readBuf(2);
pDataHead.length = getWord();
}
/*
**
** S U B R O U T I N E S
**
*/
/*
**
** GetGlobalVars()
**
** GetGlobalVars reads in the 20 bytes of information expected in the
** global area section of the stored MacWrite document. None of these
** are used except the versionNumber, which must be equal to 3 if this
** is a valid MacWrite 2.2 document. This test fairly adequately weeds
** out non-MacWrite documents that are passed to the program for
** translation (there is a 1 in 65536 chance that a bad document will
** have a 3 in this slot, but those are small odds). The other variables
** are read in but never used. If compiled with the DEBUG flag, the
** routine will print out the values of all these variables on stderr.
**
** Called by: main
** Calls: readbuf
** getByte, getWord
** Parms: <none>
** Returns: <none>
**
*/
GetGlobalVars()
{
readBuf(20);
globVar.versionNumber = getWord();
if (globVar.versionNumber != VALIDVERSION) {
fprintf(stderr,"mwxlate: macwrite version # %d wrong, should be %d\n",
globVar.versionNumber,VALIDVERSION);
exit(INVALIDVERSION);
}
globVar.paragraphOffset = getWord();
globVar.paragraphCount[MAIN] = getWord();
globVar.paragraphCount[HEADER] = getWord();
globVar.paragraphCount[FOOTER] = getWord();
globVar.titlePageFlag = getByte();
globVar.scrapShowFlag = getByte();
globVar.footerDisplayedFlag = getByte();
globVar.headerDisplayedFlag = getByte();
globVar.rulersShowingFlag = getByte();
globVar.spareByte = getByte();
globVar.activeDocumentNumber = getWord();
globVar.startingPageNumber = getWord();
#ifdef DEBUG
fprintf(stderr,"versionNumber = %d\n",globVar.versionNumber);
fprintf(stderr,"paragraphOffset = %d\n",globVar.paragraphOffset);
fprintf(stderr,"paragraphCount[MAIN] = %d\n", globVar.paragraphCount[MAIN]);
fprintf(stderr,"paragraphCount[HEADER] = %d\n", globVar.paragraphCount[HEADER]);
fprintf(stderr,"paragraphCount[FOOTER] = %d\n", globVar.paragraphCount[FOOTER]);
fprintf(stderr,"titlePageFlag = %d\n",globVar.titlePageFlag);
fprintf(stderr,"scrapShowFlag = %d\n",globVar.scrapShowFlag);
fprintf(stderr,"footerDisplayedFlag = %d\n",globVar.footerDisplayedFlag);
fprintf(stderr,"headerDisplayedFlag = %d\n",globVar.headerDisplayedFlag);
fprintf(stderr,"rulersShowingFlag = %d\n",globVar.rulersShowingFlag);
fprintf(stderr,"spareByte = %d\n",globVar.spareByte);
fprintf(stderr,"activeDocumentNumber = %d\n",globVar.activeDocumentNumber);
fprintf(stderr,"startingPageNumber = %d\n",globVar.startingPageNumber);
#endif
}
/*
**
** GetPrintingVars()
**
** This routine simply reads in the 120 bytes of printing variables
** stored in the MacWrite document for purposes of flushing them.
**
** Called by: main
** Calls: readBuf
** Parms: <none>
** Returns: <none>
**
*/
GetPrintingVars()
{
readBuf(120); /* throw away printing variables for time being */
}
/*
**
** GetDocumentVars(j)
**
** GetDocumentVars reads in the document variables associated with
** each of the the three types of documents stored in the MacWrite file
** and stores them in the appropriate entry in the global array "docs."
** These currently aren't used, but the date and time values will be of
** use in trying to implement the date and time tags for full headers
** (currently not implemented). Compiled with the DEBUG flag, the values
** of the variables are printed on stderr.
**
** Called by: main
** Calls: readBuf
** Parms: int -- 0 for main doc, 1 for hdr doc, 2 for footer doc
** Returns: <none>
**
*/
GetDocumentVars(j)
int j; /* 0 = main, 1 = header, 2 = footer */
{
readBuf(34);
docs[j].startOfSelection.paragraphNumber = getWord();
docs[j].startOfSelection.characterPosition = getWord();
docs[j].endOfSelection.paragraphNumber = getWord();
docs[j].endOfSelection.characterPosition = getWord();
docs[j].verticalOffset = getWord();
docs[j].needToRedraw = getWord();
docs[j].pageNumberPosition.vertical = getWord();
docs[j].pageNumberPosition.horizontal = getWord();
docs[j].datePosition.vertical = getWord();
docs[j].datePosition.horizontal = getWord();
docs[j].timePosition.vertical = getWord();
docs[j].timePosition.horizontal = getWord();
docs[j].timeCoordinates.vertical = getWord();
docs[j].timeCoordinates.horizontal = getWord();
docs[j].iconRedraw = getByte();
docs[j].iconFlag = getByte();
docs[j].activeFontNumber = getWord();
docs[j].activeStyleNumber = getWord();
#ifdef DEBUG
fprintf(stderr,"docs[%d].startOfSelection.paragraphNumber = %d\n",j,docs[j].startOfSelection.paragraphNumber);
fprintf(stderr,"docs[%d].startOfSelection.characterPosition = %d\n",j,docs[j].startOfSelection.characterPosition);
fprintf(stderr,"docs[%d].endOfSelection.paragraphNumber = %d\n",j,docs[j].endOfSelection.paragraphNumber);
fprintf(stderr,"docs[%d].endOfSelection.characterPosition = %d\n",j,docs[j].endOfSelection.characterPosition);
fprintf(stderr,"docs[%d].verticalOffset = %d\n",j,docs[j].verticalOffset);
fprintf(stderr,"docs[%d].needToRedraw = %d\n",j,docs[j].needToRedraw);
fprintf(stderr,"docs[%d].pageNumberPosition.vertical = %d\n",j,docs[j].pageNumberPosition.vertical);
fprintf(stderr,"docs[%d].pageNumberPosition.horizontal = %d\n",j,docs[j].pageNumberPosition.horizontal);
fprintf(stderr,"docs[%d].datePosition.vertical = %d\n",j,docs[j].datePosition.vertical);
fprintf(stderr,"docs[%d].datePosition.horizontal = %d\n",j,docs[j].datePosition.horizontal);
fprintf(stderr,"docs[%d].timePosition.vertical = %d\n",j,docs[j].timePosition.vertical);
fprintf(stderr,"docs[%d].timePosition.horizontal = %d\n",j,docs[j].timePosition.horizontal);
fprintf(stderr,"docs[%d].timeCoordinates.vertical = %d\n",j,docs[j].timeCoordinates.vertical);
fprintf(stderr,"docs[%d].timeCoordinates.horizontal = %d\n",j,docs[j].timeCoordinates.horizontal);
fprintf(stderr,"docs[%d].iconRedraw = %d\n",j,docs[j].iconRedraw);
fprintf(stderr,"docs[%d].iconFlag = %d\n",j,docs[j].iconFlag);
fprintf(stderr,"docs[%d].activeFontNumber = %d\n",j,docs[j].activeFontNumber);
fprintf(stderr,"docs[%d].activeStyleNumber = %d\n",j,docs[j].activeStyleNumber);
#endif
}
/*
**
** GetInfoArray(which)
**
** GetInfoArray, depending on the which parameter -- which selects
** whether to look at the main document (0), the header (1), or the
** footer (2) -- reads the page layout information for each paragraph
** in that document. This consists of reading 8 bytes for each paragraph
** and putting a 16-bit value in the height slot, a 16-bit value in the
** position slot, and an 8-bit value in the pageNumber slot. The
** remaining two bytes that were read are disregarded. If compiled with
** the DEBUG flag, the information for each paragraph is printed on
** stderr. Currently, this information is not used in the translator
** and is simply flushed.
**
** Called by: main
** Calls: readBuf
** getByte, getWord
** Parms: int -- identifies which doc (main,hdr,footer)
** Returns: <none>
**
*/
GetInfoArray(which)
int which;
{
register int k;
for (k = 0; k < globVar.paragraphCount[which]; k++) {
readBuf(8);
infoArray.height = getWord();
infoArray.position = getWord();
infoArray.pageNumber = getByte();
#ifdef DEBUG
fprintf(stderr,"%d, Paragraph %d, height = %d\n",which,k,infoArray.height);
fprintf(stderr,"%d, Paragraph %d, position = %d\n",which,k,infoArray.position);
fprintf(stderr,"%d, Paragraph %d, pageNumber = %d\n",which,k,infoArray.pageNumber);
#endif
}
}
/*
** GetParagraphs(which)
**
** Depending upon the which parameter (which distinguishs the main, header,
** and footer documents) this routine dispatches the appropriate routines
** to handle ruler paragraphs, text paragraphs, and picture paragraphs.
** It loops for the number of paragraphs in the "which" document, getting
** the paragraph type and the length of that paragraph each time through
** the loop. It then cases on the type and calls the appropriate routines
** to handle that type. For rulers, GetRulerData reads in the paragraph
** data in ruler format and translates it, for text, GetTextData reads in
** the users's ascii data and GetFormatData reads in the formatting data,
** combines it with the text data, and translates both. For pictures,
** GetPictureData is meant to read in the picture data and translate it.
** (Currently it only uses GetPictureData to skip over the picture data
** and generate new pages).
**
** Called by: main
** Calls: GetRulerData
** GetTextData
** GetFormatData
** GetPictureData
** getNextType
** getNextLength
** Parms: int -- which document to select
** Returns: <none>
*/
GetParagraphs(which)
int which;
{
register int k; /* loop counter */
for (k = 0; k < globVar.paragraphCount[which]; k++) {
getNextType();
getNextLength();
switch(pDataHead.type) {
case RULER: GetRulerData();
break;
case TEXT: GetTextData();
GetFormatData();
break;
case PICTURE: GetPictureData();
break;
default: fprintf(stderr, "Erroneous type %d\n",pDataHead.type);
/* should never be reached */
}
}
}
/*
**
** GetRulerData()
**
** GetRulerData reads the information about a ruler paragraph into the
** global "rulerRec" structure. First the routine uses readBuf to read
** in the number of bytes specified in the pDataHead.length global
** variable (which was filled in the GetParagraphData routine using
** the getNextLength utility routine). Next, it reads the information
** into the appropriate structure slots, using getWord and getByte.
** LeftMargin, rightMargin, indentMargin, and tabs are specified in
** 1/80ths of an inch, with an offset of 1", such that a value of
** 60 corresponds to 1 3/4" on the MacWrite ruler. In tabs, a negative
** value means that is a decimal tab; the absolute value specifies the
** position. If the DEBUG flag is set, than the contents of each slot
** is printed on stderr. When all is read, this routine calls
** ProcessRulerData to invoke the translation for the rulers.
**
** Called by: GetParagraphData
** Calls: readBuf
** getByte, getWord
** ProcessRulerData
** Parms: <none>
** Returns: <none>
**
*/
GetRulerData()
{
register int j;
readBuf(pDataHead.length);
rulerRec.leftMargin = getWord();
rulerRec.rightMargin = getWord();
rulerRec.justification = getByte();
rulerRec.numberOfTabs = getByte();
rulerRec.unused1 = getByte();
rulerRec.spacing = getByte();
rulerRec.indentMargin = getWord();
for (j = 0; j < 10; j++)
rulerRec.tabs[j] = getWord();
for (j = 0; j < 2; j++) {
rulerRec.unused2[j] = getWord();
}
#ifdef DEBUG
fprintf(stderr,"rulerRec.leftMargin = %d\n",rulerRec.leftMargin);
fprintf(stderr,"rulerRec.rightMargin = %d\n",rulerRec.rightMargin);
fprintf(stderr,"rulerRec.spacing = %d\n",rulerRec.spacing);
fprintf(stderr,"rulerRec.numberOfTabs = %d\n",rulerRec.numberOfTabs);
fprintf(stderr,"rulerRec.unused1 = %d\n",rulerRec.unused1);
fprintf(stderr,"rulerRec.justification = %d\n",rulerRec.justification);
fprintf(stderr,"rulerRec.indentMargin = %d\n",rulerRec.indentMargin);
for (j = 0; j < 10; j++)
fprintf(stderr,"rulerRec.tabs[j] = %d\n",rulerRec.tabs[j]);
for (j = 0; j < 2; j++)
fprintf(stderr,"rulerRec.unused2[j] = %d\n",rulerRec.unused2[j]);
#endif
ProcessRulerData(); /* invoke the translation process */
}
/*
**
** GetTextData()
**
** GetTextData reads in the ascii text of a text paragraph. The first
** two bytes of a text paragraph hold the number of characters to read,
** and as such, the first action in this routine is to use readBuf to
** read those bytes in and getWord to assign them to pTextRec.length.
**
** Next, malloc is used to generate dynamic storage to hold text of this
** length (+1 for an ending null) and the global text pointer "textBuf"
** is set to point to this storage. Next, using a system read, the ascii
** text is actually read into textBuf, and the last character of textBuf
** is assigned a terminating null. Since MacWrite starts the next significant
** data on a word boundary, the routine realigns if the number of bytes
** read was odd. Finally, DocParaProlog is called to tell the backend that
** we are ready to start translation for a text paragraph. If VERBOSEDEBUG
** is set, the full text is printed out.
**
** Called by: GetParagraphData
** Calls: readBuf
** getWord
** DocParaProlog
** Parms: <none>
** Returns: <none>
**
*/
GetTextData()
{
readBuf(2);
pTextRec.length = getWord();
#ifdef VERBOSEDEBUG
fprintf(stderr,"pTextRec.length = %d\n", pTextRec.length);
#endif
textBuf = (BYTE *) malloc(pTextRec.length+1);
read(0,textBuf,pTextRec.length);
textBuf[pTextRec.length] = 0;
#ifdef VERBOSEDEBUG
fprintf(stderr,"Text is: %s\n",textBuf);
#endif
if (pTextRec.length % 2)
readBuf(1); /* if str len was odd, need to word align */
DocParaProlog((rulerRec.indentMargin - rulerRec.leftMargin)/80.0);
}
/*
**
** GetFormatData()
**
** GetFormatData is one of the workhorses of the translator. After a
** text paragraph's text data is read in, GetFormatData is called to
** read in the corresponding format data, which is stored as a sequence
** of FORMATELEMENT structures, one for each change in formatting in the
** paragraph. Initially the routine readBufs in 2 bytes and assigns it
** to pTextRec.formatRunLength; this holds the size in bytes of the
** set of FORMATELEMENT structures for this paragraph. Next numRuns (the
** number of FORMATELEMENTs) is computed by dividing this byte size by
** the number of bytes in a single FORMATELEMENT. Then, an array of
** numRuns FORMATELEMENTs is dynamically created using calloc and the
** local variable "fmt" is set to point at it. Similarly, an array of
** numRuns BYTEs is dynamically created using calloc and the local
** variable saveChar is set to point at it. After this, the routine
** loops numRuns times -- once for each FORMATELEMENT, reading the
** information into the slots in the FORMATELEMENT record. Once all
** these have been read in it again loops numRuns times. At the top of
** this loop, it calls the backend three times to send font number,
** font size, and font style information. Since the FORMATELEMENTS
** only specify at what character the new formatting STARTS, the next part
** of the loop splits up the text in textBuf based upon the runs. When running
** through the loop for run k (except when k is the last run), the first
** character of the text for run k+1 (which directly follows the last
** character of the text for k) is saved in array savechar[k+1] and a null
** (x00) is substituted in its place. In this way, run k now constitutes
** a full string, as it is terminated by a null, without having to do
** any string copying. In the case of k being the last run, we know
** it already ends in a null, so we needn't do this. After each run is
** temporarily null-terminated, the routine calls WrapText, a procedure
** that will take the string of the run along with its formatting
** information, break it into strings short enough for most target
** batch text process, and filter it to effect appropriate character
** translation. After this is called, the character saved in the
** savechar array is replaced back into the global textBuf. When the loop
** is completed, the dynamic storage is freed. Next, an appropriate
** number of unused bytes at the end of the format runs are flushed.
** Finally, the backend is called with DocParaEpilog to mark the end
** of processing for this paragraph.
**
** Called by: GetParagraphData
** Calls: readBuf
** getByte, getWord
** WrapText
** DocParaEpilog
** Parms: <none>
** Returns: <none>
**
*/
GetFormatData()
{
register int k; /* loop counter */
FORMATELEMENT *fmt; /* -> current format element */
register BYTE *saveChar; /* -> loc in which to save a char */
register int numRuns; /* number of runs in this paragraph */
register WORD extraBytes; /* padding at end of the paragraph */
readBuf(2); /* this is the format run length */
pTextRec.formatRunLength = getWord();
readBuf(pTextRec.formatRunLength);
numRuns = pTextRec.formatRunLength/sizeof(FORMATELEMENT);
fmt = (FORMATELEMENT *) calloc(numRuns, sizeof(FORMATELEMENT));
saveChar = (BYTE *) calloc(numRuns, sizeof(BYTE));
for (k = 0; k < numRuns; k++) {
fmt[k].characterPosition = getWord();
fmt[k].pointSize = getByte();
fmt[k].style = getByte();
fmt[k].fontNumber = getWord();
}
for (k = 0; k < numRuns; k++) {
#ifdef DEBUG
fprintf(stderr,"charPos = %d\n",fmt[k].characterPosition);
fprintf(stderr,"pointSize = %d\n",fmt[k].pointSize);
fprintf(stderr,"style = %d\n",fmt[k].style);
fprintf(stderr,"fontNumber = %d\n",fmt[k].fontNumber);
#endif
DocTypeFace(fmt[k].fontNumber); /* call backend with curr font # */
DocTypeSize(fmt[k].pointSize); /* call backend with curr pt size */
DocTypeStyle(fmt[k].style); /* call backend with curr typestyle */
if (k + 1 < numRuns) { /* for all but last run */
saveChar[k+1] = textBuf[fmt[k+1].characterPosition];
textBuf[fmt[k+1].characterPosition] = 0;
WrapText(textBuf+fmt[k].characterPosition,fmt[k].fontNumber,
fmt[k].style,0);
}
else { /* for last run only */
WrapText(textBuf+fmt[k].characterPosition,
fmt[k].fontNumber,fmt[k].style,1);
}
if (k + 1 < numRuns) /* for all but last run */
textBuf[fmt[k+1].characterPosition] = saveChar[k+1];
}
free(textBuf);
free(saveChar);
free(fmt);
extraBytes = sizeof(pTextRec.length) + pTextRec.length +
sizeof(pTextRec.formatRunLength) + pTextRec.formatRunLength;
if (pTextRec.length % 2) extraBytes++;
if (extraBytes < pDataHead.length)
readBuf(pDataHead.length - extraBytes);
DocParaEpilog(); /* call to backend to mark completion of paragraph */
}
/*
**
** WrapText(strg, fontNum,fontStyle,lastLine)
**
** WrapText takes from the runlength decoding routine
** a string, a font number and style, and a flag indicating
** whether the string contains the last line of the paragraph.
** Upon receipt of this, WrapText simply breaks the string into
** manageable pieces defined by the constant DOCLINELEN, making sure
** to break lines on word boundaries, and passes them on to FilterText
** for character translation. The character pointer p is initially set to
** point to the passed string. While p points to a string that is greater
** than the desired DOCLINELEN, a loop is executed. Inside that loop, chase
** is set to be DOCLINELEN characters past p, and is decremented until
** chase points to either a space or meets up with p. If chase is less than
** or equal to p, then a line the length of DOCLINELEN is put out and
** chase is set to point to the character after this line. If chase has
** found a space, it is incremented to point directly after the space. At
** this point, the character that chase is pointing at is changed to be a
** string terminator (null) while the old char is saved, the line is
** written out, and the old character is restored. p is then set equal to
** the new value of chase
**
** Called by: GetParagraphData
** Calls: FilterText
** Parms: BYTE *strg -> string to wrap
** WORD fontNum -- number of font for runLength
** BYTE fontStyle -- style of typeface
** int lastLine -- true if strg contains last line of para
** Returns: <none>
**
*/
WrapText(strg, fontNum,fontStyle,lastLine)
BYTE *strg;
WORD fontNum;
BYTE fontStyle;
int lastLine;
{
#define DOCLINELEN 50
register BYTE *p, *chase;
register BYTE saveChar;
p = strg;
while (strlen(p) > DOCLINELEN) {
for (chase = p + DOCLINELEN; chase > p && *chase != ' '; chase--);
if (chase <= p)
chase = p + DOCLINELEN;
else
chase++;
saveChar = *chase;
*chase = 0;
FilterText(p,fontNum,fontStyle,0);
*chase = saveChar;
p = chase;
}
FilterText(p,fontNum,fontStyle,lastLine); /* if lastline of para, no cont. char */
}
/*
** FilterText(p,fontNum,fontStyle,lastLine)
**
** FilterText takes the same type of parameters as WrapText (though the
** string pointer p now points to a string of DOCLINELEN or less because
** of WrapText. FilterText is the workhorse of the program, in that it
** it does the translation of each character in the string into the
** appropriate backend character codes. FilterText has two pointers to
** character translation tables, with each translation table being an array
** of 128 strings. xFormBot is dynamically assigned to point to the table
** that represents characters 0x00 - 0x7f; xFormTop is assigned to point to
** desired table for charas 0x80 - 0xff. For example, xFormTop[0xAF]
** is the pointer to the character translation string for the character 0xAF.
** For the default, a table called stdTop is set up with the appropriate
** translations for the standard Macintosh character set between 0x80 and
** 0xFF, and xFormTop is set to point to this. Sine 0x00 - 0x7f is standard
** ASCII, there is no stdBot, and xFormBot is set to 0 to indicate that
** no translation need be done.
**
** In the main loop, each character in string p is sent through a
** cascading if-then-else to check backend specific conditions that
** might necessitate a non-standard translation (capturing special
** characters like a "." in troff). Backend-specific documentation is
** provided below.
**
** Called by: WrapText
** Calls: DocSubSuper
**
** Parms: BYTE -> shortend string from WrapText
** WORD -- font number of typeface for this run
** BYTE -- style for this run
** int -- true if this line is last line of paragraph
** Returns: <none>
**
*/
FilterText(p,fontNum,fontStyle,lastLine)
BYTE *p;
WORD fontNum;
BYTE fontStyle;
int lastLine;
#ifdef TROFF
{
register BYTE *strg;
static BYTE xBuf[1024]; /* holds translated string */
BYTE *xBufPtr;
char **xFormTop, **xFormBot;
static char *stdBot[] = {
"\000","\001","\002","\003","\004","\005","\006","\007",
"\010","\011","\012","\013","\014","\n", "\016","\017", /* CR -> \n */
"\020","\021","\022","\023","\024","\025","\026","\027",
"\030","\031","\032","\033","\034","\035","\036","\037",
" ", "!", "\"", "#", "$", "%", "&", "'",
"(", ")", "*", "+", ",", "-", ".", "/",
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", ":", ";", "<", "=", ">", "?",
"@", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W",
"X", "Y", "Z", "[", "\\\\","]", "^", "_", /* \ */
"\\(ga","a", "b", "c", "d", "e", "f", "g", /* ` */
"h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z", "{", "|", "}", "~", "\177"};
static char *stdTop[] = { /* Std Mac characters 0x80 - 0xff */
"\\*(UDA", /* 80 A diaeresis */
"\\*(ANA", /* 81 A angstrom */
"\\*(CEC", /* 82 C cedilla */
"\\*(UAE", /* 83 E acute */
"\\*(UCN", /* 84 N tilde */
"\\*(UDO", /* 85 O diaeresis */
"\\*(UDU", /* 86 U diaeresis */
"\\*Aa", /* 87 a acute */
"\\*Ga", /* 88 a grave */
"\\*Ha", /* 89 a circumflex */
"\\*Da", /* 8A a diaeresis */
"\\*Ca", /* 8B a tilde */
"\\*(ANa", /* 8C a angstrom */
"\\*(CEc", /* 8D c cedilla */
"\\*Ae", /* 8E e acute */
"\\*Ge", /* 8F e grave */
"\\*He", /* 90 e circumflex */
"\\*De", /* 91 e diaeresis */
"\\*Ai", /* 92 i acute */
"\\*Gi", /* 93 i grave */
"\\*Hi", /* 94 i circumflex */
"\\*Di", /* 95 i diaeresis */
"\\*Cn", /* 96 n tilde */
"\\*Ao", /* 97 o acute */
"\\*Go", /* 98 o grave */
"\\*Ho", /* 99 o circumflex */
"\\*Do", /* 9A o diaeresis */
"\\*Co", /* 9B o tilde */
"\\*Au", /* 9C u acute */
"\\*Gu", /* 9D u grave */
"\\*Hu", /* 9E u circumflex */
"\\*Du", /* 9F u diaeresis */
"\\(dg", /* A0 |t dagger */
"\\(de", /* A1 |* degree */
"\\(ct", /* A2 |4 cent sign */
"\\(bu", /* A3 |3 british pound sign*/
"\\(sc", /* A4 |6 section */
"\\(bu", /* A5 |8 bullet */
"\\(bu", /* A6 |7 paragraph */
"\\(*b", /* A7 |s beta */
"\\o'\\(ci\\R'", /* A8 |r registered */
"\\(co", /* A9 |g copyright */
"\\*[TM\\*]", /* AA |2 TM */
"\\*A\\&", /* AB |E accent acute */
"\\*D\\&", /* AC |U diaeresis */
"\\(!=", /* AD |= not equals */
"A\\h'-0.3m'E", /* AE |" AE */
"\\o'O/'", /* AF |O O slash */
"\\(if", /* B0 |5 infinity */
"\\(+-", /* B1 |+ plus minus */
"\\(<=", /* B2 |, <= */
"\\(>=", /* B3 |. >= */
"\\o'Y='", /* B4 |y yen sign */
"\\(*m", /* B5 |[ mu */
"\\(pd", /* B6 |d partial deriv */
"\\(*S", /* B7 |w sigma */
"\\(*P", /* B8 |P uppercase pi */
"\\(*p", /* B9 |p lowercase pi */
"\\(is", /* BA |b integral */
"\\o'a_'", /* BB |9 a underscore */
"\\o'o_'", /* BC |0 o underscore */
"\\(*W", /* BD |z omega */
"a\\h'-0.2m'e", /* BE |' ae */
"\\o'o/'", /* BF |o o slash */
"\\(bu", /* C0 |? spanish ? */
"\\(bu", /* C1 |! spanish ! */
"\\(no", /* C2 |l not sign */
"\\(sr", /* C3 |v square root */
"\\fIf\\fP", /* C4 |f script f */
"\\*(AP", /* C5 |x approximately */
"\\(*D", /* C6 |j uppercase delta */
">\\h'-0.5m'>", /* C7 |\ >> (|| illegal) */
"<\\h'-0.5m'<", /* C8 |< << (|\ illegal) */
"...", /* C9 ellipsis */
"\\ ", /* CA |S nonbreaking space */
"\\*(UGA", /* CB A grave */
"\\*(UCA", /* CC A tilde */
"\\*(UCO", /* CD O tilde */
"O\\h'-0.3m'E", /* CE |Q OE */
"o\\h'-0.2m'e", /* CF |q oe */
"\\(hy", /* D0 |- small dash */
"\\-", /* D1 |_ large dash */
"``", /* D2 |[ open " */
"''", /* D3 |{ close " */
"`", /* D4 |] open ' */
"'", /* D5 |} close ' */
"\\(di", /* D6 |/ division sign */
"\\(gr", /* D7 |V diamond */
"\\*Dy", /* D8 y umlaut */
"\\(bu", /* D9 MISSING CHAR */
"\\(bu", /* DA MISSING CHAR */
"\\(bu", /* DB MISSING CHAR */
"\\(bu", /* DC MISSING CHAR */
"\\(bu", /* DD MISSING CHAR */
"\\(bu", /* DE MISSING CHAR */
"\\(bu", /* DF MISSING CHAR */
"\\(bu", /* E0 MISSING CHAR */
"\\(bu", /* E1 MISSING CHAR */
"\\(bu", /* E2 MISSING CHAR */
"\\(bu", /* E3 MISSING CHAR */
"\\(bu", /* E4 MISSING CHAR */
"\\(bu", /* E5 MISSING CHAR */
"\\(bu", /* E6 MISSING CHAR */
"\\(bu", /* E7 MISSING CHAR */
"\\(bu", /* E8 MISSING CHAR */
"\\(bu", /* E9 MISSING CHAR */
"\\(bu", /* EA MISSING CHAR */
"\\(bu", /* EB MISSING CHAR */
"\\(bu", /* EC MISSING CHAR */
"\\(bu", /* ED MISSING CHAR */
"\\(bu", /* EE MISSING CHAR */
"\\(bu", /* EF MISSING CHAR */
"\\(bu", /* F0 MISSING CHAR */
"\\(bu", /* F1 MISSING CHAR */
"\\(bu", /* F2 MISSING CHAR */
"\\(bu", /* F3 MISSING CHAR */
"\\(bu", /* F4 MISSING CHAR */
"\\(bu", /* F5 MISSING CHAR */
"\\(bu", /* F6 MISSING CHAR */
"\\(bu", /* F7 MISSING CHAR */
"\\(bu", /* F8 MISSING CHAR */
"\\(bu", /* F9 MISSING CHAR */
"\\(bu", /* FA MISSING CHAR */
"\\(bu", /* FB MISSING CHAR */
"\\(bu", /* FC MISSING CHAR */
"\\(bu", /* FD MISSING CHAR */
"\\(bu", /* FE MISSING CHAR */
"\\(bu" /* FF MISSING CHAR */
};
/* greekBot and greekTop are xlate tables for a special Brown Greek */
/* font. Contact us for availability. */
/* x00 - x7f translation codes */
static char *greekBot[] = {
"\000","\001","\002","\003","\004","\005","\006","\007",
"\010","\011","\012","\013","\014","\n", "\016","\017", /* CR -> \n */
"\020","\021","\022","\023","\024","\025","\026","\027",
"\030","\031","\032","\033","\034","\035","\036","\037",
" ", /* 20 space */
"!", /* 21 ! */
"\"", /* 22 " */
"\\*(SC\\*(IS\\(*a", /* 23 alpha/smooth/circ/iotasub */
"\\*(RC\\*(IS\\(*a", /* 24 alpha/rough/circ/iotasub */
"\\*C\\*(IS\\(*a", /* 25 alpha/circ/iotasub */
"\\*(RA\\*(IS\\(*a", /* 26 alpha/rough/acute/iotasub */
"\\*(SA\\*(IS\\(*a", /* 27 alpha/smooth/acute/iotasub*/
"\\*(RG\\*(IS\\(*a", /* 28 alpha/rough/grave/iotasub */
"\\*(SG\\*(IS\\(*a", /* 29 alpha/smooth/grave/iotasub*/
"\\*G\\*(IS\\(*a", /* 2A alpha/grave/iotasub */
"\\*A\\*(IS\\(*a", /* 2B alpha/acute/iotasub */
",", /* 2C */
"-", /* 2D */
".", /* 2E */
"/", /* 2F */
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"\\*R\\*(IS\\(*a", /* 3A alpha/rough/iotasub */
".",
"\\*S\\*(IS\\(*a", /* 3C alpha/smooth/iotasub */
"\\*(SC\\*(IS\\(*y", /* 3D eta/smooth/circ/iotasub */
"\\*(RC\\*(IS\\*y", /* 3E eta/rough/circ/iotasub */
";", /* 3F */
"\\*S\\*(IS\\(*y", /* 40 eta/smooth/iotasub */
"\\(*A", /* 41 Alpha */
"\\(*B", /* 42 Beta */
"\\(*Q", /* 43 Psi */
"\\(*D", /* 44 Delta */
"\\(*E", /* 45 Epsilon */
"\\(*F", /* 46 Phi */
"\\(*G", /* 47 Gamma */
"\\(*Y", /* 48 Eta */
"\\(*I", /* 49 Iota */
"\\(*C", /* 4A Xi */
"\\(*K", /* 4B Kappa */
"\\(*L", /* 4C Lambda */
"\\(*M", /* 4D Mu */
"\\(*N", /* 4E Nu */
"\\(*O", /* 4F Omicron */
"\\(*P", /* 50 Pi */
"\\*R\\*(IS\\(*y", /* 51 eta/rough/iotasub */
"\\(*R", /* 52 Rho */
"\\(*S", /* 53 Sigma */
"\\(*T", /* 54 Tau */
"\\(*H", /* 55 Theta */
"\\(*W", /* 56 Omega */
"\\(*y", /* 57 eta */
"\\(*X", /* 58 Chi */
"\\(*U", /* 59 Upsilon */
"\\(*Z", /* 5A Zeta */
"\\*(RA\\*(IS\\(*y", /* 5B eta/rough/acute/iotasub */
"\\*A\\*(IS\\(*y", /* 5C eta/acute/iotasub */
"\\*(SG\\*(IS\\(*y", /* 5D eta/smooth/grave/iotasub */
"^", /* 5E ^ */
"_", /* 5F _ */
"`", /* 60 grave */
"\\(*a", /* 61 alpha */
"\\(*b", /* 62 beta */
"\\(*w", /* 63 psi */
"\\(*d", /* 64 delta */
"\\(*e", /* 65 epsilon */
"\\(*f", /* 66 phi */
"\\(*g", /* 67 gamma */
"\\(*y", /* 68 eta */
"\\(*i", /* 69 iota */
"\\(*c", /* 6A xi */
"\\(*k", /* 6B kappa */
"\\(*l", /* 6C lambda */
"\\(*m", /* 6D mu */
"\\(*n", /* 6E nu */
"\\(*o", /* 6F omicron */
"\\(*p", /* 70 pi */
"\\*(SG\\*(IS\\(*y", /* 71 eta/smooth/grave/iotasub */
"\\(*r", /* 72 rho */
"\\(*s", /* 73 sigma */
"\\(*t", /* 74 tau */
"\\(*h", /* 75 theta */
"\\(*w", /* 76 omega */
"\\*(TS", /* 77 terminal sigma */
"\\(*x", /* 78 chi */
"\\(*u", /* 79 upsilon */
"\\(*z", /* 7A zeta */
"\\*G\\*(IS\\(*y", /* 7B eta/grave/iotasub */
"|", /* 7C ^ */
"\\*S\\*(IS\\(*w", /* 7D omega/smooth/iotasub */
"~", /* 7E circumflex */
"\\*R\\(*a" /* 7F alpha/rough */
};
static char *greekTop[] = { /* Greek characters 0x80 - 0xff */
"\\*S\\(*a", /* 80 alpha/smooth */
"\\*(SA\\(*a", /* 81 alpha/smooth/acute */
"\\*(SG\\(*a", /* 82 alpha/smooth/grave */
"\\*A\\(*E", /* 83 Epsilon/acute */
"\\*C\\(*y", /* 84 eta/circumflex */
"\\*(RG\\(*a", /* 85 alpha/rough/grave */
"\\*(RA\\(*a", /* 86 alpha/rough/acute */
"\\*A\\(*a", /* 87 alpha/acute */
"\\*G\\(*a", /* 88 alpha/grave */
"\\*R\\(*e", /* 89 epsilon/rough */
"\\*S\\(*e", /* 8A epsilon/smooth */
"\\*C\\(*a", /* 8B alpha/circumflex */
"\\*(IS\\(*a", /* 8C alpha/iota subscript */
"\\*(RA\\(*e", /* 8D epsilon/rough/acute */
"\\*A\\(*e", /* 8E epsilon/acute */
"\\*G\\(*e", /* 8F epsilon/grave */
"\\*(SA\\(*e", /* 90 epsilon/smooth/acute */
"\\*(SG\\(*e", /* 91 epsilon/smooth/grave */
"\\*A\\(*i", /* 92 iota/acute */
"\\*G\\(*i", /* 93 iota/grave */
"\\*R\\(*i", /* 94 iota/rough */
"\\*D\\(*i", /* 95 iota/diaresis */
"\\*S\\(*i", /* 96 iota/smooth */
"\\*A\\(*o", /* 97 ormicron/acute */
"\\*G\\(*o", /* 98 ormicron/grave */
"\\*(RA\\(*i", /* 99 iota/rough/acute */
"\\*D\\(*o", /* 9A ormicron/diaeresis */
"\\*C\\(*o", /* 9B ormicron/circumflex */
"\\*S\\(*o", /* 9C ormicron/smooth */
"\\*(SC\\(*i", /* 9D iota/smooth/circumflex */
"\\*(SA\\(*i", /* 9E iota/smooth/acute */
"\\*D\\(*u", /* 9F upsilon/diaeresis */
"\\*(SG\\(*i", /* A0 iota/smooth/grave */
"\\*R\\(*y", /* A1 eta/rough */
"\\*(SG\\&", /* A2 smooth/grave */
"\\*(RC\\&", /* A3 rough/circumflex */
"\\*(SA\\&", /* A4 smooth/acute */
"\\(bu", /* A5 bullet */
"\\*(RA\\&", /* A6 rough acute */
"\\*(RG\\(*y", /* A7 eta/rough/grave */
"\\*(RA\\(*y", /* A8 eta/rough/acute */
"\\*(SA\\(*y", /* A9 eta/smooth/acute */
"\\*(SC\\&", /* AA smooth/circumflex */
"\\*A\\&", /* AB acute */
"\\*D\\&", /* AC diaeresis */
"\\*(RG\\(*e", /* AD rough/grave/epsilon */
"\\*A\\(*u", /* AE upsilon/acute */
"\\*R\\(*o", /* AF ormicron/rough */
"\\*S\\&", /* B0 smooth */
"\\*(SG\\(*y", /* B1 eta/smooth/grave */
"\\*A\\(*y", /* B2 eta/acute */
"\\*S\\(*y", /* B3 eta/smooth */
"\\*C\\(*i", /* B4 iota/circumflex */
"\\*(RG\\(*i", /* B5 iota/rough/grave */
"\\*A\\(*A", /* B6 Alpha/acute */
"\\*G\\(*y", /* B7 eta/grave */
"\\*(RG\\(*o", /* B8 ormicron/rough/grave */
"\\*(SC\\*(IS\\(*w", /* B9 omega/smooth/circ/iotasub*/
"\\*C\\(*W", /* BA Omega/circumflex */
"\\*R\\&", /* BB rough */
"\\*R\\(*u", /* BC upsilon/rough */
"\\*S\\(*u", /* BD upsilon/smooth */
"\\*C\\(*u", /* BE upsilon/circumflex */
"\\*(RG\\(*u", /* BF upsilon/rough/grave */
"\\*(RA\\(*u", /* C0 upsilon/rough/acute */
"\\*(RG", /* C1 rough/grave */
"\\*(SA\\(*u", /* C2 upsilon/smooth/acute */
"\\*(IS\\(*w", /* C3 omega/iotasub */
"\\*C\\(*O", /* C4 Ormicron/circumflex */
"\\*(RC\\*(IS\\(*w", /* C5 omega/rough/circ/iotasub */
"\\*C\\(*E", /* C6 Eta/circumflex */
"\\*(SG\\(*u", /* C7 upsilon/smooth/grave */
"\\*G\\(*O", /* C8 Ormicron/grave */
"\\*S\\(*w", /* C9 omega/smooth */
"\\*G\\(*U", /* CA Upsilon/grave */
"\\*G\\(*A", /* CB Alpha/grave */
"\\*C\\(*A", /* CC Alpha/circumflex */
"\\*G\\(*W", /* CD Omega/grave */
"\\*C\\*(IS\\(*w", /* CE omega/circ/iotasub */
"\\*C\\(*I", /* CF Iota/circumflex */
"\\-", /* D0 dash */
"\\*(RA\\*(IS\\(*w", /* D1 omega/rough/acute/iotasub*/
"\\*(SA\\*(IS\\(*w", /* D2 omega/smooth/acute/iotas */
"\\*(SG\\*(IS\\(*w", /* D3 omega/smooth/grave/iotas */
"\\*(RG\\*(IS\\(*w", /* D4 omega/rough/grave/iotasub*/
"\\*G\\*(IS\\(*w", /* D5 omega/grave/iotasub */
"\\*A\\*(IS\\(*w", /* D6 omega/acute/iotasub */
"\\*G\\(*Y", /* D7 Eta/grave */
"\\*G\\(*I", /* D8 Iota/grave */
"\\*G\\(*E", /* D9 Epsilon/grave */
"\\*C\\(*U", /* DA Upsilon/circumflex */
"\\*A\\(*W", /* DB Omega/acute */
"\\*A\\(*U", /* DC Upsilon/acute */
"\\*A\\(*O", /* DD Ormicron/acute */
"\\*A\\(*I", /* DE Iota/acute */
"\\*C\\*(IS\\(*e", /* DF eta/circumflex/iotasub */
"\\*R\\*(IS\\(*w", /* E0 omega/rough/iotasub */
"\\*(RC\\(*u", /* E1 upsilon/rough/circumflex */
"\\*(SC\\(*u", /* E2 upsilon/smooth/circumflex*/
"\\*(SG\\(*o", /* E3 ormicron/smooth/grave */
"\\*(SA\\(*o", /* E4 ormicron/smooth/acute */
"\\*(RA\\(*o", /* E5 ormicron/rough/acute */
"\\*(RC\\(*o", /* E6 ormicron/rough/circumflex*/
"\\*(SC\\(*o", /* E7 ormicron/smooth/circum */
"\\*(SC\\(*y", /* E8 eta/smooth/circumflex */
"\\*(RC\\(*y", /* E9 eta/rough/circumflex */
"\\*(RC\\(*i", /* EA iota/rough/circumflex */
"\\*G\\(*u", /* EB upsilon/grave */
"\\*(RC\\(*e", /* EC epsilon/rough/circumflex */
"\\*(SC\\(*e", /* ED epsilon/smooth/circumflex*/
"\\*(RC\\(*a", /* EE alpha/rough/circumflex */
"\\*(SC\\(*a", /* EF alpha/smooth/circumflex */
"\\*R\\(*r", /* F0 rho/rough */
"\\*(RC\\(*w", /* F1 omega/rough/circumflex */
"\\*(SC\\(*w", /* F2 omega/smooth/circumflex */
"\\*(SG\\(*w", /* F3 omega/smooth/grave */
"\\*(SA\\(*w", /* F4 omega/smooth/acute */
"\\*(RG\\(*w", /* F5 omega/rough/grave */
"\\*(RA\\(*w", /* F6 omega/rough/acute */
"\\*C\\(*w", /* F7 omega/circumflex */
"\\*G\\(*w", /* F8 omega/grave */
"\\*A\\(*w", /* F9 omega/acute */
"\\*(IS\\(*y", /* FA eta/iotasub */
"\\*R\\(*w", /* FB omega/rough */
"\\*A\\(*Y", /* FC Eta/acute */
"\\*C\\(*e", /* FD epsilon/circumflex */
"\\*C\\(*E", /* FE Epsilon/circumflex */
"\\(bu" /* FF MISSING CHAR */
};
/*
** FilterText ==> TROFF
**
** In the processing for the TROFF dependent FilterText, we first check
** to see if fontNum is equal to any special fonts, and if so, set the
** appropriate translation tables. If not, then we default to setting
** xFormBot to point to stdBot and xFormTop to point at stdTop.
** We set xBufPtr to point to xBuf, which is a new output buffer in which
** to do our translation. We then loop for each character in the
** string, and send it to the appropriate translation table. After this
** loop, we check to make sure that a . or ' is not in the first column
** (since these are control word indicators in troff). If one is found,
** the troff 0-width character (\&) is prepended. After this, we send
**
*/
#define tTop 0x80
#define SUPERSCRIPT 0x20
#define SUBSCRIPT 0x40
if (fontNum == 14) {
xFormBot = greekBot;
xFormTop = greekTop;
}
else {
xFormBot = stdBot;
xFormTop = stdTop;
}
xBufPtr = xBuf;
for (strg = p; *strg != 0; strg++) {
if (*strg < tTop) { /* 0x00 - 0x7f */
strcpy(xBufPtr,xFormBot[*strg]);
xBufPtr += strlen(xFormBot[*strg]);
}
else { /* 0x80 - 0xff */
strcpy(xBufPtr,xFormTop[*strg - tTop]);
xBufPtr += strlen(xFormTop[*strg - tTop]);
}
}
*xBufPtr = 0; /* null terminate the string */
if (xBuf[0] == '.' || xBuf[0] == '\'')
/* don't allow . or ' in column 1 to be treated */
printf("\\&"); /* as the control word indicator */
if (fontStyle & SUBSCRIPT)
DocPrintSubSuper(xBuf,SUBSCRIPT,lastLine);
else if (fontStyle & SUPERSCRIPT)
DocPrintSubSuper(xBuf,SUPERSCRIPT,lastLine);
else
printf("%s",xBuf);
if (!lastLine)
printf("\\c\n");
}
#endif
#ifdef WSCRIPT
{
register BYTE *strg;
static BYTE xBuf[1024]; /* holds translated string */
BYTE *xBufPtr;
char **xFormTop, **xFormBot;
static char *stdBot[] = {
"\000","\001","\002","\003","\004","\005","\006","\007",
"\010","|T", "\012","\013","\014","\n", "\016","\017",/* TAB, CR */
"\020","\021","\022","\023","\024","\025","\026","\027",
"\030","\031","\032","\033","\034","\035","\036","\037",
" ", "!", "\"", "#", "$", "%", "|Y", "'", /* & */
"(", ")", "*", "+", ",", "-", "|e", "/", /* . */
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", ":", ";", "<", "=", ">", "?",
"@", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W",
"X", "Y", "Z", "[", "\\", "]", "|I", "_", /* ^ */
"|G", "a", "b", "c", "d", "e", "f", "g", /* ` */
"h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z", "{", "|", "}", "|N", "\177"};/* ~ */
static char *stdTop[] = { /* Std Mac characters 0x80 - 0xff */
"A|B&S'|U.", /* 80 A umlaut */
"A|B&x'A1.", /* 81 A angstrom */
"C|B&x'76.", /* 82 C cedilla */
"E|B&S'|E.", /* 83 E acute */
"N|B&S'|N.", /* 84 N tilde */
"O|B&S'|U.", /* 85 O umlaut */
"U|B&S'|U.", /* 86 U umlaut */
"a|B|E", /* 87 a acute */
"a|B|G", /* 88 a grave */
"a|B|I", /* 89 a circumflex */
"a|B|U", /* 8A a umlaut */
"a|B|N", /* 8B a tilde */
"a|B&x'A1.", /* 8C a angstrom */
"c|B&x'76.", /* 8D c cedilla */
"e|B|E", /* 8E e acute */
"e|B|G", /* 8F e grave */
"e|B|I", /* 90 e circumflex */
"e|B|U", /* 91 e umlaut */
"i|B|U", /* 92 i acute */
"i|B|G", /* 93 i grave */
"i|B|I", /* 94 i circumflex */
"i|B|U", /* 95 i umlaut */
"n|B|N", /* 96 n tilde */
"o|B|E", /* 97 o acute */
"o|B|G", /* 98 o grave */
"o|B|I", /* 99 o circumflex */
"o|B|U", /* 9A o umlaut */
"o|B|N", /* 9B o tilde */
"u|B|E", /* 9C u acute */
"u|B|G", /* 9D u grave */
"u|B|I", /* 9E u circumflex */
"u|B|U", /* 9F u umlaut */
"|t", /* A0 |t dagger */
"|*", /* A1 |* degree */
"|4", /* A2 |4 cent sign */
"|3", /* A3 |3 british pound sign*/
"|6", /* A4 |6 section */
"|8", /* A5 |8 bullet */
"|7", /* A6 |7 paragraph */
"|s", /* A7 |s beta */
"|r", /* A8 |r registered */
"|g", /* A9 |g copyright */
"&S'TM.", /* AA |2 TM (missing) */
"|E", /* AB |E accent acute */
"|U", /* AC |U umlaut */
"|=", /* AD |= not equals */
"|\"", /* AE |" AE */
"O|B/", /* AF |O O slash */
"|5", /* B0 |5 infinity */
"|+", /* B1 |+ plus minus */
"|,", /* B2 |, <= */
"|.", /* B3 |. >= */
"|y", /* B4 |y antenna? */
"|[", /* B5 |[ mu */
"|d", /* B6 |d lowercase delta */
"|w", /* B7 |w sigma */
"|P", /* B8 |P uppercase pi */
"|p", /* B9 |p lowercase pi */
"|b", /* BA |b integral */
"a|B&x'6D.", /* BB |9 a underscore */
"o|B&x'6D.", /* BC |0 o underscore */
"|z", /* BD |z omega */
"|'", /* BE |' ae */
"o|B/", /* BF |o o slash */
"|?", /* C0 |? spanish ? */
"|!", /* C1 |! spanish ! */
"|l", /* C2 |l not sign */
"|v", /* C3 |v square root */
"|f", /* C4 |f script f */
"|x", /* C5 |x equivalent */
"|j", /* C6 |j uppercase delta */
"|>", /* C7 |\ >> (|| illegal) */
"|<", /* C8 |< << (|\ illegal) */
"...", /* C9 ellipsis */
"|S", /* CA |S nonbreaking space */
"A|B&S'|G.", /* CB A grave */
"A|B&S'|N.", /* CC A tilde */
"O|B&S'|N.", /* CD O tilde */
"|Q", /* CE |Q OE */
"|q", /* CF |q oe */
"|-", /* D0 |- small dash */
"|_", /* D1 |_ large dash */
"|[", /* D2 |[ open " */
"|{", /* D3 |{ close " */
"|]", /* D4 |] open ' */
"|}", /* D5 |} close ' */
"|/", /* D6 |/ division sign */
"|V", /* D7 |V diamond */
"\\y\\:", /* D8 y umlaut */
"|M", /* D9 MISSING CHAR */
"|M", /* DA MISSING CHAR */
"|M", /* DB MISSING CHAR */
"|M", /* DC MISSING CHAR */
"|M", /* DD MISSING CHAR */
"|M", /* DE MISSING CHAR */
"|M", /* DF MISSING CHAR */
"|M", /* F0 MISSING CHAR */
"|M", /* E1 MISSING CHAR */
"|M", /* E2 MISSING CHAR */
"|M", /* E3 MISSING CHAR */
"|M", /* E4 MISSING CHAR */
"|M", /* E5 MISSING CHAR */
"|M", /* E6 MISSING CHAR */
"|M", /* E7 MISSING CHAR */
"|M", /* E8 MISSING CHAR */
"|M", /* E9 MISSING CHAR */
"|M", /* EA MISSING CHAR */
"|M", /* EB MISSING CHAR */
"|M", /* EC MISSING CHAR */
"|M", /* ED MISSING CHAR */
"|M", /* EE MISSING CHAR */
"|M", /* EF MISSING CHAR */
"|M", /* F0 MISSING CHAR */
"|M", /* F1 MISSING CHAR */
"|M", /* F2 MISSING CHAR */
"|M", /* F3 MISSING CHAR */
"|M", /* F4 MISSING CHAR */
"|M", /* F5 MISSING CHAR */
"|M", /* F6 MISSING CHAR */
"|M", /* F7 MISSING CHAR */
"|M", /* F8 MISSING CHAR */
"|M", /* F9 MISSING CHAR */
"|M", /* FA MISSING CHAR */
"|M", /* FB MISSING CHAR */
"|M", /* FC MISSING CHAR */
"|M", /* FD MISSING CHAR */
"|M", /* FE MISSING CHAR */
"|M" /* FF MISSING CHAR */
};
#define tTop 0x80
#define SUPERSCRIPT 0x20
#define SUBSCRIPT 0x40
xFormBot = stdBot; /* use standard ASCII for 0x00 - 0x7f */
xFormTop = stdTop; /* use std Mac chars for 0x80 - 0xff */
xBufPtr = xBuf;
for (strg = p; *strg != 0; strg++) {
if (*strg < tTop) { /* 0x00 - 0x7f */
strcpy(xBufPtr,xFormBot[*strg]);
xBufPtr += strlen(xFormBot[*strg]);
}
else { /* 0x80 - 0xff */
strcpy(xBufPtr,xFormTop[*strg - tTop]);
xBufPtr += strlen(xFormTop[*strg - tTop]);
}
}
*xBufPtr = 0; /* null terminate the string */
if (fontStyle & SUBSCRIPT)
DocPrintSubSuper(xBuf,SUBSCRIPT,lastLine);
else if (fontStyle & SUPERSCRIPT)
DocPrintSubSuper(xBuf,SUPERSCRIPT,lastLine);
else if (strlen(xBuf) == 1 && xBuf[0] == '\n')
printf(" \n");
else
printf("%s",xBuf);
if (!lastLine)
printf("\\\n");
}
#endif
/*
** GetPictureData()
**
** GetPictureData simply reads in the number of bytes specified in the
** picture's data header. Since MacWrite uses blank pictures for creating
** page advances, all this routine does is call the DocPageAdvance. This means
** that currently, each time a picture is hit (even if it is a bitmap and
** NOT a page advance, a page advance code will be put in).
**
** Called by: GetParagraphData
** Calls: DocPageAdvance [backend]
** Parms: <none>
** Returns: <none>
**
*/
GetPictureData()
{
#ifdef DEBUG
fprintf(stderr,"This is a PICTURE\n");
#endif
readBuf(pDataHead.length);
DocPageAdvance();
}
/*
** ProcessRulerData
**
** Upon finding RULER paragraph, ProcessRulerData is called to interpret
** the ruler settings and call the appropriate backend functions. It
** calls DocMarginRight and DocMargin left with the ruler settings divided
** by 80, since the data is stored in 1/80ths of an inch and the backend
** expects inches. Line spacing is called with the standard setting (0=
** single spacing, 1 = 1-1/2 spacing, 2 = double spacing.
**
*/
ProcessRulerData()
{
register int j;
DocMarginRight(rulerRec.rightMargin/80.0);
DocMarginLeft(rulerRec.leftMargin/80.0);
DocLineSpacing(rulerRec.spacing);
DocTabProlog();
/* MacWrite treats l. marg as tab */
if (rulerRec.indentMargin < rulerRec.leftMargin)
DocTabReg(rulerRec.leftMargin/80.0,rulerRec.leftMargin/80.0,
rulerRec.indentMargin/80.0);
for (j = 0; j < rulerRec.numberOfTabs; j++)
if (rulerRec.tabs[j] >= 0)
DocTabReg(rulerRec.tabs[j]/80.0,rulerRec.leftMargin/80.0,
rulerRec.indentMargin/80.0);
else
DocTabDecimal(-rulerRec.tabs[j]/80.0,rulerRec.leftMargin/80.0,
rulerRec.indentMargin/80.0);
DocTabEpilog();
DocAdjust(rulerRec.justification);
}
DocAdjust(adjType)
BYTE adjType;
{
#ifdef TROFF
static char *adjString[4] = {"l","c","r","b"};
printf(".ad %s\n", adjString[adjType]);
#endif
#ifdef WSCRIPT
static char *adjString[4] = {"left","center","right","on"};
printf(".ju %s\n", adjString[adjType]);
#endif
}
DocEpilog()
{
#ifdef TROFF
printf("\n");
#endif
}
DocHeaderEpilog()
{
#ifdef WSCRIPT
printf(".hn end\n");
#endif
}
DocHeaderProlog()
{
#ifdef WSCRIPT
printf(".hn begin\n");
#endif
}
/*
**
** DocLineSpacing
**
** Create a line for spacing. MacWrite uses 0 for single spacing,
** 1 for 1 1/2 spacing, 2 for double spacing.
**
** We must add 1 for corresponding troff setting.
** WScript doesn't support 1 1/2 space. We must also
** put in .sp since MacWrite adds the line spacing before any
** lines are output.
**
*/
DocLineSpacing(spacing)
BYTE spacing;
{
#ifdef TROFF
printf(".ls %d\n", spacing);
printf(".sp %d\n", spacing);
#endif
#ifdef WSCRIPT
if (spacing > 1) spacing = 1; /* treat 1 1/2 and double space the same */
printf(".ls %d\n", spacing);
printf(".sp %d A\n", spacing);
#endif
}
/*
**
** DocMarginLeft
**
** MacWrite calculates all measurements relative to a fixed zero point
** which happens to be located at the 1" mark on the ruler. The left
** margin, therefore, is really an indent from that zero point, and we
** treat is as such here.
**
*/
DocMarginLeft(left)
float left;
{
#ifdef TROFF
printf(".ti 0\n.in %.3fi\n", left);
#endif
#ifdef WSCRIPT
printf(".il 0;.in %.3fi\n", left);
#endif
}
DocMarginRight(right)
float right;
{
#ifdef TROFF
printf(".ll %.3fi\n",right);
#endif
#ifdef WSCRIPT
printf(".ll %.3fi\n",right);
#endif
}
DocPageAdvance()
{
#ifdef TROFF
printf(".bp\n");
#endif
#ifdef WSCRIPT
printf(".pa\n");
#endif
}
DocParaEpilog()
{
#ifdef TROFF
/* printf(".br\n"); */
#endif
#ifdef WSCRIPT
/* printf(".br\n"); */
#endif
}
DocParaProlog(indent)
float indent;
{
#ifdef TROFF
if (indent >= 0)
printf(".ti +%.3fi\n", indent); /* need to put in + size for relative */
else
printf(".ti %.3fi\n", indent); /* minus sign already for relative */
#endif
#ifdef WSCRIPT
printf(".br;.il 0;.il %.3fi\n", indent);
#endif
}
DocPrintSubSuper(strg,flag,lastLine)
char *strg; /* text to print */
unsigned char flag;
int lastLine;
#ifdef TROFF
{
char *prefix; /* superscript or subscript prefix */
char *suffix; /* superscript or subscript suffix */
if (flag == SUBSCRIPT) {
prefix = "\\*<";
suffix = "\\*>";
}
else {
prefix = "\\*[";
suffix = "\\*]";
}
printf("%s%s%s",prefix,strg,suffix);
if (lastLine) printf ("\n");
}
#endif
#ifdef WSCRIPT
{
register char *chase, *p;
char *prefix; /* superscript or subscript prefix */
if (flag == SUBSCRIPT)
prefix = "&s'";
else
prefix = "&S'";
p = strg;
if (strlen(p) < 1) return; /* sub/superscripts of null strgs don't work */
chase = p;
while (*p != 0) {
while (*chase == ' ') { /* no blanks in superscripts, just write out */
printf("%c",' ');
p++;
chase++;
}
while (*chase != 0 && *chase != ' ') chase++;
if (*chase != 0) {
*chase = 0;
printf("%s%s.",prefix,p);
*chase = ' ';
}
else if (*p != 0) /* if *p = 0, then blanking above exhausted the str */
printf("%s%s.",prefix,p);
p = chase;
}
}
#endif
DocProlog(version)
char *version; /* current version string */
{
#ifdef TROFF
/* The following are troff statements for local motion to generate */
/* diacritics, generously provided by Greg Crane, Dept. of Classics, */
/* Harvard University. */
static char * smoothcirc = "\\v'-.3n'\\z~\\v'.1n'\\h'.2n'\\z'\\v`.2n'\\h'-.2n'";
static char * smoothgrave = "\\v'-.2n'\\z'\\h'.4n'\\z\\(ga\\v'.2n'\\h'-.4n'";
static char * smoothacute = "\\v'-.2n'\\z'\\h'.1n'\\z\\(aa\\v'.2n'\\h'-.1n'";
static char * iotasub = "\\v'.8n'\\s-4\\z\\(*i\\s+4\\v'-.8n'";
static char * roughcirc = "\\v'-.3n'\\z~\\v'.1n'\\h'.2n'\\z`\\v'.2n'\\h'-.2n'";
static char * roughgrave = "\\v'-.2n'\\z`\\h'.3n'\\z\\(ga\\v'.2n'\\h'-.3n'";
static char * roughacute = "\\v'-.2n'\\z`\\h'.1n'\\z\\(aa\\v'.2n'\\h'-.1n'";
static char * acute = "\\v'-.1n'\\z\\(aa\\v'.1n'";
static char * grave = "\\v'-.1n'\\z\\(ga\\v'.1n'";
static char * rough = "\\v'-.2n'\\z`\\v'.2n'";
static char * smooth = "\\v'-.2n'\\z'\\v'.2n'";
static char * circum = "\\v'-.1n'\\z~\\v'.1n'";
static char * upperAcute = "\\v'-.5n'\\h'.1n'\\z\\(aa\\v'.5n'\\h'-.1n'";
static char * upperGrave = "\\v'-.5n'\\h'.1n'\\z\\(ga\\v'.5n'\\h'-.1n'";
static char * upperRough = "\\v'-.6n'\\h'.1n'\\z`\\v'.6n'\\h'-.1n'";
static char * upperSmooth = "\\v'-.6n'\\h'.1n'\\z'\\v'.6n'\\h'-.1n'";
static char * upperCircum = "\\v'-.5n'\\h'.1n'\\z~\\v'.5n'\\h'-.1n'";
static char * upperDiaeresis = "\\v'-1.5n'\\z.\\h'.4n'\\z.\\h'-.4n'\\v'1.5n'";
static char * diaeresis = "\\v'-1n'\\z.\\h'.4n'\\z.\\h'-.4n'\\v'1n'";
static char * diaergrave = "\\v'-1n'\\z.\\h'.1n'\\v'.7n'\\z\\`\\v'-.7n'\\h'.5n'\\z.\\h'-.6n'\\v'1n'";
static char * diaeracute = "\\v'-1n'\\z.\\h'.1n'\\v'.7n'\\z\\'\\v'-.7n'\\h'.5n'\\z.\\h'-.6n'\\v'1n'";
static char * hidot = "\\v'-.7n'.\\v'.7n'";
static char * hat = "\\v'-.1n'\\z^\\v'.1n'";
static char * angstrom = "\\v'-.1n'\\z\\(de\\v'.1n'";
static char * cedilla = "\\v'.1n'\\h'.5n'\\s-4\\z,\\s+4\\h'-.5n'\\v'-.1n'";
static char * terminalSigma = "\\v'.2n'\\h'.5n'\\s-4\\z,\\s+4\\h'-.5n\\v'-.2n'\fIc\fP";
static char * approx = "\\v'-.6n'\\z~\\v'.6n'~";
printf("\\\" mwtroff version %s\n.po .5in\n.tp\n",version); /* margin starts at 1" per MacWrite */
printf(".ds SC %s\n",smoothcirc);
printf(".ds SG %s\n",smoothgrave);
printf(".ds SA %s\n",smoothacute);
printf(".ds IS %s\n",iotasub);
printf(".ds RC %s\n", roughcirc);
printf(".ds GC %s\n", roughgrave);
printf(".ds RA %s\n", roughacute);
printf(".ds A %s\n",acute);
printf(".ds R %s\n",rough);
printf(".ds G %s\n",grave);
printf(".ds S %s\n",smooth);
printf(".ds C %s\n",circum);
printf(".ds D %s\n",diaeresis);
printf(".ds DG %s\n",diaergrave);
printf(".ds DA %s\n",diaeracute);
printf(".ds HI %s\n",hidot);
printf(".ds AN %s\n",angstrom);
printf(".ds CE %s\n",cedilla);
printf(".ds H %s\n",hat);
printf(".ds UA %s\n",upperAcute);
printf(".ds UR %s\n",upperRough);
printf(".ds UG %s\n",upperGrave);
printf(".ds US %s\n",upperSmooth);
printf(".ds UC %s\n",upperCircum);
printf(".ds UD %s\n",upperDiaeresis);
printf(".ds TS %s\n",terminalSigma);
printf(".ds AP %s\n",approx);
#endif
#ifdef WSCRIPT
printf(".* mwscript version %s\n.im mwprof\n",version); /* file containing script char translations */
#endif
}
DocTabDecimal(stop,left,indent)
float stop;
float left;
float indent;
{
#ifdef TROFF
if (left == indent)
printf("%.3fiR ",stop-left);
else
printf("%.3fiR ",stop-indent);
#endif
#ifdef WSCRIPT
register int propSpace; /* SCRIPT expects tabs as fixed char offsets */
/* based upon its CPI value (use 32) */
propSpace = stop * 32 + 1;
if (propSpace > 0)
printf("%d'.' ",propSpace);
#endif
}
DocTabEpilog()
{
#ifdef TROFF
printf("\n");
#endif
#ifdef WSCRIPT
printf("\n");
#endif
}
DocTabProlog()
{
#ifdef TROFF
printf(".ta ");
#endif
#ifdef WSCRIPT
printf(".tb ");
#endif
}
DocTabReg(stop,left,indent)
float stop;
float left;
float indent;
{
#ifdef TROFF
if (left == indent)
printf("%.3fi ",stop-left);
else
printf("%.3fi ",stop-indent);
#endif
#ifdef WSCRIPT
register int propSpace; /* SCRIPT expects tabs as fixed char offsets */
/* based upon its CPI value (32) */
propSpace = stop * 32 + 1;
if (propSpace > 0)
printf("%d ",propSpace);
#endif
}
DocTypeFace(face)
WORD face;
{
}
DocTypeSize(size)
BYTE size;
{
#ifdef TROFF
printf("'vs %d\n\\s%d",size/9 + size + 1,size);
#endif
#ifdef WSCRIPT
#endif
}
DocTypeStyle(style)
BYTE style;
{
#ifdef TROFF
#define numStyles 7
register int bitPtr;
static char *typeStyle[7][2] = {"\\fR","\\fB", /* bold */
"","\\fI", /* italic */
"","", /* unders */
"","", /* outline*/
"","", /* shadow */
"","", /* subscript */
"",""}; /* superscr */
for (bitPtr = 0; bitPtr < numStyles; bitPtr++)
printf("%s",typeStyle[bitPtr][(style >> bitPtr) & 0x01]);
#endif
#ifdef WSCRIPT
#define numStyles 7
register int bitPtr;
static char *typeStyle[7][2] = {".bd off;",".bd on;", /* bold */
".us off;",".us on;", /* italic */
"","", /* unders */
"","", /* outline*/
"","", /* shadow */
"","", /* subscript */
"",""}; /* superscr */
for (bitPtr = 0; bitPtr < numStyles; bitPtr++)
printf("%s",typeStyle[bitPtr][(style >> bitPtr) & 0x01]);
printf("\n");
#endif
}