If you've got lots of users, all of them using various printers, then you probably want to consider header pages as a necessary evil.
Header pages, also known as banner or burst pages identify to whom jobs belong after they're printed. They're usually printed in large, bold letters, perhaps with decorative borders, so that in a stack of printouts they stand out from the real documents that comprise users' jobs. They enable users to locate their jobs quickly. The obvious drawback to a header page is that it's yet one more sheet that has to be printed for every job, their ephemeral usefulness lasting not more than a few minutes, ultimately finding themselves in a recycling bin or rubbish heap. (Note that header pages go with each job, not each file in a job, so the paper waste might not be that bad.)
The LPD system can provide header pages automatically for your printouts if your printer can directly print plain text. If you've got a PostScript printer, you'll need an external program to generate the header page; see Header Pages on PostScript Printers .
In the
Simple Printer Setup
, we turned off header pages by specifying
sh
(meaning ``suppress header'') in the
/etc/printcap
file. To enable header pages for
a printer, just remove the sh
capability.
Sounds too easy, right?
You're right. You might have to provide an output filter to send initialization strings to the printer. Here's an example output filter for Hewlett Packard PCL-compatible printers:
#!/bin/sh # # hpof - Output filter for Hewlett Packard PCL-compatible printers # Installed in /usr/local/libexec/hpof printf "\033&k2G" || exit 2 exec /usr/libexec/lpr/lpf
of
capability. See
Output Filters
for more information.
Here's an example /etc/printcap
file for the printer
teak
that we introduced earlier; we enabled header
pages and added the above output filter:
# # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf:\ :of=/usr/local/libexec/hpof:
teak
, they get a header
page with each job. If users want to spend time searching
for their printouts, they can suppress header pages by
submitting the job with lpr -h
; see
Header Page Options
for more lpr
options.
Note:
LPD prints a form feed character after the
header page. If your printer uses a different character
or sequence of characters to eject a page, specify them
with the ff
capability in /etc/printcap
.
By enabling header pages, LPD will produce a long header, a full page of large letters identifying the user, host, and job. Here's an example (kelly printed the job named outline from host rose):
k ll ll
k l l
k l l
k k eeee l l y y
k k e e l l y y
k k eeeeee l l y y
kk k e l l y y
k k e e l l y yy
k k eeee lll lll yyy y
y
y y
yyyy
ll
t l i
t l
oooo u u ttttt l ii n nnn eeee
o o u u t l i nn n e e
o o u u t l i n n eeeeee
o o u u t l i n n e
o o u uu t t l i n n e e
oooo uuu u tt lll iii n n eeee
r rrr oooo ssss eeee
rr r o o s s e e
r o o ss eeeeee
r o o ss e
r o o s s e e
r oooo ssss eeee
Job: outline
Date: Sun Sep 17 11:04:58 1995
LPD appends a form feed after this text so the job starts
on a new page (unless you've got sf
(suppress form
feeds) in the destination printer's entry in
/etc/printcap
).
If you prefer, LPD can make a short header; specify
sb
(short banner) in the /etc/printcap
file.
The header page will look like this:
rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995
Also by default, LPD prints the header page first, then
the job. To reverse that, specify hl
(header last)
in /etc/printcap
.
Using LPD's built-in header pages enforces a particular paradigm when it comes to printer accounting: header pages must be free of charge.
Why?
Because the output filter is the only external program
that will have control when the header page is printed
that could do accounting, and it isn't provided with any
user or host information or an accounting file, so it
has no idea whom to charge for printer use. It's also not
enough to just ``add one page'' to the text filter or any
of the conversion filters (which do have user and host
information) since users can suppress header pages with
lpr -h
. They could still be charged for header pages
they didn't print. Basically, lpr -h
will be the
preferred option of environmentally-minded users, but you
can't offer any incentive to use it.
It's still not enough to have each of the filters
generate their own header pages (thereby being able to
charge for them). If users wanted the option of
suppressing the header pages with lpr -h
, they will
still get them and be charged for them since LPD does not
pass any knowledge of the -h
option to any of the
filters.
So, what are your options?
You can
af
capability), but if you have a well-known accounting
file, you can hard-code that into the output filter.
To facilitate the parsing step, use the sh
(short
header) capability in /etc/printcap
.
Then again, all that might be too much trouble, and
users will certainly appreciate the more generous
system administrator who makes header pages free.
As described above, LPD can generate a plain text header page suitable for many printers. Of course, PostScript can't directly print plain text, so the header page feature of LPD is useless---or mostly so.
One obvious way to get header pages is to have every
conversion filter and the text filter generate the header
page. The filters should should use the user and host
arguments to generate a suitable header page. The
drawback of this method is that users will always get a
header page, even if they submit jobs with lpr -h
.
Let's explore this method. The following script takes three arguments (user login name, host name, and job name) and makes a simple PostScript header page:
#!/bin/sh # # make-ps-header - make a PostScript header page on stdout # Installed in /usr/local/libexec/make-ps-header # # # These are PostScript units (72 to the inch). Modify for A4 or # whatever size paper you're using: # page_width=612 page_height=792 border=72 # # Check arguments # if [ $# -ne 3 ]; then echo "Usage: `basename $0` <user> <host> <job>" 1>&2 exit 1 fi # # Save these, mostly for readability in the PostScript, below. # user=$1 host=$2 job=$3 date=`date` # # Send the PostScript code to stdout. # exec cat <<EOF %!PS % % Make sure we don't interfere with user's job that will follow % save % % Make a thick, unpleasant border around the edge of the paper. % $border $border moveto $page_width $border 2 mul sub 0 rlineto 0 $page_height $border 2 mul sub rlineto currentscreen 3 -1 roll pop 100 3 1 roll setscreen $border 2 mul $page_width sub 0 rlineto closepath 0.8 setgray 10 setlinewidth stroke 0 setgray % % Display user's login name, nice and large and prominent % /Helvetica-Bold findfont 64 scalefont setfont $page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto ($user) show % % Now show the boring particulars % /Helvetica findfont 14 scalefont setfont /y 200 def [ (Job:) (Host:) (Date:) ] { 200 y moveto show /y y 18 sub def } forall /Helvetica-Bold findfont 14 scalefont setfont /y 200 def [ ($job) ($host) ($date) ] { 270 y moveto show /y y 18 sub def } forall % % That's it % restore showpage EOF
#!/bin/sh # # DVI to PostScript printer filter # Installed in /usr/local/libexec/psdf # # Invoked by lpd when user runs lpr -d # orig_args="$@" fail() { echo "$@" 1>&2 exit 2 } while getopts "x:y:n:h:" option; do case $option in x|y) ;; # Ignore n) login=$OPTARG ;; h) host=$OPTARG ;; *) echo "LPD started `basename $0` wrong." 1>&2 exit 2 ;; esac done [ "$login" ] || fail "No login name" [ "$host" ] || fail "No host name" ( /u/kelly/freebsd/printing/filters/make-ps-header $login $host "DVI File" /usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args
As we've mentioned before, the above scheme, though fairly
simple, disables the ``suppress header page'' option (the
-h
option) to lpr
. If users wanted to save a
tree (or a few pennies, if you charge for header pages),
they wouldn't be able to do so, since every filter's going
to print a header page with every job.
To allow users to shut off header pages on a per-job
basis, you'll need to use the trick introduced in section
Accounting for Header Pages
: write an output
filter that parses the LPD-generated header page and
produces a PostScript version. If the user submits the
job with lpr -h
, then LPD won't generate a header
page, and neither will your output filter. Otherwise,
your output filter will read the text from LPD and send
the appropriate header page PostScript code to the
printer.
If you've got a PostScript printer on a serial line, you
can make use of lprps
, which comes with an output
filter, psof
, which does the above. Note that
psof
doesn't charge for header pages.