Huge script that makes booklets from PDFs

There’ll be lots of code in this post. Here’s the tldr. Answer as many as you care to…

  1. I use an applescript progress bar with “set progress total steps to 7” Problem is… it doesn’t stay on top. It gets buried when I tell the Finder to do something (that is my suspicion). It’s only useful when it’s on top. Suggestions?

This big script basically takes pdfs, uses jPDFTweak (java application, open source, if you want to try the code, you’ll have to clone my github https://github.com/jsphweid/bookletMacros ) to make booklets, reorder, combine the pdfs to make for example 8.5 x 11 pdfs of all orchestra parts and outputs EVERYTHING into 2 simple pdfs that are twice the width for booklets (8.5 x 11 turns into 11 x 17). You simply print all of one side, then the other and magically your work is done. It works quite well and saves a TON of work.

  1. The script currently get’s the paths for the files to be manipulated from the clipboard. How do they get there? I run a small script as a service that goes on the context menus with automater. There’s actually 2, 1 for a single file, and another for 2+. Both of these are below. Basically you highlight your files, right click, select say “copy paths of multiple files” or whatever then they are copied. Then you simply run the macro and it does its thing. Is there a better way to do this? Ideally I would like for someone to select the files then run the app so each user doesn’t have to go through the trouble of installing anything as a service or clutter their context menus. Maybe there are other clever ideas? I’m open to anything.

  2. I’m happy with the speed of this and it seems to be reliable but do you see any terrible coding mistakes that are either poorly written or slow down the execution?

The bulk of the code. Wherever this script resides, there must also be a folder called “jPDF” that contains all of jPDF’s files. ALSO, the clipboard must contain the paths of the files you want to perform the script on.

Currently, this script is attached to a context menu item.


tell application "Finder" to set the clipboard to the POSIX path of (the selection as alias)

Currently, this script is also attached to a context menu item. (this won’t return the right thing for a single file, is why I have both)


-- from here: http://www.mactips.info/2010/11/how-to-easily-copy-the-path-of-a-file

set the_items to {}
tell application "Finder" to set selected_items to the selection as alias list
repeat with i from 1 to count of the selected_items
	copy (POSIX path of (item i of the selected_items)) to the end of the_items
end repeat
set text item delimiters to return
set the clipboard to the_items as text


set progress total steps to 7

-- DIALOG FOR DETERMINING PRINTER TYPE
set response to the button returned of (display dialog "How does the paper come out of your printer?" buttons {"face up to face up", "face down to face down", "face up to face down"})

-- OBTAIN CLIPBOARD'S CONTENTS (must have accompanying script(s))
set listContents to get the clipboard
set delimitedList to paragraphs of listContents

-- GET INITIAL DATE AND TIME
set dateTime to do shell script "date '+%Y-%m-%d'" & "_%T"
set {TID, text item delimiters} to {text item delimiters, ":"}
set dateTime to text items of dateTime
set text item delimiters to ""
set dateTime to dateTime as text
set text item delimiters to TID

-- GET SCRIPT FOLDER PATH
set path_ to (path to me)
tell application "Finder"
	set theFolder to (container of item path_)
end tell
set thePOSIXFolder to ((POSIX path of (theFolder as alias)) as string)

set progress completed steps to 1

-- DETERMINE SIZE OF FIRST PDF (assuming they are all the same)
set firstItem to item 1 of delimitedList
set moreInfo to do shell script ¬
	"cd " & thePOSIXFolder & "; ¬
	cd jPDF/; ¬
	java -jar jpdftweak.jar -i " & "\"" & firstItem & "\"" & " -moreinfo -"
set moreInfoArray to my theSplit(moreInfo, " ")
set moreInfoArrayCount to count of moreInfoArray
set lastElementInMoreInfoArray to item moreInfoArrayCount of moreInfoArray
set sizeArray to my theSplit(lastElementInMoreInfoArray, "x")
set width to item 1 of sizeArray
set height to item 2 of sizeArray

set progress completed steps to 2

-- make temp folder
set workingFolder to do shell script "dirname " & quoted form of firstItem
set tempFolderName to "tempPDFs_" & dateTime
do shell script "cd " & workingFolder & "; mkdir " & tempFolderName

-- perhaps I will add a dialog box here with some infos...>?

set progress completed steps to 3

-- MAKE BOOKLETS, PART ONE
set misScaledOutputs to {}
repeat with currentItem in delimitedList
	tell application "Finder"
		set parentPathName to do shell script "dirname " & quoted form of currentItem
		set fileName to my basename(currentItem)
		set output to parentPathName & "/" & tempFolderName & "/_" & fileName
		set the |misScaledOutputs| to the |misScaledOutputs| & output
		do shell script ¬
			"cd " & thePOSIXFolder & "; ¬
			cd jPDF/; ¬
			java -jar jpdftweak.jar -i \"" & currentItem & "\"" & " -scale 1684,1191,r -shuffle -4:!-4L0.707+0%-100%,+1L.707+0%-200%,!+2L0.707+0%-100%,-3L.707+0%-200% -rotate R -o " & "\"" & output & "\""
	end tell
end repeat

set progress completed steps to 4

-- CORRECT PAGE DIMENSIONS, PART TWO
set correctOutputs to {}
set newWidth to width * 2
repeat with currentItem in misScaledOutputs
	
	-- check if file exists first (it has finished from last operation)
	-- must first convert file path into something "exists file" understands
	set x to (currentItem) as string
	set posixPath to POSIX path of x
	set ascriptPath to POSIX file posixPath
	tell application "Finder"
		activate
		repeat while not (exists file ascriptPath)
			delay 0.1
		end repeat
		
		-- resize
		--
		set parentPathName to do shell script "dirname " & quoted form of currentItem
		set fileName to my basename(currentItem)
		set output to parentPathName & "/__booklet" & fileName
		set end of correctOutputs to output
		do shell script ¬
			"cd " & thePOSIXFolder & "; ¬
			cd jPDF/; ¬
			java -jar jpdftweak.jar -i \"" & currentItem & "\" -scale " & newWidth & "," & height & ",r -o " & "\"" & output & "\""
	end tell
end repeat

set progress completed steps to 5

-- SEPARATE EVEN AND ODD FILES
set evens to {}
set odds to {}
repeat with currentItem in correctOutputs
	
	-- check if file exists
	set x to (currentItem) as string
	set posixPath to POSIX path of x
	set ascriptPath to POSIX file posixPath
	tell application "Finder"
		activate
		repeat while not (exists file ascriptPath)
			delay 0.1
		end repeat
		
		-- separate even and odd
		set parentPathName to do shell script "dirname " & quoted form of currentItem
		set fileName to my basename(currentItem)
		-- separate even
		set outputEven to parentPathName & "/even_" & fileName
		set end of evens to outputEven
		do shell script ¬
			"cd " & thePOSIXFolder & "; ¬
			cd jPDF/; ¬
			java -jar jpdftweak.jar -ie \"" & currentItem & "\" -o " & "\"" & outputEven & "\""
		-- separate odd
		set outputOdd to parentPathName & "/odd_" & fileName
		set end of odds to outputOdd
		do shell script ¬
			"cd " & thePOSIXFolder & "; ¬
			cd jPDF/; ¬
			java -jar jpdftweak.jar -io \"" & currentItem & "\" -o " & "\"" & outputOdd & "\""
	end tell
end repeat

set progress completed steps to 6

-- MERGE EVEN AND ODDS

-- stage names from response
if response is "face down to face down" then
	set evenFileName to "/1-even-mergedPDFs.pdf"
	set oddFileName to "/2-odd-mergedPDFs.pdf"
end if
if response is "face up to face up" then
	set oddFileName to "/1-odd-mergedPDFs.pdf"
	set evenFileName to "/2-even-mergedPDFs.pdf"
end if
if response is "face up to face down" then
	set oddFileName to "/1-odd-mergedPDFs.pdf"
	set evenFileName to "/2-evenAndReversed-mergedPDFs.pdf"
end if

-- create evens long string
set longEvensString to ""
repeat with currentItem in evens
	-- check if file exists
	set x to (currentItem) as string
	set posixPath to POSIX path of x
	set ascriptPath to POSIX file posixPath
	tell application "Finder"
		activate
		repeat while not (exists file ascriptPath)
			delay 0.1
		end repeat
		
		-- basically, come up with long 'even' string
		set parentPathName to do shell script "dirname " & quoted form of currentItem
		set fileName to my basename(currentItem)
		set longEvensString to longEvensString & " -i \"" & currentItem & "\""
	end tell
end repeat

-- get the logic right for the evens... gah
if (response is "face down to face down") or (response is "face up to face up") then
	
	do shell script "cd " & thePOSIXFolder & "; cd jPDF/; java -jar jpdftweak.jar " & longEvensString & " -o \"" & workingFolder & evenFileName & "\""
end if

if response is "face up to face down" then
	set unreversed to parentPathName & "/_____evenUnreversed.pdf"
	-- make it but unreversed
	do shell script "cd " & thePOSIXFolder & "; cd jPDF/; java -jar jpdftweak.jar " & longEvensString & " -o \"" & unreversed & "\""
	-- wait for file to exist
	set x to (unreversed) as string
	set posixPath to POSIX path of x
	set ascriptPath to POSIX file posixPath
	tell application "Finder"
		activate
		repeat while not (exists file ascriptPath)
			delay 0.1
		end repeat
	end tell
	-- reverse it and make it in the main folder
	do shell script "cd " & thePOSIXFolder & "; cd jPDF/; java -jar jpdftweak.jar -i \"" & unreversed & "\" -shuffle 1:!-1N1+0%+0% -o \"" & workingFolder & evenFileName & "\""
end if

-- create odds long string
set longOddsString to ""
repeat with currentItem in odds
	-- check if file exists
	set x to (currentItem) as string
	set posixPath to POSIX path of x
	set ascriptPath to POSIX file posixPath
	tell application "Finder"
		activate
		repeat while not (exists file ascriptPath)
			delay 0.1
		end repeat
		
		-- basically, come up with long 'odd' string
		set parentPathName to do shell script "dirname " & quoted form of currentItem
		set fileName to my basename(currentItem)
		set longOddsString to longOddsString & " -i \"" & currentItem & "\""
	end tell
end repeat

-- no logic for the odds... yay
do shell script "cd " & thePOSIXFolder & "; cd jPDF/; java -jar jpdftweak.jar " & longOddsString & " -o \"" & workingFolder & oddFileName & "\""


set progress completed steps to 7





-- helper functions
on theSplit(theString, theDelimiter)
	-- save delimiters to restore old settings
	set oldDelimiters to AppleScript's text item delimiters
	-- set delimiters to delimiter to be used
	set AppleScript's text item delimiters to theDelimiter
	-- create the array
	set theArray to every text item of theString
	-- restore the old setting
	set AppleScript's text item delimiters to oldDelimiters
	-- return the result
	return theArray
end theSplit

on basename(x)
	if x is "/" then return "/"
	if item -1 of x is "/" then set x to text 1 thru -2 of x
	set text item delimiters to "/"
	text item -1 of x
end basename

Cheers and thanks.

Operating System: Mac OS X (10.10)