[comp.sys.amiga] split

richard@gryphon.CTS.COM (Richard Sexton) (01/28/88)

Alright.  I'm sick of seeing those "where can I get the include
files printed two columns to a page" postings.

Here is a program that splits text into any number of columns
and produces a postscript file, suitable for framing.

It handles any font, any size, you can specify # of lines
per page, all that good stuff.

It probably isn't as good as the one Clayton Cramer announced
in comp.newprod, but it's free.

This is not a great example of intelli... inteli... intael.. real
swift PostScript programming, but it works.

======== snip snip snip =================== snippity snip snip ===========


#include "stdio.h"

/* Copyright 1988 Richard John Sexton */
/* All rights reserved */

/* Not to be used for commercial purposes without the express written
   permission of the author.

   Richard J. Sexton

   richard@gryphon.CTS.COM
   rutgers!marque!gryphon!richard

*/

#define CR 10
#define LF 13

#define TRUE 1
#define FALSE 0

#define TOP_MARGIN_DEFAULT 25
#define BOTTOM_MARGIN_DEFAULT 25

#define POINTS_ACROSS ((85 * 72) / 10)
#define POINTS_DOWN ((110 * 72) / 10)

FILE *in, *out;
unsigned char *fword, swarray [26], fontname[256] = "Helvetica";
unsigned long swvalues [26];
short i, fontsize, pt_row_cntr, lines, linecntr, col_nbr, nbr_cols, xpos;
short  ypos, yils, page_nbr, colums = 1, rotate = 0, maxx, maxy, temp1;
short temp2, switch_num, border_value, lm_offset, title;
short top_margin, bottom_margin;

unsigned char outfilename[50];
char *pp = "%%";

