#!/bin/sh
version=N.NN
#########################################################################
##                                                                     ##
##  pdfjam: A shell-script interface to the "pdfpages" LaTeX package   ##
##  ------                                                             ##
##                                                                     ##
##  Author: David Firth (http://warwick.ac.uk/dfirth)                  ##
##                                                                     ##
##  Usage: see https://github.com/rrthomas/pdfjam                      ##
##         or "pdfjam --help"                                          ##
##                                                                     ##
##  Relies on:                                                         ##
##  -- pdflatex (or xelatex or lualatex)                               ##
##  -- the 'pdfpages' package for LaTeX (ideally version >= 0.4f)      ##
##                                                                     ##
##  License: GPL version 2 or later.  This software comes with         ##
##  ABSOLUTELY NO WARRANTY of fitness for any purpose at all; if you   ##
##  do not accept that, then you must not use it.                      ##
##                                                                     ##
##  The path searched for site-wide configuration files can be set     ##
##  by editing the following variable:                                 ##
##                                                                     ##
    configpath='/etc:/usr/share/etc:/usr/local/share:/usr/local/etc'   ##
##                                                                     ##
##  Nothing else in this file should need to be changed.               ##
##                                                                     ##
#########################################################################
##
##  HELP TEXT
##
##  Defines the output of 'pdfjam --help'
##
helptext="
insert contents of pdfjam-help.txt here
"
##
##  END OF HELP TEXT
##
#########################################################################
##
##  PRELIMINARIES
##
##  First determine:
##    --- whether verbose commentary should be provided (not if --quiet 
#         or --configpath was specified); 
##    --- whether this call to pdfjam is a "batch" call; 
##    --- whether just the help text is required; 
##    --- or whether all configuration files should be ignored.
##
verbose=true
for arg
do
    case $arg in
	--quiet | -q | --configpath)
	    verbose=false ;
	    ;;
	--version | -V)
	    echo "$version"
	    exit 0 ;
	    ;;
	--batch)
	    batch=true ;
	    ;;
	--help | -u | -h)
		printf "%s\n" "$helptext" ;
		exit 0 ;
	    ;;
	--vanilla)
	    vanilla=true ;
	    ;;
	*)
	    ;;
    esac
done
##
##  Check to see whether this is a "secondary" call to pdfjam:
##
if test -z "$PDFJAM_CALL_NUMBER"  ## not a secondary call
then
    PDFJAM_CALL_NUMBER=0
fi
##
##  Keep a copy of the internal file separator, so we can change it safely
##
OIFS="$IFS"
##
##  Record the full filename of the current working diractory
##
pwd=$(pwd)
##
##  Trap interrupts so that they kill everything:
##
trap 'IFS=$OIFS; exit 1' 1 2 15
##
##  The following will be useful for readability of the script:
##
newline='
'
##
##  Define a function to escape tricky characters in file names etc:
##
escape_chars () {
    (printf "%s" "${1}" | sed 's/[^a-zA-Z0-9._/\-]/\\&/g')
}
##
##  Define a function to output verbose comments:
##
prattle () { ## second argument here is non-null for continuation lines
    if test $verbose = true; then
	prefix1="  pdfjam:" ;
	prefix2=$(printf "%s" "$prefix1" | sed 's/pdfjam:/       /') ;
	indent="" ;
	if test "$PDFJAM_CALL_NUMBER" -gt 0  &&
	    test "$batch" != true
	then
	    indent="    "
	fi
	IFS="$newline" ;
	lineCounter=0 ;
	for line in ${1}
	do
	    lineCounter=$((lineCounter + 1)) ;
	    if  test $lineCounter -eq 1  &&  test ! -n "${2}" ;
	    then 
		if test -w "$PDFJAM_MESSAGES_FILE"
		then printf "$prefix1$indent %s\n" "$line" >> \
                       "$PDFJAM_MESSAGES_FILE"
		else messages="$messages$prefix1$indent $line$newline"  
                       ## msg file not made yet
		fi
	    else 
		if test -w "$PDFJAM_MESSAGES_FILE"
		then printf "$prefix2$indent %s\n" "$line" >> \
                       "$PDFJAM_MESSAGES_FILE"
		else messages="$messages$prefix2$indent $line$newline"  
                       ## msg file not made yet
		fi
	    fi ;
	done ;
	IFS="$OIFS" ;
    fi ;
    return ;
}
##
##  And here's the first piece of verbose commentary:
##
prattle "----" 1
prattle "This is pdfjam version ${version}."
##
#########################################################################
##
##  CONFIGURATION
##
##  THESE SETTINGS WILL BE OVER-RIDDEN by any found in configuration
##  files.  By default such files are found at any or all of
##     /etc/pdfjam.conf
##     /usr/share/etc/pdfjam.conf
##     /usr/local/share/pdfjam.conf
##     /usr/local/etc/pdfjam.conf
##     $HOME/.pdfjam.conf
##  (And they are read in that order; if a setting is made more than
##  once, the last instance prevails.)
##
##  An example configuration file can be found at
##     https://github.com/rrthomas/pdfjam
##
##  The path searched for site-wide configuration files can be changed
##  by editing the variable 'configpath' at the top of this file.
##
##
##  First get the full path (if it exists) to pdflatex:
##
latex=$(command -v pdflatex)
if [ -z "$latex" ] ; then latex="not found" ; fi
##
##  Likewise for the pdfinfo and iconv (only needed for `--keepinfo'):
##
pdfinfo=$(command -v pdfinfo)
if [ -z "$pdfinfo" ] ; then pdfinfo="not found"; fi
iconv=$(command -v iconv)
if [ -z "$iconv" ] ; then iconv="not found"; fi
##
##
##  Next a permitted location for temporary files on your system:
##
tempfileDir='/var/tmp'   ##  /var/tmp is standard on most unix systems
##
##
##  Default for the output file location:
##
outFile="$pwd"           ##  Output to the current working directory
##
##
##  A few more default settings for pdfjam:
##
shortedge='true'           ## Default paper is rotated shortedge when doing book
##
runs=1                     ## Run latex just once
##
tidy='true'                ##  Delete all temporary files at the end
##
keepinfo='false'           ##  Don't try to preserve "pdfinfo" data
##
checkfiles='false'         ##  Don't use the Unix 'file -Lb' utility to
##                           identify PDF files from their contents;
##                           rely on the .pdf or .PDF extension instead.
##
suffix='pdfjam'            ##  Default filename suffix to be used when 
##                           --outfile is either (a) a directory, or (b) 
##                           not specified in a --batch call.
##
preamble=''                ##  Default LaTeX preamble string.
##
##  Guess default paper size from locale if possible, otherwise A4
##
if command -v locale >/dev/null ; then
    paperheight=$(locale -k LC_PAPER | sed -e '1!d' -e 's/.*=//') ;
    case $paperheight in
	297)
	    paper='a4paper' ;
	    ;;
	279)
	    paper='letterpaper' ;
	    ;;
	*)
	    paper='a4paper' ;
	    ;;
    esac
