#!/bin/bash # # addpsctrl # # Adds printer control commands to the given PostScript data. # Currently requires bash - sorry but I have no time to support too many # dumb shells (like Solaris /bin/sh). The korn shell (ksh) would be suitable, # but the syntax is not the same as that of bash. bash is free - ksh loses out. # Works with bash 1.x and 2.x. # # Copyright (C) by Volker Kuhlmann # Copyright (C) by Volker Kuhlmann # Released under the terms of the GNU General Public License (GPL) Version 2. # See http://www.gnu.org/ for details. # # Volker Kuhlmann # 5, 6, 12 Apr; 2 Aug 2000 # 26 Jan 2006 # VERSION="VK 1.3, 26 Jan 2006" #### #### Constants and initial variables # # Use kpsewhich: ADDPSCTRL_DFLTOPT="${ADDPSCTRL_DFLTOPT:=--kpsewhich}" # If you don't have kpsewhich, or would like to load the config files from a # different directory, give the directory with the config files by setting # the environment variable ADDPSCTRL_DFLTOPT: #ADDPSCTRL_DFLTOPT="${ADDPSCTRL_DFLTOPT:=--nokpsewhich --dir YOURPATH}" #### #### Usage # show_usage() { echo " Usage: ${0##*/} [OPTION]... [FILE] [CTRL]... Version $VERSION " } usage() { show_usage echo "Call with -h for help. " exitwith ErrUsage } #### #### Help # Help() { show_help; exitwith ErrHelp; } show_help() { show_usage echo "\ Inserts printer control instructions (e.g. duplex) into a PostScript file. OPTIONS: -h, --help show help -k, --kpsewhich use kpsewhich to locate config files if necessary -K, --nokpsewhich never use kpsewhich -f, --file FILE insert control commands into file FILE ('-' for stdin) -d, --dir DIR control files are in directory DIR -c, --ctrl CTRL locate + insert control file 'config.CTRL' -i, --insert INSRT insert file INSRT before any other control files (give full path and filename) -o, --output OUT write to file OUT instead of stdout -V, --version display version and exit -s, -1 same as -c simplex -2L same as -c duplong -2S same as -c dupshort -a4, -a3 same as -c a4 / -c a3 -man same as -c manualfeed If -f is not used, the first non-option argument is taken as FILE. Remaining arguments are names of control files to be inserted (after those given with -i and -c). Control file searching: 1) In directory DIR (if given) 2) By running kpsewhich, unless disabled with -K Default (can be changed by setting environment variable ADDPSCTRL_DFLTOPT): $ADDPSCTRL_DFLTOPT " } #### #### Error/Exit codes # exitwith() { exec 1>&2 # write stdout on stderr instead case "$1" in ErrUsage|ErrHelp) # usage already displayed exit 1;; ErrNoread) echo "Config/header file not readable: '$2'." exit 2;; ErrNoconf) echo "Can not locate config/header file '$2'." exit 3;; ErrNodatafile) echo "No file specified to insert control commands into." echo "Call with -h for help on command argument syntax." exit 9;; ErrNoinsfile) echo "No control commands specified to insert." echo "Call with -h for help on command argument syntax." exit 9;; ErrMissingParameter) echo "A required parameter for option $2 is missing." echo "Call with -h for help." exit 9;; *) echo "Error: exitwith() was called with illegal error code '$1'." exit 19;; esac } #### #### Parse command line parameters # checkargmm() { test "$1" != "--" -a "$2" != "--" #true # uncomment this to allow "--" as argument to an option } checkarg2() { test $# -ge 2 && checkargmm "$2" && return exitwith ErrMissingParameter "$1" } checkarg3() { test $# -ge 3 && checkargmm "$2" "$3" && return exitwith ErrMissingParameter "$1" } parse_cmd_line() { local cmdline arg unset -v debug usekpsewhich configdir insfile datafile outfile ctrl set -- $ADDPSCTRL_OPT "$@" # pre-init options while [ "$1" ]; do #test $debug && echo "Current arg: $1" arg="${1#-}" test "$arg" = "$1" && break # does word start with "-"? test "$arg" = "-" && { shift; break; } # allow both "-long" and "--long" for long options: arg="${arg#-}" case "$arg" in #debug) debug=1;; usage) usage;; V|version) usage;; h|help) Help;; k|kpsewhich) usekpsewhich=1;; K|nokpsewhich) usekpsewhich="";; d|dir) checkarg2 "$@"; configdir="$2"; shift;; i|insert) checkarg2 "$@"; insfile="$2"; shift;; f|file) checkarg2 "$@"; datafile="$2"; shift;; o|output) checkarg2 "$@"; outfile="$2"; shift;; c|ctrl) checkarg2 "$@"; ctrl="$2"; shift;; s|1) ctrl=simplex;; 2L) ctrl=duplong;; 2S) ctrl=dupshort;; a4|a3) ctrl="$arg";; man) ctrl="manualfeed";; "") break;; # allow "-" as file arg *) exitwith ErrBadoption "$1";; esac shift done numfileargs=$# } locate_config_file() { insfile="" test -n "$configdir" && insfile="$configdir/config.$1" if [ -n "$usekpsewhich" -a \( -z "$insfile" -o ! -r "$insfile" \) ]; then insfile="`kpsewhich --format 'dvips config' config.$1`" fi test -z "$insfile" && exitwith ErrNoconf "config.$1" test -r "$insfile" || exitwith ErrNoread "$insfile" } insert_into_ps() { # 0: start # 1: !% found # 2: %% found # 3: insertion done in="$1"; shift #echo \ AWK '\ BEGIN {n = 0; ins="'"$*"'"} \ n == 3 {print $0; next} \ /^%%EndSetup/ || /^%%Page:/ || ((n == 1) && (! /^[% ]/) && (! /^$/)) { \ if ((n == 1) || (n == 2)) { \ n = 3; \ while ((getline line 0) { print line } \ }} \ /^%\!/ {if (n == 0) {n = 1}} \ /^%%/ {if (n == 1) {n = 2}} \ {print $0} \ END {if (n < 3) { \ while ((getline line 0) { print line } } } \ ' \ "$in" # gawk 3.1.4 doesn't understand while ("cat " ins | getline # and tries to run ins as a command. -VK26Jan06 } #### #### Main if [ $# -eq 0 ]; then usage; fi ADDPSCTRL_OPT="${ADDPSCTRL_OPT:-$ADDPSCTRL_DFLTOPT}" # find a useful awk (solaris awk is not) p="`type -p gnuawk gawk nawk | head -1`" && eval 'AWK() { '"${p:-awk}"' "$@"; }' parse_cmd_line "$@" #echo $#, $numfileargs, `expr $# - $numfileargs` shift `expr $# - $numfileargs` #echo fileargs: "$@" #echo "opts=$ADDPSCTRL_OPT;; use=$usekpsewhich" #echo "ctrl=$ctrl, insfile=$insfile, dir=$configdir, out=$outfile" if [ -z "$datafile" ]; then test -z "$1" && exitwith ErrNodatafile datafile="$1"; shift fi #echo "datafile=$datafile" insfiles="" if [ -n "$insfile" ]; then test -r "$insfile" || exitwith ErrNoread "$insfile" insfiles="$insfile" fi for c in "$ctrl" "$@"; do test -z "$c" && continue #echo locate_config_file "$c" locate_config_file "$c" #echo "insfile=$insfile" insfiles="$insfiles $insfile" done #echo "insfiles=$insfiles" test -z "$insfiles" && exitwith ErrNoinsfile if [ -z "$outfile" ]; then #echo insert_into_ps "$datafile" $insfiles insert_into_ps "$datafile" $insfiles else insert_into_ps "$datafile" $insfiles >"$outfile" fi