I've posted several question to the list lately, and the list (Patrick
especially) has been extraordinarily helpful, so I thought I'd summarize
things a bit in the hope of inspiring other people...
(1) Flexible filtering.
At home I have a postscript printer and an old apple imagewriter II. I
want them both to be able to print the same selection of document types
without having to maintain seperate file_output_match entries.
Because I recently started working with LPRng in a professional capacity,
the following techniques became even more useful with 50 instead of 2
printers involved.
I made the assumption that for output to any device, the filter path
is going to look something like:
<filetype> -> ... -> postscript -> ... -> printer
For non-postscript printers (like my imagewriter), I use ghostscript to
rasterize the job.
This means I was able to create a default file_output_match that looks
like this:
file_output_match = [
# decompression filters
*gzip_compressed* filter \%s{gzip_decompress}
*bzip2_compressed* filter \%s{bzip2_decompress}
# image filters
*gif* filter \%s{gif_converter}
*jpeg* filter \%s{jpeg_converter}
*tiff* filter \%s{tiff_converter}
*png* filter \%s{png_converter}
# misc document types
*pdf* filter \%s{pdf_converter}
*dvi* filter \%s{dvi_converter}
## pbm stuff
*pnm* filter \%s{pnm_converter}
*ppm* filter \%s{pnm_converter}
*pgm* filter \%s{pnm_converter}
*pbm* filter \%s{pnm_converter}
## text files
*roff* filter \%s{troff_converter}
]
All of the converters in the above list produce postscript output. You'll
notice that '*text*' is conspicuously missing -- this is because some
printers can handle raw text output without conversion to postscript, so
this entry is handled on a per-printer basis.
All of the above entries use the 'filter' keyword so that their output is
run back through ifhp where it will be handled by indivdual printer
entries.
I have a "generic postscript printer" entry that looks something like this:
[ apple postscript ps ]
pjl@
pcl@
ps
text@
file_output_match += [
*postscript* ps
*text* filter \%s{a2ps_converter}
]
It uses the '+=' operator to add to the default file_output_match entry,
above, an entry for postscript files (which are passed to the printer) and
an entry for text files (which are processed with a2ps).
With this in place, any additional printers (such as my lexmark optra e312)
look like this:
[ lope312 ]
tc=ps
And they can print any document type defined in the default
file_output_match setting. Of course, the entry needs to be extended with
the various feature code from the appropriate PPD file, but basic printing
will work just fine at this point.
A non-postscript printer, such as my imagewriter, would look something like
this:
[ imagewriter ]
status@
pjl@
pcl@
ps@
text
raw
gs_device=iwhi
file_output_match += [
*text* text
*postscript* raw \%s{gs_converter}
]
Text is passed raw to the printer, and postscript documents -- either those
submitted by the user or those that result from the default
file_output_match -- are handled by ghostscript.
All this means that when I want ifhp to handle a new document type for all
of my printers, I only need to edit a single entry, and it will effect all
printer entries in the file.
(2) Code reuse.
After typing in the information from the Lexmark PPD file, I realized that
several features (such as media type or paper size) were repeating the same
code over and over again. This is, of course, a sure sign that some sort
of "subroutine" would be a good solution. Fortunately, ifhp provides a
reasonably elegant solution.
Let's say that my printer supports letter, legal, and a4 paper, and the
code to set the paper size looks like this:
2 dict dup /PageSize [\%s{pagesize}] put dup /ImagingBBox null put setpagedevice
I make on entry that looks like this:
ps_pagesize = % Set paper size
2 dict dup /PageSize [\%s{pagesize}] put dup /ImagingBBox null put
setpagedevice
Now, for each paper size, I only need the following:
ps_letter = [ pagesize=612\040792 ]
ps_legal = [ pagesize=612\0401008 ]
ps_a4 = [ pagesize=595\040842]
(note that \040 is octal for an ASCII space character)
If the user prints a document using the following command line:
lpr -Z legal file.ps
The following code will be prepended to the print job:
% Set paper size
2 dict dup /PageSize [612 1008] put dup /ImagingBBox null put setpagedevice
The same technique can be used for media types:
ps_media = % Set media type
<< /MediaType (\%s{media}) /Policies << /MediaType 2 >> >> setpagedevice
ps_plain = [ media=Letter ]
ps_cardstock = [ media=Card\040Stock ]
ps_transparency = [ media=Transparency ]
ps_labels = [ media=Labels ]
If your printer supports 15 or 20 different types of media, this can save
a lot of space in your ifhp.conf, and make it far more readable.
Hope someone found this useful,
-- Lars
PS The example entry above for the imagewriter is a simplication of what
I'm actually using. I've got things set up so that:
lp -d imagewriter -o draft file.txt
will print using text mode on the imagewriter, but
lp -d imagewriter -o faster file.txt
lp -d imagewriter -o best file.txt
Will both run the text through a text-to-ps converter (a2ps or enscript)
and then print using bitmap mode.
Additionally,
lp -d imagewriter -o draft file.ps
will correctly detect that file.ps is not a text file and will pass it
off to ghostscript for correct handling.
If you've got an old dot matrix printer and are interested in the
script I'm using, let me know.
--
Lars Kellogg-Stedman <[EMAIL PROTECTED]> --> http://www.larsshack.org/
-----------------------------------------------------------------------------
If you need help, send email to [EMAIL PROTECTED] (or lprng-requests
or lprng-digest-requests) with the word 'help' in the body. For the impatient,
to subscribe to a list with name LIST, send mail to [EMAIL PROTECTED]
with: | example:
subscribe LIST <mailaddr> | subscribe lprng-digest [EMAIL PROTECTED]
unsubscribe LIST <mailaddr> | unsubscribe lprng [EMAIL PROTECTED]
If you have major problems, send email to [EMAIL PROTECTED] with the word
LPRNGLIST in the SUBJECT line.
-----------------------------------------------------------------------------