else paper='a4paper' ;  ## fallback paper size is ISO A4
fi
##
##  END OF SETTINGS MADE DIRECTLY WITHIN THE SCRIPT
##
##  Now read the site's or user's configuration file(s) if such exist,
##  unless '--vanilla' was specified.
##
if test "$vanilla" != true
then
    if test "$PDFJAM_CALL_NUMBER" = 0   ## not a secondary call to pdfjam
    then
	configFiles=$(printf "%s" "$configpath" | \
	    sed 's/:/\/pdfjam.conf:/g; s/$/\/pdfjam.conf/')
	configFiles="${configFiles}:$HOME/.pdfjam.conf"
	PDFJAM_CONFIG=""
	prattle "Reading any site-wide or user-specific defaults..."
	IFS=':'
	for d in $configFiles
	do
	    if test -f "$d"; then
		change=$(sed '/^ *#.*/d ; s/ *#.*//; s/^ *//' "$d")
		comment="## ${newline}## From ${d}: ${newline}##"
		PDFJAM_CONFIG="$PDFJAM_CONFIG$comment$newline$change$newline"
	    fi
	done
	IFS="$OIFS"
	PDFJAM_CONFIG=$(printf "%s" "$PDFJAM_CONFIG" | sed 's/^/    /')
	if test "$batch" = true ; then export PDFJAM_CONFIG ; fi
	if test -z "$PDFJAM_CONFIG"
	then
	    prattle "(none found)" 1
	else
	    prattle "$PDFJAM_CONFIG" 1
	fi
    fi
    if test -n "$PDFJAM_CONFIG" ; then eval "$PDFJAM_CONFIG" ; fi
else
    if test $PDFJAM_CALL_NUMBER -eq 0
    then
	prattle "Called with '--vanilla': no user or site configuration"
	prattle "files will be read." 1
    fi
fi
## For backwards compatibility, check here for a $pdflatex setting in the config file
if [ -n "${pdflatex:-}" ] ; then latex="$pdflatex" ; fi
##
##  END OF CONFIGURATION BLOCK
##
#########################################################################
##
##  ERROR CODES
##
E_USAGE=64           #  command line usage error
E_NOINPUT=66         #  cannot open input
E_UNAVAILABLE=69     #  service unavailable
E_SOFTWARE=70        #  internal software error
E_OSFILE=72          #  file does not exist or cannot be opened
E_CANTCREATE=73      #  can't create (user) output file
E_CONFIG=78          #  configuration error
##
##  Define a function to print an error message and exit:
##
error_exit () {
    if [ -r "$PDFJAM_MESSAGES_FILE" ]
    then cat "$PDFJAM_MESSAGES_FILE" >&2
    else printf "%s" "$messages" 1>&2
    fi
    printf "  pdfjam ERROR: %s\n" "$1" 1>&2 ;
    exit "$2" ;
}
##
#########################################################################
##
##  READ AND PROCESS THE ARGUMENTS
##
##  In case of NO argument supplied, mention 'pdfjam --help':
##
if  test $# -eq 0
then
    prattle "No arguments supplied; continuing anyway. (See"
    prattle "'pdfjam --help' for information on usage.)"  1
