[mod.sources] v06i106: Filter for HP Laserjet

sources-request@mirror.UUCP (08/13/86)

Submitted by: cca!seismo!vsedev!ron (Ron Flax)
Mod.sources: Volume 6, Issue 106
Archive-name: lj_filter

[  I wrote the Makefile; also see my notes at the end of the README.
   I don't have a LaserJet with which to test this program.  -r$ ]

#!/bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# Wrapped by mirror!rs on Tue Aug 12 18:11:24 EDT 1986
# Contents:  README laser.1 laser.c Makefile
 
echo x - README
if test -f README ; then
    echo README exists, putting output in $$README
    OUT=$$README
else
    OUT=README
fi
sed 's/^XX//' > $OUT <<'@//E*O*F README//'
XXThe file laser.c is the source to a program that will prepend the
XXdesired setup codes for the Hewlet Packard LaserJet Printers.  It takes
XXinto account such things as page orientation, line spacing, typeface
XXselection, and most, if not all of the other print attributes available
XXon the LaserJet.

XXTo compile simply type "make" then install the program and manpage in the
XXappropriate directories for your system.  If anyone has any problems
XXthey can reply to me at the address below.

XXThe only system dependencies that I can think of off hand are the fact
XXthat the program uses 'getopt(3)' of which a PD version was posted a
XXwhile back, and a selection of the print spooling program usually
XX'lpr(1)' or on System V 'lp(1)'.  Either will work, there's even an
XXoption to allow results to be send to the standard output.

XXMost of the typeface selections set default settings for other options
XXin case you are lazy and only want to select a font by it's typeface
XXname.  One other VERY IMPORTANT point I would like to make is that if
XXyou don't have a particular font cartridge to use some of the features
XXdescribed in the source, then you can't get there from here...

XX--
XXron@vsedev.UUCP	       (Ron Flax)
XXUUCP:	..!seismo!vsedev!ron
XXARPA:	vsedev!ron@seismo.CSS.GOV

XX[ MODERATOR'S NOTE:  The /lib/cpp on my 4.2BSD Vax750 couldn't deal
XX  with the long #define for HELP in the source; I added code to
XX  #ifdef it out, but note that the Makefile by default enables it.
XX  If get a "token too long" error, that's probably the cause.  -r$ ]
@//E*O*F README//
chmod u=rw,g=rw,o=rw README
 
echo x - laser.1
if test -f laser.1 ; then
    echo laser.1 exists, putting output in $$laser.1
    OUT=$$laser.1
else
    OUT=laser.1
fi
sed 's/^XX//' > $OUT <<'@//E*O*F laser.1//'
XX.TH LASER 1 
XX.SH NAME
XXlaser \- laser printer preprocessor
XX.SH SYNTAX
XX.B laser
XX[ -{options} ]
XX[ file ] ...
XX.SH DESCRIPTION
XX.I Laser
XXcauses the
XX.I files
XXto be queued for printing on the laser printer.  If no files are named, the
XXstandard input is read.  Actually 
XX.I Laser
XXreally only prepends the proper codes to set up the printer then
XXfeeds the output to the system line printer spooler 
XXfor further processing and spooling.
XX.TP
XXLaser Command Options:
XX.TP
XX.B c num
XXCharacter Set where num is in the range of 1 to 18.  The numbers have
XXthe following meanings:
XX.DS L
XX 1   Roman-8          2   USASCII         3   Roman Ext
XX 4   Danish/Norwegian 5   United Kingdom  6   French
XX 7   German           8   Italian         9   Swedish
XX 10  Spanish          11  Legal           12  Linedraw
XX 13  Math8            14  Math8a          15  Math8b
XX 16  Math7            17  PiFont          18  PiFonta
XX.DE
XX.TP
XX.B o [ P or L ]
XXOrientation, portrait or landscape.
XX.TP
XX.B t num
XXTypeface selection should be between the range of 1 to 10.  The numbers
XXhave the following meanings:
XX.DS L
XX 1   Courier          2   Line Printer   3   Helvetica
XX 4   Times Roman      5   Prestige Elite 6   Gothic
XX 7   Pica             8   Script         9   Caslon
XX 10  Orator
XX.DE
XX.TP
XX.B h num
XXPoint size which can be selected with a number between 1 and 6.  The
XXnumbers have the following meanings:
XX.DS L
XX 1   7 Pt.            2   8 Pt.         3   8.5 Pt.
XX 4   10 Pt.           5   12 Pt.        6   14.4 Pt.
XX.DE
XX.TP
XX.B p num
XXPitch selection can be either 1) 10cpi 2) 12cpi, or 3) 16.66cpi.
XX.TP
XX.B s [ P or L ]
XXSpacing, proportional or fixed.
XX.TP
XX.B l num
XXLines per inch, valid values are 1, 2, 3, 4, 6, 8, 12, 16, 24, etc.
XX.TP
XX.B i
XXItalic, turns on italic mode for entire document.
XX.TP
XX.B b
XXBold, turns on bold mode for entire document.
XX.TP
XX.B O num
XXOffset from column zero.  Values can be any positive integer less than
XXeighty.
XX.TP
XX.B P num
XXPagestep, this is the number of lines that are needed to force the
XXprinter to handle standard size sheets of paper.  This option is
XXhardwired in at eight lines.  The option is provided so that you can
XXdisable this feature.
XX.TP
XX.B F num
XXForms length, this is the size (number of lines) of the paper. Default
XXvalues for both portrait and landscape sheets are 66 and 54
XXrespectfully.
XX.TP
XX.B w
XXTells 
XX.I laser
XXto send the output to the standard output so that it can be piped to
XXanother process or directed to another device.
XX.PP
XXIt is also possible and probably advisable to simply select a 
XX.I typeface
XXand maybe a left margin
XX.I offset
XXvalue and let the rest of the options run at their default values for
XXthe typeface selected.
XX.SH SEE ALSO
XXlpr(1),
XXlp(1),
XXHewlet-Packard Technical Reference Guide
XX.SH "AUTHOR"
XXRon Flax
@//E*O*F laser.1//
chmod u=rw,g=rw,o=rw laser.1
 
