#!/bin/sh # # =head1 NAME # # lz - print to postscript printers, doublesided with multiple pages to a sheet # # =head1 SYNOPSIS # # lz [options] [files...] # # =head1 DESCRIPTION # # I is a command for generating printouts for PostScript printers. # It accepts text, PDF or PostScript as input # and performs scaling and layout # to do things like use both sides of the paper and put multiple logical # pages on a surface. # It is intended to be used instead of the supplied # B or B commands, which B itself calls to submit # the generated PostScript. This saves users having to switch command # sets when they switch platforms # and keeps the per-machine printer configurations very simple # as typically they need define only "pure PostScript" printer names. # : ${OS:=`uname -s|tr '[A-Z]' '[a-z]'`} : ${PRINTER:=$LPDEST} : ${PAPER:=A4} multipsargs= postps= topsargs= pshufargs= filter= domessage= # only works at UNSW CSE itype= title= cmd=`exec basename "$0"` usage="Usage: $cmd [-Pprinter[/paper]] [-f filter]... [multips-options] [--] [files...] -Pprinter[/paper] Send to specified printer. Specifiable via \$PRINTER (currently \"$PRINTER\"). An optional PostScript papersize directive may be included (eg a3). NOTE: a plain -P is reserved for multips' portrait flag. -f filter Run each file (or stdin) through filter, which may include options, _before_ conversion to PostScript. Multiple filters are connected by pipes in the order supplied. /pattern/ Highlight regular expression (only works for a2ps as the postscript conversion). Pshuf options: -numbers Shuffling order. -o range Only output pages in \"range\". -O shuffle-pages Shuffling order. -r Reverse pages. multips options (defaults as per multips): -[1248] 1,2,4, or 8 logical pages per surface. -d Put dividers between logical pages. -dh Horizontal dividers only. -dv Vertical dividers only. +d No dividers. -fg r,g,b Set foreground colour to be the RGB value (r,g,b). -fg g Set foreground colour to be the grey value g. -bg r,g,b Set background colour to be the RGB value (r,g,b). -bg g Set background colour to be the grey value g. -t tray Select paper tray. -title string Specify printout title. -L Landscape mode. -P Portrait mode. -D Duplex mode - use both sides of the paper. +D No duplex mode - use only one side of the paper. -T Tumble mode - second side of page is upsidedown. +T No tumble. -i type Specify input type: ps or postscript No text->PostScript conversion. pdf Adobe PDF->PostScript. text Force text->PostScript. mentor Mentor Metafile. any Guess from first line. -C Arrange pages in columns. -R Arrange pages in rows. -r rows Number of rows. -c cols Number of columns." ################################# # Disabled/missing functionality. # # -m message Print message upon job completion. (Default) # +m No message. # -lh [aff] Produce letterhead on the first page. # Use the affiliation \"aff\" if supplied. set x $LZOPTIONS ${1+"$@"}; shift # =head1 OPTIONS # # =over 4 # badopts= while : do case "$1" in # =item B<-P>I[B>] # # Direct output to the specified I. # The default is taken from # the environment variable B<$PRINTER>. # The printer named "B<->" means standard output. # An optional I may be specified, # in which case the corresponding PostScript paper medium # directive will be inserted in the output # (eg B, B etc). # # Note that a plain B<-P> is reserved for multips' portrait flag; # using "C<-P I>" with a space is a common mistake. # -P?*) PRINTER=`expr "x$1" : 'x-P\(.*\)'` ;; # =item B<-t> I # # Request media from the specified I (numeric). # Pretty obsolete these days; # the B> option above is preferred. # -t) multipsargs="$multipsargs $1 $2"; shift ;; # =item B<-title> I # # Specify the printout title. # Some of the conversion backends make use of this value, # in particular the text->PostScript one. -title) title=$2; shift ;; # =item B<-1>, B<-2>, B<-4>, B<-8> # # Generate output for 1, 2, 4 or 8 logical pages per sheet. # These imply duplex mode and the appropriate tumble mode. # # =item B<-d>, B<-dv>, B<-dh>, B<+d> # # Put horizontals and vertical dividing lines # between logical pages, # verticals only, horizontals only, no dividers respectively. # # =item B<-D>, B<+D> # # Duplexmode: use both sides of the paper. # B<+D>: don't use both sides. # # =item B<-T>, B<+T> # # Tumblemode: second sheet is upside down. # B<+T>: no tumble. # # =item B<-R> # # Arrange logical pages in rows (the default). # # =item B<-C> # # Arrange logical pages in columns. # -[1248dDTRC] | +[dDT] | -d[hv]) multipsargs="$multipsargs $1" ;; # =item B<-L> # # Presume input data is in landscape format. # # =item B<-P> # # Presume input data is in portrait format (the default). # -[LP]) multipsargs="$multipsargs $1" topsargs="$topsargs $1" if [ "x$1" = x-P -a -t 2 ] then echo "$cmd: warning: plain -P (portrait mode) is the default" >&2 echo " did you mean -Pprinter? if so, there should be no space" >&2 fi ;; # =item B<-c> I # # Generate I columns of logical pages. # # =item B<-r> I # # Generate I rows of logical pages. # # =item B<-fg> {I|IB<,>IB<,>I} # # Set the default foreground I # (or Ied/Ireen/Ilue tuple). # Useful for printing overheads. # # =item B<-bg> {I|IB<,>IB<,>I} # # Set the default background I # (or Ied/Ireen/Ilue tuple). # Useful for printing overheads. # B tends to mean transparent in this context. # -[rc]|-[fb]g) multipsargs="$multipsargs $1 $2"; shift ;; ## UNSW only # -lh) multipsargs="$multipsargs -1" # case "$2" in # -*) aff= ;; # *) aff="-aff '$2'"; shift ;; # esac # filter="$filter lh $aff |" # ;; ## UNSW lpr only ## -m) domessage=1 message=$2; shift ;; ## +m) domessage= ;; # =item B<-o> I # # Emit only the logical pages specified by I. # This is a comma separated list of page numbers or ranges # of page numbers # (eg B<1,2,5-8>). # -o) pshufargs="$pshufargs -o $2"; shift ;; # =item B<-O> I # # Accept a comma separated list of numbers. # Shuffle input pages into that order. # Missing numbers in the sequence are added at the end. # -O) pshufargs="$pshufargs -O $2"; shift ;; # =item B<-r> # # Reverse the order of the logical pages. # -r) pshuftargs="$pshufargs $1" ;; # =item B<-f> I # # Insert the I, which must be a shell command, # at the front of the pipeline. # -f) case "$2" in '') echo "$cmd: -f requires a filter" >&2 badopts=1 ;; *) filter="$filter $2 |" shift ;; esac ;; # =item B<-i> I # # Treat the input as being of the named I. # The types are as for the 2ps(1) command # and include # B (the default: guess the type from the content), # B and B, B, B, and B. # MIME types are also accepted. # -i) itype=$2; shift; [ "x$itype" = xany ] && itype= ;; -i*) itype=`expr "x$1" : 'x-i\(.*\)'`; [ "x$itype" = xany ] && itype= ;; --) shift; break ;; -?*|+?*) echo "$cmd: unknown option '$1'" >&2; badopts=1 ;; /*/) regexp=`expr "x$1" : '^x/\(.*\)/$'` filter="highlight '$regexp' | $filter" ;; *) break;; esac shift done [ -n "$PRINTER" ] || { echo "$cmd: no -Pprinter and no \$PRINTER" >&2 badopts=1 } # =back # [ $badopts ] && { echo "$usage" >&2; exit 2; } # page selection and shuffling [ -n "$pshufargs" ] && postps="$postps | pshuf $pshufargs" # multisheeting [ -n "$multipsargs" ] && postps="$postps | multips \$multipsargs" ## UNSW lpr only ## case "$#,$domessage" in ## 0,0) msgflag='-m"$cmd"' ;; ## *,0) msgflag='-m"$cmd: $arg"' ;; ## 0,1) msgflag='-m"$message"' ;; ## *,1) msgflag='-m"$message: $arg"' ;; ## *,) msgflag= ;; ## esac xit=0 # catch paper type case "$PRINTER" in */*) paper=`expr "x$PRINTER" : 'x.*/\(.*\)'` case "$paper" in A[12345]) topsargs="$topsargs -m A4" ;; *) topsargs="$topsargs -m \"\$paper\"" ;; esac PRINTER=`expr "x$PRINTER" : 'x\(.*\)/.*'` ;; *) paper= ;; esac export PRINTER lp=$LZPRINTCOMMAND if [ -z "$lp" ] then case "$OS" in # SysVish solaris) lp='lp -d "$PRINTER" -T postscript' ;; linux|freebsd|openbsd|sunos) lp='lpr "-P$PRINTER"' ;; # BSDish *) ##echo "$cmd: warning: unknown \$OS \"$OS\" - assuming bsd" >&2 lp='lpr "-P$PRINTER"' ;; esac fi # insert paper setting outside postscript [ -n "$paper" ] && postps="$postps | sed -e '1a\\ $paper'" # use printer unless sending to stdout [ "x$PRINTER" = x- ] || postps="$postps | bgstdin $lp" # =head2 Files # # After the options comands an optional list of filenames to print. # If the list is empty # the document to print is read from standard input. # If a filename commences with B or B # then the filename is considered to be an URL # and the w3m(1) command is called to fetch (and format) the specified web page # for printing. # [ $# = 0 ] && set -- - tops="2ps $topsargs -i \"\$thisitype\" -T \"\$thistitle\"" pipeline="$filter $tops $postps" didstdin= for arg do thisitype=$itype thistitle=${title:-"$arg"} case "$arg" in -) if [ $didstdin ] then echo "$cmd: skipping second mention of stdin (\"$arg\")" >&2 xit=1 else didstdin=1 thistitle=${title:-"stdin"} eval "$pipeline" fi ;; http://* | ftp://* ) if [ -n "$URL2TXT" ] then eval "$URL2TXT \"\$arg\"" else w3m -dump -T text/html -cols 80 -F "$arg" fi \ | eval "$pipeline" ;; *) [ -n "$thisitype" ] || thisitype=`file2mime "$arg"` eval "$pipeline" <"$arg" ;; esac ## set +x done exit $xit # =head1 ENVIRONMENT # # PRINTER: default printer to use. # # LZOPTIONS: default command line options. # # LZPRINTCOMMAND: low level printer delivery command. # Example: # # /opt/LPRng/bin/lpr "-P$PRINTER" # # URL2TXT: filter to convert fetch a URL and emit as plain text. # Default: # # w3m -dump -T text/html -cols 80 -F "$arg" # # =head1 CAVEATS # # Command line options are processed left to right # (preceeded by any options in the B<$LZOPTIONS> environment variable). # Thus order can matter. # For example, the B<-4> option sets 4 pages to a sheet, # deactivates the landscape setting and deactivates tumblemode. # Thus the B<-L> and B<-T> options should succeed this option # if both are used. # # =head1 EXAMPLES # # =over 4 # # =item lz -Psuper/a3 foo.ps # # Print the postscript file B on the printer B with A3 paper, # double sided. # # =item lz -P- foo.pdf | gv - # # Convert the PDF file B to PostScript and view with the B program. # # =item lz -i text foo.ps # # Print the PostScript file B as text (i.e. you want to print the # PostScript itself, not render it). # # =item LZOPTIONS='-4 -C -dv'; export LZOPTIONS # # Arrange that by default, B will print 4 pages to a sheet, # arranged in columns (instead of the default: rows) with only # vertical dividers. # I find this handy for almost everything, # especially web pages. # # =item lz -o10-19 foo.pdf # # Print pages 10 through 19 of the PDF file B. # # =item wide-report | lz -L # # Print the output of B in landscape mode. # # =back # # =head1 SEE ALSO # # multips(1), pshuf(1), 2ps(1), a2ps(1), acroread(1) # # =head1 AUTHOR # # Cameron Simpson Ecs@zip.com.auE January 1992 #