fi
##
##  Now do the argument loop.
##
fileSpec=""
miscOptions=""
callOptions=""
optionsFinished=""
##
##  First note any '--checkfiles' or '--no-checkfiles' option
##
for arg 
do
    case $arg in
	--checkfiles)
	    checkfiles=true ;
	    callOptions="$callOptions --checkfiles" ;
	    ;;
	--no-checkfiles)
	    checkfiles=false ;
	    callOptions="$callOptions --no-checkfiles" ;
	    ;;
    esac
done
while test -n "${1}${2}"; do
    argUnmatched=""
    if test "$optionsFinished" != true
    then
	case ${1} in
	    --) ## signals end of command-line options
		optionsFinished=true ;
		shift ;
		continue ;
		;;
	    --configpath)
		printf "%s\n" "$configpath" ;
		exit 0;;
	    --* | -q | -o)
		if test "$pageSpecAwaited" = true ; then
		## fill in any missing page specs before continuing
		    fileSpec=$(printf "%s" "$fileSpec" | sed 's/|awaited/|-/g')
		    pageSpecAwaited=false
		fi
		case ${1} in
		    --latex)
			latex="${2}" ;
			callOptions="$callOptions --latex ${2}" ;
			shift ;;
		    --batch)
			batch=true ;
			;;
		    --vanilla)
			callOptions="$callOptions ${1}" ;
			;;
		    --quiet | -q)
			verbose=false ;
			callOptions="$callOptions ${1}" ;
			;;
		    --outfile | -o)
			outFile="${2}" ;
			if test "$batch" = true
			then
			    outFile=$(escape_chars "$outFile")
			fi
			callOptions="$callOptions --outfile $outFile" ;
  			shift ;;
		    --suffix)
			if test -n "${2}"
			then
			    suffix="${2}" ;
			    if test "$batch" = true
			    then
				suffix=$(escape_chars "$suffix")
			    fi
			    callOptions="$callOptions --suffix $suffix"
			    shift
			else
			    error_exit \
				"'--suffix' string has zero length" \
				$E_USAGE ;
			fi
			;;
		    --runs)
			runs="${2}" ;
			## check if the argument is a number > 0
                        if [ "$runs" -lt 1 ] 2> /dev/null; then
                          error_exit \
                                "'--runs' number must be at least 1" \
                                $E_USAGE ;
                        fi
                        callOptions="$callOptions --runs ${2}" ;
                        shift ;;
		    --tidy)
			tidy=true ;
			callOptions="$callOptions --tidy" ;
			;;
		    --no-tidy)
			tidy=false ;
			callOptions="$callOptions --no-tidy" ;
			;;
		    --shortedge)
			shortedge=true ;
			callOptions="$callOptions --shortedge" ;
			;;
		    --longedge)
			shortedge=false ;
			callOptions="$callOptions --longedge" ;
			;;
		    --keepinfo)
			keepinfo=true ;
			callOptions="$callOptions --keepinfo" ;
			;;
		    --no-keepinfo)
			keepinfo=false ;
			callOptions="$callOptions --no-keepinfo" ;
			;; 
		    --checkfiles)
			;; ## already done above
		    --no-checkfiles)
			;; ## already done above
		    --pdftitle)
			pdfTitle="${2}" ;
			if test "$batch" = true
			then
			    pdfTitle=$(escape_chars "$pdfTitle")
			fi
			callOptions="$callOptions --pdftitle $pdfTitle" ;
			shift ;;
		    --pdfauthor)
			pdfAuthor="${2}" ;
			if test "$batch" = true
			then
			    pdfAuthor=$(escape_chars "$pdfAuthor")
			fi
			callOptions="$callOptions --pdfauthor $pdfAuthor" ;
			shift ;;
		    --pdfsubject)
			pdfSubject="${2}" ;
			if test "$batch" = true
			then
			    pdfSubject=$(escape_chars "$pdfSubject")
			fi
			callOptions="$callOptions --pdfsubject $pdfSubject" ;
			shift ;;
		    --pdfkeywords)
			pdfKeywords="${2}" ;
			if test "$batch" = true
			then
			    pdfKeywords=$(escape_chars "$pdfKeywords")
			fi
			callOptions="$callOptions --pdfkeywords $pdfKeywords" ;
			shift ;;
		    --paper)
			paper="${2}"
			callOptions="$callOptions ${1} ${2}" ;
			shift ;;
		    --pagecolor)
			pagecolor="${2}" ;
			callOptions="$callOptions ${1} ${2}" ;
			shift ;;
                    --a4paper | --a5paper | --b5paper | --letterpaper | \
                        --executivepaper | --legalpaper)
			##  standard LaTeX paper sizes
			paper=$(printf "%s" "${1}" | sed 's/^--//') ;
			callOptions="$callOptions ${1}" ;
			;;
		    --a0paper | --a1paper | --a2paper | --a3paper | \
                        --a6paper | --b0paper | --b1paper | --b2paper | \
			--b3paper | --b4paper | --b6paper)
			##  the 'geometry' package is needed
			if test "$geometry" != false ;
			then
			    paper=$(printf "%s" "${1}" | sed 's/^--//') ;
			    callOptions="$callOptions ${1}" ;
			    geometry=true ;
			fi ;
			;;
		    --papersize)
			##  the 'geometry' package is needed
			if test "$geometry" != false ;
			then
			    papersize="papersize=${2}" ;
			    callOptions="$callOptions ${1} '${2}'" ;
			    geometry=true ;
			fi ;
			shift ;;
		    --landscape)
			landscape=true ;
			callOptions="$callOptions --landscape" ;
			;;
		    --no-landscape)
			landscape=false ;
			callOptions="$callOptions --no-landscape" ;
			;;
		    --twoside)
			twoside=true ;
			callOptions="$callOptions --twoside" ;
			;;
		    --no-twoside)
			twoside=false ;
			callOptions="$callOptions --no-twoside" ;
			;;
		    --preamble)
			preamble="$preamble${2}" ;
			shift ;;
		    --enc) # command line encoding
			enc="${2}"
			callOptions="$callOptions ${1} ${2}"
			shift ;;
		    --*)
                        ##  options for \includepdfmerge
			argName=$(printf "%s" "${1}" | sed 's/^--//');
			value="${2}"
			miscOptions=$miscOptions,"$argName=$value" ;
		        ## saved for possible use in LaTeX file
			callOptions="$callOptions ${1} '$value'" ;
		        ## saved for possible use in a further call to pdfjam
			shift ;
			;;
		esac ;;
	    '' | *)
		argUnmatched=true
		;;
	esac
    fi
    if test "$optionsFinished" = true  ||  test "$argUnmatched" = true
    then
	case ${1} in
	    "" | /dev/stdin)
		fileSpec="${fileSpec}${newline}/dev/stdin|awaited"
		pageSpecAwaited=true
		inputFromStdin=true ;;
	    -)
		if test "$pageSpecAwaited" = true  ; then
		    fileSpec=$(printf "%s" "$fileSpec" | \
			sed 's/|awaited/|-/g')
		    pageSpecAwaited=false
		else
		    error_exit "no PDF/JPG/PNG file found at ${1}" \
			$E_NOINPUT
		fi ;;
	    *)  ##  All other args should be PDF (or JPG/PNG) 
                ##  source files and page selections; if not, we'll quit
		if test "$checkfiles" = true ;  ## not always available
		then
		    case $(file -Lb "${1}") in
			"PDF document"*|"JPEG image data"*|"PNG image"*)   
                            ##  it's a PDF file (or JPG/PNG) as expected
			    fileSpec="$fileSpec${newline}${1}|awaited"
			    pageSpecAwaited=true
			    ;;
			*)
			    case ${1} in
				*.[pP][dD][fF] | *.[jJ][pP][eE][gG] | \
				    *.[jJ][pP][gG] | *.[pP][nN][gG]) 
                                    ## should be PDF/JPG/PNG file, but isn't
				    error_exit "no PDF/JPG/PNG file found at ${1}" \
					$E_NOINPUT
				    ;;
				*) ##  if page spec needed, assume this is it;
		                   ##  otherwise something is wrong
				    if test "$pageSpecAwaited" = true  ; then
					fileSpec=$(printf "%s" "$fileSpec" | \
					    sed "s/|awaited/|$1/g")
					pageSpecAwaited=false
				    else
					error_exit "no PDF/JPG/PNG file found at ${1}" \
					    $E_NOINPUT
				    fi
				    ;;
			    esac
			    ;;
		    esac
		else  ## no checking of file contents; rely on .pdf extension
		    case ${1} in
			*.[pP][dD][fF] | *.[jJ][pP][eE][gG] \
			    | *.[jJ][pP][gG] | *.[pP][nN][gG])  
                            ## assume it's a PDF/JPG/PNG file
			    test -f "${1}" || error_exit \
				"${1} not found" $E_NOINPUT
			    fileSpec="$fileSpec"$newline${1}"|"awaited
			    pageSpecAwaited=true
			    ;;
			*) ##  if page spec needed, assume this is it;
		           ##  otherwise something is wrong
			    if test "$pageSpecAwaited" = true  ; then
				fileSpec=$(printf "%s" "$fileSpec" | \
				    sed "s/|awaited/|$1/g")
				pageSpecAwaited=false
			    else
				error_exit "no PDF/JPG/PNG file found at ${1}" \
				    $E_NOINPUT
			    fi
			    ;;
		    esac
		fi
		;;
	esac
    fi
    shift
