Linux tip: Printing DVI files with CUPS

Linux tip: Printing DVI files with CUPS

How to create a CUPS DVI print filter for Linux

Ian Shields, Senior Programmer, IBM Japan

Summary:  Have you ever tried to print DVI or other files in Linux® and gotten an "unsupported format" message? This tip shows you how to combine existing tools to make a CUPS print filter for printing DVI files.

The Common UNIX Printing System (CUPS) is the print spooler used on many Linux and UNIX® systems today. You can use the filters provided with CUPS to format and print many types of files on a wide variety of printers. But what happens if CUPS doesn't support the kind of file you want to print? You can first convert the file to something that CUPS will print, such as PostScript or PDF. Or, you can create a filter so the CUPS printing system will recognize your file and print it correctly. This article, excerpted from the LPI exam 102 prep: Printing tutorial, shows you how to create a simple filter.

MIME types and CUPS

So how does CUPS determine the filter to use for formatting a particular file type? CUPS uses MIME (Multipurpose Internet Mail Extensions) types to determine the appropriate conversion filter when printing a file. Note that other printing packages may use the magic number mechanism as used by the file command. See the man pages for file or magic for more details.

MIME types are used for transmitting various files as mail attachments. They consist of a type, such as text or image, and a subtype, such as html, postscript gif, or jpeg. The type and subtype are separated by a semicolon (;). Optional parameters may include information such as character set encoding or language. CUPS uses rules from /etc/cups/mime.types to determine the type of a file and then uses a suitable filter chosen from those listed in /etc/cups/conv.types for the given MIME type. MIME types are registered with IANA, the Internet Assigned Numbers Authority. If you need a type that is not registered, prefix the subtype with 'x-'. Some image type examples are shown in Listing 1.


