From: kswatek@su19az.ess.harris.com (Ken Swatek)
Subject: Re: PostScript filter
Followup-To: comp.sys.sun.apps
Date: Tue, 22 Dec 1992 17:11:34 GMT
Reply-To: kswatek@su19az.ess.harris.com
Organization: Harris Corporation, Government Aerospace Systems Division

In article 92Dec21161647@gdstech.GRUMMAN.COM, billd@gdstech.GRUMMAN.COM (Bill D'Camp) writes:
>I want to hang an Apple LaserWriter off of a SPARC 1.  Can someone
>tell me where to find a PostScript filter which will convert output
>for lpr, either public domain (ftpable) or commercial?
>--
>    _   /|
>    \`o_O'
>      ( )    Aachk! Phft!
>       U     billd@gdstech.grumman.com
>"All opinions expressed herein are my own, they do not represent the
>opinions of my employer."
>

Try this one.  I also have a version which will change paper trays, if there
is more than one.

Ken
______________________________________________________________________________

Ken Swatek                             INTERNET: kswatek@su19az.ess.harris.com
Harris Corporation                     UUCP:     uunet!su19az!kswatek
Government Aerospace Systems Division  CCMail:   harris.kswatek
Mail Stop: 102-4827                    FAX:      407-729-3116
P.O. Box 94000                         Pager:    407-690-8548 (Digital)
Melbourne, Florida 32902               Voice:    407-727-6081
______________________________________________________________________________

/*****************************************************************************/
/*                                                                           */
/*   text2ps.c : this program is an ASCII text-to-postscript filter.         */
/*               Input is any Ascii text file.                               */
/*               Output is a postscript text file, printable on a postscript */
/*                  printer, such as the Apple Laser Writer II.              */
/*                                                                           */
/*               Invoke this program with:                                   */
/*                     "text2ps < [text-file] > [postscript-file]"           */
/*                                                                           */
/*               History:                                                    */
/*               6/3/88   written by: Sharon Mitchell                        */
/*               6/16/88  modified to allow 80 character wrap (necessary     */
/*                        for DOS files) -- skm                              */
/*               7/15/88  modified to recognize all blank lines as valid     */
/*               10/11/91 modified to pass through files that are already PS */
/*               11/19/92 Corrected TAB spacing                              */
/*                                                                           */
/*****************************************************************************/

#include "stdio.h"

#define bool char
#define TRUE    1
#define FALSE   0
#define MAX_LINES 65  /* This may be changed to adjust text on page */
#define CPL 80        /* Characters per line */

int  locate_next_tab();
int  output_line();
int  output_blank_lines();
char line_buff[256];  /* holds up to one line of postscript output */
char *buff_ptr;       /* pointer to the postscript output buffer */
bool blank_line, non_blank_char;
int  blank_line_ctr=0;
int  line_ctr = 0;

/*****************************************************************************/
/*                                                                           */
/*    main() : this procedure reads the stream input one character at a      */
/*             time, determining the output to the postcript file (stdout)   */
/*             based upon the value of the input character.                  */
/*                                                                           */
/*****************************************************************************/

void main()
{
   char    a,b;

/* if the file is already PostScript just pass it straight through           */
   a = getchar();
   b = getchar();
   if (a == '%') 
   {
     if (b =='!') 
     {
       putchar (a);
       putchar (b);
       while ((a = getchar()) != EOF) 
       {
         putchar(a);
       }
       exit(0);
     }
   }
/* generate prologue (postscript file header) */

   printf ("%%!PS-Adobe-1.0\n");
   printf ("/StartPage{/sv save def 48 760 moveto}def\n");
   printf ("/ld -11.4 def\n");
   printf ("/S{count{gsave show grestore}repeat 0 ld rmoveto}def\n");
   printf ("/L{ld mul 0 exch rmoveto}def\n");
   printf ("/B{0 ld rmoveto}def\n");
   printf ("/EndPage{showpage sv restore}def\n");
   printf ("/Courier findfont 11 scalefont setfont\n");
   printf ("StartPage\n");

/* initialize counters and buffers */

   blank_line = FALSE;
   non_blank_char = FALSE;
   buff_ptr = &line_buff[0];

/* read the input file, one character at a time, generating appropriate
   control characters in the postscript file */
   
   convert2ps(a);
   convert2ps(b);
   while ((a=getchar()) != EOF) convert2ps(a);

   if ((buff_ptr-&line_buff[0]) > 0)
   {  output_line (line_buff,buff_ptr,line_ctr);
      printf (")S\n");
   }
   printf ("EndPage\n");
   exit(0);
}
/*****************************************************************************/
/*  convert2ps :  Test char and generate appropriate control characters      */
/*****************************************************************************/
convert2ps(c)
char c;
{
   int     start_pos,stop_pos;
   int     num_blanks;

      switch (c)
      {

/* Carriage-control/line-feed character encountered */

         case '\n' :  if (!blank_line && non_blank_char)
                      {  line_ctr = output_line (line_buff,buff_ptr,line_ctr);
                         printf (")S\n");
                         blank_line_ctr=0;
                         non_blank_char=FALSE;
                         if (++line_ctr >= MAX_LINES)
                         {  printf ("EndPage\nStartPage\n");
                            line_ctr=0;
                         }
                      }
                      else  {
                         blank_line = TRUE;
                         blank_line_ctr++;
                         }
                      buff_ptr = &line_buff[0];
                      break;

/* Form-feed character encountered */

         case '\f' :  if (!blank_line && non_blank_char)
                      {  line_ctr = output_line (line_buff,buff_ptr,line_ctr);
                         printf (")S\n");
                         buff_ptr = &line_buff[0];
                         blank_line_ctr=0;
                         non_blank_char=FALSE;
                      }
                      else
                         if (blank_line)
                         {  line_ctr = output_blank_lines(blank_line_ctr,
                                                          line_ctr);
                            blank_line=FALSE;
                         }
                      printf ("EndPage\nStartPage\n");
                      line_ctr=0;
                      break;

/* Carriage-return character encountered */

         case '\r' :  if (!blank_line && non_blank_char)
                      {  line_ctr = output_line (line_buff,buff_ptr,line_ctr);
                         printf (")\n");
                         buff_ptr = &line_buff[0];
                         blank_line_ctr=0;
                      }
                      else
                         line_ctr=output_blank_lines(blank_line_ctr,line_ctr);
                      break;

/*  Blank character */

         case ' '  :  *buff_ptr++=c;
                      break;

/*  Tab character -- expand tab according to tab-table.  The tab table
    may be changed and this program recompiled if different tab expansion
    desired                                                               */

         case '\t' :  start_pos = buff_ptr - &line_buff[0] -1;
                      stop_pos = locate_next_tab(start_pos);
                      for (num_blanks=1; num_blanks<=stop_pos; num_blanks++) {
                          *buff_ptr++=' ';
                          }
                      break;

/* Special characters requiring a "\" to be placed in front of them in the
   postscript file                                                          */

         case '\\' :
         case '('  :
         case ')'  :  if (blank_line) {
                         line_ctr=output_blank_lines(blank_line_ctr,line_ctr);
                         blank_line=FALSE;
                         }
                      non_blank_char=TRUE;
                      *buff_ptr++='\\';
                      *buff_ptr++=c;
                      break;

/*  Any other character */

         default   :  if (blank_line) {
                         line_ctr=output_blank_lines(blank_line_ctr,line_ctr);
                         blank_line=FALSE;
                         }
                      non_blank_char=TRUE;
                      *buff_ptr++=c;

      }  /*  end case  */
} /* end convert2ps */

/*****************************************************************************/
/*                                                                           */
/*   locate_next_tab: this routine uses the tab table "tab[10]" to           */
/*                    determine the number of blanks which need to           */
/*                    be placed into the postscript output buffer.           */
/*                                                                           */
/*          Input:  pos - position of current pointer into postscript        */
/*                        output buffer                                      */
/*                                                                           */
/*          Returns: integer value representing the number of blanks         */
/*                   which need to be placed into the postscript             */
/*                   output file in order to expand the tab to the           */
/*                   correct position.                                       */
/*                                                                           */
/*****************************************************************************/

int locate_next_tab(pos)

int   pos;
{
   int n=0;
   static int tab[10] = {7,15,23,31,39,47,55,63,71,79};

   while (pos >= tab[n++]);
   return (tab[n-1]-pos);
}


/*****************************************************************************/
/*                                                                           */
/*   output_line: this routine outputs the postscript line buffer to         */
/*                stdout (which is directed to the postscript output         */
/*                file), placing a "(" in the initial line position.         */
/*                                                                           */
/*          Input:  line_buff[] - postscript line buffer                     */
/*                  buff_ptr - pointer into line_buff                        */
/*                                                                           */
/*          Returns: line_ctr - number of lines output on page so far        */
/*                                                                           */
/*****************************************************************************/

int output_line(line_buff,buff_ptr,line_ctr)

char *buff_ptr;
char line_buff[];
int  line_ctr;

{
   bool eol = FALSE;
   char *i;
   int j = 0;  /* character counter for the output line */

   i = &line_buff[0];
   while (!eol)  {

      putchar('(');
      while ( j++ < CPL && i < buff_ptr )  {
         if (*i == '\\') {
            putchar(*i++);
            putchar(*i++);
            } 
         else
            putchar(*i++);
         }
      if (i >= buff_ptr)  /* end of line has been reached */
         eol = TRUE;
      else  {  /* line has exceeded maximum line length */
         printf (")S\n");
         line_ctr++;
         j=0;
         if (line_ctr > MAX_LINES) {
            printf("EndPage\nStartPage\n");
            line_ctr = 0;
            }  /* end if */
         } /* end else */

      } /* end while */

   return (line_ctr);
}


/*****************************************************************************/
/*                                                                           */
/*   output_blank_lines: this routine outputs appropriate postscript         */
/*                notation for blank lines ("B" or "nL", where n             */
/*                indicates 2 or more blank lines.                           */
/*                                                                           */
/*          Input:  blank_line_ctr - number of blank lines encountered       */
/*                                   since the last non-blank line was       */
/*                                   output                                  */
/*                  line_ctr - number of lines output to postscript file     */
/*                             so far                                        */
/*                                                                           */
/*          Returns: new value of line_ctr                                   */
/*                                                                           */
/*****************************************************************************/

int output_blank_lines(blank_line_ctr,line_ctr)

int blank_line_ctr;
int line_ctr;

{  int count;
   int lines_left;
   int lines_on_next_page;

   count = line_ctr;
   if (blank_line_ctr + line_ctr >= MAX_LINES) {
      lines_left = MAX_LINES - line_ctr;
      lines_on_next_page = blank_line_ctr - lines_left;
      printf("%d L\n",lines_left);
      printf("EndPage\nStartPage\n");
      printf("%d L\n",lines_on_next_page);
      count = lines_on_next_page;
      }
   else
      if (blank_line_ctr==1) {
         printf ("B\n");
         count++;
         }
      else
         if (blank_line_ctr>1) {
            printf ("%d L\n",blank_line_ctr);
            count += blank_line_ctr;
            }
   return(count);
}

Newsgroups: comp.sys.sun.apps