#! /bin/sh -e # -*- ksh -*- # psset --- Put page device definition somewhere in a PS document. # Copyright (c) 1999 Akim Demaille, Miguel Santana # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, you can either send email to this # program's maintainer or write to: The Free Software Foundation, # Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. # Author: Akim Demaille # Get the name of the program program=`echo $0 | sed 's#.*/##g'` # Local vars at=0 # Insert call in the document's Setup section. debug= file= fixps=${FIXPS:-fixps} output=- pagedevices= # `;' separated list of `key:value' quiet=: # i.e., verbose tmpdir=${TMPDIR:-/tmp}/$program.$$ sedscript=$tmpdir/psset.sed # The version/usage strings version="$program 1.3 (GNU a2ps 4.13) Written by Akim Demaille. Copyright (c) 1998-1999 Akim Demaille, Miguel Santana This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." usage="\ Usage: $program FILE Produce a version of the PostScript FILE with a protected call to the PostScript operator \`setpagedevice'. Typical use is making FILE print duplex, or on the manual tray etc. Options: -h, --help display this help and exit -v, --version display version information and exit -q, --quiet don't print informational messages -o, --output=FILE save result in FILE. If FILE is \`-', send to stdout -n, --no-fix don't run \`fixps' to fix PS problems in FILE -S, --setpagedevice=KEY[:VALUE] pass a page device definition to output. Multiple values accumulate -a, --at=PAGE insert the page device definitions at PAGE. Default is PAGE=0, standing for the Document's Setup section Shortcuts: -m, --manualfeed alias for -SManualFeed:true -s, --simplex alias for -SDuplex:false -d, --duplex alias for -SDuplex:true -STumble:false corresponds to Duplex, binding along the long edge -t, --tumble alias for -SDuplex:true -STumble:true corresponds to Duplex, binding along the short edge Produced output is meant for PS level 2 printers. News, updates and documentation: visit http://www.inf.enst.fr/~demaille/a2ps/ Report bugs to " help="Try \`$program --help' for more information." # Parse command line arguments. option_without_arguments='vhqnDmdts' # Push a token among the arguments that will be used to notice when # we ended options/arguments parsing. arg_sep="$$--$$" set dummy "${1+"$@"}" "$arg_sep" shift while test "x$1" != "x$arg_sep"; do # Handle --option=value by splitting apart and putting back on argv. case "$1" in --*=*) opt=`echo "$1" | sed -e 's/=.*//'` val=`echo "$1" | sed -e 's/[^=]*=//'` shift set dummy "$opt" "$val" "${1+"$@"}" shift ;; -[$option_without_arguments]?*) # Prefix $1 with x to avoid running `echo -na' for instance. opt=`echo "x$1" | sed -e 's/x-\(.\).*/-\1/'` rest=`echo "x$1" | sed -e 's/x-.\(.*\)/-\1/'` shift set dummy "$opt" "$rest" "${1+"$@"}" shift ;; # This case needs to be protected so that the case `-??*' does # not split long options without arguments --*) ;; # This is an option with argument. Split apart and put back on argv. -??*) opt=`echo "x$1" | sed -e 's/x-\(.\).*/-\1/'` arg=`echo "x$1" | sed -e 's/x-.\(.*\)/\1/'` shift set dummy "$opt" "$arg" "${1+"$@"}" shift ;; esac # Now, handle the options. $1 is the option *only*. If it has an # argument, it is now necessarily in $2 etc. Remember to shift # when fetching an argument. case "$1" in -v | --v*) echo "$version"; exit 0;; -h | --h*) echo "$usage"; exit 0;; -q | --sil* | --q*) quiet=echo;; # Delay debugging so that options parsing does not appear -D | --debug) debug=: ;; -o | --output) shift ; output=$1 ;; -a | --at) shift ; at=$1 ;; -S | --set*) shift case $1 in *:*) pagedevices="${pagedevices}$1;" ;; *) echo "$program: invalid argument for -S: $1" 1>&2 exit 1 ;; esac ;; -m | --man* ) pagedevices="${pagedevices}ManualFeed:true;" ;; -d | --dup* ) pagedevices="${pagedevices}Duplex:true;Tumble:false;" ;; -t | --tum* ) pagedevices="${pagedevices}Duplex:true;Tumble:true;" ;; -s | --sim* ) pagedevices="${pagedevices}Duplex:false;" ;; -) # We are working with stdin ;; set dummy "$@" "$1" shift ;; -n|--no-fix) fixps="$fixps -n" ;; --) # What remains are not options. shift while test "x$1" != "x$arg_sep"; do set dummy "${1+"$@"}" "$1" shift shift done break;; -*) echo "$program: Unknown or ambiguous option \`$1'." >&2 echo "$program: Try \`--help' for more information." >&2 exit 1;; *) set dummy "${1+"$@"}" "$1" shift ;; esac shift done # Pop the token shift # Check the number of arguments. case $# in 0) file=;; 1) # We want $file to be empty to mean stdin if test "x$file" = "x-"; then file= else file=$1 fi ;; *) echo "$program: too many arguments" 1>&2 echo "$help" 1>&2 exit 1;; esac mkdir $tmpdir if test -n "$debug"; then # Set -x now if debugging set -x else # Temp dir. Get ready not to leave junk (if not debugging) trap "/bin/rm -rf $tmpdir" 0 1 2 3 13 15 fi # Well, if there is nothing to do, just do nothing. if test -z "$pagedevices"; then exec $fixps `$quiet -q` $file -o "$output" fi # Prepare the PostScript snippet we plan to insert if needed pspagedevice= saved_IFS=$IFS IFS=";" for pagedevice in $pagedevices do IFS=$saved_IFS key=`echo $pagedevice | sed -e 's/:.*//g'` value=`echo $pagedevice | sed -e 's/.*://g'` # I use `cvx exec' in order to let the stopped environment catch the # errors. This way, the user can do -SDuplex:fuubar and have a # PS file that behaves well. pspagedevice="$pspagedevice %%BeginFeature: *$key $value (<<) cvx exec /$key ($value) cvx exec (>>) cvx exec systemdict /setpagedevice get exec %%EndFeature" done pspagedevice="% Pagedevice definitions: countdictstack % Push our own mark, since there can be several PS marks pushed depending % where the failure really occured. /psset_mark {$pspagedevice } stopped % My cleartomark { /psset_mark eq { exit } if } loop countdictstack exch sub dup 0 gt { { end } repeat }{ pop } ifelse" # Prepare the sed command we want to run. # End of lines must be protected by `\' but the last one, and leading # spaces with a `\' too... pspagedevicelen=`echo "$pspagedevice" | wc -l` pspagedevice=`echo "$pspagedevice" | \ sed -e "$pspagedevicelen!s/\$/\\\\\\/;s/^ /\\\\\\ /"` case $at in 0) # Insert last in the Setup, so that we win over other requests. address="^%%EndSetup$" insert="i" ;; *) # Insert right after the beginning of the page. Trying to find a # better place than right after %%Page: is an overkill. address="^%%Page: .*$at$" insert="a" ;; esac # The script is complicated by the fact that we don't want to issue # twice the setpagedevice. And it is correct for an included document # to have a Setup section. cat >$sedscript <$output $fixps `$quiet -q` $file | sed -f $sedscript # We don't remove the tmp directory: trap does it. exit 0