Listing 1. Some MIME type entries from /etc/cups/mime.types

                
image/gif                  gif string(0,GIF87a) string(0,GIF89a)
image/png                  png string(0,<89>PNG)
image/jpeg                 jpeg jpg jpe string(0,<FFD8FF>) &&\
                           (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
                            char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
                            char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
                            char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
image/tiff                 tiff tif string(0,MM) string(0,II)
image/x-photocd            pcd string(2048,PCD_IPI)
image/x-portable-anymap    pnm

 

The format of the entries is beyond the scope of this article. Check the files /usr/share/mime/magic or /usr/share/file/magic for some insight on how the magic numbers are used to identify files.

Once the MIME type of a file has been determined, the correct filter is found using the /etc/cups/mime.convs file. Lines in this file have four entries: a source and destination MIME type, a cost, and the name of the filter. The least-cost filter is used. Some examples are shown in Listing 2.


Listing 2. Filter entries from /etc/cups/mime.convs

                 
text/plain              application/postscript  33      texttops
text/html               application/postscript  33      texttops
image/gif               application/vnd.cups-postscript 66      imagetops
image/png               application/vnd.cups-postscript 66      imagetops
image/jpeg              application/vnd.cups-postscript 66      imagetops
image/tiff              application/vnd.cups-postscript 66      imagetops
image/x-bitmap          application/vnd.cups-postscript 66      imagetops

 

If a suitable filter cannot be found, your attempt to print a file will result in an error message. If you are using a printer daemon other than CUPS, you may get unexpected output instead. Listing 3 shows how this works with a DVI file (the normal output from TeX and LaTex).


Listing 3. Printing an unsupported file type

                 
[ian@attic4 ~]$ lpr samp1.dvi
lpr: Unsupported format 'application/octet-stream'!

 

A DVI filter for CUPS printing

Fortunately, the tetex package that provides TeX and LaTeX also provides a conversion utility, dvips, to convert from DVI to PostScript. Unfortunately, it won't work as a filter because it does not know how to handle the arguments that a CUPS filter must handle, namely, job id, user, job title, number of copies, and job options. The first filter in a filter pipeline will also have an additional parameter, the filename, if the input comes from a file.

The solution is to create a wrapper script that will be the filter. The dvips command does not accept input from stdin, so the script may need to create a temporary file and copy stdin to that file before calling dvips. A possible script is shown in Listing 4.


Listing 4. A CUPS DVI to PostScript filter script

                
#!/bin/bash
# CUPS filter to process DVI files using dvips
# Create a sandbox for working if input on stdin
if [ $# -lt 6  ]; then
    sandbox=${TMPDIR-/tmp}/cups-dvitops.$$
    (umask 077 && mkdir $sandbox) || {
        echo "Cannot create temporary directory! Exiting." 1>&2
        exit 1
    }
    fn="$sandbox/cups-dvitops.$$"
    cat > "$fn"
else
    fn="$6"
fi
# Call dvips quietly, securely and with output to stdout
dvips -R -q -o - "$fn"
# Erase sandbox if we created one
if [ $# -lt 6  ]; then
    rm -rf  "$sandbox"
fi

 

Recall that CUPS uses two files in /etc/cups to determine the MIME type and filter to use. These files will be overwritten whenever you reinstall or upgrade CUPS. Fortunately, CUPS will read all files with an extension of .types or .convs whenever it starts or restarts. So you should create a pair of files for your new filter, for example /etc/cups/dvitops.types and /etc/cups/dvitops.convs. Listing 5 shows the two configuration files for the DVI filter.


Listing 5. Configuration files for CUPS dvitops filter

                
[ian@attic4 ~]$ cat /etc/cups/dvitops.types
# Local MIME definition for DVI files
application/x-dvi dvi string(0,<F702>)
[ian@attic4 ~]$ cat /etc/cups/dvitops.convs
# Local DVI to PostScript filter for CUPS
application/x-dvi application/postscript 50 dvitops

 

Listing 5 says that DVI files are identified by having the hexadecimal digits F7 and 02 in the first two positions and that such files should be processed by the dvitops filter.

Next, as root, copy the script above in /usr/lib/cups/filter/dvitops, and make sure it is world readable and executable (-rwxr-xr-x). The name you give the script must match that in the /etc/cups/dvitops.convs file above. If you are running SELinux in enforcing mode, you should also run restorecon in the /usr/lib/cups/filter directory to update the security contexts. Otherwise, your lpr command will appear to work, but your file will not print.

Finally, use the restart option with the cups script located in /etc/rc.d/init.d or /etc/init.d, to restart CUPS and use your new filter.

If you are using an older print spooler, you will probably use either the magicfilter or apsfilter as input filters to convert various input files to PostScript format for printing to a PostScript printer or, using Ghostscript, to a non-PostScript printer.

Learn more

If you'd like to know more about printing in Linux, read LPI exam 102 prep: Printing tutorial, from which this article was excerpted, or see the other Resources below. Don't forget to rate this page.

 

Resources

Learn

Get products and technologies

  • Order the SEK for Linux, a two-DVD set containing the latest IBM trial software for Linux from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

  • Download IBM trial software directly from developerWorks.

Discuss

About the author

Ian Shields

Ian Shields works on a multitude of Linux projects for the developerWorks Linux zone. He is a Senior Programmer at IBM at the Research Triangle Park, NC. He joined IBM in Canberra, Australia, as a Systems Engineer in 1973, and has since worked on communications systems and pervasive computing in Montreal, Canada, and RTP, NC. He has several patents and has published several papers. His undergraduate degree is in pure mathematics and philosophy from the Australian National University. He has an M.S. and Ph.D. in computer science from North Carolina State University. Learn more about Ian in in Ian's profile on My developerWorks.

 

链接地址:http://www.ibm.com/developerworks/linux/library/l-dvi-filter/index.html

posted @ 2012-08-02 13:38  这瓜保熟吗  阅读(244)  评论(0)    收藏  举报