Linux のヒント: CUPS を使って DVI ファイルを印刷する

Linux 用の CUPS DVI プリント・フィルターを作成する方法

Comments

CUPS (Common UNIX Printing System) は、今日の多くの Linux システムや UNIX®システムで使われているプリント・スプーラーです。CUPS に提供されているフィルターを使うと、さまざまな種類のプリンター用にさまざまなタイプのファイルをフォーマットし、印刷することができます。しかし、印刷したいファイルの種類がCUPS でサポートされていない場合にはどうすればよいのでしょう。第 1 の方法として、そのファイルをPostScript あるいは PDF など、CUPS で印刷できるものに変換します。あるいは、CUPS印刷システムがファイルを認識して正しく印刷するように、フィルターを作成する方法があります。この記事は、チュートリアル「LPI exam 102 prep: Printing」の抜粋として、単純なフィルターを作成するための方法を説明します。

MIME タイプと CUPS

では、CUPS は、ある特定のファイル・タイプをフォーマットするために使用するフィルターを、どのように判別するのでしょう。CUPSがファイルを印刷する際には、MIME (Multipurpose Internet Mail Extensions)タイプを使って適切な変換フィルターを判別します。ただし、他の印刷パッケージは、fileコマンドで使われているように magic number 機構を使うかもしれない点に注意してください。詳細については、fileあるいは magic の man ページを参照してください。

MIME タイプは、さまざまなファイルをメール添付として転送するために使われています。MIMEタイプは、タイプ (テキストや画像など) と、サブタイプ (html や、ポストスクリプトgif、jpeg など) から構成されます。タイプとサブタイプはセミコロン (;) で区切られます。オプション・パラメーターとして、文字セット・エンコーディングや言語などの情報が含まれることもあります。CUPSは /etc/cups/mime.types のルールを使ってファイルのタイプを判別し、次に、与えられたMIME タイプの /etc/cups/conv.types にリストされたフィルターの中から選択された、適切なフィルターを使います。MIMEタイプは IANA (the Internet Assigned Numbers Authority) に登録されています。登録されていないタイプが必要な場合は、サブタイプに「x-」という接頭辞を付けます。いくつかの画像タイプの例をリスト1 に示します。

リスト 1. /etc/cups/mime.types の中にある、いくつかの MIME タイプ・エントリー
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

こうしたエントリーのフォーマットは、この記事の範囲外なので省略します。ファイル、/usr/share/mime/magicあるいは /usr/share/file/magic を調べると、ファイルの識別に magic numberが使われている様子が多少わかるはずです。

ファイルの MIME タイプが判別できれば、/etc/cups/mime.convs ファイルを使って正しいファイルを見つけることができます。このファイルの各行には、ソースのMIME タイプと宛先の MIME タイプ、コスト、フィルターの名前という、4 つのエントリーがあり、最もコストの低いフィルターが使われています。リスト2 にその例をいくつか示します。

リスト 2. /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

もし適切なフィルターが見つからないと、そのファイルを印刷しようとしてもエラー・メッセージで終わってしまいます。CUPS以外のプリンター・デーモンを使っている場合には、エラー・メッセージの代わりに、思いがけないものが印刷されるかもしれません。リスト3 は、DVI ファイルの場合にどうなるかを示しています (TeX と LaTex からの正常な出力です)。

リスト 3. サポートされていないファイル・タイプを印刷する
[ian@attic4 ~]$ lpr samp1.dvi
lpr: Unsupported format 'application/octet-stream'!

CUPS 印刷のための DVI フィルター

幸い、TeX と LaTeX を提供する tetex パッケージには、DVI を PostScript に変換する変換ユーティリティーであるdvips も用意されています。ただし残念なことに、dvips は CUPS フィルターが処理すべき引数(つまりジョブ id やユーザー、ジョブ・タイトル、印刷部数、ジョブ・オプションなど)の処理方法を理解できないため、フィルターとしては使えません。フィルター・パイプラインの最初のフィルターは、もしファイルからの入力である場合には、追加パラメーターとしてファイル名も持ちます。

この解決方法としては、フィルターとなるラッパー・スクリプトを作成することです。dvipsコマンドは stdin からの入力を受け付けません。そのためこのスクリプトは、dvipsをコールする前に一時ファイルを作成し、そのファイルに stdin をコピーする必要があるかもしれません。考えられるスクリプトの例をリスト4 に示します。

リスト 4. CUPS DVI から PostScript へのフィルター・スクリプト
#!/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

CUPS が、MIME タイプと使用するフィルターの判別に /etc/cups の 2 つのファイルを使うことを思い出してください。これらのファイルは、CUPSを再インストール、あるいはアップグレードすると必ず上書きされます。幸いCUPS は、起動または再起動すると必ず、拡張子が .types あるいは .convs であるすべてのファイルを読み取ります。つまり、新しいフィルター用に1 対のファイルを作成する必要があるということです (例えば /etc/cups/dvitops.typesと /etc/cups/dvitops.convs など)。リスト 5 は DVI フィルター用の 2 つのコンフィギュレーション・ファイルを示しています。

リスト 5. CUPS dvitops フィルター用のコンフィギュレーション・ファイル
[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

リスト 5 を見ると、これらの DVI ファイルが最初の 2 つの位置に 16 進数のF7 と 02 を持つことで識別されること、そしてそうしたファイルを dvitops フィルターで処理するべきということがわかります。

次に、ルートとして、上記のスクリプトを /usr/lib/cups/filter/dvitops にコピーし、このスクリプトが世界中で読め、実行可能であること(-rwxr-xr-x) を確認します。スクリプトの名前は、上記の /etc/cups/dvitops.convsファイルの中の名前と一致する必要があります。もし SELinux を強制モードで実行している場合には、/usr/lib/cups/filterディレクトリーの restorecon も実行して、セキュリティー・コンテキストを更新する必要もあります。そうしないと、lprコマンドは動作しているように見えてもファイルは印刷されません。

最後に、/etc/rc.d/init.d あるいは /etc/init.d にある再起動オプションとcups スクリプトを使って CUPS を再起動し、新しいフィルターを使用します。

古いプリンター・スプーラーを使っている場合には、おそらく入力フィルターとしてmagicfilter あるいは apsfilter を使うことになるでしょう。これらを使ってさまざまな入力ファイルをPostScript フォーマットに変換し、PostScript プリンターに印刷するか、あるいはPostScript プリンターではない場合には Ghostscript を使います。

詳しく学ぶには

Linux での印刷について詳しく知りたい方は、チュートリアル、「LPI exam 102 prep: Printing」を読んでください (この記事はこのチュートリアルから抜粋したものです)。あるいは下記の「参考文献」を参照してください。また、この記事を評価することも忘れないでください。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=251499
ArticleTitle=Linux のヒント: CUPS を使って DVI ファイルを印刷する
publish-date=02072007