Combine PDFs

Hi John.

It’s the Python script in the Automator action which does the combining, of course. If it’s stripping comments in the process, and you don’t want that, you’ll need to find someone who knows about combining PDFs to write you a new version of it. It appears to use Quartz CoreGraphic routines, so presumably it doesn’t necessarily have to be written in Python.

Indeed:

use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff

set inFiles to (choose file of type {"pdf"} with prompt "Choose your PDF files:" with multiple selections allowed)
set destPosixPath to POSIX path of (choose file name default name "Combined.pdf" with prompt "Save new PDF to:")
its combineFiles:inFiles savingTo:destPosixPath

on combineFiles:inFiles savingTo:destPosixPath
	--  make URL of the first PDF
	set inNSURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of item 1 of inFiles)
	-- make PDF document from the URL
	set theDoc to current application's PDFDocument's alloc()'s initWithURL:inNSURL
	-- loop through the rest
	set oldDocCount to theDoc's pageCount()
	set inFiles to rest of inFiles
	repeat with aFile in inFiles
		--  make URL of the next PDF
		set inNSURL to (current application's class "NSURL"'s fileURLWithPath:(POSIX path of aFile))
		-- make PDF document from the URL
		set newDoc to (current application's PDFDocument's alloc()'s initWithURL:inNSURL)
		-- loop through, moving pages
		set newDocCount to newDoc's pageCount()
		repeat with i from 1 to newDocCount
			-- get page of old PDF
			set thePDFPage to (newDoc's pageAtIndex:(i - 1)) -- zero-based indexes
			-- insert the page
			(theDoc's insertPage:thePDFPage atIndex:oldDocCount)
			set oldDocCount to oldDocCount + 1
		end repeat
	end repeat
	set outNSURL to current application's class "NSURL"'s fileURLWithPath:destPosixPath
	-- save the new PDF
	(theDoc's writeToURL:outNSURL)
end combineFiles:savingTo:

Nice one, Shane. :cool:

I don’t have the means to test if it solves John’s comment problem, but it definitely works. And having the process in-script has to be better than tapping into the guts of an Automator action!

Here it is incorporating John’s original request for the script to handle PDFs located two levels down from the selected folder. The original solution fed the Python script POSIX paths, so those are what your handler expects here.

use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff

main()

on main()
	set topFolder to (choose folder with prompt "Please choose a folder with pdfs to be combined..." default location "/Work/")
	-- Get a list of POSIX paths to the input PDFs and a derived path for the output file.
	set {inPaths:inPaths, outPath:outPath} to getPDFPaths(topFolder)
	-- Combine the PDFs and save to the output file.
	its combineFiles:inPaths savingTo:outPath
	
	set outFile to (POSIX file outPath) as alias
	tell application "Adobe Acrobat Pro"
		activate
		open outFile		
	end tell
end main

on getPDFPaths(topFolder) -- topFolder is an alias from 'choose folder'.
	-- Get the POSIX paths to all the PDFs in folder PDFs/Cycle./ of the top folder and derive an output path (name of top folder & ".pdf" in the Cycle. folder).
	set pathScript to "find -f " & quoted form of POSIX path of topFolder & " \\( -path '*/PDFs/Cycle*/*' -depth 3 -type f -name '*.pdf' \\) |
sed -E '# Make the double slashes in the paths single. (Probably not necessary.)
s|//|/|
# Derive the output path from the first pdf path and output it first.
1 {
	h
	s|(([^/]+)/PDFs/Cycle[^/]*/)[^/]+$|\\1\\2.pdf|p
	g
}'"
	set pdfPaths to (do shell script pathScript)
	set outPath to paragraph 1 of pdfPaths
	set inPaths to paragraphs 2 thru -1 of pdfPaths
	
	return {inPaths:inPaths, outPath:outPath}
end getPDFPaths

on combineFiles:inPaths savingTo:destPosixPath -- Handler by Shane Stanley.
	--  make URL of the first PDF
	set inNSURL to current application's class "NSURL"'s fileURLWithPath:(item 1 of inPaths)
	-- make PDF document from the URL
	set theDoc to current application's PDFDocument's alloc()'s initWithURL:inNSURL
	-- loop through the rest
	set oldDocCount to theDoc's pageCount()
	set inPaths to rest of inPaths
	repeat with aPath in inPaths
		--  make URL of the next PDF
		set inNSURL to (current application's class "NSURL"'s fileURLWithPath:aPath)
		-- make PDF document from the URL
		set newDoc to (current application's PDFDocument's alloc()'s initWithURL:inNSURL)
		-- loop through, moving pages
		set newDocCount to newDoc's pageCount()
		repeat with i from 1 to newDocCount
			-- get page of old PDF
			set thePDFPage to (newDoc's pageAtIndex:(i - 1)) -- zero-based indexes
			-- insert the page
			(theDoc's insertPage:thePDFPage atIndex:oldDocCount)
			set oldDocCount to oldDocCount + 1
		end repeat
	end repeat
	set outNSURL to current application's class "NSURL"'s fileURLWithPath:destPosixPath
	-- save the new PDF
	(theDoc's writeToURL:outNSURL)
end combineFiles:savingTo:

Hi,

It works like a charm.

Thanks a lot, Shane Stanley & Nigel Garvey.

You Guys are always Rock!!!

Thanks,
John