main (argc, argv)
short argc;
unsigned char *argv[];
   {
   unsigned short ctemp;
   unsigned char c, *s, *d;


   printf ("\n  Copyright 1988 by Richard J. Sexton.  All rights reserved.\n  May not sold for profit.\n\n");
   init_data ();

   /* Get values of switches, if any */

   for (i = 1; i < argc; i++)
      {
      if (*argv[i] == '-')
         {
         c = (*(argv[i] + 1));

         if (c >= 'a' && c <= 'z')
           {
           c &= 0xdf;
           }

         if (c <= '9' && c >= '0')
            {
            ctemp = c;

            switch_num = ctemp;
            }

         if (c <= 'Z' && c >= 'A')
            {
            register short tt;
            static unsigned short kk;
            long temp;

            swarray[c - 'A'] = 1;

            if (*(argv[i] + 2))
               {
               tt = sscanf ((argv[i] + 2), "%d", &kk);
               temp = kk;
               swvalues[c - 'A'] = (long)temp;

               if (!tt)
                  {
                  swvalues[c - 'A'] = (unsigned char *)(argv[i] + 2);
                  }
               }
            }
         }
      }


   if (argc == 1)
      {
      printf ("\n  Usage:   '%s file',  output goes to 'file.ps'.\n\n '%s -h' displays help screen.\n\n", argv[0], argv[0]);
      exit (3);
      }

   if (swarray['H' - 'A'])
      {
      /* Bozo asked for help */

      print_help (argv, swvalues['H' - 'A']);
      exit (0);
      }

   if (switch_num != (-1))
      {
      switch (switch_num)
         {
         case '1':
            {
            fontsize = 6; nbr_cols = 2;
            break;
            }

          case '2':
            {
            set_rotate (1);
            fontsize = 6; nbr_cols = 2;
            break;
            }

         case '3':
            {
            fontsize = 18;
            scopy ("Times-Roman", fontname);
            }
         }
      }

   set_params_from_switches ();

   if (!lines)   /* %% */
      {
      lines = (rotate ? 500 : 675) / (((fontsize ? fontsize : 10) * 3) / 2);
      }

   in = fopen (argv[1], "r");

   d = outfilename;
   s = argv[1];

   for (;*s;)
      {
      *d++ = *s++;
      }

   *d++ = '.';   *d++ = 'p';   *d++ = 's';   *d++ = 0;

   out = fopen (outfilename, "w");

   if (in == 0)  {printf ("(%s): Can't open file '%s' for input.\n", argv[0], argv[1]); exit(1);}
   if (out == 0) {printf ("(%s): Can't open %s.ps for output.\n", argv[0], argv[1]); exit (2);}

   printf ("\n%s --> %s\n", argv[1], outfilename);

   /* Insert stupid Adobe header */

   fprintf (out, "%s!PS-Adobe-1.0\n", pp);
   fprintf (out, "%sCreator: The program '%s'\n", pp, argv[0]);
   fprintf (out, "%sTitle: %s\n", pp, outfilename);
   fprintf (out, "%sPages: (atend)\n", pp);
   fprintf (out, "%sDocumentFonts: (atend)\n", pp);
   fprintf (out, "%sEndComments\n\n", pp);

   fprintf (out, "/yline %d def\n/xline %d def\n/%s findfont %d scalefont setfont\n/yils %d def\n",
   (rotate ? (-lm_offset) : 725), lm_offset, fontname, fontsize, fontsize + (fontsize / 2));

   /* Define clipping path(s) */

   for (i = 0; i < nbr_cols; i++)
      {
      temp1 = lm_offset + (((maxx - 110) / (nbr_cols)) * i);

      temp2 = lm_offset + (((maxx - 110) / (nbr_cols)) * (i + 1));
      temp2 -= 6;
 
      fprintf (out, "/clippath%d { newpath %d 999 moveto %d -999 lineto",
      i, temp1, temp1);

      fprintf (out, " %d -999 lineto %d 999 lineto closepath} def\n",
      temp2, temp2);
      }

   fprintf (out, "/nl {/yline yline yils sub def xline yline moveto show } def\n");
   fprintf (out, "/move {moveto} def\n/draw {lineto} def\n");

   if (rotate)
      {
      fprintf (out, "90 rotate\n");
      }

   fprintf (out, "gsave\nclippath0 clip\n");

   fprintf (out, "%sEndProlog\n%sPage 0 1\n", pp, pp);

   fprintf (out, "\n(");

   while ((c = getc (in)) != 0xff)
      {
      if ((c == CR) || (c == LF))
         {
         /* Hit a CR or LF, move to a new line */
         /* If your files have CR LF then you have a problem */
         /* Mine don't */

         fprintf (out, ") nl");
         pt_row_cntr -= yils;
         linecntr++;

         if (((lines == 0) && (pt_row_cntr <= 150)) ||
            ((lines) && (linecntr == lines)))
            {
            colum_break ();
            pt_row_cntr = maxy;
            linecntr = 0;
            }

         fprintf (out, "\n(");
         }
      else
         {
         /* Output a line of text */
         if (c == '(' || c == ')')
            {
            fprintf (out, "\\");
            }
         fprintf (out, "%c", c);
         }
      }

   fprintf (out, ")\n/yline yline yils sub def\nxline yline moveto\nshow\n");

   draw_border ();
   draw_title ();

   fprintf (out, "showpage\n grestore\n");

   fprintf (out, "%sTrailer\n%sDocumentFonts: %s\n%sPages: %d\n",
           pp, pp, fontname, pp, page_nbr);

   fclose (out);
   fclose (in);

   printf ("\n%d page%s printed.\n", page_nbr, (page_nbr == 1 ? "" : "s"));

   }

/*************** switch and debug routines ********************/

dump_switches ()
   {
   short i;

   for (i = 0; i < 26; i++)
      {
      if (swarray[i])
         {
        /*  printf ("switch -%c = %d   ", i + 'A', swvalues[i]); */
         }
      }
   }

/******************** Local support routines ***************************/

scopy (s, d)
unsigned char *s, *d;
   {
   while (*s) *d++ = *s++; *d = 0;
   }

colum_break ()
   {
   if (col_nbr++ >= nbr_cols - 1)
      {
      page_break ();
      col_nbr = 0;
      }
   else
      {
      xpos = lm_offset + (((maxx - 110) / (nbr_cols)) * col_nbr);  /*  used to be nbr_cols + 1 */

      ypos = rotate ? (-lm_offset) : 725;
      fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
      }
   fprintf (out, "grestore gsave\nclippath%d clip\n", col_nbr);
   }

