lbp-ifとesc-ifの効能

はじめに

ホストにプリンタを接続し、lprでプリントアウトしてみたがうまくいかない のですが、なぜでしょう?
という質問を目にすることがときどきあります。 例えば、さぁ、プリンタが継ったぞ、ってんで、早速
        It was a dark
        and stormy night.
と書かれたファイルfoo
% lpr foo
とやってプリントアウトしてみたら、紙には
        It was a dark
                     and stormy night.
と出力されてしまった、とか、漢字を含むファイルをプリントアウトしてみた けど化けてしまって、変な記号がプリントされてしまう、とかいったトラブル ですね。 これらを望み通りにプリントアウトするためには、適切なフィルタを用意し、 /etc/printcapでそのフィルタを指定しなければなりません。
lbp-ifはCanon LASERSHOTのLIPSを、 esc-ifはESC/Pを用いてプリントアウトするためのフィルタです。

lprとlpd の機構についてちょっとだけ

lprは入力を受け取ると、直接はプリンタを操作せず、 lpdに渡します。lpdlpr 他にも何種類かあるのですが、フィルタに関するオプションが指定されていな ければifofに指定されているフィルタにの標準入力に向けて、 lprから送られてきたデータを送ります。 そして、lpdはそれらのフィルタの標準出力を読み取り、 /etc/printcaplpフィールドで指定された デバイスファイルに送り出します。
               +----------+
        lpr -> |   lpd    | -> lp フィールドに指定されたプリンタ
               +----------+
                 |- df -|
                 |- nf -|
                 |- if -|
                 |- of -|
ifofの違いはifは アカウンティング(課金情報の記録)を行なうことができ、 ofはできないことです。 これらのフィルタの役目は、lprに入力されたデータを、 プリンタが解釈できるデータに変換することです。 例えば、dfはTeX のdviフォーマットを解釈し、 pkフォントなどを読んで、ビットマップ展開し、 ESC/PやLIPSなどのコードに変換しなりませんし、 ofは改行コードや漢字コードなどを適当に加工し、 意図した出力が得られるようにしたデータに変換しなければなりません。 これは、プリンタの機種に依存した部分を lpr/lpdから独立させ、 lpr/lpdに手を加えなくても さまざまなプリンタを接続可能にするための機構で、 言い替えれば、lpr/lpdを使ってプリントアウトするためには、 プリンタの違いを吸収するためのフィルタを用意することが必要なのです。 フィルタを用意しなければいけないのは、 決してあなたのプリンタが特殊だからと言うわけではありません。

なぜ思うようなプリントアウトが得られなかったか…原因と対策

まず、
        It was a dark
        and stormy night
        It was a dark
                     and stormy night
になってしまったケースを考えてみましょう。
UNIXのテキストファイルでは、改行コードはLF(0x0a)です。 プリントアウトしたファイルには、1行目の行末、kの次にLFが入っています。 ところが、このプリンタにとっては、LF は桁の位置は関係なく、 紙を1行送れ、という命令だったので、プリンタは忠実に命令を実行したところ、 上のような出力になった、というわけです。 このプリンタに対しては、LFをCR(0x0d...桁位置を行頭へ戻せという命令) とLFの並びに置き換えてやれば、意図した出力が得られるものとしましょう。 この場合は、ofでLF->CR LFへの置き換えを行なえば目的は達成されます。
つぎに、漢字が化けてしまった場合を考えましょう。 漢字を出力できないプリンタの場合は、 フォントをビットマップイメージに展開してからプリンタに送りつける、 などといった大変なことをやらないと漢字は出せませんので、 今は触れないことにします。しかし、漢字が出力できるプリンタなのにうまく出ない、 という場合は、lprへの入力のコード体系と プリンタが解釈できるコード体系のくい違いが原因であることが考えられます。 この場合もofでコード体系を変換すれば、 ちゃんとした出力を得ることができます。
例えばプリンタはJISコードを解釈し、 プリントアウトしたいデータがShift JISコードの場合は、 ofでShift JIS->JISへの変換を行なえばいいことになります。 ところが、プリンタもJISコードを解釈し、 プリントアウトしたいデータもJISコードなのにうまくいかない場合は、 1Byte文字から2Byte文字(漢字)への切替え、 2Byte文字から1Byte文字への切替えの制御コードが くい違っていることが考えられます。
UNIXで使われる制御コードの一例として、
漢字の開始
ESC $ @
1Byte コードの開始
ESC ( B
というのがあります。一方、プリンタ側では
漢字の開始
0x1c 0x26
1Byte コードの開始
0x1c 0x2e
なんてのだったりします(この例は ESC/P)。
この場合は of
        ESC $ @ -> 0x1c 0x26
        ESC ( B -> 0x1c 0x2e
という変換をすればいいわけです。

本ドキュメントの取り扱い

このドキュメントが元で、どんなトラブルが起ころうとも、筆者は責任を持ち ません。
日本の法律では、完全な Public Domain というのは不可能だと聞いておりま すが、このドキュメントに関しては Public Domain にある著作物に準じて取 り扱って下さい。
こんなドキュメントでも必要として下さる方があるならば、必要に応じてコピー したり、プリントアウトしてから煮て喰ったり焼いて喰ったりして下さい。
このドキュメントに誤りや不適切な記述を発見された場合は、積極的に修正し ていただくことを期待します。

参考文献


Last update $Date: 2018-10-21 16:09:48 +0900 (Sun, 21 Oct 2018) $ Copyright on this page is abandon. Please treat as one in public domain.