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