echo x - laser.c
if test -f laser.c ; then
    echo laser.c exists, putting output in $$laser.c
    OUT=$$laser.c
else
    OUT=laser.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F laser.c//'
XX/*
XX *			L A S E R . C 
XX *
XX * $Revision: 1.5 $
XX *
XX * $Log:	laser.c,v $
XX * Revision 1.5  86/07/14  17:51:09  ron
XX * Prepared for distribution
XX * 
XX * Revision 1.4  86/07/14  16:34:19  ron
XX * Cleaned up code, generally made more human readable.
XX * 
XX * Revision 1.3  86/07/14  15:05:31  ron
XX * Basically re-wrote the whole damned thing to support all, well most
XX * of the LaserJet features that are available.  Instead of simply supporting
XX * those that were originally used.  The program now supports all of the
XX * HP font cartridges with most of the attributes available...
XX * 
XX * Revision 1.2  86/07/14  09:46:30  ron
XX * Added distinctive RCS header
XX * 
XX */
XX#ifndef lint
XXstatic char RCSid[] = "@(#)$Header: laser.c,v 1.5 86/07/14 17:51:09 ron Exp $";
XX#endif

XX#include <stdio.h>


XX#define	LPRCMD "/usr/bin/lp 2>/dev/null 2>&1"

XX/*  If your system can handle it... */
XX/* #define BIGHELPTEXT		/* ... mine can't */

XX#ifndef	BIGHELPTEXT
XX#define HELP() fprintf (stderr, "Please read the manpage.\n");
XX#define USAGE() fprintf (stderr, "Please read the manpage.\n");

XX#else
XX#define USAGE() fprintf (stderr, \
XX    ">>>> Type 'laser -H' to display a help screen.\n")
XX#define HELP()	fprintf (stderr, \
XX"Laser Command Options:\n\
XX  c	--	Character Set\n\
XX    (1)  Roman-8        (2)  USASCII  (3)  Roman Ext. (4)  Danish/Norwegian\n\
XX    (5)  United Kingdom (6)  French   (7)  German     (8)  Italian\n\
XX    (9)  Swedish       (10)  Spanish (11)  Legal     (12)  Linedraw\n\
XX   (13)  Math8         (14)  Math8a  (15)  Math8b    (16)  Math7\n\
XX   (17)  PiFont        (18)  PiFonta\n\
XX  o	--	Orientation (Portrait or Landscape, P or L)\n\
XX  t	--	Typeface\n\
XX    (1)  Courier        (2)  Line Printer   (3)  Helvetica\n\
XX    (4)  Times Roman    (5)  Prestige Elite (6)  Gothic\n\
XX  h	--	Point Size (character height)\n\
XX    (1)  7 Pt. (2)  8 Pt. (3)  8.5 Pt. (4)  10 Pt. (5)  12 Pt. (6)  14.4 Pt.\n\
XX  p	--	Pitch\n\
XX    (1)  10 cpi (2)  12 cpi (3)  16.66 cpi\n\
XX  s	--	Spacing (Proportional or Fixed, P or F)\n\
XX  l	--	Lines per inch (1, 2, 3, 4, 6, 8, 12, 16, 24)\n\
XX  i	--	Italic\n\
XX  b	--	Bold\n\
XX  O	--	Offset from left edge (number of spaces)\n\
XX  P	--	Page Step (number of extra lines)\n\
XX  F	--	Forms Length (number of lines in form)\n\
XX  w	--	Send results to standard output\n")
XX#endif