done
##
##  Use the default page spec for any that remain unspecified:
##
fileSpec=$(printf "%s" "$fileSpec" | sed '/^$/d; s/^ //; s/|awaited$/|-/')
##
##  Check whether input from stdin should be used by default:
if  test $PDFJAM_CALL_NUMBER -eq 0  &&  test "$inputFromStdin" != true
then
    ## the special argument '/dev/stdin' was not used
    if test -z "$fileSpec" ; then
    ## no argument specifying a PDF source was given
	inputFromStdin=true
	fileSpec="/dev/stdin|-"
	prattle "No PDF/JPG/PNG source specified: input is from stdin."
    fi
fi
##
##  Delete leading comma from $miscOptions:
##
miscOptions=$(printf "%s" "$miscOptions" | sed 's/^,//')
##
if test -n "$preamble"
then callOptions="$callOptions --preamble '$preamble'"
fi
##  Delete leading space from $callOptions:
##
callOptions=$(printf "%s" "$callOptions" | sed 's/^ //')
##
##  Set up a document options variable:
##
case $landscape in
    true)
	orientation=landscape ;;
    *)
	orientation="" ;;
esac
case $twoside in
    true)
	twoside=twoside ;;
    *)
	twoside="" ;;
esac
case $shortedge in
    true)
	shortedge="" ;;
    *)
	shortedge='\usepackage{everyshi}\makeatletter\EveryShipout{\ifodd\c@page\pdfpageattr{/Rotate 180}\fi}\makeatother' ;;
