📄 printing-advanced.html
字号:
<p>In our example, we will add the DVI conversion filter to the entry for the printernamed <var class="LITERAL">bamboo</var>. Here is the example <ttclass="FILENAME">/etc/printcap</tt> file again, with the new <varclass="LITERAL">df</var> capability for the printer <varclass="LITERAL">bamboo</var>.</p><pre class="PROGRAMLISTING">## /etc/printcap for host rose - added df filter for bamboo#rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple:bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf:</pre><p>The DVI filter is a shell script named <ttclass="FILENAME">/usr/local/libexec/psdf</tt>. Here is that script:</p><pre class="PROGRAMLISTING">#!/bin/sh## psdf - DVI to PostScript printer filter# Installed in /usr/local/libexec/psdf## Invoked by lpd when user runs lpr -d#exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"</pre><p>This script runs <tt class="COMMAND">dvips</tt> in filter mode (the <varclass="OPTION">-f</var> argument) on standard input, which is the job to print. It thenstarts the <span class="TRADEMARK">PostScript</span> printer filter <ttclass="COMMAND">lprps</tt> (see section <ahref="printing-advanced.html#PRINTING-ADVANCED-IF-CONVERSION">Accommodating Plain TextJobs on <span class="TRADEMARK">PostScript</span> Printers</a>) with the arguments <bclass="APPLICATION">LPD</b> passed to this script. <tt class="COMMAND">lprps</tt> willuse those arguments to account for the pages printed.</p></div><div class="SECT4"><h4 class="SECT4"><a id="AEN11546" name="AEN11546">9.4.1.4.4 More Conversion FilterExamples</a></h4><p>Since there is no fixed set of steps to install conversion filters, let me insteadprovide more examples. Use these as guidance to making your own filters. Use themdirectly, if appropriate.</p><p>This example script is a raster (well, GIF file, actually) conversion filter for aHewlett Packard LaserJet III-Si printer:</p><pre class="PROGRAMLISTING">#!/bin/sh## hpvf - Convert GIF files into HP/PCL, then print# Installed in /usr/local/libexec/hpvf PATH=/usr/X11R6/bin:$PATH; export PATHgiftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ && exit 0 \ || exit 2</pre><p>It works by converting the GIF file into a portable anymap, converting that into aportable graymap, converting that into a portable bitmap, and converting that intoLaserJet/PCL-compatible data.</p><p>Here is the <tt class="FILENAME">/etc/printcap</tt> file with an entry for a printerusing the above filter:</p><pre class="PROGRAMLISTING">## /etc/printcap for host orchid#teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf:</pre><p>The following script is a conversion filter for troff data from the groff typesettingsystem for the <span class="TRADEMARK">PostScript</span> printer named <varclass="LITERAL">bamboo</var>:</p><pre class="PROGRAMLISTING">#!/bin/sh## pstf - Convert groff's troff data into PS, then print.# Installed in /usr/local/libexec/pstf#exec grops | /usr/local/libexec/lprps "$@"</pre><p>The above script makes use of <tt class="COMMAND">lprps</tt> again to handle thecommunication with the printer. If the printer were on a parallel port, we would use thisscript instead:</p><pre class="PROGRAMLISTING">#!/bin/sh## pstf - Convert groff's troff data into PS, then print.# Installed in /usr/local/libexec/pstf#exec grops</pre><p>That is it. Here is the entry we need to add to <ttclass="FILENAME">/etc/printcap</tt> to enable the filter:</p><pre class="PROGRAMLISTING">:tf=/usr/local/libexec/pstf:</pre><p>Here is an example that might make old hands at FORTRAN blush. It is a FORTRAN-textfilter for any printer that can directly print plain text. We will install it for theprinter <var class="LITERAL">teak</var>:</p><pre class="PROGRAMLISTING">#!/bin/sh## hprf - FORTRAN text filter for LaserJet 3si:# Installed in /usr/local/libexec/hprf#printf "\033&k2G" && fpr && printf "\033&l0H" && exit 0exit 2</pre><p>And we will add this line to the <tt class="FILENAME">/etc/printcap</tt> for theprinter <var class="LITERAL">teak</var> to enable this filter:</p><pre class="PROGRAMLISTING">:rf=/usr/local/libexec/hprf:</pre><p>Here is one final, somewhat complex example. We will add a DVI filter to the LaserJetprinter <var class="LITERAL">teak</var> introduced earlier. First, the easy part:updating <tt class="FILENAME">/etc/printcap</tt> with the location of the DVI filter:</p><pre class="PROGRAMLISTING">:df=/usr/local/libexec/hpdf:</pre><p>Now, for the hard part: making the filter. For that, we need a DVI-to-LaserJet/PCLconversion program. The FreeBSD Ports Collection (see <a href="ports.html">The PortsCollection</a>) has one: <tt class="COMMAND">dvi2xx</tt> is the name of the package.Installing this package gives us the program we need, <tt class="COMMAND">dvilj2p</tt>,which converts DVI into LaserJet IIp, LaserJet III, and LaserJet 2000 compatiblecodes.</p><p><tt class="COMMAND">dvilj2p</tt> makes the filter <tt class="COMMAND">hpdf</tt> quitecomplex since <tt class="COMMAND">dvilj2p</tt> cannot read from standard input. It wantsto work with a filename. What is worse, the filename has to end in <ttclass="FILENAME">.dvi</tt> so using <tt class="FILENAME">/dev/fd/0</tt> for standardinput is problematic. We can get around that problem by linking (symbolically) atemporary file name (one that ends in <tt class="FILENAME">.dvi</tt>) to <ttclass="FILENAME">/dev/fd/0</tt>, thereby forcing <tt class="COMMAND">dvilj2p</tt> to readfrom standard input.</p><p>The only other fly in the ointment is the fact that we cannot use <ttclass="FILENAME">/tmp</tt> for the temporary link. Symbolic links are owned by user andgroup <tt class="USERNAME">bin</tt>. The filter runs as user <ttclass="USERNAME">daemon</tt>. And the <tt class="FILENAME">/tmp</tt> directory has thesticky bit set. The filter can create the link, but it will not be able clean up whendone and remove it since the link will belong to a different user.</p><p>Instead, the filter will make the symbolic link in the current working directory,which is the spooling directory (specified by the <var class="LITERAL">sd</var>capability in <tt class="FILENAME">/etc/printcap</tt>). This is a perfect place forfilters to do their work, especially since there is (sometimes) more free disk space inthe spooling directory than under <tt class="FILENAME">/tmp</tt>.</p><p>Here, finally, is the filter:</p><pre class="PROGRAMLISTING">#!/bin/sh## hpdf - Print DVI data on HP/PCL printer# Installed in /usr/local/libexec/hpdfPATH=/usr/local/bin:$PATH; export PATH## Define a function to clean up our temporary files. These exist# in the current directory, which will be the spooling directory# for the printer.#cleanup() { rm -f hpdf$$.dvi}## Define a function to handle fatal errors: print the given message# and exit 2. Exiting with 2 tells LPD to do not try to reprint the# job.#fatal() { echo "$@" 1>&2 cleanup exit 2}## If user removes the job, LPD will send SIGINT, so trap SIGINT# (and a few other signals) to clean up after ourselves.#trap cleanup 1 2 15 ## Make sure we are not colliding with any existing files.#cleanup## Link the DVI input file to standard input (the file to print).#ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0"## Make LF = CR+LF#printf "\033&k2G" || fatal "Cannot initialize printer"# # Convert and print. Return value from dvilj2p does not seem to be# reliable, so we ignore it.#dvilj2p -M1 -q -e- dfhp$$.dvi## Clean up and exit#cleanupexit 0</pre></div><div class="SECT4"><h4 class="SECT4"><a id="PRINTING-ADVANCED-AUTOCONV"name="PRINTING-ADVANCED-AUTOCONV">9.4.1.4.5 Automated Conversion: an Alternative toConversion Filters</a></h4><p>All these conversion filters accomplish a lot for your printing environment, but atthe cost forcing the user to specify (on the <ahref="http://www.FreeBSD.org/cgi/man.cgi?query=lpr&sektion=1"><spanclass="CITEREFENTRY"><span class="REFENTRYTITLE">lpr</span>(1)</span></a> command line)which one to use. If your users are not particularly computer literate, having to specifya filter option will become annoying. What is worse, though, is that an incorrectlyspecified filter option may run a filter on the wrong type of file and cause your printerto spew out hundreds of sheets of paper.</p><p>Rather than install conversion filters at all, you might want to try having the textfilter (since it is the default filter) detect the type of file it has been asked toprint and then automatically run the right conversion filter. Tools such as <ttclass="COMMAND">file</tt> can be of help here. Of course, it will be hard to determinethe differences between <span class="emphasis"><i class="EMPHASIS">some</i></span> filetypes--and, of course, you can still provide conversion filters just for them.</p><p>The FreeBSD Ports Collection has a text filter that performs automatic conversioncalled <tt class="COMMAND">apsfilter</tt>. It can detect plain text, <spanclass="TRADEMARK">PostScript</span>, and DVI files, run the proper conversions, andprint.</p></div></div><div class="SECT3"><h3 class="SECT3"><a id="PRINTING-ADVANCED-OF" name="PRINTING-ADVANCED-OF">9.4.1.5 OutputFilters</a></h3><p>The <b class="APPLICATION">LPD</b> spooling system supports one other type of filterthat we have not yet explored: an output filter. An output filter is intended forprinting plain text only, like the text filter, but with many simplifications. If you areusing an output filter but no text filter, then:</p><ul><li><p><b class="APPLICATION">LPD</b> starts an output filter once for the entire job insteadof once for each file in the job.</p></li><li><p><b class="APPLICATION">LPD</b> does not make any provision to identify the start orthe end of files within the job for the output filter.</p></li><li><p><b class="APPLICATION">LPD</b> does not pass the user's login or host to the filter,so it is not intended to do accounting. In fact, it gets only two arguments:</p><p><tt class="COMMAND">filter-name</tt> -w<var class="REPLACEABLE">width</var> -l<varclass="REPLACEABLE">length</var></p><p>Where <var class="REPLACEABLE">width</var> is from the <var class="LITERAL">pw</var>capability and <var class="REPLACEABLE">length</var> is from the <varclass="LITERAL">pl</var> capability for the printer in question.</p></li></ul><p>Do not be seduced by an output filter's simplicity. If you would like each file in ajob to start on a different page an output filter <span class="emphasis"><iclass="EMPHASIS">will not work</i></span>. Use a text filter (also known as an inputfilter); see section <a href="printing-intro-setup.html#PRINTING-TEXTFILTER">Installingthe Text Filter</a>. Furthermore, an output filter is actually <span class="emphasis"><iclass="EMPHASIS">more complex</i></span> in that it has to examine the byte stream beingsent to it for special flag characters and must send signals to itself on behalf of <bclass="APPLICATION">LPD</b>.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -