From: bhansen@valve.heart.rri.uwo.ca (Bjarne Hansen)
Subject: Re: Postscript files in WordPerfect 5.1
Reply-To: bhansen@valve.heart.rri.uwo.ca
Organization: University of Western Ontario
Date: Tue, 26 Jan 1993 19:57:34 GMT
Keywords: Postscript, printing, control codes

In article <1993Jan22.213806.6123@sol.UVic.CA> rhorner@ugly.UVic.CA (Roger   
Horner) writes:
> ...
> I then uploaded the postscript file to the unix machine with kermit
> in text mode and tried to print it.  The printer gave an error
> message (C5 I think), and then removed the file from the queue without
> printing anything.
> 
> I have a friend who successfully printed the a file created in
> MS-Word using a similar technique.  I compared his and my postscript
> files and mine seems to have a slightly different format, but both
> files can be displayed successfully with ghostscript. 
>
> Roger Horner (rhorner@sirius.UVic.ca)          University of Victoria
> 4th Year Electrical Engineering Student        Victoria, BC, Canada
>

I don't know what the error codes on your particular printer mean, but
we have struggled in the past with printing PostScript files exported
from various DOS programs (CorelDraw and WP51 come to mind).  In each 
case the printer (a NEC LC-890) consistently choked on the PS file,
regardless of whether it was brought over to our network via Kermit,
FTP, or floppy.  

We discovered that the files that wouldn't print had unprintable 
characters (often a control-D together with other assorted control
characters) at the beginning and/or at the end of the file.  Once 
these were removed, the files printed OK.  You can check whether the
file you had problems with is corrupted the same way by opening it
with an editor capable of displaying control characters.  Under
Unix, vi or emacs will work.  The start of a PS file should look
something like:  

%!PS-Adobe-1.0
%%comments and document details
%%more comments and document details
..
( if you want more detailed info, the 'PostScript Language Reference
Manual' by Adobe Systems Inc, Addison-Wesley Publishing Co., will 
tell you more than you want to know :-)

Solution:  If this is why your file isn't printing, then try deleting
all the unprintable characters.  The above editors can do this, or you
can use the program below.  Cut out the C code and compile it either
on your PC or on a Unix machine (I tested it with MS-QuickC 2.51 on
a PC, and with the compiler on our Silicon Graphics.  Both work.)
To use, type 'isps postscript_print_file output_file' and 'output_file'
will be created from 'postscript_print_file' minus the nasty 
characters.  

Hope this helps with your problem.  If not, email me a copy of the 
PS file.  If you need a copy of the isps executable, let me know...

Bjarne Hansen  <bhansen@valve.heart.rri.uwo.ca>
               or NeXTmail at <bhansen@next2god.heart.rri.uwo.ca>

The axis of the earth sticks out visibly through the centre of each
and every town or city.  Oliver Wendell Holmes 1809-1894.
(especially Toronto...)
====================================================================

Sorry about the lines longer than 80 characters - hard not to exceed
in a program.  If the text is too messed up to make sense of, I can 
email, or repost without the tabs...
---------------------cut here-----isps.c source code------------------
/* isps.c  accepts two arguments, an input filename and an output
	filename.  It reads the first 2 characters of the input file
	and if they are "%!", it assumes that it is a Postscript file.
	Return codes are:
		0 - No errors, file is not Postscript
		1 - No filename or more than one supplied as arguments
		2 - Error in opening filename (e.g. doesn't exist)
		3 - Couldn't allocate enough memory for the file buffer
		4 - File had embedded control characters, and doesn't
			appear to be Postscript
		5 - File had embedded control characters, but appears to
			be Postscript
		6 - File is Postscript

	Some CorelDraw files seem to include a <CTRL>D as the first
	character.  To get around this, the program will scan the 1st
	256 characters for the strings "%!" and "PS" if the initial
	%! is not found.  WordPerfect generated PS files have also
	been observed that contain control characters.

	Written by Bjarne Hansen.  4-1318 Highbury Ave, London, Ont,
	Canada N5Y 5E5.    bhansen@valve.heart.RRI.UWO.CA
		
	You may freely distribute and use this program, but may not
	charge any fee for doing so.  Any modified versions of this
	program are subject to the same conditions.  

	Last modified 25 Jan 93.
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
#include <errno.h>

#define TRUE 1
#define FALSE 0
#define VERSION 1.04
#define KEYWORDS_THRESHOLD 13 /*# PS keywords to declare file PS*/
#define NUM_KEYWORDS 13
#define MIN_BUF_SIZE 1000 /*arbitrary min buffer for PS file*/

