Copy PDF file in Finder and Paste into another PDF file

Seems simple but just cannot get it to work. Actually have two questions what am I doing that is incorrect and how if I can get it to work can I place the document that I copied at the at the start of the existing file.

When I run the script below I get a new page that shows the PDF smile logo a pen a few lines (no text just a graphic) and thats it.

I am using PDFPenPro 9.0.1

Thanks

Peter


tell application "Finder" to activate
tell application "System Events"
	tell process "Finder"
		--The File in this test is already highlighted
		keystroke "c" using command down
		delay 3	
	end tell
end tell
tell application "PDFpenPro" to activate
tell application "System Events"
	tell process "PDFpenPro"
		keystroke "v" using command down
	end tell
end tell

I don’t understand.

I downloaded and installed PDFPenPro.
I started it to create a blank PDF.
In Finder I selected the icon of a PDF document then I executed your script.
I got the 16 pages of the document in the PDFPenPro new doc.

As I just downloaded, the used version is 12.0.1. which may explain the different behavior.

I will return to the Smile site to see if I may get version 9.

I got version 9.2.3.

With this one, nothing is pasted but nothing is pasted also when I try to paste by hand in a new blank document.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 4 mai 2020 19:51:39

Hi Yvan

Thanks as always, downloaded 12.0.1 and still had the same problem. Then I tried it like you did with a blank PDF and it worked. So maybe something to do with my original file.Duplicated that and ran the script again and it worked. So I have a workaround for that if it remains an issue.

Forgive me for asking but one other question I mention before was making the new document the 1st page or pages as the case maybe can you help.

Thanks

Peter

Exists AsObjC examples somewhere on this site to combine PDF files without any GUI scripting.

If it’s really what you want to achieve, as KniazidisR wrote, there are several examples of scripts spitting PDFs or concatenating pages on the net and particularily in this forum.

Here are three of them based upon Shane Stanley’s codes.

(* Split a PDF in pages *)

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

#===== Handlers

-- Supposed to create a new PDF file for every page from the passed PDF fine.