XXstatic char *Symbols[] = 
XX{
XX	"\033(8U", 	/* Roman-8 */
XX	"\033(0U",	/* USASCII */
XX    	"\033(0E",	/* Roman Ext. */
XX	"\033(0D",	/* Danish/Norwegian */
XX	"\033(1E",	/* United Kingdom */
XX	"\033(0F",	/* French */
XX	"\033(0G",	/* German */
XX	"\033(0I",	/* Italian */
XX	"\033(0S",	/* Swedish/Finnish */
XX	"\033(1S",	/* Spanish */
XX	"\033(1U",	/* Legal */
XX	"\033(0B",	/* Line Draw */
XX	"\033(8M",	/* Math8 */
XX	"\033(0Q",	/* Math8a */
XX	"\033(1Q",	/* Math8b */
XX	"\033(0M",	/* Math7 */
XX	"\033(15U",	/* PiFont */
XX	"\033(2Q",	/* PiFonta */
XX	0
XX};

XXstatic char *Spacing[] = 
XX{
XX	"\033(s1P",	/* Proportional */
XX	"\033(s0P",	/* Fixed */
XX	0
XX};

XXstatic char *Type[] =
XX{			/* Yes I know their not in order... */
XX	"\033(s3T",	/* Courier (default) */
XX	"\033(s0T",	/* Line Printer */
XX	"\033(s4T",	/* Helvetica */
XX	"\033(s5T", 	/* Times Roman */
XX	"\033(s8T", 	/* Prestige Elite */
XX	"\033(s6T", 	/* Gothic */
XX	"\033(s1T",	/* Pica */
XX	"\033(s7T",	/* Script */
XX	"\033(s9T",	/* Caslon */
XX	"\033(s10T",	/* Orator */
XX	0
XX};

XXstatic char *Orientation[] = 
XX{
XX	"\033&l0O", 	/* Portrait */
XX	"\033&l1O",	/* Landscape */
XX	0
XX};

XXstatic char *Point[] = 
XX{
XX	"\033(s7V",	/* 7 Pt. */
XX	"\033(s8V",	/* 8 Pt. */
XX	"\033(s8.5V",	/* 8.5 Pt. */
XX	"\033(s10V", 	/* 10 Pt. */
XX	"\033(s12V",	/* 12 Pt. */
XX	"\033(s14.4V",	/* 14.4 Pt */
XX	0
XX};

XXstatic char *Pitch[] =
XX{
XX	"\033(s10H",	/* 10 CPI */
XX	"\033(s12H",	/* 12 CPI */
XX	"\033(s16.6H",	/* 16.66 CPI */
XX	"",		/* no pitch for proportional spacing */
XX	0
XX};

XXstatic char *Lpi[] = 
XX{
XX	"\033&l7.27c66F", /* 66 lines per page with 1/2 at top and bot */
XX	"\033&l1d66F",    /* 1 lpi */
XX	"\033&l2d66F",    /* 2 lpi */
XX	"\033&l3d66F",    /* 3 lpi */
XX	"\033&l4d66F",    /* 4 lpi */
XX	"\033&l6d66F",    /* 6 lpi */
XX	"\033&l8d66F",    /* 8 lpi */
XX	"\033&l12d66F",   /* 12 lpi */
XX	"\033&l16d66F",   /* 16 lpi */
XX	"\033&l24d66F",   /* 24 lpi */
XX	0
XX};

XXstatic char *Italic = "\033(s1S";

XXstatic char *Bold   = "\033(s3B";

XX#define		CTRL(c)		('c' & 037)

XX/*
XX *  Defaults
XX */