esac
if test "$geometry" != false
then
##  we haven't already found that geometry.sty is missing
    case $paper in
	a0paper | a1paper | a2paper | a3paper | \
            a6paper | b0paper | b1paper | b2paper | \
	    b3paper | b4paper | b6paper)
	    ##  the 'geometry' package is needed
	    geometry=true ;
	    ;;
	*)
	    ;;
    esac
fi
documentOptions="$paper","$orientation","$twoside"
documentOptions=$(printf "%s" "$documentOptions" | sed 's/^,//' | sed 's/,$//')
##
##  END OF ARGUMENT PROCESSING
##
#########################################################################
##
##  CHECK SYSTEM SETUP
##
##  These checks are not repeated in secondary calls.
##
if test $PDFJAM_CALL_NUMBER -eq 0  ## not a secondary call
then
    ##  Check whether there's a suitable latex to use:
    case "$latex" in
	"not found")
	    error_exit "can't find pdflatex!" $E_UNAVAILABLE
	    ;;
	*)  ## 
	    if test ! -x "$latex"
	    then
		error_exit \
		    "configuration error, $latex is not an executable file" \
		    $E_CONFIG
	    fi
	    ;;
    esac
    ##
    ##  Check that necessary LaTeX packages are installed:
    ##
    modifyPath=$(printf "%s" "$latex" | sed 's/\/[^\/]*$//')
    if [ -n "$modifyPath" ] ; then
	PATH="$modifyPath:$PATH"
	export PATH
    fi
    (kpsewhich pdfpages.sty >/dev/null) ||
    error_exit \
	"LaTeX package pdfpages.sty is not installed" \
	$E_UNAVAILABLE

    for pack in pdflscape eso-pic everyshi atbegshi ; do
        (kpsewhich $pack.sty >/dev/null) ||
        error_exit \
	    "LaTeX package $pack.sty is not installed (see the pdfpages manual)" \
	    $E_UNAVAILABLE
    done
    if test "$geometry" = true
    ##  ie, if the 'geometry' package is needed for paper size
    then
	(kpsewhich geometry.sty >/dev/null) || {
	    prattle "LaTeX package geometry.sty is not installed, so only the"
	    prattle "standard LaTeX paper sizes are available." 1
	    geometry=false
	    if test "$batch" = true
	    then
		export geometry   ## for use in any secondary calls
	    fi
	}
    fi
fi
if  test "$keepinfo" = true
then
    case "$pdfinfo" in
	"not found")
	  if test $PDFJAM_CALL_NUMBER -eq 0
	  then
	    prattle \
	      "The pdfinfo utility was not found, so --keepinfo is ignored."
	  fi
	  keepinfo=false
	  ;;
	pdfinfo)
	  ;;
	*)  ## $pdfinfo was set in a configuration file
	  if test ! -x "$pdfinfo"
	  then
	    if test $PDFJAM_CALL_NUMBER -eq 0
	    then
	      prattle \
		"No pdfinfo utility at $pdfinfo, so --keepinfo is ignored."
	      keepinfo=false
	    fi
	  fi
	  ;;
    esac
    case "$iconv" in
	"not found")
	  if test $PDFJAM_CALL_NUMBER -eq 0
	  then
	    prattle \
	      "The iconv utility was not found, so --keepinfo is ignored."
	  fi
	  keepinfo=false
	  ;;
	iconv)
	  ;;
	*)  ## $iconv was set in a configuration file
	  if test ! -x "$iconv"
	  then
	    if test $PDFJAM_CALL_NUMBER -eq 0
	    then
	      prattle \
		"No iconv utility at $iconv, so --keepinfo is ignored."
	      keepinfo=false
	    fi
	  fi
	  ;;
    esac