typedef short int Boolean;

extern int main( int argc, char *argv[])
{
	FILE *fptr, *fptr2;
	char *buf, *tmp_buf_ptr;
	char keywords[NUM_KEYWORDS][12] =   {   "{",
									 
		"}",
									 
		" def",
									 
		" dup",
									 
		" pop",
									 
		" exch",
									 
		" dict",
									 
		" bind",
									 
		" lineto",
									 
		" moveto",
									 
		" newpath",
									 
		" stroke",
									 
		" showpage"
									 
	};
	Boolean First_Time_Thru = TRUE;
	Boolean Found_Ctrl_Chr = FALSE;
	Boolean Found_PS = FALSE, Found_PS_in_middle = FALSE;
	Boolean Found_Trailer = FALSE;
	Boolean Verbose = FALSE;
	int i, j, num_keywords_found = 0, num_end = 0;
	long int file_length, buf_length = 40000;
	size_t num_char_read, num_char_written;

	if( argc == 4 && (argv[3][0] == '/') && 
			(toupper(argv[3][1]) == 'V') )
		Verbose = TRUE;
	if( argc == 3 || (argc == 4 && Verbose) )
	{   if( (fptr = fopen(argv[1], "rb")) && 
			(fptr2 = fopen(argv[2], "wb")) )
		{   fseek(fptr, (long)0, SEEK_END);
			file_length = ftell(fptr);
			rewind(fptr);
			if( Verbose ) printf("Length = %ld\n",  
file_length);
			
			/*use the length of the file as buffer size, or*/
			/*40000, whichever is less*/ 
			if( file_length < buf_length )
				buf_length = file_length;   
			
			/* Dynamically allocate a large file buffer.*/
			/* If there's not enough memory for it, cut the*/
			/* buffer size in half and try again.*/
			while( (buf = (char *)malloc( (size_t)buf_length  
)) == NULL )
			{   buf_length /= 2;
				if( buf_length < MIN_BUF_SIZE )
				{   fprintf( stderr, "Can't allocate  
enough memory for the file buffer.\n");
					exit( 3 );
				}
			}
			
			/*Read in file to buffer, changing non-printable*/
 			/*characters to whitespace*/
			/*Rewrite the file to 'outputfile'.Repeat until  
EOF */
			while( !ferror(fptr) && !feof(fptr) && 
				!ferror(fptr2) && !feof(fptr2) )
			{   num_char_read = fread( buf, 1, (size_t)
					 buf_length-1, fptr );
				buf[num_char_read] = '\0';  
				/*change buf to a string for string fcns*/
				for( i = 0; i < num_char_read-1; i++ )
				{   if( !isprint( buf[i] ) && ( buf[i] !=
 0xa) && ( buf[i] != 0xd) && (buf[i] != 0x9) )
					{   buf[i] = ' ';  /*CTRL chrs to  
whitespace*/
						Found_Ctrl_Chr = TRUE;
					}
				}

				if( First_Time_Thru )
				{   /*check 1st two char for '%!'*/
					if( buf[0] == '%' && buf[1] == '!'  
)
					{   Found_PS = TRUE;
					}else
					{   /*look for strings "%!"  
followed by "PS"*/
						if( ((tmp_buf_ptr =  
strstr( buf, "%!") ) != NULL) && (strstr( tmp_buf_ptr, "PS") != NULL) )
						{   /*seems to be PS, so  
put 1st two */
							/*char to "%!" and  
whitespace the */
							/*rest up to  
tmp_buf_ptr+2  */
							buf[0] = '%';
							buf[1] = '!';
							for( i = 2; i <  
tmp_buf_ptr - buf + 2; i++ )
							{   buf[i] = ' ';
							}
							Found_PS_in_middle  
= TRUE;
						}

						/*count # keywords in 1st  
2000 chars */
						for( i=0; i<NUM_KEYWORDS;  
i++)
						{   tmp_buf_ptr = buf;
							if( Verbose )  
printf("counting keyword %s", keywords[i]);
							j = 0;
							do
							{   tmp_buf_ptr =  
strstr( tmp_buf_ptr+1, keywords[i]);
								j++;
							}while(  
(tmp_buf_ptr != NULL) && ((tmp_buf_ptr - buf) < 2000) );
							j--;
							if( Verbose )  
printf(" - %d instances\n", j);
							num_keywords_found  
+= j;
						}
					}   /*end of else, when '%!' are  
not 1st */
						/*two chrs in file*/
					First_Time_Thru = FALSE;
				}   /*end of 1st time thru checks*/

				/*look for %%Trailer*/
				if( (tmp_buf_ptr = strstr(buf,  
"%%Trailer")) != NULL )
				{   if( Verbose ) printf("found Trailer  
comment.\n");
					Found_Trailer = TRUE;
					/*search for "end" */
					if( (tmp_buf_ptr =  
strstr(tmp_buf_ptr, "end")) != NULL )
					{   if( Verbose ) printf("found  
'end'.\n");
						*(tmp_buf_ptr + 3) = '\0';
						strcat( buf,  
"\nshowpage\n");
					}else
					{   if( Verbose ) printf("did not  
find 'end'.\n");
						tmp_buf_ptr = strstr(buf,  
"%%Trailer");
						*(tmp_buf_ptr + 9) = '\0';
						strcat( buf,  
"\nshowpage\n");
					}
				}else
				{   /*did not find a %%Trailer*/
				}

				/*write the changed buffer to output file  
*/
				num_char_written = fwrite( buf, 1,  
strlen(buf), fptr2 );
			
			}   /*end of while that reads in file, writes out  
*/
			if( ferror(fptr) )
			{   fclose(fptr);
				fclose(fptr2);
				fprintf(stderr, "Error occurred while  
reading file.\n");
				exit( 2 );
			}else if( ferror(fptr2) | feof(fptr2) )
			{   fclose(fptr);
				fclose(fptr2);
				fprintf(stderr, "Error occurred while  
writing file.\n");
				exit( 2 );
			}else if( feof(fptr) )
			{   /*finished reading in file,  ctrl chrs to '  
'*/
				/*and writing to output file.*/

				fclose(fptr);
				fclose(fptr2);

				/*now check the various flags to decide  
what */
				/*type of file it is*/
				if( Found_PS )
				{   if( Verbose ) 
					{   printf("Found 'percent-bang'  
as 1st two characters in the file.\n");
						if( Found_Ctrl_Chr )
							printf("Found  
non-printable characters in file.  They were removed.\n");
						printf("It is  
PostScript.\n");
					}
					if( Found_Ctrl_Chr ) 
						exit( 5 );
					else
						exit( 6 );
				}else if( Found_PS_in_middle )
				{   if( Verbose ) 
					{   printf("Found 'percent-bang',  
but not as 1st two characters in the file.\n");
						if( Found_Ctrl_Chr )
							printf("Found  
non-printable characters in file.  They were removed.\n");
						printf("Found %d instances  
of PostScript keywords in file.\n", num_keywords_found);
						if( num_keywords_found >  
KEYWORDS_THRESHOLD )
							printf("It is  
PostScript.\n");
						else
							printf("It is not  
PostScript.\n");
					}
					if( num_keywords_found >  
KEYWORDS_THRESHOLD )
						exit( 5 );
					else
						exit( 4 );
				}else if( num_keywords_found  
>KEYWORDS_THRESHOLD )
				{   if( Verbose )
					{   printf("Found %d instances of  
PostScript keywords in file.\n", num_keywords_found);
						printf("It is  
PostScript.\n");
					}
					exit( 5 );
				}else
				{   if( Verbose ) printf("File is not  
PostScript.\n");
					exit( 0 );
				}
			}
		}   /*end of if that tried to open file */
		else
		{   printf( "Error in opening file %s.\n", argv[1] );
			exit( 2 );
		}
	}   /*end of if that checked command-line parameters rec'd*/
	else
	{   printf("\n\nISPS - Checks text files to determine if they are  
PostScript.\n");
		printf("Corrects some irregularities and rewrites the file  
to 'outputfile'.\n");
		printf("Version %4.2f by Bjarne Hansen\n\n", VERSION);
		printf("Return codes are:\n");
		printf("\t0 - No errors, file is not Postscript\n"); 
		printf("\t1 - No filename or more than one supplied as  
arguments\n"); 
		printf("\t2 - Error in opening filename (e.g. doesn't  
exist)\n"); 
		printf("\t3 - Couldn't allocate enough memory for the file  
buffer\n"); 
		printf("\t4 - File had too few PS characteristics to be  
sure it is Postscript\n"); 
		printf("\t5 - File had extraneous characters, but appears  
to be Postscript\n"); 
		printf("\t6 - File is Postscript\n\n"); 
		printf("Syntax:  %s filetotest outputfile  
[/V[erbose]]\n\n", argv[0] );
		exit( 1 );
	}
}	/*end of isps.c */
------------------------------end----------------------------------------