home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Ph 1.1.1 / Lib / cvrt.c next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  25.8 KB  |  962 lines  |  [TEXT/MPS ]

  1. /*______________________________________________________________________
  2.  
  3.     cvrt.c - Tool to Convert a Text File to a Sequence of STR# Resources.
  4.     
  5.     Copyright © 1988-1991 Northwestern University.
  6.     
  7.     This tool is used to prepare text for the report module rep.c
  8.     and the help module hlp.c.
  9.     
  10.     When preparing type 1 reports for the report module rep.c, the wrap tool
  11.     should be run first (with the -p option), then the output of wrap should 
  12.     be processed by cvrt.
  13.     
  14.     cvrt -o file1 -i nnn [-t aaa] [-g bbb] [-c ccc]
  15.         [-p file2 -h xxx -w yyy] [file3]
  16.     
  17.     file1 = output resource file.
  18.     nnn = starting STR# resource id.
  19.     aaa = TCON resource id.
  20.     bbb = TAG resource id.
  21.     ccc = CELL resource id.
  22.     file2 = pict resource file.
  23.     xxx = height of report cells in pixels.
  24.     yyy = width of report cells in pixels.
  25.     file3 = input text file.
  26.     
  27.     The text file is converted to a consecutive sequence of STR# 
  28.     resources starting with id nnn.
  29.     
  30.     The source text is intermixed with special cvrt directives.  Any line 
  31.     starting with the character "\" is treated as a directive.  Directives
  32.     must be all lower case.  The syntax checking by this tool is minimal.
  33.     
  34.     \str#
  35.     
  36.         Starts a new STR# resource.
  37.     
  38.     \tcon title
  39.     
  40.         Table of contents entry.  The title and the current line number
  41.         (zero based) are saved in the TCON resource.
  42.         
  43.     \tag nnn
  44.     
  45.         Tag resource entry.  The number nnn and the current line number
  46.         (zero based) are saved in the TAG resource.
  47.         
  48.     \style xxx xxx xxx
  49.  
  50.         The next text line is drawn in the specified style or styles.  xxx may
  51.         be any of the following:
  52.         
  53.         normal    (default)
  54.         bold
  55.         italic
  56.         underline
  57.         outline
  58.         shadow
  59.         condense
  60.         extend
  61.         
  62.     \just xxx
  63.     
  64.         The next text line or picture is drawn with the specified justification.
  65.         xxx may be any of the following:
  66.         
  67.         left        (default for text lines)
  68.         center    (default for pictures)
  69.         right
  70.         
  71.     \size xxx
  72.     
  73.         Print the following line of text xxx% larger than normal.  Printing
  74.         only.  The normal font size is multiplied by xxx%, then truncated.  
  75.         For non-laserwriters it is then rounded down to the nearest font
  76.         size which can be printed without Font Manager scaling. 
  77.         
  78.     \only xxx xxx
  79.     
  80.         The next text line or picture or table of contents entry should only 
  81.         be output as specified.  xxx may be any of the following:
  82.         
  83.         screen    Only in the report on the screen.
  84.         print        Only in the printed document.
  85.         save        Only in the saved document.
  86.         
  87.         The default for text lines is: screen print save
  88.         The default for pictures is: screen print
  89.         The default for tcon entries is: screen print
  90.     
  91.     \pict id
  92.     
  93.         A picture from the pict resource file should be inserted at this point.
  94.         "id" is the resource id of the pict.
  95.         
  96.     \page noheader
  97.     
  98.         Start a new page.  Printing only.  The "noheader" parameter is 
  99.         optional.  If the parameter is present, header printing is disabled
  100.         until the next \page directive is encountered.
  101.         
  102.     \keep
  103.     
  104.         Keep the following block of text on the same page.  Force a page
  105.         break if necessary.  Printing only.  Paragraphs are always kept
  106.         on a page, never split across page boundaries.
  107.         
  108.     \endkeep
  109.     
  110.         End a keep block.  Printing only.
  111.         
  112.     \itcon nnn
  113.     
  114.         Insert table of contents.  Printing only.
  115.         
  116.         nnn = total number of printing tcon entries.  This number must be
  117.         adjusted by hand whenever you add or remove tcon entries (sorry). It
  118.         is verified at the end of the cvrt run, and if it is incorrect the
  119.         correct value is printed in an error message (this helps a bit).
  120.         
  121.     Some of the  directives above cause escape sequences to be generated at 
  122.     the beginnings of lines in the STR# resources.  These escape sequences 
  123.     have the following common format:
  124.     
  125.         byte 0 = escape code = a small number less than 31.
  126.         byte 1 = number of bytes in the escape sequence.
  127.         remaining bytes = parameters.
  128.         
  129.     The following escape sequences are used:
  130.     
  131.     Style:
  132.     
  133.         byte 0 = docStyle = 0
  134.         byte 1 = 3
  135.         byte 2 = style
  136.         
  137.     Justification:
  138.     
  139.         byte 0 = docJust = 1
  140.         byte 1 = 3
  141.         byte 2 = justification:
  142.             0 = Left
  143.             1 = Center
  144.             2 = Right
  145.             
  146.     Size:
  147.     
  148.         byte 0 = docSize = 2
  149.         byte 1 = 4
  150.         bytes 2,3 = percent size change
  151.             
  152.     Only:
  153.     
  154.         byte 0 = docOnly = 3
  155.         byte 1 = 3
  156.         byte 2 = flags
  157.             bit 0 = Screen
  158.             bit 1 = Print
  159.             bit 2 = Save
  160.             
  161.     Pict:
  162.     
  163.         byte 0 = docPict = 4
  164.         byte 1 = 6
  165.         bytes 2,3 = PICT resource id
  166.         bytes 4,5 = band number
  167.         
  168.         For pictures multiple lines are output to the STR# resource, each
  169.         in the format above.  Enough lines are output to completely cover
  170.         the picture in hands of of the same height as the cell height.
  171.         Pictures wider than the (cell width - 8) are scaled so that their
  172.         width is exactly (cell width - 8). The band numbers in the escape 
  173.         sequences increment from 0 to number of bands - 1.
  174.  
  175.     The remaining escape sequences are only used for printing, and they always
  176.     occur on lines by themselves, preceded by on "Only" escape sequence that 
  177.     says the line only applies to printing.
  178.         
  179.     Page:
  180.     
  181.         byte 0 = docPage = 5
  182.         byte 1 = 3
  183.         byte 2 = 1 if noheader param specified, else 0.
  184.         
  185.     Keep:
  186.     
  187.         byte 0 = docKeep = 6
  188.         byte 1 = 2
  189.         
  190.     EndKeep:
  191.     
  192.         byte 0 = docEndKeep = 7
  193.         byte 1 = 2
  194.         
  195.     ITcon:
  196.     
  197.         byte 0 = docITcon = 8
  198.         byte 1 = 3
  199.         byte 2 = tcon line number
  200.         
  201.         For the table of contents multiple lines are output to the STR#
  202.         resource, each in the format above.  A separate line is output for
  203.         each line in the printed table of contents, with the line numbers
  204.         incrementing from 0 to the numbr of entries - 1.
  205.         
  206.     There is one other special escape code, the end-of-paragraph escape
  207.     code 31.  This escape code is not inserted by cvrt, but by the wrap
  208.     tool.  It marks ends of paragraphs.  The printing code in rep.c uses
  209.     these codes when rewrapping paragraphs to new margins.
  210.     
  211.     The TCON resource, if one is generated, has the following format
  212.     (using Rez syntax):
  213.     
  214.     type 'TCON' {
  215.         integer = $$CountOf(list);
  216.         array list {
  217.             integer;                { line number for online doc }
  218.             byte;                    { only code - docScreen, docPrint, or 
  219.                                         docScreen | docPrint }
  220.             pstring;                { table of contents entry }
  221.             align word;
  222.         }
  223.     }
  224.     
  225.     The TAG resource, if one is generated, has the following format
  226.     (using Rez syntax):
  227.     
  228.     type 'TAG ' {
  229.         integer = $$CountOf(list);
  230.         array list {
  231.             integer;                { line number }
  232.             integer;                { tag }
  233.         }
  234.     }
  235.     
  236.     The CELL resource, if one is generated, contains one entry per
  237.     screen line, in the following format (using Rez syntax):
  238.     
  239.     type 'CELL' {
  240.         array list {
  241.             byte;                    { ordinal of STR# resource containing line }
  242.             integer;                { offset in STR# of line }
  243.         }
  244.     }
  245.     
  246.     CELL resources must be generated for type 1 reports.  The CELL resource
  247.     becomes the "cell array" in the list manager data structure for the 
  248.     report (see rep.c).  Prebuilding this array here in cvrt speeds up the
  249.     initialization of large type 1 reports.
  250. _____________________________________________________________________*/
  251.  
  252. #pragma load "precompile"
  253. #include "doc.h"
  254.  
  255. unsigned char    *p;                /* pointer to cur pos in STR# rsrc */
  256.  
  257. static void putOnlyPrint (void)
  258.  
  259. {
  260.     *p++ = docOnly;
  261.     *p++ = 3;
  262.     *p++ = docPrint;
  263. }
  264.  
  265. short main(int argc, char *argv[])
  266.  
  267. {
  268.     short                i;                        /* loop index */
  269.     Boolean            inFileSpecified = false;    
  270.     Boolean            outFileSpecified = false; 
  271.     Boolean            idSpecified = false;        
  272.     Boolean            tconSpecified = false;        
  273.     Boolean            tagSpecified = false;
  274.     Boolean            cellSpecified = false;
  275.     Boolean            pictFileSpecified = false;
  276.     Boolean            cellWidthSpecified = false;
  277.     Boolean            cellHeightSpecified = false;
  278.     char                *ofile;                /* output file name */
  279.     char                *ifile;                /* input file name */
  280.     short                id;                    /* STR# resource id */
  281.     short                firstID;                /* first STR# resource id */
  282.     short                tconID;                /* TCON resource id */
  283.     short                tagID;                /* TAG resource id */
  284.     short                cellID;                /* CELL resource id */
  285.     char                 *pfile;                /* pict file name */
  286.     short                cellWidth;            /* cell width */
  287.     short                cellHeight;            /* cell height */
  288.     Handle            theRez;                /* handle to STR# resource */
  289.     Handle            tconRez;                /* handle to TCON resource */
  290.     Handle            tagRez;                /* handle to TAG resource */
  291.     Handle            cellRez;                /* handle to CELL resource */
  292.     unsigned char    *pp;                    /* pointer to beginning of cur line
  293.                                                     in STR# rsrc */
  294.     unsigned char    *q;                    /* pointer to cur pos in TCON rsrc */
  295.     unsigned char    *r;                    /* pointer to cur pos in TAG rsrc */
  296.     unsigned char    *t;                    /* pointer to cur pos in CELL rsrc */
  297.     unsigned short    offset;                /* offset of line if STR# resource */ 
  298.     short                strLen;                /* length of STR# line */
  299.     FILE                *input;                /* input file */
  300.     OSErr                rCode;                /* result code */
  301.     short                ofileNum;            /* output file ref num */
  302.     short                pfileNum;            /* pict file ref num */
  303.     short                nlines;                /* number of lines in cur STR# rsrc */
  304.     short                totLines = 0;        /* total number of screen-visible lines */
  305.     short                ntcon;                /* number of tcon entries */
  306.     short                nptcon;                /* number of printed tcon entries */
  307.     short                ntag;                    /* number of tag entries */
  308.     char                str[256];            /* line buffer */
  309.     short                len;                    /* length of line */
  310.     char                *s;                    /* pointer to cur pos in str */
  311.     short                size;                    /* size of resource */
  312.     Boolean            newRez;                /* true if new STR# should be started */
  313.     Boolean            nextStyle = false;    /* true if next line has style */
  314.     Boolean            nextJust = false;    /* true if next line or pict has just */
  315.     Boolean            nextSize = false;    /* true if next line has size multiplier */
  316.     Boolean            nextOnly = false;    /* true if next line or pict has only */
  317.     unsigned char    styleCode;            /* style code for next line */
  318.     unsigned char    justCode;            /* justification code for next line or
  319.                                                     pict */
  320.     short                sizePercent;        /* size percentage for next line */                                                    
  321.     unsigned char    onlyCode;            /* only code for next line or pict */                                                    
  322.     short                picID;                /* pict resource id */
  323.     PicHandle        picHandle;            /* handle to pict */
  324.     short                picWidth;            /* pict width */
  325.     short                picHeight;            /* pict height */
  326.     short                maxPicWidth;        /* max pict width */
  327.     short                maxPicHeight;        /* max pict height */
  328.     short                picScaledHeight;    /* pict height after scaling */
  329.     short                picBands;            /* number of bands in scaled pict */
  330.     short                ktcon;                /* number of tcon entries from \itcon
  331.                                                     directive */
  332.  
  333.     /* Crack and check parameters. */
  334.  
  335. #ifdef THINK_C
  336.     argc = ccommand(&argv);
  337. #endif
  338.  
  339.     i = 1;
  340.     while (i < argc) {
  341.         if (*argv[i] == '-') {
  342.             if (tolower(*(argv[i]+1)) == 'o') {
  343.                 outFileSpecified = true;
  344.                 ofile = argv[i+1];
  345.                 i += 2;
  346.             } else if (tolower(*(argv[i]+1)) == 'i') {
  347.                 idSpecified = true;
  348.                 firstID = atoi(argv[i+1]);
  349.                 i += 2;
  350.             } else if (tolower(*(argv[i]+1)) == 't') {
  351.                 tconSpecified = true;
  352.                 tconID = atoi(argv[i+1]);
  353.                 i += 2;
  354.             } else if (tolower(*(argv[i]+1)) == 'g') {
  355.                 tagSpecified = true;
  356.                 tagID = atoi(argv[i+1]);
  357.                 i += 2;
  358.             } else if (tolower(*(argv[i]+1)) == 'c') {
  359.                 cellSpecified = true;
  360.                 cellID = atoi(argv[i+1]);
  361.                 i += 2;
  362.             } else if (tolower(*(argv[i]+1)) == 'p') {
  363.                 pictFileSpecified = true;
  364.                 pfile = argv[i+1];
  365.                 i += 2;
  366.             } else if (tolower(*(argv[i]+1)) == 'w') {
  367.                 cellWidthSpecified = true;
  368.                 cellWidth = atoi(argv[i+1]);
  369.                 i += 2;
  370.             } else if (tolower(*(argv[i]+1)) == 'h') {
  371.                 cellHeightSpecified = true;
  372.                 cellHeight = atoi(argv[i+1]);
  373.                 i += 2;
  374.             } else {
  375.                 fprintf(stderr, "### %s - \"%s\" is not an option.\n",
  376.                     argv[0], argv[i]);
  377.                 return 1;
  378.             }
  379.         } else {
  380.             inFileSpecified = true;
  381.             ifile = argv[i];
  382.             i++;
  383.         }
  384.     }
  385.     if (!outFileSpecified) {
  386.         fprintf(stderr, "### %s - output file not specified.\n", argv[0]);
  387.         return 1;
  388.     }
  389.     if (!idSpecified) {
  390.         fprintf(stderr, "### %s - resource id not specified.\n", argv[0]);
  391.         return 1;
  392.     }
  393.     if (pictFileSpecified && (!cellWidthSpecified || !cellHeightSpecified)) {
  394.         fprintf(stderr, "### %s - when the p option is used the w and h options\n", 
  395.             argv[0]);
  396.         fprintf(stderr, "### must also be specified.\n");
  397.         return 1;
  398.     }
  399.  
  400.     /* Open the input file.  Create it if it doesn't already exist. */
  401.     
  402.     if (!inFileSpecified) {
  403.         input = stdin;
  404.     } else if ((input = fopen(ifile, "r")) == nil) {
  405.         fprintf(stderr, "### %s - unable to open file %s.\n",
  406.             argv[0], ifile);
  407.         return 2;
  408.     }
  409.     
  410.     /* Open the pict file. */
  411.     
  412.     if (pictFileSpecified) {
  413.         pfileNum = openresfile(pfile);
  414.         if (pfileNum == -1) {
  415.             fprintf(stderr, "### %s - unable to open pict file %s.\n",
  416.                 argv[0], pfile);
  417.             return 2;
  418.         }
  419.     }
  420.     
  421.     /* Open the output file. */
  422.     
  423.     SetResLoad(false);
  424.     ofileNum = openresfile(ofile);
  425.     if (ofileNum == -1) {
  426.         createresfile(ofile);
  427.         ofileNum = openresfile(ofile);
  428.         if (ofileNum == -1) {
  429.             fprintf(stderr, "### %s - unable to open or create file %s.\n",
  430.                 argv[0], ofile);
  431.             return 2;
  432.         }
  433.     }
  434.     SetResLoad(true);
  435.     
  436.     /* Get the old TCON resource and increase its size to 32K.  If it
  437.         doesn't exist create a 32K new one. */
  438.         
  439.     if (tconSpecified) {
  440.         if ((tconRez = GetResource('TCON', tconID))  && 
  441.             HomeResFile(tconRez) == ofileNum) {
  442.             SetHandleSize(tconRez, 0x7fff);
  443.             if (rCode = MemError()) {            
  444.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  445.                     argv[0], rCode);
  446.                 return 2;
  447.             }
  448.         } else {
  449.             tconRez = NewHandle(0x7fff);
  450.             if (rCode = MemError()) {            
  451.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  452.                     argv[0], rCode);
  453.                 return 2;
  454.             }
  455.             AddResource(tconRez, 'TCON', tconID, "\p");
  456.             if (rCode = ResError()) {            
  457.                 fprintf(stderr, "### %s - error %d on TCON addresource.\n",
  458.                     argv[0], rCode);
  459.                 return 2;
  460.             }
  461.         }
  462.         HLock(tconRez);
  463.         ntcon = nptcon = 0;
  464.         q = (unsigned char*)*tconRez + 2;
  465.     }
  466.     
  467.     /* Get the old TAG resource and increase its size to 32K.  If it
  468.         doesn't exist create a 32K new one. */
  469.         
  470.     if (tagSpecified) {
  471.         if ((tagRez = GetResource('TAG ', tagID))  && 
  472.             HomeResFile(tagRez) == ofileNum) {
  473.             SetHandleSize(tagRez, 0x7fff);
  474.             if (rCode = MemError()) {            
  475.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  476.                     argv[0], rCode);
  477.                 return 2;
  478.             }
  479.         } else {
  480.             tagRez = NewHandle(0x7fff);
  481.             if (rCode = MemError()) {            
  482.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  483.                     argv[0], rCode);
  484.                 return 2;
  485.             }
  486.             AddResource(tagRez, 'TAG ', tagID, "\p");
  487.             if (rCode = ResError()) {            
  488.                 fprintf(stderr, "### %s - error %d on TAG addresource.\n",
  489.                     argv[0], rCode);
  490.                 return 2;
  491.             }
  492.         }
  493.         HLock(tagRez);
  494.         ntag = 0;
  495.         r = (unsigned char*)*tagRez + 2;
  496.     }
  497.     
  498.     /* Get the old CELL resource and increase its size to 32K.  If it
  499.         doesn't exist create a 32K new one. */
  500.         
  501.     if (cellSpecified) {
  502.         if ((cellRez = GetResource('CELL', cellID))  && 
  503.             HomeResFile(cellRez) == ofileNum) {
  504.             SetHandleSize(cellRez, 0x7fff);
  505.             if (rCode = MemError()) {            
  506.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  507.                     argv[0], rCode);
  508.                 return 2;
  509.             }
  510.         } else {
  511.             cellRez = NewHandle(0x7fff);
  512.             if (rCode = MemError()) {            
  513.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  514.                     argv[0], rCode);
  515.                 return 2;
  516.             }
  517.             AddResource(cellRez, 'CELL', cellID, "\p");
  518.             if (rCode = ResError()) {            
  519.                 fprintf(stderr, "### %s - error %d on CELL addresource.\n",
  520.                     argv[0], rCode);
  521.                 return 2;
  522.             }
  523.         }
  524.         HLock(cellRez);
  525.         t = (unsigned char*)*cellRez;
  526.     }
  527.     
  528.     /* Main loop.  Create each new STR# resource one at a time. */
  529.     
  530.     id = firstID;
  531.     maxPicWidth = maxPicHeight = 0;
  532.     while (true) {
  533.         
  534.         /*    Get the old STR# resource and increase its size to 32K.  If it
  535.             doesn't exist create a 32K new one. */
  536.         
  537.         if (id-firstID >= 64) {
  538.             fprintf(stderr, "### %s - more than 64 STR# resources.\n",
  539.                 argv[0], rCode);
  540.             return 2;
  541.         }
  542.         if ((theRez = GetResource('STR#', id))  && 
  543.             HomeResFile(theRez) == ofileNum) {
  544.             SetHandleSize(theRez, 0x7fff);
  545.             if (rCode = MemError()) {            
  546.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  547.                     argv[0], rCode);
  548.                 return 2;
  549.             }
  550.         } else {
  551.             theRez = NewHandle(0x7fff);
  552.             if (rCode = MemError()) {            
  553.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  554.                     argv[0], rCode);
  555.                 return 2;
  556.             }
  557.             AddResource(theRez, 'STR#', id, "\p");
  558.             if (rCode = ResError()) {            
  559.                 fprintf(stderr, "### %s - error %d on STR# id=%d addresource.\n",
  560.                     argv[0], rCode, id);
  561.                 return 2;
  562.             }
  563.         }
  564.         
  565.         /* Read lines from the input file, convert them to pascal format,
  566.             and append them to the STR# buffer. */
  567.             
  568.         HLock(theRez);
  569.         p = (unsigned char*)*theRez + 2;
  570.         nlines = 0;
  571.         while (fgets(str, 255, input)) {
  572.             len = strlen(str);
  573.             if (len && *(str+len-1) == '\n') {
  574.                 *(str+len-1) = 0;
  575.                 len--;
  576.             }
  577.             newRez = false;
  578.             if (len && *str == '\\') {
  579.                 if (*(str+len-1) == docEop) {
  580.                     *(str+len-1) = 0;
  581.                     len--;
  582.                 }
  583.                 if (newRez = len >= 5 && !strncmp(str, "\\str#", 5)) break;
  584.                 if (len >= 5 && !strncmp(str, "\\tcon", 5)) {
  585.                     if (!tconSpecified) {
  586.                         fprintf(stderr, "### %s - tcon id not specified.\n",
  587.                             argv[0]);
  588.                         return 2;
  589.                     }
  590.                     *((short*)q) = totLines;
  591.                     q += 2;
  592.                     *q = nextOnly ? onlyCode : docScreen | docPrint;
  593.                     nextOnly = false;
  594.                     if (*q++ & docPrint) nptcon++;
  595.                     *q++ = len-6;
  596.                     memcpy(q, str+6, len-6);
  597.                     q += len-6;
  598.                     if ((long)q & 1) q++;
  599.                     ntcon++;
  600.                 } else if (len >= 4 && !strncmp(str, "\\tag", 4)) {
  601.                     if (!tagSpecified) {
  602.                         fprintf(stderr, "### %s - tag id not specified.\n",
  603.                             argv[0]);
  604.                         return 2;
  605.                     }
  606.                     *((short*)r) = totLines;
  607.                     r += 2;
  608.                     *((short*)r) = atoi(str+5);
  609.                     r += 2;
  610.                     ntag++;
  611.                 } else if (len >= 8 && !strncmp(str, "\\style", 6)) {
  612.                     nextStyle = true;
  613.                     styleCode = 0;
  614.                     s = str+6;
  615.                     while (s < str+len) {
  616.                         s += strspn(s, " \t");
  617.                         if (!strncmp(s, "normal", 6)) {
  618.                             styleCode = normal;
  619.                         } else if (!strncmp(s, "bold", 4)) {
  620.                             styleCode |= bold;
  621.                         } else if (!strncmp(s, "italic", 6)) {
  622.                             styleCode |= italic;
  623.                         } else if (!strncmp(s, "underline", 9)) {
  624.                             styleCode |= underline;
  625.                         } else if (!strncmp(s, "outline", 7)) {
  626.                             styleCode |= outline;
  627.                         } else if (!strncmp(s, "shadow", 6)) {
  628.                             styleCode |= shadow;
  629.                         } else if (!strncmp(s, "condense", 8)) {
  630.                             styleCode |= condense;
  631.                         } else if (!strncmp(s, "extend", 6)) {
  632.                             styleCode |= extend;
  633.                         } else {
  634.                             fprintf(stderr, 
  635.                                 "### %s - illegal style option %s.\n",
  636.                                 argv[0], s);
  637.                             return 2;
  638.                         }
  639.                         s += strcspn(s, " \t");
  640.                     }
  641.                 } else if (len >= 7 && !strncmp(str, "\\just", 5)) {
  642.                     nextJust = true;
  643.                     s = str+6;
  644.                     s += strspn(s, " \t");
  645.                     if (!strncmp(s, "left", 4)) {
  646.                         justCode = docLeft;
  647.                     } else if (!strncmp(s, "center", 6)) {
  648.                         justCode = docCenter;
  649.                     } else if (!strncmp(s, "right", 5)) {
  650.                         justCode = docRight;
  651.                     } else {
  652.                         fprintf(stderr, 
  653.                             "### %s - illegal justification option %s.\n",
  654.                             argv[0], s);
  655.                         return 2;
  656.                     }
  657.                 } else if (len >= 7 && !strncmp(str, "\\size", 5)) {
  658.                     nextSize = true;
  659.                     s = str+6;
  660.                     s += strspn(s, " \t");
  661.                     sizePercent = atoi(s);
  662.                 } else if (len >= 7 && !strncmp(str, "\\only", 5)) {
  663.                     nextOnly = true;
  664.                     onlyCode = 0;
  665.                     s = str+6;
  666.                     while (s < str+len) {
  667.                         s += strspn(s, " \t");
  668.                         if (!strncmp(s, "screen", 6)) {
  669.                             onlyCode |= docScreen;
  670.                         } else if (!strncmp(s, "print", 5)) {
  671.                             onlyCode |= docPrint;
  672.                         } else if (!strncmp(s, "save", 4)) {
  673.                             onlyCode |= docSave;
  674.                         } else {
  675.                             fprintf(stderr, 
  676.                                 "### %s - illegal only option %s.\n",
  677.                                 argv[0], s);
  678.                             return 2;
  679.                         }
  680.                         s += strcspn(s, " \t");
  681.                     }
  682.                 } else if (len >= 7 && !strncmp(str, "\\pict", 5)) {
  683.                     if (!pictFileSpecified) {
  684.                         fprintf(stderr, "### %s - picture file not specified.\n",
  685.                             argv[0]);
  686.                         return 2;
  687.                     }
  688.                     s = str+6;
  689.                     s += strspn(s, " \t");
  690.                     picID = atoi(s);
  691.                     picHandle = GetPicture(picID);
  692.                     if (!picHandle) {
  693.                         fprintf(stderr, "### %s - picture id %d not found.\n",
  694.                             argv[0], picID);
  695.                         return 2;
  696.                     }
  697.                     picWidth = (**picHandle).picFrame.right -
  698.                         (**picHandle).picFrame.left;
  699.                     picHeight = (**picHandle).picFrame.bottom -
  700.                         (**picHandle).picFrame.top;
  701.                     if (picWidth > maxPicWidth) maxPicWidth = picWidth;
  702.                     if (picHeight > maxPicHeight) maxPicHeight = picHeight;
  703.                     ReleaseResource((Handle)picHandle);
  704.                     if (picWidth <= cellWidth-8) {
  705.                         picScaledHeight = picHeight;
  706.                     } else {
  707.                         picScaledHeight = picHeight * (cellWidth-8) / picWidth;
  708.                     }
  709.                     picBands = (picScaledHeight + cellHeight - 1) / cellHeight;
  710.                     for (i = 0; i < picBands; i++) {
  711.                         if (p+13 - (unsigned char*)*theRez > 0x7f00) {
  712.                             fprintf(stderr, 
  713.                                 "### %s - too much text in STR# resource (>32K).\n", 
  714.                                 argv[0]);
  715.                             return 2;
  716.                         }
  717.                         pp = p;
  718.                         p++;
  719.                         strLen = 6;
  720.                         if (nextJust && justCode != docCenter) {
  721.                             *p++ = docJust;
  722.                             *p++ = 3;
  723.                             *p++ = justCode;
  724.                             strLen += 3;
  725.                         }
  726.                         if (nextOnly && onlyCode != (docScreen + docPrint)) {
  727.                             *p++ = docOnly;
  728.                             *p++ = 3;
  729.                             *p++ = onlyCode;
  730.                             strLen += 3;
  731.                         }
  732.                         *p++ = docPict;
  733.                         *p++ = 6;
  734.                         *p++ = picID >> 8;
  735.                         *p++ = picID & 0xff;
  736.                         *p++ = i >> 8;
  737.                         *p++ = i & 0xff;
  738.                         *pp = strLen;
  739.                         nlines++;
  740.                         if (!nextOnly || (onlyCode & docScreen)) {
  741.                             totLines++;
  742.                             if (cellSpecified) {
  743.                                 *t++ = id-firstID;
  744.                                 offset = pp - (unsigned char*)*theRez;
  745.                                 *t++ = offset >> 8;
  746.                                 *t++ = offset & 0xff;
  747.                             }
  748.                         }
  749.                     }
  750.                     nextStyle = nextJust = nextSize = nextOnly = false;
  751.                 } else if (len >= 5 && !strncmp(str, "\\page", 5)) {
  752.                     *p++ = 6;
  753.                     putOnlyPrint();
  754.                     s = str+5;
  755.                     s += strspn(s, " \t");
  756.                     *p++ = docPage;
  757.                     *p++ = 3;
  758.                     *p++ = (*s) ? 1 : 0; 
  759.                     nlines++;
  760.                 } else if (len >= 5 && !strncmp(str, "\\keep", 5)) {
  761.                     *p++ = 5;
  762.                     putOnlyPrint();
  763.                     *p++ = docKeep;
  764.                     *p++ = 2;
  765.                     nlines++;
  766.                 } else if (len >= 8 && !strncmp(str, "\\endkeep", 8)) {
  767.                     *p++ = 5;
  768.                     putOnlyPrint();
  769.                     *p++ = docEndKeep;
  770.                     *p++ = 2;
  771.                     nlines++;
  772.                 } else if (len >= 8 && !strncmp(str, "\\itcon", 6)) {
  773.                     s = str+6;
  774.                     s += strspn(s, " \t");
  775.                     ktcon = atoi(s);
  776.                     for (i = 0; i < ktcon; i++) {
  777.                         if (p+6 - (unsigned char*)*theRez > 0x7f00) {
  778.                             fprintf(stderr,
  779.                                 "#### %s - too much text in STR# resource (>32K).\n",
  780.                                 argv[0]);
  781.                             return 2;
  782.                         }
  783.                         *p++ = 6;
  784.                         putOnlyPrint();
  785.                         *p++ = docITcon;
  786.                         *p++ = 3;
  787.                         *p++ = i;
  788.                         nlines++;
  789.                     }
  790.                 }
  791.             } else {
  792.                 if (p+len+1 - (unsigned char*)*theRez > 0x7f00) {
  793.                     fprintf(stderr, "### %s - too much text (>32K).\n", 
  794.                         argv[0]);
  795.                     return 2;
  796.                 }
  797.                 pp = p;
  798.                 p++;
  799.                 strLen = len;
  800.                 if (nextStyle && styleCode != normal) {
  801.                     *p++ = docStyle;
  802.                     *p++ = 3;
  803.                     *p++ = styleCode;
  804.                     strLen += 3;
  805.                 }
  806.                 if (nextJust && justCode != docLeft) {
  807.                     *p++ = docJust;
  808.                     *p++ = 3;
  809.                     *p++ = justCode;
  810.                     strLen += 3;
  811.                 }
  812.                 if (nextSize && sizePercent != 100) {
  813.                     *p++ = docSize;
  814.                     *p++ = 4;
  815.                     *p++ = sizePercent >> 8;
  816.                     *p++ = sizePercent & 0xff;
  817.                     strLen += 4;
  818.                 }
  819.                 if (nextOnly && onlyCode != 7) {
  820.                     *p++ = docOnly;
  821.                     *p++ = 3;
  822.                     *p++ = onlyCode;
  823.                     strLen += 3;
  824.                 }
  825.                 memcpy(p, str, len);
  826.                 p += len;
  827.                 *pp = strLen;
  828.                 nlines++;
  829.                 if (!nextOnly || (onlyCode & docScreen)) {
  830.                     totLines++;
  831.                     if (cellSpecified) {
  832.                         *t++ = id-firstID;
  833.                         offset = pp - (unsigned char*)*theRez;
  834.                         *t++ = offset >> 8;
  835.                         *t++ = offset & 0xff;
  836.                     }
  837.                 }
  838.                 nextStyle = nextJust = nextSize = nextOnly = false;
  839.             }
  840.         }
  841.         
  842.         /* Store the number of lines. */
  843.         
  844.         **(short**)theRez = nlines;
  845.         HUnlock(theRez);
  846.         
  847.         /* Adjust STR# resource size and mark it purgable and changed. */
  848.         
  849.         size = p - (unsigned char*)*theRez;
  850.         SetHandleSize(theRez, size);
  851.         if (rCode = MemError()) {            
  852.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  853.                 argv[0], rCode);
  854.             return 2;
  855.         }
  856.         SetResAttrs(theRez, 0x20);
  857.         ChangedResource(theRez);
  858.         if (rCode = ResError()) {            
  859.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  860.                 argv[0], rCode);
  861.             return 2;
  862.         }
  863.         
  864.         /* Increment STR# resource id and loop. */
  865.         
  866.         if (!newRez) break;
  867.         id++;
  868.     }
  869.     
  870.     /* Store the number of tcon entries, adjust the TCON resource size,
  871.         and mark it purgable and changed. */
  872.     
  873.     if (tconSpecified) {
  874.         if (nptcon != ktcon) {
  875.             fprintf(stderr, 
  876.                 "### %s - number of entries in \itcon directive should be %d.\n",
  877.                 argv[0], nptcon);
  878.                 return 2;
  879.         }
  880.         **((short**)tconRez) = ntcon;
  881.         size = q - (unsigned char*)*tconRez;
  882.         SetHandleSize(tconRez, size);
  883.         if (rCode = MemError()) {            
  884.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  885.                 argv[0], rCode);
  886.             return 2;
  887.         }
  888.         SetResAttrs(tconRez, 0x20);
  889.         ChangedResource(tconRez);
  890.         if (rCode = ResError()) {            
  891.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  892.                 argv[0], rCode);
  893.             return 2;
  894.         }
  895.     }
  896.     
  897.     /* Store the number of tag entries, adjust the TAG resource size,
  898.         and mark it purgable and changed. */
  899.     
  900.     if (tagSpecified) {
  901.         **((short**)tagRez) = ntag;
  902.         size = r - (unsigned char*)*tagRez;
  903.         SetHandleSize(tagRez, size);
  904.         if (rCode = MemError()) {            
  905.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  906.                 argv[0], rCode);
  907.             return 2;
  908.         }
  909.         SetResAttrs(tagRez, 0x20);
  910.         ChangedResource(tagRez);
  911.         if (rCode = ResError()) {            
  912.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  913.                 argv[0], rCode);
  914.             return 2;
  915.         }
  916.     }
  917.     
  918.     /* Adjust the CELL resource size, and mark it purgable and changed. */
  919.     
  920.     if (cellSpecified) {
  921.         size = t - (unsigned char*)*cellRez;
  922.         SetHandleSize(cellRez, size);
  923.         if (rCode = MemError()) {            
  924.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  925.                 argv[0], rCode);
  926.             return 2;
  927.         }
  928.         SetResAttrs(cellRez, 0x20);
  929.         ChangedResource(cellRez);
  930.         if (rCode = ResError()) {            
  931.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  932.                 argv[0], rCode);
  933.             return 2;
  934.         }
  935.     }
  936.     
  937.     /* Print the max pic width and height - commented out for now.
  938.         Uncomment out if you want this info.
  939.     
  940.     if (maxPicWidth) {
  941.         printf("### %s - Max picture width = %d.\n",
  942.             argv[0], maxPicWidth);
  943.         printf("### %s - Max picture height = %d.\n",
  944.             argv[0], maxPicHeight);
  945.     } 
  946.     
  947.     */
  948.     
  949.     /* Close the output and input files. */
  950.         
  951.     CloseResFile(ofileNum);
  952.     if (pictFileSpecified) CloseResFile(pfileNum);
  953.     if (rCode = ResError()) {            
  954.         fprintf(stderr, "### %s - error %d on CloseResFile.\n",
  955.             argv[0], rCode);
  956.         return 2;
  957.     }
  958.     fclose(input);
  959.     return 0;
  960. }
  961.  
  962.