fi
## A function to check if using non-Cygwin "${latex}" from Cygwin
using_non_cygwin_latex_from_cygwin () {
    if [ -z "${__cache__using_non_cygwin_latex_from_cygwin}" ]; then
	if [ "$(uname -o)" = "Cygwin" ] \
	    && "${latex}" -version | head -1 | grep -qv Cygwin; then
	    __cache__using_non_cygwin_latex_from_cygwin=0
	else
	    __cache__using_non_cygwin_latex_from_cygwin=1
	fi
    fi
    return "${__cache__using_non_cygwin_latex_from_cygwin}"
}
##
##  END OF CHECKING THE SETUP
##
#########################################################################
##
##  TEMPORARY FILES
##
##  Make a secure temporary directory (following
##  the autoconf manual).
##
##  Use mktemp if possible; otherwise fall back on mkdir,
##  with random name to make file collisions less likely.
##
original_umask=$(umask)
umask 177
if test $PDFJAM_CALL_NUMBER = 0  ## don't repeat this work for secondary calls
then
    PDFJAM_TEMP_DIR=''
    trap 'IFS="$OIFS"; \
  if test $tidy != false ; then cd "$pwd"; rm -rf "$PDFJAM_TEMP_DIR"; fi; exit 1' \
	1 2 15
    trap 'IFS="$OIFS"; \
  if test $tidy != false ; then cd "$pwd"; rm -rf "$PDFJAM_TEMP_DIR"; fi' 0
    {
	PDFJAM_TEMP_DIR=$( (umask 077 && mktemp -d "$tempfileDir/pdfjam-XXXXXX") 2>/dev/null) &&
	test -n "$PDFJAM_TEMP_DIR" && test -d "$PDFJAM_TEMP_DIR"
    } || {
    ##  We'll use awk to make random number, for portability
	random=$(awk 'END { srand(); printf ("%d\n", rand()*1000000); }' /dev/null)
	PDFJAM_TEMP_DIR="$tempfileDir"/pdfjam"$$"-"$random"
	(umask 077 && mkdir "$PDFJAM_TEMP_DIR")
    } || exit $?
##
    export PDFJAM_TEMP_DIR    ##  so that same dir is used in secondary calls
    if test $tidy = false ; then
	prattle "Temporary directory for this job is
          $PDFJAM_TEMP_DIR"
    fi
    PDFJAM_MESSAGES_FILE="$PDFJAM_TEMP_DIR"/messages.txt
    export PDFJAM_MESSAGES_FILE  
        ## so that secondary calls can write messages there as well
    printf "%s" "$messages" > "$PDFJAM_MESSAGES_FILE"  ## initial file contents
    messages=""  ## we won't be using this variable again!
else
    PDFJAM_TEMP_DIR="$PDFJAM_TEMP_DIR/file$PDFJAM_CALL_NUMBER"
    (umask 077 && mkdir "$PDFJAM_TEMP_DIR")
fi
umask "$original_umask"
## Next is from the Cygwin patch contributed by Lucas
if using_non_cygwin_latex_from_cygwin; then
    PDFJAM_TEMP_DIR=$(cygpath -w "$PDFJAM_TEMP_DIR")
fi
##
##  TEMPORARY DIRECTORY ALL DONE
##
#########################################################################
##
##  HANDLING THE "--batch" OPTION
##
##  If --batch was used, we'll call pdfjam separately on each input
##  file.
##
if test "$batch" = true ; then
    if test "$fileSpec" = "" ; then
	error_exit "--batch was used, but no PDF/JPG/PNG source file(s) specified" \
	    $E_USAGE
    fi
    if test "$inputFromStdin" = true ; then
	error_exit "--batch cannot be used with input from stdin" \
	    $E_USAGE
    fi
    IFS="$newline"
    for k in $fileSpec ; do
	sourcePath=$(printf "%s" "$k" | sed 's/|[^|]*$//')
	pageSpec=$(printf "%s" $k | sed 's/.*|//')
	callNumber=$((PDFJAM_CALL_NUMBER + 1))
	prattle "--"
	prattle "Processing file ${callNumber}, '$sourcePath'..."
	prattle "Page spec is '$pageSpec'."
	sourcePath=$(escape_chars "$sourcePath")
	PDFJAM_EFFECTIVE_CALL="$0 $callOptions -- $sourcePath $pageSpec"
	export PDFJAM_EFFECTIVE_CALL
	PDFJAM_CALL_NUMBER=$callNumber
	export PDFJAM_CALL_NUMBER
	eval "$PDFJAM_EFFECTIVE_CALL"
        ## i.e., call pdfjam again with one input file
    done
    if [ "$verbose" = "true" ]; then cat "$PDFJAM_MESSAGES_FILE" >&2 ; fi
    IFS=$OIFS
    exit 0
fi
##
##  END OF THE '--batch' PROCESSING
##
#########################################################################
##
##  RECORD THE EFFECTIVE CALL TO PDFJAM, FOR POSSIBLE DEBUGGING PURPOSES
##
##  Save the text of this (effective) call to pdfjam in a temporary file,
##  for later inspection if necessary.
##
##  For secondary calls, the effective call text is already made;
##  otherwise we make it here.
##
if test "$PDFJAM_CALL_NUMBER" -gt 0
then
    theCall="$PDFJAM_EFFECTIVE_CALL"
else
    filePageSpec=""
    IFS="$newline"
    for k in $fileSpec ; do
	##  Last substitution on next line is needed for silly characters in
	##  file names...
	sourcePath=$(printf "%s" $k | sed 's/|[^|]*$//')
	sourcePath=$(escape_chars "$sourcePath")
	pageSpec=$(printf "%s" $k | sed 's/.*|//')
	filePageSpec="$filePageSpec$sourcePath $pageSpec "
    done
    IFS="$OIFS"
    theCall="$0 $callOptions -- $filePageSpec"
