Creating a New Print Filter
A filter is used by the LP print service each time it
has to print a type of file that the printer cannot interpret. Creating
a new print filter is not easy, and it usually requires extensive experimentation.
The process of defining a new print filter consists of two steps:
A print filter can be as simple or as complex as needed.
Filters contain input types, output types, and complex options that provide a language
to process command-line arguments within the filter.
If you have nonPostScript printers, you have to create and add print filters
as required. First, you need to understand what print filters are and the
requirements that must be met by a filter program.
Writing a Print Filter Program
The LP print service provides filter programs in the /usr/lib/lp/postscript directory. These
filters cover most PostScript printing situations, where the destination printer requires the data
to be in PostScript format. A print filter program must be a binary
executable file.
Types of Filters
There are two types of print filters: fast filters and slow filters.
Fast filters do not require much processing time to prepare a file for printing.
They must have access to the printer when they run. To be capable
of detecting printer faults, a print filter must be a fast filter. Any
filter that uses the PRINTER keyword as a filter option must be installed
as a fast filter.
Slow filters require a great deal of processing time to prepare a file for
printing. They do not require access to the printer when they run. Slow
filters are run in the background so they do not tie up the
printer, allowing other files that do not need slow filtering to be
printed.
Converting Files
The LP print service uses print filters to convert files from one
content type to another content type. You can specify the accepted file content
types for each printer. The user specifies the file content type when submitting a
print request. Then, the LP print service finds a printer that can
print files of that content type. Because many applications can generate files for various
printers, this method is often sufficient. However, some applications can generate files that
cannot be printed on any available printers.
Each time the LP print service receives a request to print a type
of file that is in a format that cannot be accepted directly by
a printer, the LP print service tries to match the content type of
the print request with the content type of the available (or specified) printer.
If there is a match, the file can be sent directly to the
printer without filtering. If no match is found, or if the content type
specifies that a filter be used, the LP print service tries to match
the content type of the file with the input content type of
available filters. In addition, the LP print service tries to match the output
type of the filter with the content type of the printer. When an
appropriate filter is found, the print request is passed through the filter.
Handling Special Printing Modes
A print filter handles special printing modes and requests to print specific pages.
A special printing mode is needed to print any characteristics of print requests
that require a customized filter.
Filters handle the following characteristics:
Printer type
Character pitch
Line pitch
Page length
Page width
Pages to print
Character set
Form name
Number of copies
The LP print service provides default settings for these characteristics. However, a print
filter can handle some characteristics more efficiently. For example, some printers can handle
multiple copies more efficiently than the LP print service. So, in this case,
you can provide a filter for multiple-copy page control.
Detecting Printer Faults
Each printer has its own way of detecting printer faults and transmitting fault
signals to the LP print service. The LP print service only checks
for hang-ups (loss of carrier) and excessive delays in printing.
Some printers provide good fault coverage and can send a message that describes
the reason for a fault. Other printers indicate a fault by using signals
other than the signals for loss of carrier signal or shut off
of data flow. A filter is required to interpret this additional printer fault
information.
A filter can also put a print request on hold, wait for a
printer fault to clear, and then resume printing. With this capability, the print
request that was interrupted does not need to be reprinted in its entirety.
Only a filter that knows the control sequences used by a printer can
determine where to break a file into pages. Consequently, only such a filter
can find the place in the file where printing should start after a
fault is cleared.
When a print filter generates messages, those messages are handled by the LP
print service. If alerts are enabled, the LP print service sends alerts to
the system administrator. For further information, see Setting Up Printer Fault Alerts by Using LP Print Commands.
Requirements for a Print Filter Program
A print filter can be simple or complex, but it has to
meet the following requirements:
The filter should get the contents of a file from its standard input and send the converted file to the standard output.
A program cannot be used as a filter if it references external files. You might be tempted to use a program such astroff, nroff, or a similar word processing program as a filter. The LP print service does not recognize references to other files, known as include files, from a filter program. Because troff and nroff programs allow include files, they can fail when used as filters. If the program needs other files to complete its processing. The program t should not be used as a filter.
The filter should not depend on files that normally would not be accessible to a user. If a filter fails when run directly by a user, it will fail when run by the LP print service.
A slow filter can send messages about errors in the file to standard error. a fast filter should not. Error messages from a slow filter are collected and sent to the user who submitted the print request.
If a slow filter dies because it received a signal, the print request is stopped and the user who submitted the request is notified. Likewise, if a slow filter exits with a nonzero exit code, the print request is stopped and the user is notified. The exit codes from fast filters are treated differently.
If you want the filter to detect printer faults, it should also
meet the following requirements:
If possible, the filter should wait for a fault to be cleared before exiting. The filter should also continue to print at the top of the page where printing stopped after the fault is cleared. If you do not want use the continuation feature, the LP print service stops the filter before alerting the administrator.
The filter should send printer fault messages to its standard error as soon as the fault is recognized. The filter does not have to exit, but can wait for the fault to be cleared.
The filter should not send messages about errors in the file to standard error. These messages should be included in the standard output, where they can be read by the user.
The filter should exit with a zero exit code if the file is finished printing (even if errors in the file have prevented it from being printed correctly).
The filter should exit with a nonzero exit code, only if a printer fault has prevented the filter from finishing a print request.
When added to the filter table, the filter must be added as a fast filter.
Creating a Print Filter Definition
A print filter definition tells the LP print service about the filter, what
print filter program to run, what kind of conversion the print filter does,
and so on. A set of filter descriptor files are provided in
the /etc/lp/fd directory. These files describe the characteristics of the filters (for example,
fast filter or slow filter), and point to the filter programs (for example,
/usr/lib/lp/postscript/postdaisy).
When defining a new print filter, you must create a print filter
definition.
A print filter definition contains the following information used by the LP print
service:
Name of the filter program to run
Input types the filter program accepts
Output types the filter program produces
Printer types to which the filter program can send jobs
Names of specific printers to which the filter program can send jobs
Filter types (either fast or slow)
Options
You can type the characteristics as direct input to the lpfilter command. You
also can create a file that specifies the filter's characteristics, and use the
file name as input to the lpfilter command arguments. Such a file is
called a filter descriptor file and should be located in the /etc/lp/fd directory. These files
are not the filters themselves. Rather, these files point to the filters.
Whether you store the information in a file, or type the information directly
on the command line, use the following format:
Command: command-pathname [options]
Input types: input-type-list
Output types: output-type-list
Printer types: printer-type-list
Printers: printer-list
Filter type: fast or slow
Options: template-list
Note - If you provide more than one definition (that is, more than one line)
for any filter characteristic other than Options, only the second definition is used
by the print service.
The information can be arranged in any order, and not all the
information is required. When you do not specify values, the values shown in
the following table are assigned by default. These values are not very useful,
which is why you should specify values.
Table 8-1 Default Values for lpfilter Command
Item |
Default Value |
Input types |
any |
Output type |
any |
Printer types |
any |
Printers |
any |
Filter type |
slow |
lpfilter Command
Use the full path of the filter program. If there are any
fixed options that the program always needs, include them here.
lpfilter Input Types Argument
Input types is a list of file content types that the print
filter can process. The LP print service does limit the number of input
types, but most filters can accept only one input type. Several file types
can be similar enough, such that the filter can deal with them. You
can use whatever names you prefer, with a maximum of 14 alphanumeric characters
and dashes. Do not use underscores as part of the input type name.
The LP print service uses these names to match a filter to
a file type, so follow a consistent naming convention. For example, if more
than one filter can accept the same input type, use the same name
for that input type when you specify it for each filter. Inform your
users of these names so that they know how to identify the file
type when submitting a file for printing.
lpfilter Output Types Argument
Output types is list of file types that the filter can produce
as output. For each input type, the filter produces a single output type.
The output type can vary, however, from job to job. The name of
the output type is restricted to 14 alphanumeric characters and dashes.
The output type names should either match the types of available (local or
remote) printers, or match the input types handled by other filters. The LP
print service groups filters in a shell pipeline if it finds that
several passes by different filters are needed to convert a file. You will
unlikely need this level of sophistication, but the LP print service allows it.
Try to find a set of filters that takes as input types all
the different files the users might want printed, and that converts those files
directly into file types the printer can handle.
lpfilter Printer Types Argument
Printer types is a list of the types of printers into which
the print filter can convert files. For most printers and filters, you can
leave this part of the filter definition blank, because this list is identical
to the list of output types. However, this list can be different. For
example, you could have a printer with a single printer type for purposes
of initialization. However, that printer can recognize several different file content types. Essentially, this
printer has an internal filter that converts the various file types into a
filter type that it can handle. Thus, a filter might produce one of
several output types that match the file types that the printer can handle.
The print filter should be marked as working with that printer type.
As another example, you might have two different models of printers that are
listed as accepting the same file types. Due to slight differences in manufacture,
however, one printer deviates in the results it produces. You label the printers
as being of different printer types, say A and B, where B is
the printer that deviates. You create a filter that adjusts files to account
for the deviation produced by printers of type B. Because this filter is
needed only for those printer types, you would list this filter as
working only on type B printers.
lpfilter Printers Argument
A print filter normally can work with all printers that accept its
output, so you can usually skip this part of the filter definition.
You might, however, have some printers that are inappropriate for the output that
the filter produces. For example, you might want to dedicate one printer for
fast turnaround, only sending files that require no filtering to that printer. Other
printers of identical type can be used for files that need extensive filtering
before they can be printed.
lpfilter Filter Type Argument
The LP print service recognizes fast filters and slow filters, as described in
Types of Filters.
Slow filters that are invoked by printing modes, by using the lp
-y command, must be run on the system from which the print
request originated. The LP print service cannot pass values for modes to print
servers. It can, however, match a file content type (specified after the -T
option of the lp command) to a content type on a print server. Therefore,
if you want to activate special modes on a print server, you
must specify content types that permit the LP print service to match input
types and output types.
lpfilter Options Argument
Options specify how different types of information are converted into command-line arguments to
the filter command. This information can include specifications from a user (with the
print request), the printer definition, and the specifications implemented by any filters that
are used to process the request.
Defining Print Filter Options With Templates
There are 13 sources of information for defining print filter options, each of
which is represented by a keyword. Each option is defined in a template.
A template is a statement in a filter definition that defines an option
to be passed to the filter command, based on the value of one
of the filter characteristics
The options specified in a filter definition can include none, all, or any
subset of the 13 keywords. In addition, a single keyword can be defined
more than once, if multiple definitions are required for a complete filter definition.
The following table contains descriptions of the 13 keywords available for defining options
in a print filter definition.
Table 8-2 Keywords for Print Filter Options
Option Characteristic |
Keyword |
Patterns |
Example |
Content type (input) |
INPUT |
content-type |
troff |
Content type (output) |
OUTPUT |
content-type |
postscript, impress |
Printer type |
TERM |
printer-type |
att495 |
Printer name |
PRINTER |
printer-name |
lp1 |
Character
pitch |
CPI |
scaled-decimal |
10 |
Line pitch |
LPI |
scaled-decimal |
6 |
Page length |
LENGTH |
scaled-decimal |
66 |
Page width |
WIDTH |
scaled-decimal |
80 |
Pages to print |
PAGES |
page-list |
1-5,13-20 |
Character set |
CHARSET |
character-set |
finnish |
Form name |
FORM |
form-name |
invoice2 |
Number of copies |
COPIES |
integer |
3 |
Special modes |
MODES |
mode |
landscape |
A print filter definition can include more than one template. Multiple templates are
entered on a single line and separated with commas, or they are entered
on separate lines, preceded by the Options: prefix.
The format of a template is as follows: keywordpattern = replacement
The keyword identifies the type of option being registered for a particular characteristic
of the filter.
The pattern is a specific option for the keyword.
The replacement is what happens when the keyword has the noted value.
For an example of how an option is defined for a particular
filter, suppose you want to have the print service scheduler assign print requests to
filters following this criteria:
If the type of OUTPUT to be produced by the filter is impress, then pass the -I option to the filter.
If the type of OUTPUT to be produced by the filter is postscript, then pass the -P option to the filter.
To specify these criteria, provide the following templates as options to the lpfilter
command:
Options: OUTPUT impress=-I, OUTPUT postscript=-P
If the Options line becomes too long, put each template on a separate
line, as follows:
Options: OUTPUT impress=-I
Options: OUTPUT postscript=-P
In both templates, the keyword is defined as OUTPUT. In the first template,
the pattern is impress, and the value of the replacement is --I. In
the second template, the value of pattern is postscript, and the value
of replacement is -P.
To determine which values to supply for each type of template (that is,
for the pattern and replacement arguments for each keyword), consider the following:
The values for the INPUT templates come from the file content type that needs to be converted by the filter.
The values for the OUTPUT templates come from the output type that has to be produced by the filter.
The value for the TERM template is the printer type.
The value for the PRINTER template is the name of the printer that will print the final output.
The values for the CPI, LPI, LENGTH, and WIDTH templates come from the user's print request, the form being used, or the default values for the printer.
The value for the PAGES template is a list of pages that should be printed. Typically, the value consists of a list of page ranges separated by commas. Each page range consists of a pair of numbers separated by a dash, or a single number. (For example, 1–5,6,8,10 indicates pages 1 through 5, plus pages 6, 8, and 10.) However, whatever value was given in the -P option to a print request is passed unchanged.
The value for the CHARSET template is the name of the character set to be used.
The value for the FORM template is the name of the form requested by the lp -f command (the command used to submit a print request).
The value of the COPIES template is the number of copies of the file to print. If the filter uses this template, the LP print service reduces to one the number of copies of the filtered file it prints. This “single copy” includes the multiple copies that are produced by the filter.
The value of the MODES template comes from the lp -y command. Because a user can specify several -y options, the MODES template might have several values. The values are applied in the left-to-right order given by the user.
The replacement option shows how the value of a template should be given
to the filter program. This part typically a literal option, sometimes with the
placeholder asterisk (*) included to show where the value goes. The pattern and
replacement options also can use the regular expression syntax of the ed
command for more complex conversion of user input options into filter options. All
regular expression syntax of ed is supported, including the \( ... \) and \n constructions. These
constructions can be used to extract portions of the pattern option for copying
into the replacement option, and the & option, which can be used
to copy the entire pattern option into the replacement option. For more information,
see the ed(1) man page.
Note - If a comma or an equal sign (=) is included in a pattern
or a replacement option, precede it with a backslash (\). A backslash in
front of any of these characters is removed when the pattern or replacement
option is used.
How to Create a New Print Filter
- Log in as superuser, lp, or assume an equivalent role on the
print server.
- Create a print filter program.
For information on print filter programs, see Writing a Print Filter Program. By convention, filter programs for
PostScript printers are located in the /usr/lib/lp/postscript directory. You should put programs you create
under the /usr/lib/lp directory in a directory of your choosing.
- Create a print filter definition.
For information on print filter definitions, see Creating a Print Filter Definition. You should save the print
filter definition in a text file. By convention, filter definitions are located in
the /etc/lp/fd directory and are identified with the .fd suffix.
- Add the print filter to a print server.
For instructions, see How to Add a Print Filter.
Example 8-7 Creating a New Print Filter
This example shows a print filter definition that is used to convert
N37 or Nlp to simple.
Input types: N37, Nlp, simple
Output types: simple
Command: /usr/bin/col
Options: MODES expand = -x
Options: INPUT simple = -p -f
In this example, the print filter program is named col. Once you add
the new print filter to a print server, a user's print requests are
handled as follows:
When a user types the following command:
$ lp -y expand report.doc
The print filter program is run with the following arguments to convert the
file:
/usr/bin/col -x -p -f
When a user types the following command:
$ lp -T N37 -y expand report.doc
The print filter program is run with the following arguments to convert the
file:
/usr/bin/col -x
Example 8-8 Creating a New Print Filter by Converting One Input Type to Another Output Type
This example shows a print filter definition that is used to convert from
troff to a PostScript file.
Input types: troff
Output types: postscript
Printer types: PS
Filter type: slow
Command: /usr/lib/lp/postscript/dpost
Options: LENGTH * = -l*
Options: MODES port = -pp, MODES land = -pl
Options: MODES group \=\([1-9]\) = -n\l
In this example, the filter program is named dpost. The filter program takes
one input type, troff, produces a postscript output, and works with any printer
of type PS (PostScript). Users need to give just the abbreviation port
or land when they ask for the paper orientation to be in either
portrait mode or landscape mode. Because these options are not intrinsic to the
LP print service, users must specify them by using the lp -y command.
After you add the new print filter to a print server, print
requests will be handled as follows:
When a user types the following command to submit a troff file type for printing on a PostScript printer (type PS), with requests for landscape orientation and a page length of 60 lines:
$ lp -T troff -o length=60 -y land -d luna ch1.doc
The print filter program dpost is run with the following arguments to convert the file:
/usr/lib/lp/postscript/dpost -l60 -pl
When a user enters the following command:
$ lp -T troff -y group=4 -d luna ch1.doc
The print filter program dpost is run with the following arguments to convert the file:
/usr/lib/lp/postscript/dpost -n4