page_break()
   {
   draw_border ();
   draw_title ();

   fprintf (out, "\nshowpage\n");

   fprintf (out, "%sPage %d %d\n", pp, page_nbr - 1, page_nbr);
   if (rotate) fprintf (out, "90 rotate");

   xpos = lm_offset; ypos = (rotate ? (-lm_offset) : 725);
   fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
   col_nbr = 0;
   page_nbr++;
   }

init_data ()
   {
   register unsigned short i;

   fontsize = 10;             /* Set default font size */
   yils = 15;                 /* Y InterLine Spacing = fontsize * 1.5 */
   pt_row_cntr = POINTS_DOWN;         /* Start counter (in points) at T.O.P - 725 */
   col_nbr = 0;
   nbr_cols = 1;
   linecntr = 0;
   page_nbr = 1;
   border_value = 0;
   lines = 0;
   switch_num = -1;
   lm_offset = 45;             /* Left margin offset */
   title = 0;                  /* default to no title */

   top_margin = TOP_MARGIN_DEFAULT;
   bottom_margin = BOTTOM_MARGIN_DEFAULT;

   maxx = POINTS_ACROSS; maxy = POINTS_DOWN;

   for (i = 0; i < 26; i++)
      {
      swarray[i] = 0;
      swvalues[i] = 0;
      }
   }

print_help (argv, helpqual)
unsigned char *argv[], *helpqual;
   {
   unsigned char num;

   num = (*helpqual) & 0xdf;

   switch (num)
      {
      case 0:
         {
         printf ("\n Usage:   '%s file',  output goes to 'file.ps'.\n\n '%s -h' displays help screen.\n", argv[0], argv[0]);
         printf ("\n Options are:\n");
         printf ("    -b[n]  Draw border around text [optional format 'n']\n");
         printf ("    -cn    Set text in 'n' colums across\n");
         printf ("    -fname Set text in font 'name'\n");
         printf ("    -h[s]  '%s -h' gets help. '%s -hs' gets help about subject 's'.\n", argv[0], argv[0]);
         printf ("    -ln    Limit text to 'n' lines per column\n");
         printf ("    -n     Print 'n' copies\n");
         printf ("    -on    Orientation 'n'. n = l for landscape, p for portrait\n");
         printf ("    -pn    Set text 'n' points tall\n");
         printf ("    -n     Use predefined format n:\n");
         printf ("\n         1 = portrait, 2 columns of 6pt Helvetica\n");
         printf ("         2 = landscape, 2 columns of 6pt Helvetica\n");
         printf ("         3 = landscape, 1 column, 18pt Times Roman\n\n");
         printf ("    -ttext Print title = text on every page (also date and page #)\n");
         printf ("\nThe default output format is portrait, 10pt Helvetica\n");
         break;
         }

      case 'B':
         {
           printf ("\n                         ** Border formats **\n\n");
           printf ("       The qualifier for the -b switch is a number 0 - 127.\n");
           printf ("       The default, -b with no qualifier, draws a box around every column.\n\n");
           printf ("       The individual lines are binary encoded as follows:\n\n");
 /*border shit */          printf ("              1 = left border line          2 = top line\n");
           printf ("              4 = right border line         8 = bottom line\n");
           printf ("             16 = middle line (does not connect with top and bottom\n");
           printf ("             32 = middle connecting line (top)\n");
           printf ("             64 = middle connecting line (bottom)\n\n");
           printf ("       These last two connect the middle line to the top and bottom and\n");
           printf ("       draw a small cross where they intersect to aid registration.\n\n");
           printf ("       These numbers can be used alone or added together. For example:\n\n");
           printf ("       -b16 would draw a line between columns\n");
           printf ("       -b15 would draw the four lines forming a box around the column(s)\n");
           printf ("        (15 = 8 + 4 + 2 + 1)\n");
         break;

         }

      case 'C':
         {
         break;
         }

      case 'F':
         {
         break;
         }

      case 'H':
         {
         break;
         }

      case 'L':
         {
         break;
         }

      case 'N':
         {
         break;
         }

      case 'O':
         {
         break;
         }

      case 'P':
         {
         }

      }      /* End switch */
  exit (0);
   }