on splitPDF:thePath
	set inNSURL to current application's |NSURL|'s fileURLWithPath:thePath
	
	set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:inNSURL
	# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0
	set theCount to thePDFDocument's pageCount() as integer
	repeat with i from 1 to theCount
		set newPath to (its addString:("-page " & text -2 thru -1 of ((100 + i) as text)) beforeExtensionIn:thePath)
		set outNSURL to (current application's |NSURL|'s fileURLWithPath:newPath)
		set thePDFPage to (thePDFDocument's pageAtIndex:(i - 1)) # ?????
		set newPDFDoc to current application's PDFDocument's alloc()'s init()
		(newPDFDoc's insertPage:thePDFPage atIndex:0)
		(newPDFDoc's writeToURL:outNSURL)
	end repeat
end splitPDF:

-- inserts a string in a path before the extension
on addString:extraString beforeExtensionIn:aPath
	set pathNSString to current application's NSString's stringWithString:aPath
	set newNSString to current application's NSString's stringWithFormat_("%@%@.%@", pathNSString's stringByDeletingPathExtension(), extraString, pathNSString's pathExtension())
	return newNSString as text
end addString:beforeExtensionIn:

#===== Caller

set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})

its splitPDF:thePath

(* Combine PDFs *)

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"

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:

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

(* Remove pages from PDF *)

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

#===== Handlers

-- Remove from a PDF file the pages whose index is in theList, saving as a new version
on removePagesInPDF:thePath outputTo:newPath pagesList:theList dropThem:flag
	set inNSURL to current application's |NSURL|'s fileURLWithPath:thePath
	set outNSURL to current application's |NSURL|'s fileURLWithPath:newPath
	set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:inNSURL
	if (thePDFDocument's isEncrypted()) as boolean then
		thePDFDocument's writeToURL:outNSURL
		set thePDFDocument to current application's PDFDocument's alloc()'s initWithURL:outNSURL
	end if
	# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0
	set theCount to thePDFDocument's pageCount() as integer
	# Remove pages starting from the PDF's end
	if flag is true then
		# drop the pages listed
		repeat with i from theCount to 1 by -1
			if i is in theList then (thePDFDocument's removePageAtIndex:(i - 1))
		end repeat
	else
		# keep the pages listed
		repeat with i from theCount to 1 by -1
			if i is not in theList then (thePDFDocument's removePageAtIndex:(i - 1))
		end repeat
	end if
	thePDFDocument's writeToURL:outNSURL
end removePagesInPDF:outputTo:pagesList:dropThem:

-- inserts a string in a path before the extension
on addString:extraString beforeExtensionIn:aPath
	set pathNSString to current application's NSString's stringWithString:aPath
	set newNSString to current application's NSString's stringWithFormat_("%@%@.%@", pathNSString's stringByDeletingPathExtension(), extraString, pathNSString's pathExtension())
	return newNSString as text
end addString:beforeExtensionIn:

#===== Caller

--set thePath to POSIX path of ((path to desktop as text)&"IT01-RECUEIL-BAC.pdf")
set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})
# If the number of pages to keep is small use this code
set newPath to its addString:"-stripped" beforeExtensionIn:thePath
its removePagesInPDF:thePath outputTo:newPath pagesList:{8, 9, 10, 11, 16, 17, 19, 20, 21, 25} dropThem:false
(*
# If the count of pages to drop is small, use this code
set newPath to its addString:"-strippedAlt" beforeExtensionIn:thePath
its removePagesInPDF:thePath outputTo:newPath pagesList:{1, 2} dropThem:true
*)

About GUI scripting, I added code to insert a blank page in the original PDF before pasting but at this time, the paste process paste a huge version of the PDF icon.
As I get the same behavior when I paste by hand, I assume that it’s linked to the fact that I run the demo version.
Here is the code:

(*

CAUTION, uses the free CLI named cliclick

*)

tell application "Finder" to activate
tell application "System Events"
	tell process "Finder"
		--The File in this test is already highlighted
		keystroke "c" using command down
		delay 3
	end tell
end tell

tell application "PDFpenPro" to activate
tell application "System Events"
	tell process "PDFpenPro"
		set frontmost to true
		keystroke "b" using {command down, option down}
		tell window 1
			class of UI elements --> {splitter group, button, button, button, list, list, button, menu button, menu button, radio group, toolbar, image, static text, sheet}
			tell sheet 1
				class of UI elements --> {static text, checkbox, checkbox, scroll area, button, button}
				position of checkboxes --> {{287, 168}, {345, 168}}
				-- checkbox 1 = Vertical, checkbox 2 = Horizontal
				click checkbox 1 -- select Vertical
				tell scroll area 1
					class of UI elements --> {list, scroll bar}
					tell list 1
						class of UI elements --> {list}
						tell list 1
							class of UI elements --> {group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group, group}
							set gr to 4 -- why not ?
							tell group gr
								--class of UI elements --> {image}
								set {{x, y}, {w, h}} to {position, size}
							end tell
							tell me to do shell script "/usr/local/bin/cliclick c:" & x + w div 2 & "," & y + h div 2
						end tell -- list 1
					end tell -- list 1
				end tell -- scroll area 1
				name of buttons --> {"Choisir", "Annuler"}
				click button 1 -- insert a new page at cursor location
			end tell -- sheet 1
			
			keystroke "v" using command down
		end tell -- window 1
	end tell
end tell

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 4 mai 2020 23:21:39

Hi Yvan

Seems like I am in over my head, downloaded cliclick. Went to store it and could only find /usr/bin not usr/local/bin. Tried to copy to /usr/bin by opening the file it showed

Peters-MacBook-Pro-13:~ petermitchell$ /Volumes/cliclick/cliclick ; exit;
You did not pass any commands as argument to cliclick.

so using that I tried to copy the file to /usr/bin with the following result
Last login: Mon May 4 17:19:46 on ttys002
Peters-MacBook-Pro-13:~ petermitchell$ sudo cp /volumes/cliclick/cliclick /usr/bin
Password:
cp: /usr/bin/cliclick: Operation not permitted
Peters-MacBook-Pro-13:~ petermitchell$

I am really taking up to much of your time but very grateful.

Peter

set bootVolume to (path to startup disk as string)
tell application "Finder"
	exists folder (bootVolume & "usr") --> true
	exists folder (bootVolume & "usr:local") --> true
	exists folder (bootVolume & "usr:local:bin:") --> true
	set path2Cliclick to (bootVolume & "usr:local:bin:cliclick")
	exists file path2Cliclick --> true
end tell
POSIX path of path2Cliclick --> "/usr/local/bin/cliclick"

The folder “usr” exists but it is hidden by Apple.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 5 mai 2020 09:46:19

Below is a script which appends the second selected PDF after the first page of the first selected PDF.

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"

on appendToFirstPage:{file1, file2} savingTo:destPosixPath
	-- make URL of the first PDF
	set inNSURL to current application's |NSURL|'s fileURLWithPath:(POSIX path of file1)
	
	set outNSURL to current application's |NSURL|'s fileURLWithPath:destPosixPath
	-- make PDF document from the URL
	set theDoc to current application's PDFDocument's alloc()'s initWithURL:inNSURL
	if (theDoc's isEncrypted()) as boolean then
		theDoc's writeToURL:outNSURL
		set theDoc to current application's PDFDocument's alloc()'s initWithURL:outNSURL
	end if
	# CAUTION. theList contain indexes of pages numbered starting from 1, but ASObjC number them starting from 0
	set theCount to theDoc's pageCount() as integer
	if theCount > 1 then
		# keep only the first page
		repeat (theCount - 1) times
			theDoc's removePageAtIndex:1
		end repeat
	end if
	set oldDocCount to 1 --theDoc's pageCount()
	-- Now we have the first page
	
	set inNSURL to (current application's class "NSURL"'s fileURLWithPath:(POSIX path of file2))
	-- 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
	-- save the new PDF
	(theDoc's writeToURL:outNSURL)
end appendToFirstPage:savingTo:

set pdf1 to (choose file "Select the PDF file to use as page 1" of type {"com.adobe.pdf"})
set pdf2 to (choose file "Select the PDF file to append after the first page" of type {"com.adobe.pdf"})
set destPosixPath to POSIX path of (choose file name default name "Combined.pdf" with prompt "Save new PDF to:")
its appendToFirstPage:{pdf1, pdf2} savingTo:destPosixPath

No need for a specific PDF editor to achieve that.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 5 mai 2020 11:57:18

Edit : simplify the code removing pages minus the 1st one.

Yvan

Thanks again managed to install it so hopefully will work, did not know about it being hidden.

In respect of your last suggestion need to install all the pages not just the 1st one, so will work that out I hope.

Peter

Here is the first version which I built before retaining only the 1st page of document 1
It’s a slightly modified version of the 2nd script in message #5.
The main difference is that it trigger choose file twice to be sure of the order of the two files in the final document.
As you certainly know, we have no way to guarantee that with a multiple selection in choose file.

(* Combine two PDFs *)

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Quartz"

on combineTwoFiles:{file1, file2} savingTo:destPosixPath
	-- make URL of the first PDF
	set inNSURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of file1)
	-- 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()
	
	-- make URL of the 2nd PDF
	set inNSURL to (current application's class "NSURL"'s fileURLWithPath:(POSIX path of file2))
	-- 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
	
	set outNSURL to current application's class "NSURL"'s fileURLWithPath:destPosixPath
	-- save the new PDF
	(theDoc's writeToURL:outNSURL)
end combineTwoFiles:savingTo:


set pdf1 to (choose file "Select the PDF file to use as page 1" of type {"com.adobe.pdf"})
set pdf2 to (choose file "Select the PDF file to append after the first page" of type {"com.adobe.pdf"})
set destPosixPath to POSIX path of (choose file name default name "Combined.pdf" with prompt "Save new PDF to:")
its combineTwoFiles:{pdf1, pdf2} savingTo:destPosixPath

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 6 mai 2020 18:28:35

Thank you both I now have a working script, that combines the 3 PDF’s and stores the result in the correct place.

If I have not tested your patience I have one more question, as I said I have 3 PDF’s it would be useful not critical if I could either load them sequentially or sort them after they have they have been combined. The last alternative does not make sense when I think about it.

This is the script I am now using.


--Source Shane Stanley on Macscripter and with help from Yvan
--This has to follow the scripts that are created after the Statement is Reconciled there is are Summary and Detail Reports
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff
set theStatement to choose file with prompt "Select the Check Statement file" & return & "To get name of file to save"
tell (info for theStatement) to set {Nm, Ex} to {name, name extension}
set BStatement to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
set BStatement to BStatement & " Combined"
set inFiles to (choose file of type {"pdf"} with prompt "Choose PDF files for" & return & "Bank Statement" & return & "Reconciliation Summary" & return & "Reconciliation Detail:" with multiple selections allowed)
set destPosixPath to POSIX path of (choose file name default name BStatement 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:

Here’s one approach, using my Myriad Tables Lib script library, available here:

https://latenightsw.com/support/freeware/

There’s one caveat: since Mojave, you will have to build the script in Script Debugger, not Script Editor, and it’s become a bit fiddlier. And you need to deal with this issue the first time you use it:

https://latenightsw.com/catalina-security-and-script-libraries/

Once you have installed the library, you need to add this use statement to your script:

use script "Myriad Tables Lib" version "1.0.10"

And then replace your choose file line with the following code:

set inFiles to (choose file of type {"pdf"} with prompt "Choose PDF files for" & return & "Bank Statement" & return & "Reconciliation Summary" & return & "Reconciliation Detail:" with multiple selections allowed)
-- build list of names
set theNames to {}
set {saveTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {":"}}
repeat with aFile in inFiles
	set end of theNames to text item -1 of (aFile as text)
end repeat
set AppleScript's text item delimiters to saveTID
-- make lists to display
set theValues to swap columns and rows in {theNames, inFiles}
-- show dialog
set theTable to make new table with data theValues with prompt "Drag the file names to the required page order:" with empty selection allowed and row numbering without multiple selections allowed
modify table theTable grid style grid between columns with row dragging
set theResult to display table theTable
-- extract files
set inFiles to extract column 2 from (values returned of theResult)

Setting up is a bit of a hassle, but you’ll get a dialog where you drag the files to the order you want.

I apologize, It seems that I miss the message in which you spoke of 3 files.

Your late script uses the original combine script. There is no provision in it to guarantee the ordering of combined files.

I tried with files whose names are :
bank statement.pdf
reconciliation detail.pdf
reconciliation summary.pdf
As the folder display files in alphabetical order, inFiles contained them in the ordering displayed above. It’s not what you want.
So, I added some instructions which re-order them in the wanted order.
Below is the beginning of the modified script.


--Source Shane Stanley on Macscripter and with help from Yvan
--This has to follow the scripts that are created after the Statement is Reconciled there is are Summary and Detail Reports
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff
set theStatement to choose file with prompt "Select the Check Statement file" & return & "To get name of file to save"
tell (info for theStatement) to set {Nm, Ex} to {name, name extension}
set BStatement to text 1 thru ((get offset of "." & Ex in Nm) - 1) of Nm
set BStatement to BStatement & " Combined"
set in_Files to (choose file of type {"pdf"} with prompt "Choose PDF files for" & return & "Bank Statement" & return & "Reconciliation Summary" & return & "Reconciliation Detail:" with multiple selections allowed)
set destPosixPath to POSIX path of (choose file name default name BStatement with prompt "Save new PDF to:")
set inFiles to {}
repeat with aFile in in_Files
    if name of (get info for aFile) contains "Statement" then -- EDIT to match your real naming
        set end of inFiles to contents of aFile
        exit repeat
    end if
end repeat
repeat with aFile in in_Files
    if name of (get info for aFile) contains "Summary" then -- EDIT to match your real naming
        set end of inFiles to contents of aFile
        exit repeat
    end if
end repeat
repeat with aFile in in_Files
    if name of (get info for aFile) contains "Detail" then -- EDIT to match your real naming
        set end of inFiles to contents of aFile
        exit repeat
    end if
end repeat

its combineFiles:inFiles savingTo:destPosixPath

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 7 mai 2020 12:01:17

Hi Shane

Brilliant now working as intended. Think I may have downloaded the free version of script debugger will now buy it. However I am still using High Sierra as I have a number of routines with user forms in Excel 2011 and understand they will not work in Mojave.

Totally irrelevant but I am from Perth but now live in the US and it is great to get so much help from home.

Peter

I’m surprised to hear a sandgroper refer to eastern states as “home” :slight_smile: