home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / unix / mwxlate.c < prev    next >
C/C++ Source or Header  |  1985-02-06  |  93KB  |  2,265 lines

  1. /*
  2. **
  3. ** mwxlate
  4. **
  5. ** This program interprets a MacWrite document and translates it to a batch
  6. ** document format like troff, script, tex or scribe, depending upon the backend
  7. ** functions
  8. **
  9. ** Norman Meyrowitz
  10. ** IRIS (Institute for Research in Information and Scholarship)
  11. ** Brown University
  12. ** Box 1946
  13. ** Providence, RI  02912
  14. **
  15. ** August, 1984
  16. **
  17. ** (c) 1984 Brown University
  18. **
  19. **
  20. ** REVISION HISTORY
  21. **
  22. ** Version  Date     Author  Description
  23. **
  24. ** 0.8      8/29/84  nkm     Translates from MacWrite to WSCRIPT
  25. **                           Headers and footers disabled
  26. **
  27. ** 0.9     11/28/84  nkm     TROFF enhancements added
  28. **         12/4/84   tep     added switch for imagen output for TROFF
  29. **
  30. ** 0.95    1/2/85    nkm     Cleaned up FilterText, fixed tabs, added Greek
  31. **
  32. ** 0.97    1/26/85   nkm     Fixed terminal .br bug, added TM sign in Script
  33. **
  34. ** 1.00    1/29/85   nkm     FIRST RELEASE
  35. **
  36. ** 1.01    2/4/85    nkm     Fixed Subscript/Superscript bug in SCRIPT
  37. **
  38. ** KNOWN BUGS/FEATURES NOT IMPLEMENTED
  39. **
  40. ** - Headers and footers (including date and time) not implemented
  41. **
  42. ** - Tabs not guaranteed to work after first line of paragraph (TROFF
  43. **   only)
  44. **
  45. ** - Decimal tabs are treated as right-aligned tabs (TROFF only, TROFF
  46. **   imposed limitation)
  47. **
  48. ** - Tabs may not work on lines with font changes (TROFF only)
  49. **
  50. ** - Pictures are always treated as a page advance
  51. **
  52. **
  53. */
  54.  
  55. #include <stdio.h>
  56. #include <sys/file.h>
  57. #include <sys/types.h>
  58. #include <sys/stat.h>
  59.  
  60. /*
  61. **
  62. **   C O N S T A N T    D E F I N I T I O N S
  63. **
  64. */
  65.  
  66. #define VALIDVERSION 3              /* ID of valid document from MacWrite 2.2 */
  67.  
  68. #define TEMPFILE "/tmp/#mwxXXXXXX"  /* Template for filename of xlated file   */
  69.  
  70. #define MAIN   0   /* Document Types  */
  71. #define HEADER 1
  72. #define FOOTER 2
  73.  
  74. #define RULER 0    /* Paragraph Types */
  75. #define TEXT  1
  76. #define PICTURE 2
  77.  
  78. #ifdef WSCRIPT
  79. # define SPOOLPATH "/a/mac/mwspool"     /* Pathname of pgm that sends to 9700 */
  80. # define SPOOLNAME "mwspool"
  81. #endif
  82.  
  83. #ifdef TROFF
  84. # define SPOOLPATH "/a/mac/mwtoip"      /* Pathname of pgm to send to Imagen  */
  85. # define SPOOLNAME "mwtoip"
  86. #endif
  87.  
  88. /* Error Codes                                                                      */
  89.  
  90. #define TOOMANYARGS     -1
  91. #define CANTOPENINPUT   -2
  92. #define CANTOPENOUTPUT  -3
  93. #define CANTWRITETEMP   -4
  94. #define CANTFINDHEADER  -5
  95. #define INVALIDVERSION  -6
  96.  
  97. /*
  98. **
  99. **   T Y P E    D E F I N I T I O N S
  100. **
  101. */
  102.  
  103.  
  104. typedef unsigned char BYTE;             /* An 8-bit, unsigned quantity       */
  105. typedef short WORD;                     /* A 16-bit, unsigned quantity       */
  106.  
  107. typedef struct {                        /* Holds paragraph number, character */
  108.       WORD paragraphNumber;             /*   num of one end of a selection   */
  109.       WORD characterPosition;
  110. } SELECTION;
  111.  
  112. typedef struct {                        /* Holds y,x QuickDraw coordinates   */
  113.    WORD vertical;
  114.    WORD horizontal;
  115. } POSITION;
  116.  
  117. typedef struct {                        /* Holds information pertaining to   */
  118.    SELECTION startOfSelection;          /*   document state when document    */
  119.    SELECTION endOfSelection;            /*   was last stored (not used)      */
  120.    WORD verticalOffset;
  121.    WORD needToRedraw;
  122.    POSITION pageNumberPosition;
  123.    POSITION datePosition;
  124.    POSITION timePosition;
  125.    POSITION timeCoordinates;
  126.    BYTE iconRedraw;
  127.    BYTE iconFlag;
  128.    WORD activeFontNumber;
  129.    WORD activeStyleNumber;
  130. } DOCUMENTVARIABLES;
  131.  
  132. typedef struct {                        /* One entry for each paragraph      */
  133.    WORD height;                         /*   the document to specify page    */
  134.    WORD position;                       /*   it falls on and its position on */
  135.    BYTE pageNumber;                     /*   that page in QuickDraw coords   */
  136.    BYTE unused[3];                      /*   (not used)                      */
  137. } INFOARRAYELEMENT;
  138.  
  139. typedef struct {                        /* Each time an attribute (font,     */
  140.    WORD characterPosition;              /*   type size, type style) changes  */
  141.    BYTE pointSize;                      /*   a format element is created. It */
  142.    BYTE style;                          /*   contains the character position */
  143.    WORD fontNumber;                     /*   in the paragraph where the      */
  144. } FORMATELEMENT;                        /*   change occurs & the new attribs */
  145.  
  146. typedef struct {                        /* Created for each RULER in the doc */
  147.    WORD leftMargin;                     /* - In 1/80ths of an inch, with an  */
  148.    WORD rightMargin;                    /*   offset of 1", e.g. 30 => 1 3/8" */
  149.    BYTE justification;                  /* - 0=left, 1=ctr, 2=right, 3=full  */
  150.    BYTE numberOfTabs;                   /* - Number between 1 and 10         */
  151.    BYTE unused1;                        /* - Unused                          */
  152.    BYTE spacing;                        /* - 0=single, 1 = 1 1/2, 2=double   */
  153.    WORD indentMargin;                   /* - 1st line, same measures as abv  */
  154.    WORD tabs[10];                       /* - Up to 10, measured as above,    */
  155.    WORD unused2[2];                     /*   negative for decimal tabs       */
  156. } RULERRECORD;
  157.  
  158. typedef struct {                        /* Variables used to hold status     */
  159.    WORD versionNumber;                  /*   info while MacWrite is running  */
  160.    WORD paragraphOffset;                /*   (not used)                      */
  161.    WORD paragraphCount[3];
  162.    BYTE titlePageFlag;
  163.    BYTE scrapShowFlag;
  164.    BYTE footerDisplayedFlag;
  165.    BYTE headerDisplayedFlag;
  166.    BYTE rulersShowingFlag;
  167.    BYTE spareByte;
  168.    WORD activeDocumentNumber;
  169.    WORD startingPageNumber;
  170. } GLOBALVARIABLES;
  171.  
  172. typedef struct {                        /* Precedes paras stored on disk     */
  173.    WORD type;                           /* - 0=ruler, 1=text, 2=bitmap       */
  174.    WORD length;                         /* - Number of bytes in entire para  */
  175. } PARAGRAPHDATAHEADER;
  176.  
  177. typedef struct {                        /* For text paragraphs...            */
  178.    WORD length;                         /* -  Number of bytes of text        */
  179.    BYTE *ascii;                         /* -> To that text                   */
  180.    WORD formatRunLength;                /* -  Number of bytes of format info */
  181. } PARAGRAPHTEXTRECORD;
  182.  
  183. typedef struct {                        /* Printing variables (not used)     */
  184.    BYTE vars[120]
  185. } PRINTINGVARIABLES;
  186.  
  187.  
  188. /*
  189. **
  190. **   G L O B A L    V A R I A B L E S
  191. **
  192. */
  193.  
  194. char *versionString = "1.01 2/4/85 15:50";/* Used by DocProlog for comment */
  195.  
  196.  
  197. INFOARRAYELEMENT infoArray;             /* Used to pass over info in data    */
  198. GLOBALVARIABLES globVar;                /* Used to pass over global doc vars */
  199. DOCUMENTVARIABLES docs[3];              /* 1 for main, 1 for hdr, 1 for foot */
  200. PARAGRAPHDATAHEADER pDataHead;          /* Holds current paragraph info      */
  201. PARAGRAPHTEXTRECORD pTextRec;           /* Holds current info for text para  */
  202. PRINTINGVARIABLES printVar;             /* Used to pass over print vars      */
  203. RULERRECORD rulerRec;                   /* Holds current ruler information   */
  204.  
  205. BYTE buffer[2048];                      /* Temporary buffer                  */
  206. int  bufferPtr;                         /* Index into buffer                 */
  207. BYTE *textBuf;                          /* Pointer to buffer                 */
  208.  
  209.  
  210. /*
  211. **
  212. ** main(argc,argv)
  213. **
  214. */
  215.  
  216. main(argc,argv)
  217.  
  218. int argc;                               /* Number of arguments               */
  219. char **argv;                            /* Array of pointers to arg strings  */
  220.  
  221. {
  222.    register int j, k;                   /* Loop counters                     */
  223.    register int spool;                  /* True if -s option is used         */
  224.    register int fdIn;                   /* Holds file desc of input file     */
  225.    static char *tempFile = TEMPFILE;    /* File to write xlated version to   */
  226.    struct stat statBuf;                 /* Holds result of file status query */
  227.    char string[96];                     /* Used to prepare "system" call     */
  228.  
  229.    /* In spooling mode, *arg[1] is the MacWrite file to be translated and    */
  230.    /* *arg[2] is a header file containing filename and accounting info. In   */
  231.    /* regular mode, if there is an arg[1] and arg[2] (i.e. if file           */
  232.    /* indirection isn't being used), *arg[1] is the MacWrite file and        */
  233.    /* *arg[2] is the name of the file to be written.                         */
  234.  
  235.    /* If there are four args (including the command name) and the last is    */
  236.    /* "-s", then turn spooling on.                                           */
  237.  
  238.    if (argc == 4) {
  239.       if (argv[3][0] == '-' && argv[3][1] == 's')
  240.          spool = 1;
  241.    }
  242.    else
  243.       spool = 0;
  244.  
  245.    /* If more than four args, or four args but last isn't "-s", error       */
  246.  
  247.    if ((argc > 4) || (argc == 4 && !spool)) {
  248.       fprintf(stderr,
  249.                  "Usage: mwxlate [file1 file2 [-s]]\n");
  250.       exit(TOOMANYARGS);
  251.    }
  252.  
  253.    /* start out with std input and output coming from indirected files      */
  254.    /* and change if arguments specify explicit files                        */
  255.  
  256.    if (spool) {
  257.  
  258.       /* if we're spooling, open temp file as std output in stream mode */
  259.  
  260.       if (freopen(mktemp(tempFile),"w",stdout) == NULL) {
  261.          fprintf(stderr,"mwxlate: can't open temp file%s\n",tempFile);
  262.          exit(CANTWRITETEMP);
  263.       }
  264.       if (stat(argv[2],&statBuf)) {
  265.          fprintf(stderr,"mwxlate: cannot find spool header file %s\n",argv[2]);
  266.          exit(CANTFINDHEADER);
  267.       }
  268.    }
  269.    else if (argc == 3) {  /* both in and out files have been specified     */
  270.  
  271.       /* open file2 as std output, in stream mode for printf  */
  272.  
  273.       if (freopen(argv[2],"w",stdout) == NULL) {
  274.          fprintf(stderr,"mwxlate: invalid output filename %s\n",argv[2]);
  275.          exit(CANTOPENOUTPUT);
  276.       }
  277.    }
  278.  
  279.    if (argc >= 2) {  /* the input file has been specified explictly        */
  280.  
  281.       /* open file1 as std input, in low-level read mode                   */
  282.  
  283.       if ((fdIn = open(argv[1],O_RDONLY,0644)) < 0) {
  284.          fprintf(stderr,"mwxlate: invalid input filename %s\n",argv[1]);
  285.          exit(CANTOPENINPUT);
  286.       }
  287.       dup2(fdIn,0);  /* force std input to point to this file              */
  288.       close(fdIn);
  289.    }
  290.  
  291.    GetGlobalVars();
  292.    GetPrintingVars();
  293.    GetDocumentVars(MAIN);
  294.    GetDocumentVars(HEADER);
  295.    GetDocumentVars(FOOTER);
  296.    GetInfoArray(MAIN);
  297.    GetInfoArray(HEADER);
  298.    GetInfoArray(FOOTER);
  299.  
  300.    DocProlog(versionString);    /* Put initial information in output file          */
  301.  
  302.    GetParagraphs(MAIN);         /* Routine to read & process all para in main */
  303.  
  304. /* DocHeaderProlog();
  305.       GetParagraphs(HEADER);
  306.    DocHeaderEpilog();
  307. */
  308. /* GetParagraphs(FOOTER); */
  309.  
  310.    DocEpilog();                 /* Put terminating information in output file */
  311.  
  312.  
  313.    /* Cleanup files, if spooling, send result on down the pipeline               */
  314.  
  315.    close(0);
  316.    fclose(stdout);
  317.  
  318.    if (spool) {
  319.       /* remove MacWrite file                                                    */
  320.  
  321.       if (unlink(argv[1]) != NULL)
  322.          fprintf(stderr,"mwxlate: Can't remove macwrite file %s\n",argv[1]);
  323.  
  324.       /* send the translated file (tempfile) and the header file (argv[2])    */
  325.       /* to the spooler programe for printing                                 */
  326.  
  327.       execl(SPOOLPATH,SPOOLNAME,tempFile,argv[2],0);
  328.       _exit(1); /* exec failed */
  329.   }
  330. }
  331.  
  332. /*
  333. **
  334. **   U T I L I T Y    R O U T I N E S
  335. **
  336. */
  337.  
  338. /*
  339. **
  340. ** BYTE getByte()
  341. **
  342. ** getByte is a utility routine that maintains a current pointer into the
  343. ** global "buffer" array. When called, getByte returns the byte currently
  344. ** pointed at by bufferPtr and then increments that pointer.
  345. **
  346. */
  347.  
  348. BYTE getByte()
  349.  
  350. {
  351.    return(buffer[bufferPtr++]);
  352. }
  353.  
  354. /*
  355. **
  356. ** WORD getWord()
  357. **
  358. ** getWord is a utility routine that maintains a current pointer into the
  359. ** global "buffer" array and returns the 16-bit integer stored at that
  360. ** location. In MacWrite, these integers are stored with byte 0 (the left
  361. ** byte) holding the most significant bits and byte 1 (the right byte)
  362. ** holding the least significant bits. This routine reads byte 0,
  363. ** shifts it left 8 bits and masks it with 0xff00 to have it become
  364. ** the high-order byte and then takes byte one masked with 0xff and
  365. ** ors the two together to make a 16-bit integer. This process assures
  366. ** that regardless of the byte order of machine storage, the appropriate
  367. ** 16-bit value will be returned. The bufferPtr is moved past the word.
  368. **
  369. */
  370.  
  371. WORD getWord()
  372.  
  373. {
  374.    WORD retVal;
  375.  
  376.    retVal = (((buffer[bufferPtr]<<8)&0xFF00) | ((buffer[bufferPtr+1])&0xFF));
  377.    bufferPtr += 2;
  378.    return(retVal);
  379. }
  380.  
  381. /*
  382. **
  383. ** BYTE peekByte()
  384. **
  385. ** Provides same functionality as getByte, but does not increment bufferPtr.
  386. **
  387. */
  388.  
  389. BYTE peekByte()
  390.  
  391. {
  392.    return(buffer[bufferPtr]);
  393. }
  394.  
  395. /*
  396. **
  397. ** WORD peekWord()
  398. **
  399. ** Provides same functionality as getWord, but does not increment bufferPtr.
  400. **
  401. */
  402.  
  403. WORD peekWord()
  404.  
  405. {
  406.    return(((buffer[bufferPtr]<<8)&0xFF00) | ((buffer[bufferPtr+1])&0xFF));
  407. }
  408.  
  409. /*
  410. **
  411. ** readBuf(size)
  412. **
  413. ** readBuf fills the global "buffer" array with size bytes read directly
  414. ** from the MacWrite document on disk. After reading, the master pointer
  415. ** to that buffer -- bufferPtr -- is set to point to the byte 0 of the buffer
  416. **
  417. */
  418.  
  419. readBuf(size)
  420.  
  421. int size;
  422.  
  423. {
  424.    read(0,buffer,size);
  425.    bufferPtr = 0;
  426. }
  427.  
  428.  
  429. /*
  430. **
  431. ** getNextType()
  432. **
  433. ** A frequent necessity in the translation process is to determine the type
  434. ** of the next paragraph. getNextType fills the global buffer with the 16-bit
  435. ** integer that specifies the paragraph type.
  436. **
  437. */
  438.  
  439. getNextType()
  440.  
  441. {
  442.     readBuf(2);
  443.     pDataHead.type = getWord();
  444.  
  445. }
  446.  
  447. /*
  448. **
  449. ** getNextLength()
  450. **
  451. ** A frequent necessity in the translation process is to determine the length
  452. ** of the data for the next paragraph. getNextLength fills the global buffer
  453. ** with the 16-bit integer that specifies that length.
  454. **
  455. */
  456.  
  457. getNextLength()
  458.  
  459. {
  460.     readBuf(2);
  461.     pDataHead.length = getWord();
  462. }
  463.  
  464.  
  465. /*
  466. **
  467. **   S U B R O U T I N E S
  468. **
  469. */
  470.  
  471. /*
  472. **
  473. ** GetGlobalVars()
  474. **
  475. ** GetGlobalVars reads in the 20 bytes of information expected in the
  476. ** global area section of the stored MacWrite document. None of these
  477. ** are used except the versionNumber, which must be equal to 3 if this
  478. ** is a valid MacWrite 2.2 document. This test fairly adequately weeds
  479. ** out non-MacWrite documents that are passed to the program for
  480. ** translation (there is a 1 in 65536 chance that a bad document will
  481. ** have a 3 in this slot, but those are small odds). The other variables
  482. ** are read in but never used. If compiled with the DEBUG flag, the
  483. ** routine will print out the values of all these variables on stderr.
  484. **
  485. **      Called by:      main
  486. **      Calls:          readbuf
  487. **                      getByte, getWord
  488. **      Parms:          <none>
  489. **      Returns:        <none>
  490. **
  491. */
  492.  
  493. GetGlobalVars()
  494.  
  495. {
  496.    readBuf(20);
  497.  
  498.    globVar.versionNumber = getWord();
  499.  
  500.    if (globVar.versionNumber != VALIDVERSION) {
  501.       fprintf(stderr,"mwxlate: macwrite version # %d wrong, should be %d\n",
  502.                  globVar.versionNumber,VALIDVERSION);
  503.       exit(INVALIDVERSION);
  504.    }
  505.  
  506.    globVar.paragraphOffset = getWord();
  507.    globVar.paragraphCount[MAIN] = getWord();
  508.    globVar.paragraphCount[HEADER] = getWord();
  509.    globVar.paragraphCount[FOOTER] = getWord();
  510.    globVar.titlePageFlag = getByte();
  511.    globVar.scrapShowFlag = getByte();
  512.    globVar.footerDisplayedFlag = getByte();
  513.    globVar.headerDisplayedFlag = getByte();
  514.    globVar.rulersShowingFlag = getByte();
  515.    globVar.spareByte = getByte();
  516.    globVar.activeDocumentNumber = getWord();
  517.    globVar.startingPageNumber = getWord();
  518.  
  519. #ifdef DEBUG
  520.    fprintf(stderr,"versionNumber = %d\n",globVar.versionNumber);
  521.    fprintf(stderr,"paragraphOffset = %d\n",globVar.paragraphOffset);
  522.    fprintf(stderr,"paragraphCount[MAIN] = %d\n", globVar.paragraphCount[MAIN]);
  523.    fprintf(stderr,"paragraphCount[HEADER] = %d\n", globVar.paragraphCount[HEADER]);
  524.    fprintf(stderr,"paragraphCount[FOOTER] = %d\n", globVar.paragraphCount[FOOTER]);
  525.    fprintf(stderr,"titlePageFlag = %d\n",globVar.titlePageFlag);
  526.    fprintf(stderr,"scrapShowFlag = %d\n",globVar.scrapShowFlag);
  527.    fprintf(stderr,"footerDisplayedFlag = %d\n",globVar.footerDisplayedFlag);
  528.    fprintf(stderr,"headerDisplayedFlag = %d\n",globVar.headerDisplayedFlag);
  529.    fprintf(stderr,"rulersShowingFlag = %d\n",globVar.rulersShowingFlag);
  530.    fprintf(stderr,"spareByte = %d\n",globVar.spareByte);
  531.    fprintf(stderr,"activeDocumentNumber = %d\n",globVar.activeDocumentNumber);
  532.    fprintf(stderr,"startingPageNumber = %d\n",globVar.startingPageNumber);
  533. #endif
  534.  
  535. }
  536.  
  537. /*
  538. **
  539. ** GetPrintingVars()
  540. **
  541. ** This routine simply reads in the 120 bytes of printing variables
  542. ** stored in the MacWrite document for purposes of flushing them.
  543. **
  544. **      Called by:      main
  545. **      Calls:          readBuf
  546. **      Parms:          <none>
  547. **      Returns:        <none>
  548. **
  549. */
  550.  
  551. GetPrintingVars()
  552.  
  553. {
  554.    readBuf(120);  /* throw away printing variables for time being */
  555. }
  556.  
  557. /*
  558. **
  559. ** GetDocumentVars(j)
  560. **
  561. ** GetDocumentVars reads in the document variables associated with
  562. ** each of the the three types of documents stored in the MacWrite file
  563. ** and stores them in the appropriate entry in the global array "docs."
  564. ** These currently aren't used, but the date and time values will be of
  565. ** use in trying to implement the date and time tags for full headers
  566. ** (currently not implemented). Compiled with the DEBUG flag, the values
  567. ** of the variables are printed on stderr.
  568. **
  569. **      Called by:      main
  570. **      Calls:          readBuf
  571. **      Parms:          int -- 0 for main doc, 1 for hdr doc, 2 for footer doc
  572. **      Returns:        <none>
  573. **
  574. */
  575.  
  576. GetDocumentVars(j)
  577.  
  578. int j;     /* 0 = main, 1 = header, 2 = footer */
  579.  
  580. {
  581.       readBuf(34);
  582.       docs[j].startOfSelection.paragraphNumber = getWord();
  583.       docs[j].startOfSelection.characterPosition = getWord();
  584.       docs[j].endOfSelection.paragraphNumber = getWord();
  585.       docs[j].endOfSelection.characterPosition = getWord();
  586.       docs[j].verticalOffset = getWord();
  587.       docs[j].needToRedraw = getWord();
  588.       docs[j].pageNumberPosition.vertical = getWord();
  589.       docs[j].pageNumberPosition.horizontal = getWord();
  590.       docs[j].datePosition.vertical = getWord();
  591.       docs[j].datePosition.horizontal = getWord();
  592.       docs[j].timePosition.vertical = getWord();
  593.       docs[j].timePosition.horizontal = getWord();
  594.       docs[j].timeCoordinates.vertical = getWord();
  595.       docs[j].timeCoordinates.horizontal = getWord();
  596.       docs[j].iconRedraw = getByte();
  597.       docs[j].iconFlag = getByte();
  598.       docs[j].activeFontNumber = getWord();
  599.       docs[j].activeStyleNumber = getWord();
  600.  
  601. #ifdef DEBUG
  602.       fprintf(stderr,"docs[%d].startOfSelection.paragraphNumber = %d\n",j,docs[j].startOfSelection.paragraphNumber);
  603.       fprintf(stderr,"docs[%d].startOfSelection.characterPosition = %d\n",j,docs[j].startOfSelection.characterPosition);
  604.       fprintf(stderr,"docs[%d].endOfSelection.paragraphNumber = %d\n",j,docs[j].endOfSelection.paragraphNumber);
  605.       fprintf(stderr,"docs[%d].endOfSelection.characterPosition = %d\n",j,docs[j].endOfSelection.characterPosition);
  606.       fprintf(stderr,"docs[%d].verticalOffset = %d\n",j,docs[j].verticalOffset);
  607.       fprintf(stderr,"docs[%d].needToRedraw = %d\n",j,docs[j].needToRedraw);
  608.       fprintf(stderr,"docs[%d].pageNumberPosition.vertical = %d\n",j,docs[j].pageNumberPosition.vertical);
  609.       fprintf(stderr,"docs[%d].pageNumberPosition.horizontal = %d\n",j,docs[j].pageNumberPosition.horizontal);
  610.       fprintf(stderr,"docs[%d].datePosition.vertical = %d\n",j,docs[j].datePosition.vertical);
  611.       fprintf(stderr,"docs[%d].datePosition.horizontal = %d\n",j,docs[j].datePosition.horizontal);
  612.       fprintf(stderr,"docs[%d].timePosition.vertical = %d\n",j,docs[j].timePosition.vertical);
  613.       fprintf(stderr,"docs[%d].timePosition.horizontal = %d\n",j,docs[j].timePosition.horizontal);
  614.       fprintf(stderr,"docs[%d].timeCoordinates.vertical = %d\n",j,docs[j].timeCoordinates.vertical);
  615.       fprintf(stderr,"docs[%d].timeCoordinates.horizontal = %d\n",j,docs[j].timeCoordinates.horizontal);
  616.       fprintf(stderr,"docs[%d].iconRedraw = %d\n",j,docs[j].iconRedraw);
  617.       fprintf(stderr,"docs[%d].iconFlag = %d\n",j,docs[j].iconFlag);
  618.       fprintf(stderr,"docs[%d].activeFontNumber = %d\n",j,docs[j].activeFontNumber);
  619.       fprintf(stderr,"docs[%d].activeStyleNumber = %d\n",j,docs[j].activeStyleNumber);
  620. #endif
  621. }
  622.  
  623. /*
  624. **
  625. ** GetInfoArray(which)
  626. **
  627. ** GetInfoArray, depending on the which parameter -- which selects
  628. ** whether to look at the main document (0), the header (1), or the
  629. ** footer (2) -- reads the page layout information for each paragraph
  630. ** in that document. This consists of reading 8 bytes for each paragraph
  631. ** and putting a 16-bit value in the height slot, a 16-bit value in the
  632. ** position slot, and an 8-bit value in the pageNumber slot. The
  633. ** remaining two bytes that were read are disregarded. If compiled with
  634. ** the DEBUG flag, the information for each paragraph is printed on
  635. ** stderr. Currently, this information is not used in the translator
  636. ** and is simply flushed.
  637. **
  638. **      Called by:      main
  639. **      Calls:          readBuf
  640. **                      getByte, getWord
  641. **      Parms:          int -- identifies which doc (main,hdr,footer)
  642. **      Returns:        <none>
  643. **
  644. */
  645.  
  646. GetInfoArray(which)
  647.  
  648. int which;
  649.  
  650. {
  651.    register int k;
  652.  
  653.    for (k = 0; k < globVar.paragraphCount[which]; k++) {
  654.          readBuf(8);
  655.          infoArray.height = getWord();
  656.          infoArray.position = getWord();
  657.          infoArray.pageNumber = getByte();
  658.  
  659. #ifdef DEBUG
  660.          fprintf(stderr,"%d, Paragraph %d, height = %d\n",which,k,infoArray.height);
  661.          fprintf(stderr,"%d, Paragraph %d, position = %d\n",which,k,infoArray.position);
  662.          fprintf(stderr,"%d, Paragraph %d, pageNumber = %d\n",which,k,infoArray.pageNumber);
  663. #endif
  664.    }
  665. }
  666.  
  667. /*
  668. ** GetParagraphs(which)
  669. **
  670. ** Depending upon the which parameter (which distinguishs the main, header,
  671. ** and footer documents) this routine dispatches the appropriate routines
  672. ** to handle ruler paragraphs, text paragraphs, and picture paragraphs.
  673. ** It loops for the number of paragraphs in the "which" document, getting
  674. ** the paragraph type and the length of that paragraph each time through
  675. ** the loop. It then cases on the type and calls the appropriate routines
  676. ** to handle that type. For rulers, GetRulerData reads in the paragraph
  677. ** data in ruler format and translates it, for text, GetTextData reads in
  678. ** the users's ascii data and GetFormatData reads in the formatting data,
  679. ** combines it with the text data, and translates both. For pictures,
  680. ** GetPictureData is meant to read in the picture data and translate it.
  681. ** (Currently it only uses GetPictureData to skip over the picture data
  682. ** and generate new pages).
  683. **
  684. **      Called by:      main
  685. **      Calls:          GetRulerData
  686. **                      GetTextData
  687. **                      GetFormatData
  688. **                      GetPictureData
  689. **                      getNextType
  690. **                      getNextLength
  691. **      Parms:          int -- which document to select
  692. **      Returns:        <none>
  693. */
  694.  
  695. GetParagraphs(which)
  696.  
  697. int     which;
  698.  
  699. {
  700.     register int k;     /* loop counter                         */
  701.  
  702.     for (k = 0; k < globVar.paragraphCount[which]; k++) {
  703.  
  704.        getNextType();
  705.        getNextLength();
  706.  
  707.        switch(pDataHead.type) {
  708.  
  709.        case RULER:   GetRulerData();
  710.                      break;
  711.  
  712.        case TEXT:    GetTextData();
  713.                      GetFormatData();
  714.                      break;
  715.  
  716.        case PICTURE: GetPictureData();
  717.                      break;
  718.  
  719.        default:      fprintf(stderr, "Erroneous type %d\n",pDataHead.type);
  720.                      /* should never be reached */
  721.      }
  722.   }
  723. }
  724.  
  725. /*
  726. **
  727. ** GetRulerData()
  728. **
  729. ** GetRulerData reads the information about a ruler paragraph into the
  730. ** global "rulerRec" structure. First the routine uses readBuf to read
  731. ** in the number of bytes specified in the pDataHead.length global
  732. ** variable (which was filled in the GetParagraphData routine using
  733. ** the getNextLength utility routine). Next, it reads the information
  734. ** into the appropriate structure slots, using getWord and getByte.
  735. ** LeftMargin, rightMargin, indentMargin, and tabs are specified in
  736. ** 1/80ths of an inch, with an offset of 1", such that a value of
  737. ** 60 corresponds to 1 3/4" on the MacWrite ruler. In tabs, a negative
  738. ** value means that is a decimal tab; the absolute value specifies the
  739. ** position. If the DEBUG flag is set, than the contents of each slot
  740. ** is printed on stderr. When all is read, this routine calls
  741. ** ProcessRulerData to invoke the translation for the rulers.
  742. **
  743. **      Called by:      GetParagraphData
  744. **      Calls:          readBuf
  745. **                      getByte, getWord
  746. **                      ProcessRulerData
  747. **      Parms:          <none>
  748. **      Returns:        <none>
  749. **
  750. */
  751.  
  752. GetRulerData()
  753.  
  754. {
  755.    register int j;
  756.  
  757.    readBuf(pDataHead.length);
  758.  
  759.    rulerRec.leftMargin = getWord();
  760.    rulerRec.rightMargin = getWord();
  761.    rulerRec.justification = getByte();
  762.    rulerRec.numberOfTabs = getByte();
  763.    rulerRec.unused1 = getByte();
  764.    rulerRec.spacing = getByte();
  765.    rulerRec.indentMargin = getWord();
  766.    for (j = 0; j < 10; j++)
  767.       rulerRec.tabs[j] = getWord();
  768.    for (j = 0; j < 2; j++) {
  769.       rulerRec.unused2[j] = getWord();
  770.    }
  771.  
  772. #ifdef DEBUG
  773.    fprintf(stderr,"rulerRec.leftMargin = %d\n",rulerRec.leftMargin);
  774.    fprintf(stderr,"rulerRec.rightMargin = %d\n",rulerRec.rightMargin);
  775.    fprintf(stderr,"rulerRec.spacing = %d\n",rulerRec.spacing);
  776.    fprintf(stderr,"rulerRec.numberOfTabs = %d\n",rulerRec.numberOfTabs);
  777.    fprintf(stderr,"rulerRec.unused1 = %d\n",rulerRec.unused1);
  778.    fprintf(stderr,"rulerRec.justification = %d\n",rulerRec.justification);
  779.    fprintf(stderr,"rulerRec.indentMargin = %d\n",rulerRec.indentMargin);
  780.    for (j = 0; j < 10; j++)
  781.       fprintf(stderr,"rulerRec.tabs[j] = %d\n",rulerRec.tabs[j]);
  782.    for (j = 0; j < 2; j++)
  783.       fprintf(stderr,"rulerRec.unused2[j] = %d\n",rulerRec.unused2[j]);
  784. #endif
  785.  
  786.    ProcessRulerData();          /* invoke the translation process       */
  787. }
  788.  
  789. /*
  790. **
  791. ** GetTextData()
  792. **
  793. ** GetTextData reads in the ascii text of a text paragraph. The first
  794. ** two bytes of a text paragraph hold the number of characters to read,
  795. ** and as such, the first action in this routine is to use readBuf to
  796. ** read those bytes in and getWord to assign them to pTextRec.length.
  797. **
  798. ** Next, malloc is used to generate dynamic storage to hold text of this
  799. ** length (+1 for an ending null) and the global text pointer "textBuf"
  800. ** is set to point to this storage. Next, using a system read, the ascii
  801. ** text is actually read into textBuf, and the last character of textBuf
  802. ** is assigned a terminating null. Since MacWrite starts the next significant
  803. ** data on a word boundary, the routine realigns if the number of bytes
  804. ** read was odd. Finally, DocParaProlog is called to tell the backend that
  805. ** we are ready to start translation for a text paragraph. If VERBOSEDEBUG
  806. ** is set, the full text is printed out.
  807. **
  808. **      Called by:      GetParagraphData
  809. **      Calls:          readBuf
  810. **                      getWord
  811. **                      DocParaProlog
  812. **      Parms:          <none>
  813. **      Returns:        <none>
  814. **
  815. */
  816.  
  817. GetTextData()
  818.  
  819. {
  820.     readBuf(2);
  821.     pTextRec.length = getWord();
  822.  
  823. #ifdef VERBOSEDEBUG
  824.     fprintf(stderr,"pTextRec.length = %d\n", pTextRec.length);
  825. #endif
  826.  
  827.     textBuf = (BYTE *) malloc(pTextRec.length+1);
  828.     read(0,textBuf,pTextRec.length);
  829.     textBuf[pTextRec.length] = 0;
  830.  
  831. #ifdef VERBOSEDEBUG
  832.     fprintf(stderr,"Text is: %s\n",textBuf);
  833. #endif
  834.  
  835.     if (pTextRec.length % 2)
  836.         readBuf(1);       /* if str len was odd, need to word align */
  837.  
  838.     DocParaProlog((rulerRec.indentMargin - rulerRec.leftMargin)/80.0);
  839. }
  840.  
  841. /*
  842. **
  843. ** GetFormatData()
  844. **
  845. ** GetFormatData is one of the workhorses of the translator. After a
  846. ** text paragraph's text data is read in, GetFormatData is called to
  847. ** read in the corresponding format data, which is stored as a sequence
  848. ** of FORMATELEMENT structures, one for each change in formatting in the
  849. ** paragraph. Initially the routine readBufs in 2 bytes and assigns it
  850. ** to pTextRec.formatRunLength; this holds the size in bytes of the
  851. ** set of FORMATELEMENT structures for this paragraph. Next numRuns (the
  852. ** number of FORMATELEMENTs) is computed by dividing this byte size by
  853. ** the number of bytes in a single FORMATELEMENT. Then, an array of
  854. ** numRuns FORMATELEMENTs is dynamically created using calloc and the
  855. ** local variable "fmt" is set to point at it. Similarly, an array of
  856. ** numRuns BYTEs is dynamically created using calloc and the local
  857. ** variable saveChar is set to point at it. After this, the routine
  858. ** loops numRuns times -- once for each FORMATELEMENT, reading the
  859. ** information into the slots in the FORMATELEMENT record. Once all
  860. ** these have been read in it again loops numRuns times. At the top of
  861. ** this loop, it calls the backend three times to send font number,
  862. ** font size, and font style information. Since the FORMATELEMENTS
  863. ** only specify at what character the new formatting STARTS, the next part
  864. ** of the loop splits up the text in textBuf based upon the runs. When running
  865. ** through the loop for run k (except when k is the last run), the first
  866. ** character of the text for run k+1 (which directly follows the last
  867. ** character of the text for k) is saved in array savechar[k+1] and a null
  868. ** (x00) is substituted in its place. In this way, run k now constitutes
  869. ** a full string, as it is terminated by a null, without having to do
  870. ** any string copying. In the case of k being the last run, we know
  871. ** it already ends in a null, so we needn't do this. After each run is
  872. ** temporarily null-terminated, the routine calls WrapText, a procedure
  873. ** that will take the string of the run along with its formatting
  874. ** information, break it into strings short enough for most target
  875. ** batch text process, and filter it to effect appropriate character
  876. ** translation. After this is called, the character saved in the
  877. ** savechar array is replaced back into the global textBuf. When the loop
  878. ** is completed, the dynamic storage is freed. Next, an appropriate
  879. ** number of unused bytes at the end of the format runs are flushed.
  880. ** Finally, the backend is called with DocParaEpilog to mark the end
  881. ** of processing for this paragraph.
  882. **
  883. **      Called by:      GetParagraphData
  884. **      Calls:          readBuf
  885. **                      getByte, getWord
  886. **                      WrapText
  887. **                      DocParaEpilog
  888. **      Parms:          <none>
  889. **      Returns:        <none>
  890. **
  891. */
  892.  
  893. GetFormatData()
  894.  
  895. {
  896.     register int k;             /* loop counter                      */
  897.     FORMATELEMENT *fmt;         /* -> current format element         */
  898.     register BYTE *saveChar;    /* -> loc in which to save a char    */
  899.     register int numRuns;       /* number of runs in this paragraph  */
  900.     register WORD extraBytes;   /* padding at end of the paragraph   */
  901.  
  902.     readBuf(2);                 /* this is the format run length     */
  903.     pTextRec.formatRunLength = getWord();
  904.     readBuf(pTextRec.formatRunLength);
  905.  
  906.     numRuns = pTextRec.formatRunLength/sizeof(FORMATELEMENT);
  907.  
  908.     fmt = (FORMATELEMENT *) calloc(numRuns, sizeof(FORMATELEMENT));
  909.  
  910.     saveChar = (BYTE *) calloc(numRuns, sizeof(BYTE));
  911.  
  912.     for (k = 0; k < numRuns; k++) {
  913.         fmt[k].characterPosition = getWord();
  914.         fmt[k].pointSize = getByte();
  915.         fmt[k].style = getByte();
  916.         fmt[k].fontNumber = getWord();
  917.     }
  918.  
  919.     for (k = 0; k < numRuns; k++) {
  920.  
  921. #ifdef DEBUG
  922.         fprintf(stderr,"charPos = %d\n",fmt[k].characterPosition);
  923.         fprintf(stderr,"pointSize = %d\n",fmt[k].pointSize);
  924.         fprintf(stderr,"style = %d\n",fmt[k].style);
  925.         fprintf(stderr,"fontNumber = %d\n",fmt[k].fontNumber);
  926. #endif
  927.  
  928.         DocTypeFace(fmt[k].fontNumber); /* call backend with curr font #    */
  929.         DocTypeSize(fmt[k].pointSize);  /* call backend with curr pt size   */
  930.         DocTypeStyle(fmt[k].style);     /* call backend with curr typestyle */
  931.  
  932.         if (k + 1 < numRuns) {          /* for all but last run             */
  933.            saveChar[k+1] = textBuf[fmt[k+1].characterPosition];
  934.            textBuf[fmt[k+1].characterPosition] = 0;
  935.            WrapText(textBuf+fmt[k].characterPosition,fmt[k].fontNumber,
  936.                          fmt[k].style,0);
  937.         }
  938.         else {                          /* for last run only                */
  939.            WrapText(textBuf+fmt[k].characterPosition,
  940.                          fmt[k].fontNumber,fmt[k].style,1);
  941.         }
  942.  
  943.         if (k + 1 < numRuns)            /* for all but last run             */
  944.            textBuf[fmt[k+1].characterPosition] = saveChar[k+1];
  945.  
  946.     }
  947.  
  948.     free(textBuf);
  949.     free(saveChar);
  950.     free(fmt);
  951.  
  952.     extraBytes = sizeof(pTextRec.length) + pTextRec.length +
  953.        sizeof(pTextRec.formatRunLength) + pTextRec.formatRunLength;
  954.     if (pTextRec.length % 2) extraBytes++;
  955.     if (extraBytes < pDataHead.length)
  956.        readBuf(pDataHead.length - extraBytes);
  957.  
  958.     DocParaEpilog();    /* call to backend to mark completion of paragraph */
  959. }
  960.  
  961. /*
  962. **
  963. ** WrapText(strg, fontNum,fontStyle,lastLine)
  964. **
  965. ** WrapText takes from the runlength decoding routine
  966. ** a string, a font number and style, and a flag indicating
  967. ** whether the string contains the last line of the paragraph.
  968. ** Upon receipt of this, WrapText simply breaks the string into
  969. ** manageable pieces defined by the constant DOCLINELEN, making sure
  970. ** to break lines on word boundaries, and passes them on to FilterText
  971. ** for character translation. The character pointer p is initially set to
  972. ** point to the passed string. While p points to a string that is greater
  973. ** than the desired DOCLINELEN, a loop is executed. Inside that loop, chase
  974. ** is set to be DOCLINELEN characters past p, and is decremented until
  975. ** chase points to either a space or meets up with p. If chase is less than
  976. ** or equal to p, then a line the length of DOCLINELEN is put out and
  977. ** chase is set to point to the character after this line. If chase has
  978. ** found a space, it is incremented to point directly after the space. At
  979. ** this point, the character that chase is pointing at is changed to be a
  980. ** string terminator (null) while the old char is saved, the line is
  981. ** written out, and the old character is restored. p is then set equal to
  982. ** the new value of chase
  983. **
  984. **      Called by:      GetParagraphData
  985. **      Calls:          FilterText
  986. **      Parms:          BYTE *strg -> string to wrap
  987. **                      WORD fontNum -- number of font for runLength
  988. **                      BYTE fontStyle -- style of typeface
  989. **                      int lastLine -- true if strg contains last line of para
  990. **      Returns:        <none>
  991. **
  992. */
  993.  
  994. WrapText(strg, fontNum,fontStyle,lastLine)
  995.  
  996. BYTE *strg;
  997. WORD fontNum;
  998. BYTE fontStyle;
  999. int  lastLine;
  1000.  
  1001. {
  1002. #define DOCLINELEN 50
  1003.  
  1004.     register BYTE *p, *chase;
  1005.     register BYTE saveChar;
  1006.  
  1007.     p = strg;
  1008.  
  1009.     while (strlen(p) > DOCLINELEN) {
  1010.  
  1011.        for (chase = p + DOCLINELEN; chase > p && *chase != ' '; chase--);
  1012.        if (chase <= p)
  1013.           chase = p + DOCLINELEN;
  1014.        else
  1015.           chase++;
  1016.  
  1017.        saveChar = *chase;
  1018.        *chase = 0;
  1019.        FilterText(p,fontNum,fontStyle,0);
  1020.        *chase = saveChar;
  1021.        p = chase;
  1022.     }
  1023.  
  1024.     FilterText(p,fontNum,fontStyle,lastLine); /* if lastline of para, no cont. char */
  1025. }
  1026.  
  1027. /*
  1028. ** FilterText(p,fontNum,fontStyle,lastLine)
  1029. **
  1030. ** FilterText takes the same type of parameters as WrapText (though the
  1031. ** string pointer p now points to a string of DOCLINELEN or less because
  1032. ** of WrapText. FilterText is the workhorse of the program, in that it
  1033. ** it does the translation of each character in the string into the
  1034. ** appropriate backend character codes. FilterText has two pointers to
  1035. ** character translation tables, with each translation table being an array
  1036. ** of 128 strings. xFormBot is dynamically assigned to point to the table
  1037. ** that represents characters 0x00 - 0x7f; xFormTop is assigned to point to
  1038. ** desired table for charas 0x80 - 0xff. For example, xFormTop[0xAF]
  1039. ** is the pointer to the character translation string for the character 0xAF.
  1040. ** For the default, a table called stdTop is set up with the appropriate
  1041. ** translations for the standard Macintosh character set between 0x80 and
  1042. ** 0xFF, and xFormTop is set to point to this. Sine 0x00 - 0x7f is standard
  1043. ** ASCII, there is no stdBot, and xFormBot is set to 0 to indicate that
  1044. ** no translation need be done.
  1045. **
  1046. ** In the main loop, each character in string p is sent through a
  1047. ** cascading if-then-else to check backend specific conditions that
  1048. ** might necessitate a non-standard translation (capturing special
  1049. ** characters like a "." in troff). Backend-specific documentation is
  1050. ** provided below.
  1051. **
  1052. **      Called by:      WrapText
  1053. **      Calls:          DocSubSuper
  1054. **
  1055. **      Parms:          BYTE -> shortend string from WrapText
  1056. **                      WORD -- font number of typeface for this run
  1057. **                      BYTE -- style for this run
  1058. **                      int  -- true if this line is last line of paragraph
  1059. **      Returns:        <none>
  1060. **
  1061. */
  1062.  
  1063. FilterText(p,fontNum,fontStyle,lastLine)
  1064.  
  1065. BYTE *p;
  1066. WORD fontNum;
  1067. BYTE fontStyle;
  1068. int  lastLine;
  1069.  
  1070. #ifdef TROFF
  1071. {
  1072.     register BYTE *strg;
  1073.     static BYTE xBuf[1024];   /* holds translated string */
  1074.     BYTE *xBufPtr;
  1075.     char **xFormTop, **xFormBot;
  1076.     static char *stdBot[] = {
  1077.        "\000","\001","\002","\003","\004","\005","\006","\007",
  1078.        "\010","\011","\012","\013","\014","\n",  "\016","\017", /* CR -> \n */
  1079.        "\020","\021","\022","\023","\024","\025","\026","\027",
  1080.        "\030","\031","\032","\033","\034","\035","\036","\037",
  1081.        " ",   "!",   "\"",  "#",   "$",   "%",   "&",   "'",
  1082.        "(",   ")",   "*",   "+",   ",",   "-",   ".",   "/",
  1083.        "0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
  1084.        "8",   "9",   ":",   ";",   "<",   "=",   ">",   "?",
  1085.        "@",   "A",   "B",   "C",   "D",   "E",   "F",   "G",
  1086.        "H",   "I",   "J",   "K",   "L",   "M",   "N",   "O",
  1087.        "P",   "Q",   "R",   "S",   "T",   "U",   "V",   "W",
  1088.        "X",   "Y",   "Z",   "[",   "\\\\","]",   "^",   "_",   /* \       */
  1089.        "\\(ga","a",  "b",   "c",   "d",   "e",   "f",   "g",   /* `       */
  1090.        "h",   "i",   "j",   "k",   "l",   "m",   "n",   "o",
  1091.        "p",   "q",   "r",   "s",   "t",   "u",   "v",   "w",
  1092.        "x",   "y",   "z",   "{",   "|",   "}",   "~",   "\177"};
  1093.  
  1094.     static char *stdTop[] = {           /* Std Mac characters 0x80 - 0xff    */
  1095.                         "\\*(UDA",      /* 80              A diaeresis       */
  1096.                         "\\*(ANA",      /* 81              A angstrom        */
  1097.                         "\\*(CEC",      /* 82              C cedilla         */
  1098.                         "\\*(UAE",      /* 83              E acute           */
  1099.                         "\\*(UCN",      /* 84              N tilde           */
  1100.                         "\\*(UDO",      /* 85              O diaeresis       */
  1101.                         "\\*(UDU",      /* 86              U diaeresis       */
  1102.                         "\\*Aa",        /* 87              a acute           */
  1103.                         "\\*Ga",        /* 88              a grave           */
  1104.                         "\\*Ha",        /* 89              a circumflex      */
  1105.                         "\\*Da",        /* 8A              a diaeresis       */
  1106.                         "\\*Ca",        /* 8B              a tilde           */
  1107.                         "\\*(ANa",      /* 8C              a angstrom        */
  1108.                         "\\*(CEc",      /* 8D              c cedilla         */
  1109.                         "\\*Ae",        /* 8E              e acute           */
  1110.                         "\\*Ge",        /* 8F              e grave           */
  1111.  
  1112.                         "\\*He",        /* 90              e circumflex      */
  1113.                         "\\*De",        /* 91              e diaeresis       */
  1114.                         "\\*Ai",        /* 92              i acute           */
  1115.                         "\\*Gi",        /* 93              i grave           */
  1116.                         "\\*Hi",        /* 94              i circumflex      */
  1117.                         "\\*Di",        /* 95              i diaeresis       */
  1118.                         "\\*Cn",        /* 96              n tilde           */
  1119.                         "\\*Ao",        /* 97              o acute           */
  1120.                         "\\*Go",        /* 98              o grave           */
  1121.                         "\\*Ho",        /* 99              o circumflex      */
  1122.                         "\\*Do",        /* 9A              o diaeresis       */
  1123.                         "\\*Co",        /* 9B              o tilde           */
  1124.                         "\\*Au",        /* 9C              u acute           */
  1125.                         "\\*Gu",        /* 9D              u grave           */
  1126.                         "\\*Hu",        /* 9E              u circumflex      */
  1127.                         "\\*Du",        /* 9F              u diaeresis       */
  1128.  
  1129.                          "\\(dg",         /* A0      |t      dagger            */
  1130.                          "\\(de",         /* A1      |*      degree            */
  1131.                          "\\(ct",         /* A2      |4      cent sign         */
  1132.                          "\\(bu",         /* A3      |3      british pound sign*/
  1133.                          "\\(sc",         /* A4      |6      section           */
  1134.                          "\\(bu",         /* A5      |8      bullet            */
  1135.                          "\\(bu",         /* A6      |7      paragraph         */
  1136.                          "\\(*b",         /* A7      |s      beta              */
  1137.                          "\\o'\\(ci\\R'", /* A8      |r      registered        */
  1138.                          "\\(co",         /* A9      |g      copyright         */
  1139.                          "\\*[TM\\*]",    /* AA      |2      TM                */
  1140.                          "\\*A\\&",       /* AB      |E      accent acute      */
  1141.                          "\\*D\\&",       /* AC      |U      diaeresis         */
  1142.                          "\\(!=",         /* AD      |=      not equals        */
  1143.                          "A\\h'-0.3m'E",  /* AE      |"      AE                */
  1144.                          "\\o'O/'",       /* AF      |O      O slash           */
  1145.  
  1146.                          "\\(if",         /* B0      |5      infinity          */
  1147.                          "\\(+-",         /* B1      |+      plus minus        */
  1148.                          "\\(<=",         /* B2      |,      <=                */
  1149.                          "\\(>=",         /* B3      |.      >=                */
  1150.                          "\\o'Y='",       /* B4      |y      yen sign          */
  1151.                          "\\(*m",         /* B5      |[      mu                */
  1152.                          "\\(pd",         /* B6      |d      partial deriv     */
  1153.                          "\\(*S",         /* B7      |w      sigma             */
  1154.                          "\\(*P",         /* B8      |P      uppercase pi      */
  1155.                          "\\(*p",         /* B9      |p      lowercase pi      */
  1156.                          "\\(is",         /* BA      |b      integral          */
  1157.                          "\\o'a_'",       /* BB      |9      a underscore      */
  1158.                          "\\o'o_'",       /* BC      |0      o underscore      */
  1159.                          "\\(*W",         /* BD      |z      omega             */
  1160.                          "a\\h'-0.2m'e",  /* BE      |'      ae                */
  1161.                          "\\o'o/'",       /* BF      |o      o slash           */
  1162.  
  1163.                          "\\(bu",         /* C0      |?      spanish ?         */
  1164.                          "\\(bu",         /* C1      |!      spanish !         */
  1165.                          "\\(no",         /* C2      |l      not sign          */
  1166.                          "\\(sr",         /* C3      |v      square root       */
  1167.                          "\\fIf\\fP",     /* C4      |f      script f          */
  1168.                          "\\*(AP",        /* C5      |x      approximately     */
  1169.                          "\\(*D",         /* C6      |j      uppercase delta   */
  1170.                          ">\\h'-0.5m'>",  /* C7      |\      >> (|| illegal)   */
  1171.                          "<\\h'-0.5m'<",  /* C8      |<      << (|\ illegal)   */
  1172.                         "...",            /* C9              ellipsis          */
  1173.                         "\\ ",            /* CA      |S      nonbreaking space */
  1174.                         "\\*(UGA",        /* CB              A grave           */
  1175.                         "\\*(UCA",        /* CC              A tilde           */
  1176.                         "\\*(UCO",        /* CD              O tilde           */
  1177.                         "O\\h'-0.3m'E",   /* CE      |Q      OE                */
  1178.                         "o\\h'-0.2m'e",   /* CF      |q      oe                */
  1179.  
  1180.                         "\\(hy",          /* D0      |-      small dash        */
  1181.                         "\\-",            /* D1      |_      large dash        */
  1182.                         "``",             /* D2      |[      open "            */
  1183.                         "''",             /* D3      |{      close "           */
  1184.                         "`",              /* D4      |]      open '            */
  1185.                         "'",              /* D5      |}      close '           */
  1186.                         "\\(di",          /* D6      |/      division sign     */
  1187.                         "\\(gr",          /* D7      |V      diamond           */
  1188.  
  1189.                         "\\*Dy",          /* D8              y umlaut          */
  1190.                         "\\(bu",          /* D9      MISSING CHAR             */
  1191.                         "\\(bu",          /* DA      MISSING CHAR             */
  1192.                         "\\(bu",          /* DB      MISSING CHAR             */
  1193.                         "\\(bu",          /* DC      MISSING CHAR             */
  1194.                         "\\(bu",          /* DD      MISSING CHAR             */
  1195.                         "\\(bu",          /* DE      MISSING CHAR             */
  1196.                         "\\(bu",          /* DF      MISSING CHAR             */
  1197.  
  1198.                         "\\(bu",          /* E0      MISSING CHAR             */
  1199.                         "\\(bu",          /* E1      MISSING CHAR             */
  1200.                         "\\(bu",          /* E2      MISSING CHAR             */
  1201.                         "\\(bu",          /* E3      MISSING CHAR             */
  1202.                         "\\(bu",          /* E4      MISSING CHAR             */
  1203.                         "\\(bu",          /* E5      MISSING CHAR             */
  1204.                         "\\(bu",          /* E6      MISSING CHAR             */
  1205.                         "\\(bu",          /* E7      MISSING CHAR             */
  1206.  
  1207.                         "\\(bu",          /* E8      MISSING CHAR             */
  1208.                         "\\(bu",          /* E9      MISSING CHAR             */
  1209.                         "\\(bu",          /* EA      MISSING CHAR             */
  1210.                         "\\(bu",          /* EB      MISSING CHAR             */
  1211.                         "\\(bu",          /* EC      MISSING CHAR             */
  1212.                         "\\(bu",          /* ED      MISSING CHAR             */
  1213.                         "\\(bu",          /* EE      MISSING CHAR             */
  1214.                         "\\(bu",          /* EF      MISSING CHAR             */
  1215.  
  1216.                         "\\(bu",          /* F0      MISSING CHAR             */
  1217.                         "\\(bu",          /* F1      MISSING CHAR             */
  1218.                         "\\(bu",          /* F2      MISSING CHAR             */
  1219.                         "\\(bu",          /* F3      MISSING CHAR             */
  1220.                         "\\(bu",          /* F4      MISSING CHAR             */
  1221.                         "\\(bu",          /* F5      MISSING CHAR             */
  1222.                         "\\(bu",          /* F6      MISSING CHAR             */
  1223.                         "\\(bu",          /* F7      MISSING CHAR             */
  1224.  
  1225.                         "\\(bu",          /* F8      MISSING CHAR             */
  1226.                         "\\(bu",          /* F9      MISSING CHAR             */
  1227.                         "\\(bu",          /* FA      MISSING CHAR             */
  1228.                         "\\(bu",          /* FB      MISSING CHAR             */
  1229.                         "\\(bu",          /* FC      MISSING CHAR             */
  1230.                         "\\(bu",          /* FD      MISSING CHAR             */
  1231.                         "\\(bu",          /* FE      MISSING CHAR             */
  1232.                         "\\(bu"           /* FF      MISSING CHAR             */
  1233.  
  1234.                          };
  1235.  
  1236.  
  1237.   /* greekBot and greekTop are xlate tables for a special Brown Greek   */
  1238.   /* font. Contact us for availability.                                 */
  1239.  
  1240.  
  1241.    /* x00 - x7f translation codes                                                 */
  1242.  
  1243.    static char *greekBot[] = {
  1244.        "\000","\001","\002","\003","\004","\005","\006","\007",
  1245.        "\010","\011","\012","\013","\014","\n",  "\016","\017", /* CR -> \n */
  1246.        "\020","\021","\022","\023","\024","\025","\026","\027",
  1247.        "\030","\031","\032","\033","\034","\035","\036","\037",
  1248.  
  1249.        " ",                             /* 20           space           */
  1250.        "!",                             /* 21           !               */
  1251.        "\"",                            /* 22           "               */
  1252.        "\\*(SC\\*(IS\\(*a",             /* 23 alpha/smooth/circ/iotasub */
  1253.        "\\*(RC\\*(IS\\(*a",             /* 24 alpha/rough/circ/iotasub  */
  1254.        "\\*C\\*(IS\\(*a",               /* 25 alpha/circ/iotasub        */
  1255.        "\\*(RA\\*(IS\\(*a",             /* 26 alpha/rough/acute/iotasub */
  1256.        "\\*(SA\\*(IS\\(*a",             /* 27 alpha/smooth/acute/iotasub*/
  1257.        "\\*(RG\\*(IS\\(*a",             /* 28 alpha/rough/grave/iotasub */
  1258.        "\\*(SG\\*(IS\\(*a",             /* 29 alpha/smooth/grave/iotasub*/
  1259.        "\\*G\\*(IS\\(*a",               /* 2A alpha/grave/iotasub       */
  1260.        "\\*A\\*(IS\\(*a",               /* 2B alpha/acute/iotasub       */
  1261.        ",",                             /* 2C                           */
  1262.        "-",                             /* 2D                           */
  1263.        ".",                             /* 2E                           */
  1264.        "/",                             /* 2F                           */
  1265.  
  1266.        "0",
  1267.        "1",
  1268.        "2",
  1269.        "3",
  1270.        "4",
  1271.        "5",
  1272.        "6",
  1273.        "7",
  1274.        "8",
  1275.        "9",
  1276.        "\\*R\\*(IS\\(*a",               /* 3A alpha/rough/iotasub       */
  1277.        ".",
  1278.        "\\*S\\*(IS\\(*a",               /* 3C alpha/smooth/iotasub      */
  1279.        "\\*(SC\\*(IS\\(*y",             /* 3D eta/smooth/circ/iotasub   */
  1280.        "\\*(RC\\*(IS\\*y",              /* 3E eta/rough/circ/iotasub    */
  1281.        ";",                             /* 3F                           */
  1282.  
  1283.        "\\*S\\*(IS\\(*y",               /* 40 eta/smooth/iotasub        */
  1284.        "\\(*A",                         /* 41           Alpha           */
  1285.        "\\(*B",                         /* 42           Beta            */
  1286.        "\\(*Q",                         /* 43           Psi             */
  1287.        "\\(*D",                         /* 44           Delta           */
  1288.        "\\(*E",                         /* 45           Epsilon         */
  1289.        "\\(*F",                         /* 46           Phi             */
  1290.        "\\(*G",                         /* 47           Gamma           */
  1291.        "\\(*Y",                         /* 48           Eta             */
  1292.        "\\(*I",                         /* 49           Iota            */
  1293.        "\\(*C",                         /* 4A           Xi              */
  1294.        "\\(*K",                         /* 4B           Kappa           */
  1295.        "\\(*L",                         /* 4C           Lambda          */
  1296.        "\\(*M",                         /* 4D           Mu              */
  1297.        "\\(*N",                         /* 4E           Nu              */
  1298.        "\\(*O",                         /* 4F           Omicron         */
  1299.  
  1300.  
  1301.        "\\(*P",                         /* 50           Pi              */
  1302.        "\\*R\\*(IS\\(*y",               /* 51 eta/rough/iotasub         */
  1303.        "\\(*R",                         /* 52           Rho             */
  1304.        "\\(*S",                         /* 53           Sigma           */
  1305.        "\\(*T",                         /* 54           Tau             */
  1306.        "\\(*H",                         /* 55           Theta           */
  1307.        "\\(*W",                         /* 56           Omega           */
  1308.        "\\(*y",                         /* 57           eta             */
  1309.        "\\(*X",                         /* 58           Chi             */
  1310.        "\\(*U",                         /* 59           Upsilon         */
  1311.        "\\(*Z",                         /* 5A           Zeta            */
  1312.        "\\*(RA\\*(IS\\(*y",             /* 5B eta/rough/acute/iotasub   */
  1313.        "\\*A\\*(IS\\(*y",               /* 5C eta/acute/iotasub         */
  1314.        "\\*(SG\\*(IS\\(*y",             /* 5D eta/smooth/grave/iotasub  */
  1315.        "^",                             /* 5E           ^               */
  1316.        "_",                             /* 5F           _               */
  1317.  
  1318.        "`",                             /* 60           grave           */
  1319.        "\\(*a",                         /* 61           alpha           */
  1320.        "\\(*b",                         /* 62           beta            */
  1321.        "\\(*w",                         /* 63           psi             */
  1322.        "\\(*d",                         /* 64           delta           */
  1323.        "\\(*e",                         /* 65           epsilon         */
  1324.        "\\(*f",                         /* 66           phi             */
  1325.        "\\(*g",                         /* 67           gamma           */
  1326.        "\\(*y",                         /* 68           eta             */
  1327.        "\\(*i",                         /* 69           iota            */
  1328.        "\\(*c",                         /* 6A           xi              */
  1329.        "\\(*k",                         /* 6B           kappa           */
  1330.        "\\(*l",                         /* 6C           lambda          */
  1331.        "\\(*m",                         /* 6D           mu              */
  1332.        "\\(*n",                         /* 6E           nu              */
  1333.        "\\(*o",                         /* 6F           omicron         */
  1334.        "\\(*p",                         /* 70           pi              */
  1335.        "\\*(SG\\*(IS\\(*y",             /* 71 eta/smooth/grave/iotasub  */
  1336.        "\\(*r",                         /* 72           rho             */
  1337.        "\\(*s",                         /* 73           sigma           */
  1338.        "\\(*t",                         /* 74           tau             */
  1339.        "\\(*h",                         /* 75           theta           */
  1340.        "\\(*w",                         /* 76           omega           */
  1341.        "\\*(TS",                        /* 77           terminal sigma  */
  1342.        "\\(*x",                         /* 78           chi             */
  1343.        "\\(*u",                         /* 79           upsilon         */
  1344.        "\\(*z",                         /* 7A           zeta            */
  1345.        "\\*G\\*(IS\\(*y",               /* 7B eta/grave/iotasub         */
  1346.        "|",                             /* 7C           ^               */
  1347.        "\\*S\\*(IS\\(*w",               /* 7D omega/smooth/iotasub      */
  1348.        "~",                             /* 7E           circumflex      */
  1349.        "\\*R\\(*a"                      /* 7F alpha/rough               */
  1350.     };
  1351.  
  1352.     static char *greekTop[] = {         /* Greek characters 0x80 - 0xff      */
  1353.        "\\*S\\(*a",                          /* 80  alpha/smooth             */
  1354.        "\\*(SA\\(*a",                        /* 81  alpha/smooth/acute       */
  1355.        "\\*(SG\\(*a",                        /* 82  alpha/smooth/grave       */
  1356.        "\\*A\\(*E",                          /* 83  Epsilon/acute            */
  1357.        "\\*C\\(*y",                          /* 84  eta/circumflex           */
  1358.        "\\*(RG\\(*a",                        /* 85  alpha/rough/grave        */
  1359.        "\\*(RA\\(*a",                        /* 86  alpha/rough/acute        */
  1360.        "\\*A\\(*a",                          /* 87  alpha/acute              */
  1361.        "\\*G\\(*a",                          /* 88  alpha/grave              */
  1362.        "\\*R\\(*e",                          /* 89  epsilon/rough            */
  1363.        "\\*S\\(*e",                          /* 8A  epsilon/smooth           */
  1364.        "\\*C\\(*a",                          /* 8B  alpha/circumflex         */
  1365.        "\\*(IS\\(*a",                        /* 8C  alpha/iota subscript     */
  1366.        "\\*(RA\\(*e",                        /* 8D  epsilon/rough/acute      */
  1367.        "\\*A\\(*e",                          /* 8E  epsilon/acute            */
  1368.        "\\*G\\(*e",                          /* 8F  epsilon/grave            */
  1369.  
  1370.        "\\*(SA\\(*e",                        /* 90  epsilon/smooth/acute     */
  1371.        "\\*(SG\\(*e",                        /* 91  epsilon/smooth/grave     */
  1372.        "\\*A\\(*i",                          /* 92  iota/acute               */
  1373.        "\\*G\\(*i",                          /* 93  iota/grave               */
  1374.        "\\*R\\(*i",                          /* 94  iota/rough               */
  1375.        "\\*D\\(*i",                          /* 95  iota/diaresis            */
  1376.        "\\*S\\(*i",                          /* 96  iota/smooth              */
  1377.        "\\*A\\(*o",                          /* 97  ormicron/acute           */
  1378.        "\\*G\\(*o",                          /* 98  ormicron/grave           */
  1379.        "\\*(RA\\(*i",                        /* 99  iota/rough/acute         */
  1380.        "\\*D\\(*o",                          /* 9A  ormicron/diaeresis       */
  1381.        "\\*C\\(*o",                          /* 9B  ormicron/circumflex      */
  1382.        "\\*S\\(*o",                          /* 9C  ormicron/smooth          */
  1383.        "\\*(SC\\(*i",                        /* 9D  iota/smooth/circumflex   */
  1384.        "\\*(SA\\(*i",                        /* 9E  iota/smooth/acute        */
  1385.        "\\*D\\(*u",                          /* 9F  upsilon/diaeresis        */
  1386.  
  1387.        "\\*(SG\\(*i",                        /* A0  iota/smooth/grave        */
  1388.        "\\*R\\(*y",                          /* A1  eta/rough                */
  1389.        "\\*(SG\\&",                          /* A2  smooth/grave             */
  1390.        "\\*(RC\\&",                          /* A3  rough/circumflex         */
  1391.        "\\*(SA\\&",                          /* A4  smooth/acute             */
  1392.        "\\(bu",                              /* A5  bullet                   */
  1393.        "\\*(RA\\&",                          /* A6  rough acute              */
  1394.        "\\*(RG\\(*y",                        /* A7  eta/rough/grave          */
  1395.        "\\*(RA\\(*y",                        /* A8  eta/rough/acute          */
  1396.        "\\*(SA\\(*y",                        /* A9  eta/smooth/acute         */
  1397.        "\\*(SC\\&",                          /* AA  smooth/circumflex        */
  1398.        "\\*A\\&",                            /* AB  acute                    */
  1399.        "\\*D\\&",                            /* AC  diaeresis                */
  1400.        "\\*(RG\\(*e",                        /* AD  rough/grave/epsilon      */
  1401.        "\\*A\\(*u",                          /* AE  upsilon/acute            */
  1402.        "\\*R\\(*o",                          /* AF  ormicron/rough           */
  1403.  
  1404.        "\\*S\\&",                            /* B0  smooth                   */
  1405.        "\\*(SG\\(*y",                        /* B1  eta/smooth/grave         */
  1406.        "\\*A\\(*y",                          /* B2  eta/acute                */
  1407.        "\\*S\\(*y",                          /* B3  eta/smooth               */
  1408.        "\\*C\\(*i",                          /* B4  iota/circumflex          */
  1409.        "\\*(RG\\(*i",                        /* B5  iota/rough/grave         */
  1410.        "\\*A\\(*A",                          /* B6  Alpha/acute              */
  1411.        "\\*G\\(*y",                          /* B7  eta/grave                */
  1412.        "\\*(RG\\(*o",                        /* B8  ormicron/rough/grave     */
  1413.        "\\*(SC\\*(IS\\(*w",                  /* B9  omega/smooth/circ/iotasub*/
  1414.        "\\*C\\(*W",                          /* BA  Omega/circumflex         */
  1415.        "\\*R\\&",                            /* BB  rough                    */
  1416.        "\\*R\\(*u",                          /* BC  upsilon/rough            */
  1417.        "\\*S\\(*u",                          /* BD  upsilon/smooth           */
  1418.        "\\*C\\(*u",                          /* BE  upsilon/circumflex       */
  1419.        "\\*(RG\\(*u",                        /* BF  upsilon/rough/grave      */
  1420.  
  1421.        "\\*(RA\\(*u",                        /* C0  upsilon/rough/acute      */
  1422.        "\\*(RG",                             /* C1  rough/grave              */
  1423.        "\\*(SA\\(*u",                        /* C2  upsilon/smooth/acute     */
  1424.        "\\*(IS\\(*w",                        /* C3  omega/iotasub            */
  1425.        "\\*C\\(*O",                          /* C4  Ormicron/circumflex      */
  1426.        "\\*(RC\\*(IS\\(*w",                  /* C5  omega/rough/circ/iotasub */
  1427.        "\\*C\\(*E",                          /* C6  Eta/circumflex           */
  1428.        "\\*(SG\\(*u",                        /* C7  upsilon/smooth/grave     */
  1429.        "\\*G\\(*O",                          /* C8  Ormicron/grave           */
  1430.        "\\*S\\(*w",                          /* C9  omega/smooth             */
  1431.        "\\*G\\(*U",                          /* CA  Upsilon/grave            */
  1432.        "\\*G\\(*A",                          /* CB  Alpha/grave              */
  1433.        "\\*C\\(*A",                          /* CC  Alpha/circumflex         */
  1434.        "\\*G\\(*W",                          /* CD  Omega/grave              */
  1435.        "\\*C\\*(IS\\(*w",                    /* CE  omega/circ/iotasub       */
  1436.        "\\*C\\(*I",                          /* CF  Iota/circumflex          */
  1437.  
  1438.        "\\-",                                /* D0  dash                     */
  1439.        "\\*(RA\\*(IS\\(*w",                  /* D1  omega/rough/acute/iotasub*/
  1440.        "\\*(SA\\*(IS\\(*w",                  /* D2  omega/smooth/acute/iotas */
  1441.        "\\*(SG\\*(IS\\(*w",                  /* D3  omega/smooth/grave/iotas */
  1442.        "\\*(RG\\*(IS\\(*w",                  /* D4  omega/rough/grave/iotasub*/
  1443.        "\\*G\\*(IS\\(*w",                    /* D5  omega/grave/iotasub      */
  1444.        "\\*A\\*(IS\\(*w",                    /* D6  omega/acute/iotasub      */
  1445.        "\\*G\\(*Y",                          /* D7  Eta/grave                */
  1446.  
  1447.        "\\*G\\(*I",                          /* D8  Iota/grave               */
  1448.        "\\*G\\(*E",                          /* D9  Epsilon/grave            */
  1449.        "\\*C\\(*U",                          /* DA  Upsilon/circumflex       */
  1450.        "\\*A\\(*W",                          /* DB  Omega/acute              */
  1451.        "\\*A\\(*U",                          /* DC  Upsilon/acute            */
  1452.        "\\*A\\(*O",                          /* DD  Ormicron/acute           */
  1453.        "\\*A\\(*I",                          /* DE  Iota/acute               */
  1454.        "\\*C\\*(IS\\(*e",                    /* DF  eta/circumflex/iotasub   */
  1455.  
  1456.        "\\*R\\*(IS\\(*w",                    /* E0  omega/rough/iotasub      */
  1457.        "\\*(RC\\(*u",                        /* E1  upsilon/rough/circumflex */
  1458.        "\\*(SC\\(*u",                        /* E2  upsilon/smooth/circumflex*/
  1459.        "\\*(SG\\(*o",                        /* E3  ormicron/smooth/grave    */
  1460.        "\\*(SA\\(*o",                        /* E4  ormicron/smooth/acute    */
  1461.        "\\*(RA\\(*o",                        /* E5  ormicron/rough/acute     */
  1462.        "\\*(RC\\(*o",                        /* E6  ormicron/rough/circumflex*/
  1463.        "\\*(SC\\(*o",                        /* E7  ormicron/smooth/circum   */
  1464.        "\\*(SC\\(*y",                        /* E8  eta/smooth/circumflex    */
  1465.        "\\*(RC\\(*y",                        /* E9  eta/rough/circumflex     */
  1466.        "\\*(RC\\(*i",                        /* EA  iota/rough/circumflex    */
  1467.        "\\*G\\(*u",                          /* EB  upsilon/grave            */
  1468.        "\\*(RC\\(*e",                        /* EC  epsilon/rough/circumflex */
  1469.        "\\*(SC\\(*e",                        /* ED  epsilon/smooth/circumflex*/
  1470.        "\\*(RC\\(*a",                        /* EE  alpha/rough/circumflex   */
  1471.        "\\*(SC\\(*a",                        /* EF  alpha/smooth/circumflex  */
  1472.  
  1473.        "\\*R\\(*r",                          /* F0  rho/rough                */
  1474.        "\\*(RC\\(*w",                        /* F1  omega/rough/circumflex   */
  1475.        "\\*(SC\\(*w",                        /* F2  omega/smooth/circumflex  */
  1476.        "\\*(SG\\(*w",                        /* F3  omega/smooth/grave       */
  1477.        "\\*(SA\\(*w",                        /* F4  omega/smooth/acute       */
  1478.        "\\*(RG\\(*w",                        /* F5  omega/rough/grave        */
  1479.        "\\*(RA\\(*w",                        /* F6  omega/rough/acute        */
  1480.        "\\*C\\(*w",                          /* F7  omega/circumflex         */
  1481.        "\\*G\\(*w",                          /* F8  omega/grave              */
  1482.        "\\*A\\(*w",                          /* F9  omega/acute              */
  1483.        "\\*(IS\\(*y",                        /* FA  eta/iotasub              */
  1484.        "\\*R\\(*w",                          /* FB  omega/rough              */
  1485.        "\\*A\\(*Y",                          /* FC  Eta/acute                */
  1486.        "\\*C\\(*e",                          /* FD  epsilon/circumflex       */
  1487.        "\\*C\\(*E",                          /* FE  Epsilon/circumflex       */
  1488.        "\\(bu"                               /* FF  MISSING CHAR             */
  1489.  
  1490.                          };
  1491.  
  1492.  
  1493. /*
  1494. ** FilterText ==> TROFF
  1495. **
  1496. ** In the processing for the TROFF dependent FilterText, we first check
  1497. ** to see if fontNum is equal to any special fonts, and if so, set the
  1498. ** appropriate translation tables. If not, then we default to setting
  1499. ** xFormBot to point to stdBot and xFormTop to point at stdTop.
  1500. ** We set xBufPtr to point to xBuf, which is a new output buffer in which
  1501. ** to do our translation. We then loop for each character in the
  1502. ** string, and send it to the appropriate translation table.  After this
  1503. ** loop, we check to make sure that a . or ' is not in the first column
  1504. ** (since these are control word indicators in troff). If one is found,
  1505. ** the troff 0-width character (\&) is prepended. After this, we send
  1506. **
  1507. */
  1508.  
  1509. #define tTop 0x80
  1510. #define SUPERSCRIPT 0x20
  1511. #define SUBSCRIPT   0x40
  1512.  
  1513.     if (fontNum == 14) {
  1514.        xFormBot = greekBot;
  1515.        xFormTop = greekTop;
  1516.    }
  1517.     else {
  1518.        xFormBot = stdBot;
  1519.        xFormTop = stdTop;
  1520.     }
  1521.  
  1522.     xBufPtr = xBuf;
  1523.     for (strg = p; *strg != 0; strg++) {
  1524.        if (*strg < tTop) {              /* 0x00 - 0x7f */
  1525.           strcpy(xBufPtr,xFormBot[*strg]);
  1526.           xBufPtr += strlen(xFormBot[*strg]);
  1527.        }
  1528.        else {                           /* 0x80 - 0xff */
  1529.           strcpy(xBufPtr,xFormTop[*strg - tTop]);
  1530.           xBufPtr += strlen(xFormTop[*strg - tTop]);
  1531.        }
  1532.     }
  1533.  
  1534.     *xBufPtr = 0;        /* null terminate the string */
  1535.  
  1536.     if (xBuf[0] == '.' || xBuf[0] == '\'')
  1537.                          /* don't allow . or ' in column 1 to be treated */
  1538.        printf("\\&");    /* as the control word indicator                */
  1539.  
  1540.     if (fontStyle & SUBSCRIPT)
  1541.         DocPrintSubSuper(xBuf,SUBSCRIPT,lastLine);
  1542.     else if (fontStyle & SUPERSCRIPT)
  1543.         DocPrintSubSuper(xBuf,SUPERSCRIPT,lastLine);
  1544.     else
  1545.         printf("%s",xBuf);
  1546.  
  1547.     if (!lastLine)
  1548.        printf("\\c\n");
  1549. }
  1550. #endif
  1551.  
  1552. #ifdef WSCRIPT
  1553. {
  1554.     register BYTE *strg;
  1555.     static BYTE xBuf[1024];   /* holds translated string */
  1556.     BYTE *xBufPtr;
  1557.     char **xFormTop, **xFormBot;
  1558.     static char *stdBot[] = {
  1559.        "\000","\001","\002","\003","\004","\005","\006","\007",
  1560.        "\010","|T",  "\012","\013","\014","\n",  "\016","\017",/* TAB, CR */
  1561.        "\020","\021","\022","\023","\024","\025","\026","\027",
  1562.        "\030","\031","\032","\033","\034","\035","\036","\037",
  1563.        " ",   "!",   "\"",  "#",   "$",   "%",   "|Y",  "'",   /* &       */
  1564.        "(",   ")",   "*",   "+",   ",",   "-",   "|e",  "/",   /* .       */
  1565.        "0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
  1566.        "8",   "9",   ":",   ";",   "<",   "=",   ">",   "?",
  1567.        "@",   "A",   "B",   "C",   "D",   "E",   "F",   "G",
  1568.        "H",   "I",   "J",   "K",   "L",   "M",   "N",   "O",
  1569.        "P",   "Q",   "R",   "S",   "T",   "U",   "V",   "W",
  1570.        "X",   "Y",   "Z",   "[",   "\\",  "]",   "|I",  "_",   /* ^       */
  1571.        "|G",  "a",   "b",   "c",   "d",   "e",   "f",   "g",   /* `       */
  1572.        "h",   "i",   "j",   "k",   "l",   "m",   "n",   "o",
  1573.        "p",   "q",   "r",   "s",   "t",   "u",   "v",   "w",
  1574.        "x",   "y",   "z",   "{",   "|",   "}",   "|N",  "\177"};/* ~      */
  1575.  
  1576.     static char *stdTop[] = {           /* Std Mac characters 0x80 - 0xff    */
  1577.                         "A|B&S'|U.",    /* 80              A umlaut          */
  1578.                         "A|B&x'A1.",    /* 81              A angstrom        */
  1579.                         "C|B&x'76.",    /* 82              C cedilla         */
  1580.                         "E|B&S'|E.",    /* 83              E acute           */
  1581.                         "N|B&S'|N.",    /* 84              N tilde           */
  1582.                         "O|B&S'|U.",    /* 85              O umlaut          */
  1583.                         "U|B&S'|U.",    /* 86              U umlaut          */
  1584.                         "a|B|E",        /* 87              a acute           */
  1585.                         "a|B|G",        /* 88              a grave           */
  1586.                         "a|B|I",        /* 89              a circumflex      */
  1587.                         "a|B|U",        /* 8A              a umlaut          */
  1588.                         "a|B|N",        /* 8B              a tilde           */
  1589.                         "a|B&x'A1.",    /* 8C              a angstrom        */
  1590.                         "c|B&x'76.",    /* 8D              c cedilla         */
  1591.                         "e|B|E",        /* 8E              e acute           */
  1592.                         "e|B|G",        /* 8F              e grave           */
  1593.  
  1594.                         "e|B|I",        /* 90              e circumflex      */
  1595.                         "e|B|U",        /* 91              e umlaut          */
  1596.                         "i|B|U",        /* 92              i acute           */
  1597.                         "i|B|G",        /* 93              i grave           */
  1598.                         "i|B|I",        /* 94              i circumflex      */
  1599.                         "i|B|U",        /* 95              i umlaut          */
  1600.                         "n|B|N",        /* 96              n tilde           */
  1601.                         "o|B|E",        /* 97              o acute           */
  1602.                         "o|B|G",        /* 98              o grave           */
  1603.                         "o|B|I",        /* 99              o circumflex      */
  1604.                         "o|B|U",        /* 9A              o umlaut          */
  1605.                         "o|B|N",        /* 9B              o tilde           */
  1606.                         "u|B|E",        /* 9C              u acute           */
  1607.                         "u|B|G",        /* 9D              u grave           */
  1608.                         "u|B|I",        /* 9E              u circumflex      */
  1609.                         "u|B|U",        /* 9F              u umlaut          */
  1610.  
  1611.                          "|t",            /* A0      |t      dagger            */
  1612.                          "|*",            /* A1      |*      degree            */
  1613.                          "|4",            /* A2      |4      cent sign         */
  1614.                          "|3",            /* A3      |3      british pound sign*/
  1615.                          "|6",            /* A4      |6      section           */
  1616.                          "|8",            /* A5      |8      bullet            */
  1617.                          "|7",            /* A6      |7      paragraph         */
  1618.                          "|s",            /* A7      |s      beta              */
  1619.                          "|r",            /* A8      |r      registered        */
  1620.                          "|g",            /* A9      |g      copyright         */
  1621.                          "&S'TM.",        /* AA      |2      TM (missing)      */
  1622.                          "|E",            /* AB      |E      accent acute      */
  1623.                          "|U",            /* AC      |U      umlaut            */
  1624.                          "|=",            /* AD      |=      not equals        */
  1625.                          "|\"",           /* AE      |"      AE                */
  1626.                          "O|B/",          /* AF      |O      O slash           */
  1627.  
  1628.                          "|5",            /* B0      |5      infinity          */
  1629.                          "|+",            /* B1      |+      plus minus        */
  1630.                          "|,",            /* B2      |,      <=                */
  1631.                          "|.",            /* B3      |.      >=                */
  1632.                          "|y",            /* B4      |y      antenna?          */
  1633.                          "|[",            /* B5      |[      mu                */
  1634.                          "|d",            /* B6      |d      lowercase delta   */
  1635.                          "|w",            /* B7      |w      sigma             */
  1636.                          "|P",            /* B8      |P      uppercase pi      */
  1637.                          "|p",            /* B9      |p      lowercase pi      */
  1638.                          "|b",            /* BA      |b      integral          */
  1639.                          "a|B&x'6D.",     /* BB      |9      a underscore      */
  1640.                          "o|B&x'6D.",     /* BC      |0      o underscore      */
  1641.                          "|z",            /* BD      |z      omega             */
  1642.                          "|'",            /* BE      |'      ae                */
  1643.                          "o|B/",          /* BF      |o      o slash           */
  1644.  
  1645.                          "|?",            /* C0      |?      spanish ?         */
  1646.                          "|!",            /* C1      |!      spanish !         */
  1647.                          "|l",            /* C2      |l      not sign          */
  1648.                          "|v",            /* C3      |v      square root       */
  1649.                          "|f",            /* C4      |f      script f          */
  1650.                          "|x",            /* C5      |x      equivalent        */
  1651.                          "|j",            /* C6      |j      uppercase delta   */
  1652.                          "|>",            /* C7      |\      >> (|| illegal)   */
  1653.                          "|<",            /* C8      |<      << (|\ illegal)   */
  1654.                         "...",          /* C9              ellipsis          */
  1655.                         "|S",           /* CA      |S      nonbreaking space */
  1656.                         "A|B&S'|G.",    /* CB              A grave           */
  1657.                         "A|B&S'|N.",    /* CC              A tilde           */
  1658.                         "O|B&S'|N.",    /* CD              O tilde           */
  1659.                         "|Q",           /* CE      |Q      OE                */
  1660.                         "|q",           /* CF      |q      oe                */
  1661.  
  1662.                         "|-",           /* D0      |-      small dash        */
  1663.                         "|_",           /* D1      |_      large dash        */
  1664.                         "|[",           /* D2      |[      open "            */
  1665.                         "|{",           /* D3      |{      close "           */
  1666.                         "|]",           /* D4      |]      open '            */
  1667.                         "|}",           /* D5      |}      close '           */
  1668.                         "|/",           /* D6      |/      division sign     */
  1669.                         "|V",           /* D7      |V      diamond           */
  1670.                         "\\y\\:",       /* D8              y umlaut          */
  1671.  
  1672.                         "|M",             /* D9      MISSING CHAR             */
  1673.                         "|M",             /* DA      MISSING CHAR             */
  1674.                         "|M",             /* DB      MISSING CHAR             */
  1675.                         "|M",             /* DC      MISSING CHAR             */
  1676.                         "|M",             /* DD      MISSING CHAR             */
  1677.                         "|M",             /* DE      MISSING CHAR             */
  1678.                         "|M",             /* DF      MISSING CHAR             */
  1679.  
  1680.                         "|M",             /* F0      MISSING CHAR             */
  1681.                         "|M",             /* E1      MISSING CHAR             */
  1682.                         "|M",             /* E2      MISSING CHAR             */
  1683.                         "|M",             /* E3      MISSING CHAR             */
  1684.                         "|M",             /* E4      MISSING CHAR             */
  1685.                         "|M",             /* E5      MISSING CHAR             */
  1686.                         "|M",             /* E6      MISSING CHAR             */
  1687.                         "|M",             /* E7      MISSING CHAR             */
  1688.  
  1689.                         "|M",             /* E8      MISSING CHAR             */
  1690.                         "|M",             /* E9      MISSING CHAR             */
  1691.                         "|M",             /* EA      MISSING CHAR             */
  1692.                         "|M",             /* EB      MISSING CHAR             */
  1693.                         "|M",             /* EC      MISSING CHAR             */
  1694.                         "|M",             /* ED      MISSING CHAR             */
  1695.                         "|M",             /* EE      MISSING CHAR             */
  1696.                         "|M",             /* EF      MISSING CHAR             */
  1697.  
  1698.                         "|M",             /* F0      MISSING CHAR             */
  1699.                         "|M",             /* F1      MISSING CHAR             */
  1700.                         "|M",             /* F2      MISSING CHAR             */
  1701.                         "|M",             /* F3      MISSING CHAR             */
  1702.                         "|M",             /* F4      MISSING CHAR             */
  1703.                         "|M",             /* F5      MISSING CHAR             */
  1704.                         "|M",             /* F6      MISSING CHAR             */
  1705.                         "|M",             /* F7      MISSING CHAR             */
  1706.  
  1707.                         "|M",             /* F8      MISSING CHAR             */
  1708.                         "|M",             /* F9      MISSING CHAR             */
  1709.                         "|M",             /* FA      MISSING CHAR             */
  1710.                         "|M",             /* FB      MISSING CHAR             */
  1711.                         "|M",             /* FC      MISSING CHAR             */
  1712.                         "|M",             /* FD      MISSING CHAR             */
  1713.                         "|M",             /* FE      MISSING CHAR             */
  1714.                         "|M"              /* FF      MISSING CHAR             */
  1715.  
  1716.                          };
  1717.  
  1718. #define tTop             0x80
  1719. #define SUPERSCRIPT 0x20
  1720. #define SUBSCRIPT   0x40
  1721.  
  1722.     xFormBot = stdBot;          /* use standard ASCII for 0x00 - 0x7f */
  1723.     xFormTop = stdTop;          /* use std Mac chars for 0x80 - 0xff  */
  1724.  
  1725.     xBufPtr = xBuf;
  1726.     for (strg = p; *strg != 0; strg++) {
  1727.        if (*strg < tTop) {              /* 0x00 - 0x7f */
  1728.           strcpy(xBufPtr,xFormBot[*strg]);
  1729.           xBufPtr += strlen(xFormBot[*strg]);
  1730.        }
  1731.        else {                           /* 0x80 - 0xff */
  1732.           strcpy(xBufPtr,xFormTop[*strg - tTop]);
  1733.           xBufPtr += strlen(xFormTop[*strg - tTop]);
  1734.        }
  1735.     }
  1736.  
  1737.     *xBufPtr = 0;        /* null terminate the string */
  1738.  
  1739.     if (fontStyle & SUBSCRIPT)
  1740.         DocPrintSubSuper(xBuf,SUBSCRIPT,lastLine);
  1741.     else if (fontStyle & SUPERSCRIPT)
  1742.         DocPrintSubSuper(xBuf,SUPERSCRIPT,lastLine);
  1743.     else if (strlen(xBuf) == 1 && xBuf[0] == '\n')
  1744.         printf(" \n");
  1745.     else
  1746.         printf("%s",xBuf);
  1747.  
  1748.     if (!lastLine)
  1749.        printf("\\\n");
  1750. }
  1751. #endif
  1752.  
  1753. /*
  1754. ** GetPictureData()
  1755. **
  1756. ** GetPictureData simply reads in the number of bytes specified in the
  1757. ** picture's data header. Since MacWrite uses blank pictures for creating
  1758. ** page advances, all this routine does is call the DocPageAdvance. This means
  1759. ** that currently, each time a picture is hit (even if it is a bitmap and
  1760. ** NOT a page advance, a page advance code will be put in).
  1761. **
  1762. **      Called by:      GetParagraphData
  1763. **      Calls:          DocPageAdvance [backend]
  1764. **      Parms:          <none>
  1765. **      Returns:        <none>
  1766. **
  1767. */
  1768.  
  1769. GetPictureData()
  1770.  
  1771. {
  1772. #ifdef DEBUG
  1773.    fprintf(stderr,"This is a PICTURE\n");
  1774. #endif
  1775.    readBuf(pDataHead.length);
  1776.  
  1777.    DocPageAdvance();
  1778. }
  1779.  
  1780. /*
  1781. ** ProcessRulerData
  1782. **
  1783. ** Upon finding RULER paragraph, ProcessRulerData is called to interpret
  1784. ** the ruler settings and call the appropriate backend functions. It
  1785. ** calls DocMarginRight and DocMargin left with the ruler settings divided
  1786. ** by 80, since the data is stored in 1/80ths of an inch and the backend
  1787. ** expects inches. Line spacing is called with the standard setting (0=
  1788. ** single spacing, 1 = 1-1/2 spacing, 2 = double spacing.
  1789. **
  1790. */
  1791.  
  1792. ProcessRulerData()
  1793.  
  1794. {
  1795.     register int j;
  1796.  
  1797.     DocMarginRight(rulerRec.rightMargin/80.0);
  1798.     DocMarginLeft(rulerRec.leftMargin/80.0);
  1799.  
  1800.     DocLineSpacing(rulerRec.spacing);
  1801.  
  1802.     DocTabProlog();
  1803.  
  1804.     /* MacWrite treats l. marg as tab */
  1805.     if (rulerRec.indentMargin < rulerRec.leftMargin)
  1806.        DocTabReg(rulerRec.leftMargin/80.0,rulerRec.leftMargin/80.0,
  1807.           rulerRec.indentMargin/80.0);
  1808.  
  1809.     for (j = 0; j < rulerRec.numberOfTabs; j++)
  1810.        if (rulerRec.tabs[j] >= 0)
  1811.           DocTabReg(rulerRec.tabs[j]/80.0,rulerRec.leftMargin/80.0,
  1812.              rulerRec.indentMargin/80.0);
  1813.       else
  1814.           DocTabDecimal(-rulerRec.tabs[j]/80.0,rulerRec.leftMargin/80.0,
  1815.              rulerRec.indentMargin/80.0);
  1816.  
  1817.     DocTabEpilog();
  1818.  
  1819.     DocAdjust(rulerRec.justification);
  1820.  
  1821. }
  1822.  
  1823. DocAdjust(adjType)
  1824.  
  1825. BYTE adjType;
  1826.  
  1827. {
  1828. #ifdef TROFF
  1829.     static char *adjString[4] = {"l","c","r","b"};
  1830.  
  1831.     printf(".ad %s\n", adjString[adjType]);
  1832. #endif
  1833.  
  1834. #ifdef WSCRIPT
  1835.     static char *adjString[4] = {"left","center","right","on"};
  1836.  
  1837.     printf(".ju %s\n", adjString[adjType]);
  1838. #endif
  1839. }
  1840.  
  1841. DocEpilog()
  1842.  
  1843. {
  1844. #ifdef TROFF
  1845.         printf("\n");
  1846. #endif
  1847. }
  1848.  
  1849. DocHeaderEpilog()
  1850.  
  1851. {
  1852. #ifdef WSCRIPT
  1853.    printf(".hn end\n");
  1854. #endif
  1855. }
  1856.  
  1857. DocHeaderProlog()
  1858.  
  1859. {
  1860. #ifdef WSCRIPT
  1861.    printf(".hn begin\n");
  1862. #endif
  1863. }
  1864.  
  1865. /*
  1866. **
  1867. ** DocLineSpacing
  1868. **
  1869. ** Create a line for spacing. MacWrite uses 0 for single spacing,
  1870. ** 1 for 1 1/2 spacing, 2 for double spacing.
  1871. **
  1872. ** We must add 1 for corresponding troff setting.
  1873. ** WScript doesn't support 1 1/2 space. We must also
  1874. ** put in .sp since MacWrite adds the line spacing before any
  1875. ** lines are output.
  1876. **
  1877. */
  1878.  
  1879. DocLineSpacing(spacing)
  1880.  
  1881. BYTE spacing;
  1882.  
  1883. {
  1884. #ifdef TROFF
  1885.     printf(".ls %d\n", spacing);
  1886.     printf(".sp %d\n", spacing);
  1887. #endif
  1888.  
  1889. #ifdef WSCRIPT
  1890.     if (spacing > 1) spacing = 1;  /* treat 1 1/2 and double space the same */
  1891.     printf(".ls %d\n", spacing);
  1892.     printf(".sp %d A\n", spacing);
  1893. #endif
  1894. }
  1895.  
  1896. /*
  1897. **
  1898. ** DocMarginLeft
  1899. **
  1900. ** MacWrite calculates all measurements relative to a fixed zero point
  1901. ** which happens to be located at the 1" mark on the ruler. The left
  1902. ** margin, therefore, is really an indent from that zero point, and we
  1903. ** treat is as such here.
  1904. **
  1905. */
  1906.  
  1907. DocMarginLeft(left)
  1908.  
  1909. float left;
  1910.  
  1911. {
  1912. #ifdef TROFF
  1913.     printf(".ti 0\n.in %.3fi\n", left);
  1914. #endif
  1915.  
  1916. #ifdef WSCRIPT
  1917.     printf(".il 0;.in %.3fi\n", left);
  1918. #endif
  1919. }
  1920.  
  1921. DocMarginRight(right)
  1922.  
  1923. float right;
  1924.  
  1925. {
  1926. #ifdef TROFF
  1927.     printf(".ll %.3fi\n",right);
  1928. #endif
  1929.  
  1930. #ifdef WSCRIPT
  1931.     printf(".ll %.3fi\n",right);
  1932. #endif
  1933. }
  1934.  
  1935. DocPageAdvance()
  1936. {
  1937. #ifdef TROFF
  1938.    printf(".bp\n");
  1939. #endif
  1940.  
  1941. #ifdef WSCRIPT
  1942.    printf(".pa\n");
  1943. #endif
  1944. }
  1945.  
  1946. DocParaEpilog()
  1947. {
  1948. #ifdef TROFF
  1949. /* printf(".br\n"); */
  1950. #endif
  1951.  
  1952. #ifdef WSCRIPT
  1953. /* printf(".br\n"); */
  1954. #endif
  1955. }
  1956.  
  1957. DocParaProlog(indent)
  1958.  
  1959. float indent;
  1960.  
  1961. {
  1962. #ifdef TROFF
  1963.     if (indent >= 0)
  1964.        printf(".ti +%.3fi\n", indent); /* need to put in + size for relative */
  1965.     else
  1966.        printf(".ti %.3fi\n", indent);  /* minus sign already for relative */
  1967. #endif
  1968.  
  1969. #ifdef WSCRIPT
  1970.    printf(".br;.il 0;.il %.3fi\n", indent);
  1971. #endif
  1972.  
  1973. }
  1974.  
  1975. DocPrintSubSuper(strg,flag,lastLine)
  1976.  
  1977. char *strg;             /* text to print                   */
  1978. unsigned char flag;
  1979. int lastLine;
  1980.  
  1981. #ifdef TROFF
  1982. {
  1983.    char *prefix;                /* superscript or subscript prefix */
  1984.    char *suffix;                /* superscript or subscript suffix */
  1985.  
  1986.    if (flag == SUBSCRIPT) {
  1987.       prefix = "\\*<";
  1988.       suffix = "\\*>";
  1989.     }
  1990.     else {
  1991.        prefix = "\\*[";
  1992.        suffix = "\\*]";
  1993.     }
  1994.  
  1995.     printf("%s%s%s",prefix,strg,suffix);
  1996.     if (lastLine) printf ("\n");
  1997. }
  1998. #endif
  1999.  
  2000. #ifdef WSCRIPT
  2001. {
  2002.     register char *chase, *p;
  2003.     char *prefix;               /* superscript or subscript prefix */
  2004.  
  2005.     if (flag == SUBSCRIPT)
  2006.         prefix = "&s'";
  2007.     else
  2008.         prefix = "&S'";
  2009.  
  2010.     p = strg;
  2011.  
  2012.     if (strlen(p) < 1) return;  /* sub/superscripts of null strgs don't work */
  2013.  
  2014.     chase = p;
  2015.  
  2016.     while (*p != 0) {
  2017.        while (*chase == ' ') { /* no blanks in superscripts, just write out */
  2018.           printf("%c",' ');
  2019.           p++;
  2020.           chase++;
  2021.        }
  2022.        while (*chase != 0 && *chase != ' ') chase++;
  2023.  
  2024.        if (*chase != 0) {
  2025.           *chase = 0;
  2026.           printf("%s%s.",prefix,p);
  2027.           *chase = ' ';
  2028.        }
  2029.        else if (*p != 0) /* if *p = 0, then blanking above exhausted the str */
  2030.           printf("%s%s.",prefix,p);
  2031.  
  2032.        p = chase;
  2033.    }
  2034.  
  2035. }
  2036. #endif
  2037.  
  2038. DocProlog(version)
  2039.  
  2040. char *version;                          /* current version string */
  2041. {
  2042. #ifdef TROFF
  2043.    /* The following are troff statements for local motion to generate   */
  2044.    /* diacritics, generously provided by Greg Crane, Dept. of Classics, */
  2045.    /* Harvard University.                                               */
  2046.  
  2047.    static char * smoothcirc = "\\v'-.3n'\\z~\\v'.1n'\\h'.2n'\\z'\\v`.2n'\\h'-.2n'";
  2048.    static char * smoothgrave = "\\v'-.2n'\\z'\\h'.4n'\\z\\(ga\\v'.2n'\\h'-.4n'";
  2049.    static char * smoothacute = "\\v'-.2n'\\z'\\h'.1n'\\z\\(aa\\v'.2n'\\h'-.1n'";
  2050.  
  2051.    static char * iotasub = "\\v'.8n'\\s-4\\z\\(*i\\s+4\\v'-.8n'";
  2052.  
  2053.    static char * roughcirc = "\\v'-.3n'\\z~\\v'.1n'\\h'.2n'\\z`\\v'.2n'\\h'-.2n'";
  2054.    static char * roughgrave = "\\v'-.2n'\\z`\\h'.3n'\\z\\(ga\\v'.2n'\\h'-.3n'";
  2055.    static char * roughacute = "\\v'-.2n'\\z`\\h'.1n'\\z\\(aa\\v'.2n'\\h'-.1n'";
  2056.  
  2057.    static char * acute = "\\v'-.1n'\\z\\(aa\\v'.1n'";
  2058.    static char * grave = "\\v'-.1n'\\z\\(ga\\v'.1n'";
  2059.    static char * rough = "\\v'-.2n'\\z`\\v'.2n'";
  2060.    static char * smooth = "\\v'-.2n'\\z'\\v'.2n'";
  2061.    static char * circum = "\\v'-.1n'\\z~\\v'.1n'";
  2062.  
  2063.    static char * upperAcute = "\\v'-.5n'\\h'.1n'\\z\\(aa\\v'.5n'\\h'-.1n'";
  2064.    static char * upperGrave = "\\v'-.5n'\\h'.1n'\\z\\(ga\\v'.5n'\\h'-.1n'";
  2065.    static char * upperRough = "\\v'-.6n'\\h'.1n'\\z`\\v'.6n'\\h'-.1n'";
  2066.    static char * upperSmooth = "\\v'-.6n'\\h'.1n'\\z'\\v'.6n'\\h'-.1n'";
  2067.    static char * upperCircum = "\\v'-.5n'\\h'.1n'\\z~\\v'.5n'\\h'-.1n'";
  2068.    static char * upperDiaeresis = "\\v'-1.5n'\\z.\\h'.4n'\\z.\\h'-.4n'\\v'1.5n'";
  2069.  
  2070.    static char * diaeresis = "\\v'-1n'\\z.\\h'.4n'\\z.\\h'-.4n'\\v'1n'";
  2071.    static char * diaergrave = "\\v'-1n'\\z.\\h'.1n'\\v'.7n'\\z\\`\\v'-.7n'\\h'.5n'\\z.\\h'-.6n'\\v'1n'";
  2072.    static char * diaeracute = "\\v'-1n'\\z.\\h'.1n'\\v'.7n'\\z\\'\\v'-.7n'\\h'.5n'\\z.\\h'-.6n'\\v'1n'";
  2073.  
  2074.    static char * hidot = "\\v'-.7n'.\\v'.7n'";
  2075.  
  2076.    static char * hat = "\\v'-.1n'\\z^\\v'.1n'";
  2077.    static char * angstrom = "\\v'-.1n'\\z\\(de\\v'.1n'";
  2078.    static char * cedilla = "\\v'.1n'\\h'.5n'\\s-4\\z,\\s+4\\h'-.5n'\\v'-.1n'";
  2079.  
  2080.    static char * terminalSigma = "\\v'.2n'\\h'.5n'\\s-4\\z,\\s+4\\h'-.5n\\v'-.2n'\fIc\fP";
  2081.    static char * approx = "\\v'-.6n'\\z~\\v'.6n'~";
  2082.  
  2083.  
  2084.    printf("\\\" mwtroff version %s\n.po .5in\n.tp\n",version);  /* margin starts at 1" per MacWrite */
  2085.  
  2086.    printf(".ds SC %s\n",smoothcirc);
  2087.    printf(".ds SG %s\n",smoothgrave);
  2088.    printf(".ds SA %s\n",smoothacute);
  2089.  
  2090.    printf(".ds IS %s\n",iotasub);
  2091.  
  2092.    printf(".ds RC %s\n", roughcirc);
  2093.    printf(".ds GC %s\n", roughgrave);
  2094.    printf(".ds RA %s\n", roughacute);
  2095.  
  2096.    printf(".ds A %s\n",acute);
  2097.    printf(".ds R %s\n",rough);
  2098.    printf(".ds G %s\n",grave);
  2099.    printf(".ds S %s\n",smooth);
  2100.    printf(".ds C %s\n",circum);
  2101.  
  2102.    printf(".ds D %s\n",diaeresis);
  2103.    printf(".ds DG %s\n",diaergrave);
  2104.    printf(".ds DA %s\n",diaeracute);
  2105.  
  2106.    printf(".ds HI %s\n",hidot);
  2107.  
  2108.    printf(".ds AN %s\n",angstrom);
  2109.    printf(".ds CE %s\n",cedilla);
  2110.    printf(".ds H %s\n",hat);
  2111.  
  2112.    printf(".ds UA %s\n",upperAcute);
  2113.    printf(".ds UR %s\n",upperRough);
  2114.    printf(".ds UG %s\n",upperGrave);
  2115.    printf(".ds US %s\n",upperSmooth);
  2116.    printf(".ds UC %s\n",upperCircum);
  2117.    printf(".ds UD %s\n",upperDiaeresis);
  2118.  
  2119.    printf(".ds TS %s\n",terminalSigma);
  2120.    printf(".ds AP %s\n",approx);
  2121.  
  2122. #endif
  2123.  
  2124.  
  2125. #ifdef WSCRIPT
  2126.    printf(".* mwscript version %s\n.im mwprof\n",version);  /* file containing script char translations    */
  2127. #endif
  2128. }
  2129.  
  2130. DocTabDecimal(stop,left,indent)
  2131.  
  2132. float   stop;
  2133. float   left;
  2134. float   indent;
  2135. {
  2136. #ifdef TROFF
  2137.    if (left == indent)
  2138.       printf("%.3fiR ",stop-left);
  2139.    else
  2140.       printf("%.3fiR ",stop-indent);
  2141. #endif
  2142.  
  2143. #ifdef WSCRIPT
  2144.    register int propSpace;      /* SCRIPT expects tabs as fixed char offsets */
  2145.                                 /* based upon its CPI value (use 32)         */
  2146.    propSpace = stop * 32 + 1;
  2147.    if (propSpace > 0)
  2148.       printf("%d'.' ",propSpace);
  2149. #endif
  2150. }
  2151.  
  2152. DocTabEpilog()
  2153.  
  2154. {
  2155. #ifdef TROFF
  2156.    printf("\n");
  2157. #endif
  2158.  
  2159. #ifdef WSCRIPT
  2160.    printf("\n");
  2161. #endif
  2162.  
  2163. }
  2164.  
  2165. DocTabProlog()
  2166.  
  2167. {
  2168. #ifdef TROFF
  2169.    printf(".ta ");
  2170. #endif
  2171.  
  2172. #ifdef WSCRIPT
  2173.    printf(".tb ");
  2174. #endif
  2175. }
  2176.  
  2177. DocTabReg(stop,left,indent)
  2178.  
  2179. float   stop;
  2180. float   left;
  2181. float   indent;
  2182.  
  2183. {
  2184.  
  2185. #ifdef TROFF
  2186.    if (left == indent)
  2187.       printf("%.3fi ",stop-left);
  2188.    else
  2189.       printf("%.3fi ",stop-indent);
  2190. #endif
  2191.  
  2192. #ifdef WSCRIPT
  2193.    register int propSpace;      /* SCRIPT expects tabs as fixed char offsets */
  2194.                                 /* based upon its CPI value  (32)            */
  2195.    propSpace = stop * 32 + 1;
  2196.    if (propSpace > 0)
  2197.       printf("%d ",propSpace);
  2198. #endif
  2199. }
  2200.  
  2201. DocTypeFace(face)
  2202.  
  2203. WORD    face;
  2204.  
  2205. {
  2206.  
  2207. }
  2208.  
  2209. DocTypeSize(size)
  2210.  
  2211. BYTE    size;
  2212.  
  2213. {
  2214. #ifdef TROFF
  2215.     printf("'vs %d\n\\s%d",size/9 + size + 1,size);
  2216. #endif
  2217.  
  2218. #ifdef WSCRIPT
  2219. #endif
  2220.  
  2221. }
  2222.  
  2223. DocTypeStyle(style)
  2224.  
  2225. BYTE    style;
  2226.  
  2227. {
  2228.  
  2229. #ifdef TROFF
  2230. #define numStyles 7
  2231.  
  2232.     register int bitPtr;
  2233.     static char *typeStyle[7][2] = {"\\fR","\\fB",              /* bold   */
  2234.                                         "","\\fI",                  /* italic */
  2235.                                         "","",                      /* unders */
  2236.                                         "","",                      /* outline*/
  2237.                                         "","",                      /* shadow */
  2238.                                         "","",                      /* subscript */
  2239.                                         "",""};                     /* superscr  */
  2240.  
  2241.     for (bitPtr = 0; bitPtr < numStyles; bitPtr++)
  2242.        printf("%s",typeStyle[bitPtr][(style >> bitPtr) & 0x01]);
  2243.  
  2244. #endif
  2245.  
  2246. #ifdef WSCRIPT
  2247. #define numStyles 7
  2248.  
  2249.     register int bitPtr;
  2250.     static char *typeStyle[7][2] = {".bd off;",".bd on;",       /* bold   */
  2251.                                         ".us off;",".us on;",       /* italic */
  2252.                                         "","",                      /* unders */
  2253.                                         "","",                      /* outline*/
  2254.                                         "","",                      /* shadow */
  2255.                                         "","",                      /* subscript */
  2256.                                         "",""};                     /* superscr  */
  2257.  
  2258.     for (bitPtr = 0; bitPtr < numStyles; bitPtr++)
  2259.        printf("%s",typeStyle[bitPtr][(style >> bitPtr) & 0x01]);
  2260.  
  2261.     printf("\n");
  2262. #endif
  2263. }
  2264.  
  2265.