set_params_from_switches ()
   {
   /* Columns per page */

   if (swarray['C' - 'A'])
      {
      nbr_cols = swvalues['C' - 'A'];
      }

   /* Font name */

   if (swarray['F' - 'A'])
      {
      if (swvalues['F' - 'A'])
         {
         setfont ();
         }
      }

   /* Orientation: 'l' = landscape */

   if (swarray['O' - 'A'])
      {
      if (swvalues['O' - 'A'])
         {
         fword = (char *)swvalues['O' - 'A'];
         if ((*fword & 0xdf) == 'P')
            {
            set_rotate (0);
            }

         if ((*fword & 0xdf) == 'L')
            {
            set_rotate (1);
            }
         }
      }

   /* Lines per column */

   if (swarray['L' - 'A'])
      {
      lines = swvalues['L' - 'A'];
      }

   /* Border value  */

   if (swarray['B' - 'A'])
      {
      if (swvalues['B' - 'A'])
         {
         border_value = swvalues['B' - 'A'];     /* Get qualifier of '-b' switch */
         }
      else
         {
         border_value = 15;
         }
      }

/*   if (!border_value)
      {
       Hmm, no qualifier,  Default = all bits on

      border_value = 15;
      }        */

   /* Point size */

   if (swarray['P' - 'A'])
      {
      fontsize = swvalues['P' - 'A'];
      }

   /* Title ? */

   if (swarray['T' - 'A'])
      {
      title = 1;
      }

   /* End of processing switches */
   }


set_rotate (num)
short num;
   {
   short t;

   if (num != rotate)
      {
      t = maxx; maxx = maxy; maxy = t;
      pt_row_cntr = maxy;
      rotate ^= 1;
      }
   }

setfont()
   {
   scopy (swvalues['F' - 'A'], fontname);
   }

draw_border ()
   {
   short tx1, ty1, tx2, ty2;

    if (border_value)
      {
      tx1 = 40; ty1 = rotate ? (-lm_offset) : 760;
      tx2 = rotate ? 750 : 580; ty2 = rotate ? (-580) : 35;

  /* %% */

      fprintf (out, "\ngrestore gsave newpath\n");
      fprintf (out, "%d %d move ", tx1, ty1);

      /* Draw */

      if (border_value & 1)
         {
         fprintf (out, "%d %d draw ", tx1, ty2);
         }
      else
         {
         fprintf (out, "%d %d move ", tx1, ty2);
         }

      if (border_value & 8)
         {
         fprintf (out, "%d %d draw ", tx2, ty2);
         }
      else
         {
         fprintf (out, "%d %d move ", tx2, ty2);
         }

      if (border_value & 4)
         {
         fprintf (out, "%d %d draw ", tx2, ty1);
         }
      else
         {
         fprintf (out, "%d %d move ", tx2, ty1);
         }

      if (border_value & 2)
         {
         fprintf (out, "%d %d draw ", tx1, ty1);
         }
      else
         {
         fprintf (out, "%d %d move ", tx1, ty1);
         }

      fprintf (out, "\nclosepath\n");

      if (border_value & (16 + 32 + 64))
         {
         short tempx, indx;

         for (indx = 0; indx < nbr_cols - 1; indx++)
            {
            tempx = lm_offset + (((maxx - 110) / (nbr_cols)) * (indx + 1));
            tempx -= 6;  /* Bump over a bit */

            if (border_value & 16)
               {
               fprintf (out, "%d %d move %d %d draw\n",
                        tempx, 740, tempx, 55);
               }

            if (border_value & 32)
               {
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx, 760, tempx, 740);
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx - 20, 760, tempx + 20, 760);
               }

            if (border_value & 64)
               {
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx, 35, tempx, 55);
               fprintf (out, "%d %d move %d %d draw\n",
                       tempx - 20, 35, tempx + 20, 35);
               }
            }
         }
      fprintf (out, "stroke\n");
      }
   }


draw_title ()
   {
   if (title) fprintf (out, " 400 25 move (%s) show\n", outfilename);
   }


========= wow ! you made it ! ===================== more snipping ============

Makefile ? You gotta be kidding. try 'cc split' and see if you cant figure
it out.

If you make any neat additions, I'd appreciate a copy.

Cheers.


-- 
      "...and before too long I might, see those flashing red lights" 
                          richard@gryphon.CTS.COM 
   {ihnp4!scgvaxd!cadovax, philabs!cadovax, codas!ddsw1} gryphon!richard