*BSD News Article 24367


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!network.ucsd.edu!ogicse!cs.uoregon.edu!sgiblab!pacbell.com!toad.com!curt
From: curt@mofo.toad.com (Curt mayer)
Newsgroups: comp.os.386bsd.apps
Subject: HP laserjet enscript subset (shar file)
Message-ID: <41437@toad.com>
Date: 24 Nov 93 01:45:54 GMT
Article-I.D.: toad.41437
Sender: news@toad.com
Distribution: world
Organization: Mofo
Lines: 457
Nntp-Posting-Host: mofo.toad.com

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	Makefile
#	README
#	print.1
#	print.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X#	@(#)Makefile	5.3 (Berkeley) 5/11/90
X
XPROG=	print
X
X.include <bsd.prog.mk>
END-of-Makefile
echo x - README
sed 's/^X//' >README << 'END-of-README'
Xthis directory contains a PCL4/5 print formatter that prints 2 up.
Xit works on FreeBSD 1.0. it has been tested with a epson Actionlaser 1500.
Xit is free software. all rites reversed.
END-of-README
echo x - print.1
sed 's/^X//' >print.1 << 'END-of-print.1'
X.\"
X.Dd November 18, 1993
X.Dt PRINT 1
X.Os
X.Sh NAME
X.Nm print
X.Nd queue text files to PCL4 printer.
X.Sh SYNOPSIS
X.Nm print
X.Op Fl s
X.Op Fl l
X.Op Fl t Ar tabwidth
X.Op Fl p Ar printer_name
X.Op Ar text_file ...
X.Sh DESCRIPTION
X.Nm Print
Xprints files 2 pages side by side on 1 piece of paper on PCL4 printer.
XIf no files are specified, it reads stdin. 
X.Nm Print
Xusually does the right thing with nroff output. It fakes boldface rather well.
X.Pp
XOptions:
X.Bl -tag -width Ds
X.It Fl s
XSpecify graphically simple output, without the gaudy borders.
X.It Fl l
XSpecify formatting for 60 lines per page, instead of the default 66.
X.It Fl t
XSpecify the tab width. The default of 4 may irritate purists.
X.It Fl p
XSpecify the printer to spool to. The default printer is named
X.Em lj.
X.Sh ENVIRONMENT
XIf the following environment variables exist, they are used by
X.Nm print:
X.Bl -tag -width PAGELENGTH
X.It Ev PRINTER
XSpecifies an alternate printer.
X.It Ev TABWIDTH
XSpecifies the tab stop width.
X.It Ev PAGELENGTH
XSpecifies the page length. it may take the value of 60 or 66.
X.Sh AUTHOR
Xcurt@toad.com
X.Sh BUGS
XThere is no way to communicate a jobname to lpr. 
XThis is really a bug with BSD, since it has no printer access library.
XHasn't been tested on a real HP laserjet.
END-of-print.1
echo x - print.c
sed 's/^X//' >print.c << 'END-of-print.c'
X/*
X * take a list of filenames, and print the files 2 up on a PCL4 printer
X * Author:
X *	Curt Mayer: curt@toad.com
X * TODO:
X *	parameterize all fonts, so can do easily do 4 up someday.
X */
X#include	<stdio.h>
X#include	<sys/types.h>
X#include	<sys/stat.h>
X
X/*
X * mess with these numbers at your own peril - they are the result of
X * much jiggery-pokery
X */
X
X/* size of printable region in dots */
X#define	DOTSHIGH	2320
X#define	DOTSWIDE	3120
X
X/* these are in units of vmi and hmi of the page font */
X#define	TOPOFF		4
X#define	LEFTMARGIN	6
X#define	STARTSIDE1	87
X#define	CONTOFF		2
X
X/* height of shaded region in dots */
X#define	TOPLINE		80
X
X/* offset of printable region in dots */
X#define	TOPDOTS		50
X#define	LEFTDOTS	50
X
X/* width of rule lines on page in dots */
X#define	LINEWIDTH	2
X
X/* header font */
X#define	HFONTPOINTS	12
X#define	HFONTPITCH	10
X
X/* the header font size in dots */
X#define	HFONTHEIGHT	((HFONTPOINTS * 100) / 24)
X#define	HFONTWIDTH	(300 / HFONTPITCH)
X
X/* offset from left and right of header strings in dots */
X#define	TEXTMARGIN	50
X
X/* these are for the page font */
X#define	VMI_66		"5.5"
X#define	VMI_60		"6.1"
X#define	HMI			"7.2"
X#define	BOLDOFF		"0.6"
X
X#define	CONTCHAR	'+'
X#define	LPRCMD		"lpr -P%s -h >/dev/null 2>&1"
X
X#define	LP_DEFAULT		"lj"
X#define	TAB_DEFAULT		4
X#define	PAGELEN_DEFAULT	66
X
Xchar cmdbuf[80];
X
Xchar *printer = LP_DEFAULT;
Xint tabstop = TAB_DEFAULT;
Xint pagelen = PAGELEN_DEFAULT;
X
Xchar *vmi;
Xint gaudy = 1;
Xint line;
Xint side;
Xint col;
Xint pagenum;
X
XFILE *pp;
Xchar *filename;
Xtime_t now;
X
Xextern FILE *popen(), *fopen();
Xextern char *ctime();
Xextern char *getenv();
X
Xextern char *optarg;
Xextern int optind;
Xextern int opterr;
Xextern int getopt();
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	FILE *fp;
X	struct stat statb;
X	int i, c;
X	char *e;
X
X	time(&now);
X
X	if (e = getenv("PRINTER")) {
X		printer = e;
X	}
X
X	if (e = getenv("TABWIDTH")) {
X		tabstop = atoi(e);
X	}
X
X	if (e = getenv("PAGELEN")) {
X		pagelen = atoi(e);
X	}
X
X	opterr = 0;
X	while ((c = getopt(argc, argv, "slt:p:")) != EOF) {
X		switch(c) {
X		case 'l':
X			pagelen = 60;
X			break;
X		case 's':
X			gaudy = 0;
X			break;
X		case 't':
X			tabstop = atoi(optarg);
X			break;
X		case 'p':
X			printer = optarg;
X			break;
X		case '?':
X		default:
X			fprintf(stderr, 
X				"%s: [-sl] [-t <tabstop>] [-p <printer>] [<file> ...]\n", 
X				argv[0]);
X			exit(-1);
X		}
X	}
X
X	if (tabstop == 0) {
X		tabstop = TAB_DEFAULT;
X	}
X
X	switch (pagelen) {
X
X	case 66:
X#if PAGELEN_DEFAULT == 66
X	default:
X#endif
X		vmi = VMI_66;
X		pagelen = 66;
X		break;
X
X	case 60:
X#if PAGELEN_DEFAULT == 60
X	default:
X#endif
X		vmi = VMI_60;
X		pagelen = 60;
X		break;
X	}
X
X	argc -= optind;
X	argv += optind;
X
X	if (argc == 0) {
X		filename = "stdin";
X		sendjob(stdin);
X	} else {
X		for (i = 0; i < argc; i++) {
X			filename = argv[i];
X
X			if (stat(filename, &statb) != 0) {
X				perror(filename);
X				continue;
X			}
X
X			if ((statb.st_mode & S_IFMT) != S_IFREG) {
X				fprintf(stderr, "print: %s not a regular file\n", filename);
X				continue;
X			}
X
X			fp = fopen(filename, "r");
X			if (fp == NULL) {
X				fprintf(stderr, "print: can't open %s\n", filename);
X				continue;
X			}
X			
X			sendjob(fp);
X			fclose(fp);
X		}
X	}
X	if (pp)
X		pclose(pp);
X	exit (0);
X}
X
Xsendjob(fp)
XFILE *fp;
X{
X	int c;
X	int lastc;
X
X	if (!pp) {
X		sprintf(cmdbuf, LPRCMD, printer);
X		pp = popen(cmdbuf, "w");
X		if (pp == NULL) {
X			fprintf(stderr, "print: can't pipe to line printer\n");
X			exit(1);
X		}
X	}
X
X	line = 0;
X	side = 0;
X	col = 0;
X	pagenum = 1;
X
X	fprintf(pp, "\033E");
X	fprintf(pp, "\033&k2G");
X	fprintf(pp, "\033&l1O");
X	fprintf(pp, "\033(s0P");
X	fprintf(pp, "\033&l0L");
X	fprintf(pp, "\0339");
X	fprintf(pp, "\033&l0E");
X
X	drawpage();
X	fprintf(pp, "\033&a%dr%dC", TOPOFF + line, LEFTMARGIN + side * STARTSIDE1);
X
X	while ((c = getc(fp)) != EOF) {
X		switch (c) {
X		case 0x0c:
X			c = getc(fp);
X			if (c != EOF) {
X				line = pagelen - 1;
X				do_newline(0);
X			}
X			ungetc(c, fp);
X			break;
X		case '\n':
X			do_newline(0);
X			break;
X		case '\t':
X			do {
X				putc(' ', pp);
X			} while (++col % tabstop);
X			break;
X		case 0x8:
X			if (col) {
X				col--;
X				fprintf(pp, "\033&a%dr%dC", 
X					TOPOFF + line, LEFTMARGIN + side * STARTSIDE1 + col);
X				c = getc(fp);
X				if (c == lastc) {
X					fprintf(pp, "\033&k%sH \033&k%sH%c", BOLDOFF, HMI, c);
X					col++;
X					fprintf(pp, "\033&a%dr%dC", 
X						TOPOFF + line, LEFTMARGIN + side * STARTSIDE1 + col);
X				} else {
X					ungetc(c, fp);
X				}
X			}
X			break;
X		default:
X			if (col >= 80) {
X				do_newline(1);
X			}
X			if (c < ' ')
X				c = 0x7f;
X			putc(c, pp);
X			col++;
X			lastc = c;
X			break;
X		}
X	}
X	fprintf(pp, "\033E");
X}
X
Xdo_newline(wrap)
Xint wrap;
X{
X	putc('\n', pp);
X	if (++line == pagelen) {
X		if (side == 1) {
X			side = 0;
X			pagenum++;
X			fprintf(pp, "\014");
X			drawpage();
X		} else {
X			side = 1;
X		}
X		line = 0;
X	}
X	if (wrap) {
X		fprintf(pp, "\033&a%dr%dC%c", TOPOFF + line,
X			LEFTMARGIN + side * STARTSIDE1 - CONTOFF, CONTCHAR);
X	}
X	fprintf(pp, "\033&a%dr%dC", TOPOFF + line,
X		LEFTMARGIN + side * STARTSIDE1);
X	col = 0;
X}
X
Xdrawpage()
X{
X	char page[5];
X
X	sprintf(page, "%d", pagenum);
X
X	/* draw vertical line */
X	fprintf(pp, "\033*p%dx%dY", (DOTSWIDE / 2) + LEFTDOTS, TOPLINE + TOPDOTS);
X	fprintf(pp, "\033*c%da%dB", LINEWIDTH, DOTSHIGH);
X	fprintf(pp, "\033*c0P");
X
X	if (gaudy) {
X		/* draw filled horizontal rectangle */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", DOTSWIDE, TOPLINE);
X		fprintf(pp, "\033*c8G");
X		fprintf(pp, "\033*c2P");
X
X		/* top line */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", DOTSWIDE, LINEWIDTH);
X		fprintf(pp, "\033*c0P");
X
X		/* middle line */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, TOPLINE + TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", DOTSWIDE, LINEWIDTH);
X		fprintf(pp, "\033*c0P");
X
X		/* left line */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", LINEWIDTH, DOTSHIGH + TOPLINE);
X		fprintf(pp, "\033*c0P");
X
X		/* right line */
X		fprintf(pp, "\033*p%dx%dY", DOTSWIDE + LEFTDOTS, TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", LINEWIDTH, DOTSHIGH + TOPLINE);
X		fprintf(pp, "\033*c0P");
X
X		/* bottom line */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, DOTSHIGH + TOPLINE + TOPDOTS);
X		fprintf(pp, "\033*c%da%dB", DOTSWIDE, LINEWIDTH);
X		fprintf(pp, "\033*c0P");
X	} else {
X		/* draw horizontal line */
X		fprintf(pp, "\033*p%dx%dY", LEFTDOTS, TOPLINE + TOPDOTS);
X		fprintf(pp, "\033*c%db%dB", DOTSWIDE, LINEWIDTH);
X		fprintf(pp, "\033*c0P");
X	}
X
X	/* set header font */
X	fprintf(pp, "\033(s3T");
X	fprintf(pp, "\033(s3S");
X	fprintf(pp, "\033(s%dV", HFONTPOINTS);
X	fprintf(pp, "\033(s%dH", HFONTPITCH);
X
X	/* print header line */
X	fprintf(pp, "\033*p%dX", LEFTDOTS + TEXTMARGIN);
X	fprintf(pp, "\033*p%dY", TOPDOTS + TOPLINE - (HFONTHEIGHT / 2));
X	fputs(ctime(&now), pp);
X
X	fprintf(pp, "\033*p%dX", 
X		LEFTDOTS + (DOTSWIDE / 2) - ((strlen(page) * HFONTWIDTH) / 2));
X	fprintf(pp, "\033*p%dY", TOPDOTS + TOPLINE - (HFONTHEIGHT / 2));
X	fputs(page, pp);
X
X	fprintf(pp, "\033*p%dX", 
X		LEFTDOTS + DOTSWIDE - (strlen(filename) * HFONTWIDTH) - TEXTMARGIN);
X	fprintf(pp, "\033*p%dY", TOPDOTS + TOPLINE - (HFONTHEIGHT / 2));
X	fputs(filename, pp);
X
X	/* set page font */
X	fprintf(pp, "\033(s0T");
X	fprintf(pp, "\033(s8.5V");
X	fprintf(pp, "\033(s16.6H");
X	fprintf(pp, "\033&l%df%sC", pagelen, vmi);
X}
END-of-print.c
exit

-- 
	curt mayer
        curt@toad.com
        415-387-0217 home