fi
printf "%s\n%s\n" "cd $pwd" "$theCall" > "$PDFJAM_TEMP_DIR"/call.txt
prattle "Effective call for this run of pdfjam:"
prattle "$theCall" 1
##
#########################################################################
##
##  NOW MAKE THE INPUT FILE ETC., READY FOR LATEX
##
filePageList=""  ## initialize a string to supply to \includepdfmerge
counter=0
##
##  Make symbolic link(s) to the source file(s) in the temporary dir,
##  and make the $filePageList string for input to \includepdfmerge
##
stdinUnread=true
IFS="$newline"
for k in ${fileSpec}
do
    counter=$((counter + 1))
    sourcePath=$(printf "%s" "$k" | sed 's/|[^|]*$//')
    pageSpec=$(printf "%s" $k | sed 's/.*|//')
    ##  Check, though not exhaustively, for problems with the
    ##  page spec: leading or trailing comma, double comma or
    ##  double dash, alphabetic characters other than the word "last",
    ##  braces not paired as {} with nothing inbetween.  A fully
    ##  specified pattern for valid \includepdfmerge page spec would
    ##  be better here; but life is too short...
    if printf "%s" "$pageSpec" | sed 's/last/99/g' | \
	grep  '^,.*\|,$\|,,\|--\|[A-Za-z]\|{[^}]\|[^{]}' 1>/dev/null
    then
	error_exit "invalid page spec $pageSpec" $E_USAGE
    fi
    case $sourcePath in
	/dev/stdin)
	    uniqueName="$PDFJAM_TEMP_DIR"/stdin.pdf
	    if test "$stdinUnread" = true
	    then
		if tty -s ; then
		    error_exit \
		 "tty is connected to connected to stdin, no PDF/JPG/PNG file found" \
			$E_NOINPUT
		fi
		cat > "$uniqueName"
		stdinUnread=false
	    fi
	    ;;
	*)
	    pdfName=$(basename "$sourcePath")
	    sourceDir=$(dirname "$sourcePath") ## zsh on Mac OS 10.5 chokes here
	    cd "$sourceDir" || exit 1   ##  just to get the full path
	    sourceDir=$(pwd)
	    cd "$pwd" || exit 1
	    sourceFullPath="$sourceDir"/"$pdfName"
	    uniqueName="source-$counter.pdf"
	    uniqueName="$PDFJAM_TEMP_DIR"/"$uniqueName"
	    ## Next is from the Cygwin patch contributed by Lucas
	    if using_non_cygwin_latex_from_cygwin; then
		cp "$sourceFullPath" "$uniqueName"
	    else
		ln -s "$sourceFullPath" "$uniqueName"
	    fi
	    ;;
    esac
    filePageList="$filePageList","$uniqueName","$pageSpec"
done
IFS="$OIFS"
filePageList=$(printf "%s" "$filePageList" | \
    sed 's/^,//')  ## remove leading comma
##
##  Do the pdfinfo stuff (if relevant)...
##
select_pdfinfo () {
    printf '%s' "$2" | \
    grep -e "^$1:" | \
    sed -e 's/^'"$1"':\s*//'
}
echo_hex_iconv_utf16be () {
    printf '%s' "$1" | \
    "$iconv" -f utf8 -t utf16be | \
    od -An -v -tx1 | \
    tr -d '[:space:]'
}
echo_pdfinfodata () {
    if [ -n "$2" ]; then
	TMPA=$(echo_hex_iconv_utf16be "$2")
	printf '%s' "/$1 <feff${TMPA}>"
    fi
}

if test "$keepinfo" = true ; then
    prattle "Calling ${pdfinfo}..."
    PDFinfo=$(pdfinfo -enc UTF-8 "$uniqueName")
    pdftitl=$(select_pdfinfo 'Title'    "$PDFinfo")
    pdfauth=$(select_pdfinfo 'Author'   "$PDFinfo")
    pdfsubj=$(select_pdfinfo 'Subject'  "$PDFinfo")
    pdfkeyw=$(select_pdfinfo 'Keywords' "$PDFinfo")
fi
echo_iconv_from_enc () {
    printf '%s' "$2" | \
    "$iconv" -f "$1" -t utf8
}
if test -n "$pdfTitle" ; then
    pdftitl=$(echo_iconv_from_enc "$enc" "$pdfTitle")
fi
if test -n "$pdfAuthor" ; then
    pdfauth=$(echo_iconv_from_enc "$enc" "$pdfAuthor")
fi
if test -n "$pdfSubject" ; then
    pdfsubj=$(echo_iconv_from_enc "$enc" "$pdfSubject")
fi
if test -n "$pdfKeywords" ; then
    pdfkeyw=$(echo_iconv_from_enc "$enc" "$pdfKeywords")
fi

