/***	
 ***	psc.c --	$Revision: 1.6 $ $Date: 86/04/04 10:35:54 $
 ***	
 ***	Compress a PostScript file. 
 ***	
 ***	Ned Batchelder, University of Pennsylvania
 ***	ned@UPenn.CSnet
 ***/

# include <stdio.h>

# define RightMargin	70

char	*selfd = "[]{}/";	/* Self delimiting: Need no space around */
char	*ws = " \t\n";		/* White space characters */
char	lp = '(';		/* Opens a balanced text string */
char	rp = ')';		/* Closes a balanced text string */
char	lh = '<';		/* Opens a hex string */
char	rh = '>';		/* Closes a hex string*/
char	lit = '\\';		/* Quotes characters in strings */
char	com = '%';		/* Introduces comments (to end of line) */

/* 
 * Psc runs as a pure filter. The input is compressed to the output.
 */

main()
{
	int	plevel = 0;	/* The level of parens in a string */
	int	needspace = 0;	/* Found some space, must delimit */
	int	eatspace = 1;	/* We don't need any space now */
	int	incomment = 0;	/* Are we skipping a comment? */
	int	inhex = 0;	/* Are we in a hex string? */
	int	column = 0;	/* Counts output columns to keep lines short */
	int	keepch = 0;	/* For breaking strings */
	char	c;		/* The current character */
	
# define put(c)		{putchar(c); column++;}

	/* 
	 * First we copy the first line verbatim. This is to copy the comment
	 * for the file, the name of the file, and the initial '%!' if
	 * necessary.
	 */

	while ((c = getchar()) != '\n') {
		putchar(c);
	}
	putchar('\n');

	/* 
	 * Now we start compressing.
	 */
	
	while ((c = getchar()) != EOF) {
		if (incomment) {
			if (c == '\n') {
				incomment = 0;
			}
			continue;
		} else if (plevel) {
			if (column > RightMargin && keepch <= 0) {
				putchar('\\');
				putchar('\n');
				column = 0;
			}
			if (c == lit) {
				put(lit);
				put(getchar());
				keepch = 2;		/* Protect \ddd */
			} else if (c == lp) {
				put(lp);
				plevel++;
				keepch = 0;
			} else if (c == rp) {
				put(rp);
				plevel--;
				if (plevel == 0) {
					eatspace = 1;
					needspace = 0;
				}
			} else {
				put(c);
				keepch--;
			}
		} else if (inhex) {
			if (column > RightMargin) {
				putchar('\n');
				column = 0;
			}
			if (!index(ws, c)) {
				put(c);
			}
			if (c == rh) {
				eatspace = 1;
				needspace = 0;
				inhex = 0;
			}
		} else if (c == lh) {
			put(lh);
			inhex++;
		} else if (c == com) {
			if (column > RightMargin) {
				putchar('\n');
				column = 0;
			}
			incomment = 1;
			if (!eatspace) {
				needspace = 1;
			}
		} else if (index(ws, c)) {
			if (!eatspace) {
				needspace = 1;
			}
		} else if (index(selfd, c)) {
			if (column > RightMargin) {
				putchar('\n');
				column = 0;
			}
			put(c);
			eatspace = 1;
			needspace = 0;
		} else if (c == lp) {
			put(lp);
			plevel = 1;
			keepch = 0;
		} else {
			if (needspace) {
				putchar('\n');
				column = 0;
				needspace = 0;
			}
			put(c);
			eatspace = 0;
		}
	}

	putchar('\n');

	return 0;
}

/* end of psc.c */
