最終更新日: 2002/03/02
lp|local line printer:\ :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:と書けばおっけーです。
ここで,``lp='' はプリンタのデバイスファイルの指定 (通常は/dev/lpt0につなぐと思うのでここままでいいでしょう), ``sd='' はスプールディレクトリの指定です。 スプールディレクトリは,プリンタに送るデータを貯めておく場所です。 ここで指定したディレクトリが存在するかどうかを確認しておきましょう。
% jdvi2kps foo.dvi | gs -sDEVICE=epson -r180x180 -q -sOutputFile=- - | lprのように長ったらしいコマンドを打つ必要があります。 また,プリンタとUNIXとで使われる文字コードが違うため, 日本語を含むテキストファイルの印字もできません。 そこで,
/etc/printcapには,プリンタに送るデータをフィルタに通して加工する という機能があります。 そのフィルタはprintcapに複数登録でき, 印刷時にどのフィルタを使うかは,lprのオプションで指定します。
printcapへのフィルタの登録は,
:if=/usr/local/libexec/lpf-escp.text:\ :vf=/usr/local/libexec/lpf-escp.bin:\ :df=/usr/local/libexec/lpf-escp.dvi:\ :cf=/usr/local/libexec/lpf-escp.ps:\のような書式で行います。ここで,``='' の右辺がフィルタの名称で, 左辺の ``?f'' の ``?'' が lpr のオプションに対応します。 たとえば,
% lpr -d foo.dviのようにlprを実行すると,foo.dvi は ``df='' で指定されている フィルタ (/usr/local/libexec/lpf-escp.dvi) で処理されて, その出力がプリンタに送られます。
% lpr foo.txtのようにオプションを指定しなかった場合は,``if='' で指定した フィルタが使われます (逆に,lprには ``-i'' オプションはなかった…はず)。
…というわけで,本セクションの冒頭で想定した printcapは
# @(#)printcap 0.1 (Dai Ishijima) 2/7/96 #lp|local line printer:\ # :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs: # # lpr option this setting in lpr(1) # -----------+---------------+------------ # none regular text regular text # -c PostScript cifplot # -d DVI DVI # -v raw data raster image # -t half size troff # lp|escp|local printer|EPSON ESC/P-24 or compatible:\ :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:\ :if=/usr/local/libexec/lpf-escp.text:\ :vf=/usr/local/libexec/lpf-escp.bin:\ :df=/usr/local/libexec/lpf-escp.dvi:\ :cf=/usr/local/libexec/lpf-escp.ps:\ :tf=/usr/local/libexec/lpf-escp.small:\ :mx#0:sh:こんな感じになります。
ちなみに,``#'' から行末まではコメントです。 これは他のUNIXの設定ファイルと同じですね。 それと,最後の行の ``mx#0'' は,印刷するファイルの大きさに 制限を加えないこと, ``sh'' はバナーページ (だれが印刷したものかを書いた,表紙みたいなページ) を印刷しないことを指示するためのものです。
この設定では,日本語を含む (もちろん含まないのでもかまわないです) テキストファイルはオプションなしで, dviファイルは ``-d'' オプションをつけて, PostScriptファイルは ``-c'' オプションをつけて, バイナリデータ (ESC/P形式データ) は ``-v'' オプションを つけて印刷します。
さて,では次にprintcapで指定した フィルタをつくることにしましょう。
まず,テキストファイルを考えてみます。 ESC/Pプリンタで,日本語混じりのテキストを印刷するためには, 文字の種類が切り替わるときに ``ここからは2バイト文字'' とか ``ここからは1バイト文字'' というエスケープシーケンスを送ってやる必要があります。 ESC/Pプリンタの場合,これらはそれぞれ ``FS &'' と ``FS .'' です。
また,UNIXで使われているJISコードでは,これらのエスケープシーケンスは それぞれ, ``ESC $ B'' と ``ESC ( B'' です。 そこで,これらのエスケープシーケンスをプリンタに合うように 書き換えてやればうまくいきます。 また,JISコード以外のEUCやSJISテキストを印刷したいときは, いったん,JISコードに変換してから処理すればいいでしょう。
以上の処理をまとめると,
nkf -j | sed -e 's/'"$kin"'/'"$escp_kin"'/g' -e 's/'"$kout"'/'"$escp_kout"'/g'という処理にかければいいわけです。 ただし,ここで,$kin, $escp_kin, $kout, $escp_kout には, それぞれJIS, ESC/Pのエスケープシーケンスが設定されています。 これを設定するには,(cshスクリプトだと)
set kin=`printf '\033$B'` set kout=`printf '\033(B'` set escp_kin=`printf '\034\\&'` set escp_kout=`printf '\034\\.'`とすればいいでしょう。 (FreeBSD以外だと,printf(1)コマンドがないかもしれません。 そのときはてきとーに工夫してみてください)
次にPostScriptファイルの場合を考えてみましょう。 これは,gs(1)にかけて,
gs -sDEVICE=epson -r180x180 -sPAPERSIZE=a4 -q -sOutputFile=- -というコマンドで処理すればいいです。
dviファイルの場合は,dvi→PostScript変換フィルタをつけて,
jdvi2kps | gs -sDEVICE=epson -r180x180 -sPAPERSIZE=a4 -q -sOutputFile=- -とします。
さて,これでメイン部分はできました。 つぎに,用紙とのかねあいを考えてみましょう。 A4サイズの用紙は,横210mmです。 A4用紙を使ったときの印字可能領域は, プリンタにもよりますが,だいたい8インチくらいです。 通常のプリンタの初期設定では文字の間隔が1/10インチなので, この場合,横80桁印刷できることになります。 しかし, このままでは余白が狭すぎてとじしろがとれないので, 文字間隔を1/12インチ (エリートサイズ) にしましょう。 エリートサイズにするには,``ESC M'' というエスケープシーケンスを 送ります。 また左側の余白を設定するには,``ESC l'' というエスケープシーケンスを 送ります。
説明の順序が逆ですが, これらのモロモロの処理をまず行って,先に説明したファイル処理を おこなったのが, これ↓
#! /bin/csh -f # # lpf-escp -- ESC/Pプリンタ用のフィルタ # # lpf-escp.text: テキストファイル出力用 (日本語コードの変換などを行う) # lpf-escp.bin: 入力をそのままプリンタに送る時に使う # lpf-escp.ps, lpf-escp.dvi: それぞれ ps, dviファイル用 # lpf-escp.small: 縮小印刷用 # # revision history: # 0.0: Jan. 5, 94 by Dai Ishijima # 1.0: Feb. 6, 96 # set path=(/usr/bin /bin /usr/local/bin) set prog=$0 set type=$prog:e set basename=$prog:r if (x$type == x) then foreach t (text bin ps dvi small) rm -f $basename.$t ln -s $prog $basename.$t end exit 0 endif # プリンタ初期化 # ESC @ リセット # ESC P ESC Q 80 用紙サイズを8インチに設定 # ESC P 10文字/インチ # ESC Q 80 用紙幅を80文字に # ESC l 5 左マージンを1/2インチ (5文字分) に設定 set init='\033@\033P\033Q\120\033l\005' # ESC x 0 高速 (ドラフト) 印字指定 # FS x 1 漢字高速印字指定 # ESC M エリートサイズ (12文字/インチ) 指定 # FS S 3 3 漢字の左右余白設定 set init="$init"'\033x0\034x1\033M\034S\003\003' # タブストップの設定 (ESC D): 8文字ごと set init="$init"'\033D\010\020\030\040\050\060\070\100\110\120\010' # 印刷後、改ページ (^L) してリセット (ESC @) set fin="\014\033@" set kin=`printf '\033$B'` set kout=`printf '\033(B'` set escp_kin=`printf '\034\\&'` set escp_kout=`printf '\034\\.'` printf "$init" if ($type == text) then nkf -j |\ sed -e 's/'"$kin"'/'"$escp_kin"'/g' -e 's/'"$kout"'/'"$escp_kout"'/g' else if ($type == ps) then gs -sDEVICE=epson -r180x180 -q -sOutputFile=- - else if ($type == dvi) then jdvi2kps | gs -sDEVICE=epson -r180x180 -q -sOutputFile=- - else if ($type == small) then nkf -s | slpr else if ($type == bin) then cat else cat endif printf "$fin"です。