## Converting to PDF string
raw_pdftitl=$(echo_pdfinfodata 'Title'    "$pdftitl")
raw_pdfauth=$(echo_pdfinfodata 'Author'   "$pdfauth")
raw_pdfsubj=$(echo_pdfinfodata 'Subject'  "$pdfsubj")
raw_pdfkeyw=$(echo_pdfinfodata 'Keywords' "$pdfkeyw")

##
##  Now set up the files for latex...
##
fileName="$PDFJAM_TEMP_DIR"/a
texFile="$fileName".tex
msgFile="$fileName".msgs
tempFile="$PDFJAM_TEMP_DIR"/temp.tex
## Next is adapted from the Cygwin patch sent by Lucas
if using_non_cygwin_latex_from_cygwin; then
    filePageList=$(echo "$filePageList" | sed 's~\\~/~g')
fi
(cat <<EndTemplate
\batchmode
\documentclass[$documentOptions]{article}
\usepackage{color} \definecolor{bgclr}{RGB}{$pagecolor} \pagecolor{bgclr}
\usepackage[$papersize]{geometry}
\usepackage[utf8]{inputenc}
\ifdefined\luatexversion% LuaLaTeX
  \protected\def\pdfinfo{\pdfextension info}
\fi
\ifdefined\XeTeXversion% XeLaTeX
  \protected\def\pdfinfo#1{\AtBeginDvi{\special{pdf:docinfo << #1 >>}}}
\fi
\ifdefined\pdfinfo%
  \pdfinfo{%
    $raw_pdftitl %
    $raw_pdfauth %
    $raw_pdfsubj %
    $raw_pdfkeyw %
  }%
\fi
\usepackage{pdfpages}
EndTemplate
    )  > "$texFile"
if test -z "$geometry" ; then geometry=false ; fi
if test "$geometry" = false; then   ## geometry package is not to be used
    cp "$texFile" "$tempFile"
    sed '/\\\usepackage.*{geometry}/d' "$tempFile" > "$texFile"
    rm "$tempFile"
fi
if test -z "$pagecolor"; then   ## color package is not needed
    cp "$texFile" "$tempFile"
    sed '/\\\usepackage.*{color}/d' "$tempFile" > "$texFile"
    rm "$tempFile"
fi
(cat <<EndTemplate
$preamble
$shortedge
\begin{document}
\includepdfmerge[$miscOptions]{$filePageList}
\end{document}
EndTemplate
    )  >> "$texFile"
##
##  INPUT FILES ARE ALL READY
##
#########################################################################
##
##  RUN LATEX AND COPY THE RESULTING PDF FILE 
##
if [ "$runs" -eq 1 ] ;
then prattle "Calling ${latex}..."
else prattle "Calling ${latex} $runs times..."
fi
cd "$PDFJAM_TEMP_DIR" || exit 1
failureText=\
"FAILED.
The call to $latex resulted in an error.
If '--no-tidy' was used, you can examine the
log file at
        $fileName.log
to try to diagnose the problem."
i=1
while [ "$i" -le "$runs" ] ; do
    "$latex" "$texFile" > "$msgFile" || {
        prattle "$failureText"
        error_exit "Run $i: Output file not written" $E_SOFTWARE
    }
    i=$((i + 1))
done
cd "$pwd" || exit 1
if test -f "$fileName".pdf  ## if LaTeX didn't choke
then
    ##  Checks on output file path:
    if test -d "$outFile"  ## outfile is a directory
    then
	if test "$sourcePath" = /dev/stdin 
	then
	    error_exit \
		"--outfile cannot be a directory when input is stdin" \
		$E_USAGE
	fi
	if test ! -w "$outFile"
	then
	    error_exit \
        "FAILED: no write permission on ${outFile}." \
	    $E_OSFILE
	fi
        separator="-"
	if test "$pageSpec" != "-"
	then
	    separator=-"$pageSpec"-
	fi
	outFile=$(printf "%s" "$outFile" | sed 's/\/$//')
                ## (delete any trailing slash)
	pdfName=$(basename "$sourcePath")
	pdfName=$(printf "%s" "$pdfName" | \
	    sed 's/\.[pP][dD][fF]$//')       ## strip extension
	pdfName="$pdfName$separator$suffix".pdf
	outFile="$outFile"/"$pdfName"
    fi		
fi
if  test -f "$outFile"  &&  test ! -w "$outFile"
    ## file exists and we can't over-write it
then
    error_exit "no write permission at ${outFile}" $E_CANTCREATE
fi
#fileSize=$(wc -c < "$fileName.pdf" | sed 's/^\ *//')
## Avoid explicit output to /dev/stdout.
if test "$outFile" = "/dev/stdout" \
   && cat "$fileName".pdf 2> /dev/null \
   || cat "$fileName".pdf > "$outFile" 2>/dev/null
then
    prattle "Finished.  Output was written to '${outFile}'."
else
    error_exit "cannot write output at ${outFile}" $E_CANTCREATE
fi
if [ "$PDFJAM_CALL_NUMBER" = "0" ] && [ "$verbose" = "true" ]
then cat "$PDFJAM_MESSAGES_FILE" >&2
fi
exit 0
##
##  END
##
#########################################################################