XXint	sym = 1;
XXint	type = 0;
XXint	spc = 1;
XXint	orient = 0;
XXint	ps = 3;
XXint	ptch = 0;
XXint	lpi = 0;
XXint	offset = 0;
XXint	stdoutput = 0;
XXint	pagestep = 8;
XXint	forms = 66;
XXint	italic = 0;
XXint	bold = 0;
XXint	Debug = 0;

XXmain (argc, argv)
XX	int argc;
XX	char *argv[];
XX{
XX	FILE           *fp, *fopen();
XX	extern char    *optarg;
XX	extern int      optind;
XX	int             i, c, errflg = 0;

XX	while ((c = getopt(argc, argv, "c:o:t:h:l:s:p:O:P:F:biHwd")) != EOF) {
XX		switch (c) {
XX		case 'd':
XX			++Debug;
XX			break;

XX		case 'l':
XX			lpi = atoi(optarg);
XX			switch (lpi) {
XX			case 1: case 2: case 3: case 4: case 6:
XX			case 8: case 12: case 16: case 24:
XX				if (Debug)
XX					fprintf(stderr, "lpi = %d, ", lpi);
XX				break;
XX			default:
XX				printf("Lines Per Inch values must be one of 1, 2, 3, 4, 6, 8, 12, 16, or 24.\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			break;
XX		case 'o':
XX			if (*optarg == 'p' || *optarg == 'P')
XX				orient = 0;
XX			else if (*optarg == 'l' || *optarg == 'L')
XX				orient = 1;
XX			else {
XX				printf("Orientation must be specified as either 'P' or 'L'.\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr,"orientation -> %c, ", *optarg);
XX			break;

XX		case 't':
XX			type = atoi(optarg);
XX			--type;
XX			if (type < 0 || type > 10) {
XX				printf("Typeface selection must be in the range of 1 (one) to 6 (six).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			/* Set up some defaults in case none of these are
XX			   chosen explicitly */
XX			switch (type) {
XX			case 0:
XX				sym = orient = ptch = 0; spc = 1; ps = 4;
XX				break;
XX			case 1:
XX				sym = spc = 1; orient = 0; ps = ptch = 2;
XX				break;
XX			case 2:
XX				sym = spc = 0; orient = 1; ps = ptch = 3;
XX				break;
XX			case 3:
XX				sym = spc = orient = 0; ps = 4; ptch = 1;
XX				break;
XX			case 4:
XX				sym = orient = 0; spc = 1; ps = 3; ptch = 1;
XX				break;
XX			case 5:
XX				sym = orient = 0; spc = 1; ps = 4; ptch = 1;
XX				break;
XX			case 6:
XX				sym = orient = 0; spc = ptch = 1; ps = 4;
XX				break;
XX			}
XX			if (Debug)
XX				fprintf (stderr, "typeface = %d, ", type);
XX			break;

XX		case 's':
XX			if (*optarg == 'P' || *optarg == 'p') {
XX				spc = 0;
XX				ptch = 3;
XX			}
XX			else if (*optarg == 'F' || *optarg == 'f')
XX				spc = 1;
XX			else {
XX				printf("Spacing must be specified as either 'P' or 'F'\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr, "spacing -> %c, ", *optarg);
XX			break;

XX		case 'h':
XX			ps = atoi(optarg);
XX			--ps;
XX			if (ps < 0 || ps > 6) {
XX				printf("Point size must be specified within the range of 1 (one) to 6 (six)\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr, "point size = %d, ", ps);
XX			break;

XX		case 'p':
XX			ptch = atoi(optarg);
XX			--ptch;
XX			if (ptch < 0 || ptch > 3) {
XX				printf("Pitch must be specified within the range of 1 (one) to 6 (six).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr, "pitch = %d, ", ptch);
XX			break;

XX		case 'c':	/* Symbol Set selection */
XX			sym = atoi(optarg);
XX			--sym;
XX			if (sym < 0 || sym > 18) {
XX				printf("Character set selection must be between the range of 1 (one) and 18 (eighteen).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf(stderr, "symbol set = %d, ", sym);
XX			break;

XX		case 'O':	/* Offset from left margin */
XX			offset = atoi(optarg);
XX			if (offset < 0 || offset > 80) {
XX				printf("Offset value must be specified between the range of 0 (zero) and 80 (eighty).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf(stderr, "offset = %d, ", offset);
XX			break;

XX		case 'P':
XX			pagestep = atoi(optarg);
XX			if (pagestep < 0 || pagestep > 66) {
XX				printf("Page Step value must be specified between the range of 1 (one) and 66 (sixty six).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr, "page step = %d, ", pagestep);
XX			break;

XX		case 'F':
XX			forms = atoi(optarg);
XX			if (forms < 0) {
XX				printf("Forms value must be greater than 0 (zero).\n");
XX				USAGE();
XX				exit(1);
XX			}
XX			if (Debug)
XX				fprintf (stderr, "forms = %d, ", forms);
XX			break;

XX		case 'i':
XX			italic++;
XX			if (Debug)
XX				fprintf (stderr, "italics set, ");
XX			break;

XX		case 'b':
XX			bold++;
XX			if (Debug)
XX				fprintf (stderr, "bold set, ");
XX			break;

XX		case 'w':	/* Standard Output */
XX			if (Debug)
XX				fprintf (stderr, "results to stdout, ");
XX			stdoutput++;
XX			break;

XX		case 'H':
XX			HELP();
XX			exit (1);

XX		default:
XX			errflg++;
XX			break;
XX		}
XX	}

XX	if (errflg) {
XX		fprintf (stderr, "laser [ - {options} ] [ files ] ... \n");
XX		USAGE();
XX		exit(1);
XX	}

XX	if (Debug) fprintf (stderr, "\b \n");

XX	if (argc == optind)
XX		sendjob(stdin);
XX	else
XX		for (; optind < argc; optind++)
XX			if ((fp = fopen(argv[optind], "r")) == NULL) {
XX				fprintf(stderr, "laser: can't open %s\n", argv[optind]);
XX				exit(1);
XX			} else {
XX				sendjob(fp);
XX				fclose(fp);
XX			}
XX	exit(0);
XX}

XXsendjob (fp)
XX	FILE *fp;
XX{
XX	FILE	*pp, *popen();
XX	int pg = pagestep, c, lines;

XX	if (! stdoutput) {
XX	    if ((pp = popen (LPRCMD, "w")) == NULL) {
XX		fprintf(stderr,"laser: cannot pipe to line printer device.\n");
XX		exit (1);
XX		}
XX	} else 
XX		pp = stdout;

XX		    /* reset		perf skip ON */
XX	fprintf (pp, "\033E%s%s%s%s%s%s%s\033&l1L\r",
XX	    Symbols[sym],
XX	    Spacing[spc], 
XX	    Orientation[orient],
XX	    Type[type],
XX	    Point[ps],
XX	    Lpi[lpi], 
XX	    Pitch[ptch]);

XX	if (forms != 66)
XX	    fprintf (pp, "\033&l%dF\r", forms);

XX	if (bold)
XX	    fprintf (pp, "%s\r", Bold);

XX	if (italic)
XX	    fprintf (pp, "%s\r", Italic);

XX	if (offset)
XX		fprintf (pp, "\033&a%dL\r", offset);

XX	while ((c = getc (fp)) != EOF) {
XX		if (c == CTRL(l)) {
XX			while (lines < forms) {
XX				putc ('\n', pp);
XX				lines++;
XX				}
XX			continue;	/* eat the ^L char */
XX		}
XX		if (c == CTRL(j)) {
XX			if (lines == forms) {
XX				while (pg-- > 0)
XX					putc ('\n', pp);
XX				lines = 0;
XX				continue;
XX			} else
XX				lines++;
XX		}
XX		putc (c, pp);
XX	}
XX	fprintf (pp, "\033E"); /* reset the printer to default settings */
XX	pclose (pp);
XX}
@//E*O*F laser.c//
chmod u=rw,g=rw,o=rw laser.c
 
echo x - Makefile
if test -f Makefile ; then
    echo Makefile exists, putting output in $$Makefile
    OUT=$$Makefile
else
    OUT=Makefile
fi
sed 's/^XX//' > $OUT <<'@//E*O*F Makefile//'
XX# Where is getopt on your system?
XXGETOPT	= -lgetopt

XX# If you get errors, comment out the next line.
XXDEFS	= -DBIGHELPTEXT

XXCFLAGS	= -O $(DEFS)

XXlaser:	laser.c
XX	cc $(CFLAGS) -o laser laser.c $(GETOPT)
@//E*O*F Makefile//
chmod u=rw,g=rw,o=rw Makefile
 
echo Inspecting for damage in transit...
temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
      31     263    1528 README
     101     486    2729 laser.1
     452    1628   10042 laser.c
      10      35     200 Makefile
     594    2412   14499 total
!!!
wc  README laser.1 laser.c Makefile | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if test -s $dtemp
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0