Combine PDFs

Hi Guys,

I got the below script to combine pdfs into single pdf, which works fine.


display dialog "please choose the files to merge.." default button "OK"
set inputfiles to choose file of type "PDF" with multiple selections allowed without invisibles
delay 0.25

display dialog "please choose where to save the merged pdf..." default button "OK"
set outputfolder to choose folder
delay 0.25

display dialog "Type the name of the combined pdf: " default answer ""
set thename to text returned of the result
set outputfile to (outputfolder as text) & thename & "(" & (count of inputfiles) & ").pdf"

set pdffiles to ""
repeat with p in inputfiles
	set pdffiles to pdffiles & " " & quoted form of POSIX path of p
end repeat

do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py " & "-o " & quoted form of POSIX path of outputfile & pdffiles
return outputfile as alias

I need a simple change in it.

  1. Prompt the user to choose a folder. (example - MacIntosh\XXXX)
  2. On that chosen folder there will be a default folder “aaa” (MacIntosh\XXXX\aaa)
  3. On that folder there will be a default folder “bbb” (which contains pdfs) (MacIntosh\XXXX\aaa\bbb)
  4. Save the combined pdf in the folder (MacIntosh\XXXX\aaa\bbb) with the filename XXXX.pdf

Thanks,
Mathew

Do the folders in steps 2 and three already exist? If so, how can you target them? If not, how should they be created?

You haven’t answered Craig’s questions, but the immediate answer to your query would be to replace this section .

display dialog "Type the name of the combined pdf: " default answer ""
set thename to text returned of the result
set outputfile to (outputfolder as text) & thename & "(" & (count of inputfiles) & ").pdf"

. with this:

tell application "System Events" to set XXXX to name of outputfolder
set outputfile to (outputfolder as text) & "aaa:bbb:" & XXXX & ".pdf"

Other comments about the script would be:

  1. The “please choose” prompts could be incorporated into the ‘choose’ dialogs, which would mean less OK-ing for the user ” although the prompts themselves would then be quite small:
set inputfiles to (choose file of type "PDF" with prompt "please choose the files to merge.." with multiple selections allowed without invisibles)

set outputfolder to (choose folder with prompt "please choose where to save the merged pdf...")
  1. The delays are probably unnecessary.

  2. There should ideally be a space between the output file and the pdf files in the ‘do shell script’ line:

do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py " & "-o " & quoted form of POSIX path of outputfile & space & pdffiles

Hi Guys,

Sorry for the late reply. I am out of Office.

I think my explanation is not clear. Let I try to explain it clear.

The pdf files which is to combine are in the path as below:

MacIntosh\XXXX\aaa[b]bbb[/b]1\pdf files
MacIntosh\YYYY\aaa[b]bbb[/b]2\pdf files
MacIntosh\ZZZZ\aaa[b]bbb[/b]3\pdf files

The steps that I follow to combine pdf files is below:

I go to Acrobat\File\Create\Combine files into a single pdf
I choose XXXX or YYYY or ZZZZ folder from MacIntosh
Then I choose default folder in name “aaa”
And then I choose the folder starts with name “bbb
Select all the pdf files to combine
Save the combine pdf as below

MacIntosh[b]XXXX[/b]\aaa\bbb1[b]XXXX[/b].pdf or
MacIntosh[b]YYYY[/b]\aaa\bbb2[b]YYYY[/b].pdf or
MacIntosh[b]ZZZZ[/b]\aaa\bbb3[b]ZZZZ[/b].pdf

I am asking for a script to simplify my work, i.e., just to choose XXXX or YYYY or ZZZZ folder and to create combined pdf as above

Thanks,
Mathew

Like this?


set topFolder to (choose folder with prompt "Please choose a folder.")

-- Get the POSIX paths to all the PDFs in folder aaa/bbb./ of the chosen folder and derive an output path (name of top folder & ".pdf" in the bbb. folder).
set pathScript to "find -f " & quoted form of POSIX path of topFolder & " \\( -path '*/aaa/bbb*/*' -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|(([^/]+)/aaa/bbb[^/]*/)[^/]+$|\\1\\2.pdf|p
	g
}'"
set pdfPaths to (do shell script pathScript)

-- Grab the output path for the return at the end.
set outputPath to paragraph 1 of pdfPaths
-- Make a single line of the output path and input paths, all individually quoted and separated by spaces.
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "' '"
set pdfPaths to (paragraphs of quoted form of pdfPaths) as text
set AppleScript's text item delimiters to astid

do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py " & "-o " & pdfPaths

return (POSIX file outputPath) as alias

Hi Nigel,

Thanks for your kind reply.
Your script shows “Can’t make file into type alias”

Replies window shows as follows:


tell application "Script Editor"
	choose folder with prompt "Please choose a folder."
		--> alias "Macintosh HD:Work:15-7069-2:"
end tell
tell current application
	do shell script "find -f '/Work/15-7069-2/' \\( -path '*/aaa/bbb*/*' -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|/(([^/]+)/aaa/bbb[^/]*/)[^/]+$|\\1\\2.pdf|p
   g
}'"
		--> "/Work15-7069-2/aaa/bbb5/15-7069-2.pdf
/Work/15-7069-2/aaa/bbb5/15-7069-2.aa_t.pdf
/Work/15-7069-2/aaa/bbb5/15-7069-2.ba_t.pdf
/Work/15-7069-2/aaa/bbb5/15-7069-2.ca_t.pdf"
	do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py -o '/Work15-7069-2/aaa/bbb5/15-7069-2.pdf' '/Work/15-7069-2/aaa/bbb5/15-7069-2.aa_t.pdf' '/Work/15-7069-2/aaa/bbb5/15-7069-2.ba_t.pdf' '/Work/15-7069-2/aaa/bbb5/15-7069-2.ca_t.pdf'"
		--> ""
Result:
error "Can't make file \"Macintosh HD:Work15-7069-2:aaa:bbb5:15-7069-2.pdf\" into type alias." number -1700 from file "Macintosh HD:Work15-7069-2:aaa:bbb5:15-7069-2.pdf" to alias


Thanks

Hi John.

Sorry! A typo in the sed code was deleting a slash from the destination path. This resulted in a non-existent folder path, which prevented the destination file from being created, which meant it couldn’t be coerced to alias. :rolleyes: Now fixed in my post above.

I see the original script you posted included the number of constituent PDFs in the destination file name. You didn’t ask for that, but did you need it?

Hi Nigel,

There may be a bug in the script. Please check it.

I checked the script with below 5 pdf files.
16-3641-4.aa_t.pdf
16-3641-4.ba_t.pdf
16-3641-4.ca_t.pdf
16-3641-4.da_t.pdf
16-3641-4.ea_t.pdf

The script combined

16-3641-4.ba_t.pdf (2nd)
16-3641-4.ca_t.pdf (3rd)
16-3641-4.da_t.pdf (4th)
16-3641-4.ea_t.pdf (5th)

and replaced the combined pdf in the 1st pdf
16-3641-4.aa_t.pdf

Whereas, what I need is, to combine the 5 pdfs with the name
16-3641-4.pdf (i.e., Chosen folder name)

Attached Replies for your reference.

tell application "Script Editor"
	choose folder with prompt "Please choose a folder."
		--> alias "Macintosh HD:Work:16-3641-4:"
end tell
tell current application
	do shell script "find -f '/Work/16-3641-4/' \\( -path '*/aaa/bbb*/*' -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|(([^/]+)/aaa/bbb[^/]*/)[^/]+$|\\1\\2.pdf|p
	g
}'"
		--> "/Work/16-3641-4/aaa/bbb 03/16-3641-4.aa_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ba_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ca_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.da_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ea_t.pdf"
	do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py -o '/Work/16-3641-4/aaa/bbb 03/16-3641-4.aa_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ba_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ca_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.da_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ea_t.pdf'"
		--> ""
end tell
Result:
alias "Macintosh HD:Work:16-3641-4:aaa:bbb 03:16-3641-4.aa_t.pdf"

Thanks,
John

It’s working perfectly here, John. The only thing I can think of which would prevent the output path from appearing at the top of the first shell script result would be a mismatch between the sed regex and the first PDF path. No substitution would then take place to derive the output path and it wouldn’t be printed. The regex matches everything from the run of non-slash characters before “/aaa/bbb./” (ie. from the name of the chosen folder) to the end of the file name, memorising everything up to the slash before the file name and, separately, the chosen folder name. The match is replaced with the memorised everything-up-to-the-slash, the memorised folder name, and “.pdf”. I can’t see any reason it wouldn’t work on any machine where the folder exists. :confused:

Here are my replies with an exact duplicate of your folder/file set-up.

tell application "Script Editor"
	choose folder with prompt "Please choose a folder."
		--> alias "MacBook Pro HD:Work:16-3641-4:"
end tell
tell current application
	do shell script "find -f '/Work/16-3641-4/' \\( -path '*/aaa/bbb*/*' -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|(([^/]+)/aaa/bbb[^/]*/)[^/]+$|\\1\\2.pdf|p
	g
}'"
		--> "/Work/16-3641-4/aaa/bbb 03/16-3641-4.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.aa_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ba_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ca_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.da_t.pdf
/Work/16-3641-4/aaa/bbb 03/16-3641-4.ea_t.pdf"
	do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py -o '/Work/16-3641-4/aaa/bbb 03/16-3641-4.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.aa_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ba_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ca_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.da_t.pdf' '/Work/16-3641-4/aaa/bbb 03/16-3641-4.ea_t.pdf'"
		--> ""
end tell
Result:
alias "MacBook Pro HD:Work:16-3641-4:aaa:bbb 03:16-3641-4.pdf"

Are you using an older system? I had to authenticate the moving of the “Work” folder to the top level of my startup disk.

Hi Nigel,

I extremely sorry, I have wasted your precious time.

Before running the script, I changed the “aaa” and “bbb” folders to its original name. And I missed to change it in the below line. I found it just now.

1 {
   h
   s|(([^/]+)/aaa/bbb[^/]*/)[^/]+$|\\1\\2.pdf|p
   g
}'"

Your script works like a charm. Thanks a lot for your help.

Once again Sorrryyyyy

Thanking you,
John

Thanks, John. That’s a relief! :slight_smile:

Hi Guys,

One more help needed.
How to open that combined pdf?

Thanks,

John

You’re spoilt for choice, John. :slight_smile: ‘open’ is a standard command that even (many) unscriptable applications understand, although they may implement it in different ways.

At the end of my script, outputPath is a POSIX path to the file, so you can replace the last line with any of the following:

tell application "Preview"
	activate
	open outputPath
end tell

-- Or:
tell application "Adobe Reader"
	activate
	open outputPath
end tell

-- Or:
tell application "System Events" to open disk item outputPath -- Opens in default application.

-- Or:
set outputPath to (POSIX file outputPath) as text
-- tell application "Finder" to open file outputPath -- Opens in default application.
set appID to "com.apple.Preview"
-- set appID to "com.adobe.Reader"
tell application "Finder" to open file outputPath using application file id appID -- Opens in specified app.

Hi Nigel,

Four of your options working awsome!!!

Thanks,
John

FYI, that fails here under 10.11. The problem is that Preview is sandboxed in 10.11, and you must pass a file object to sandboxed apps, not paths. IMO, it’s a good habit to get into anyway, as a kind of future-proofing. So either:

set theFile to outputPath as «class furl»
tell application "Preview"
	activate
	open theFile
end tell

Or:

set theFile to POSIX file outputPath
tell application "Preview"
	activate
	open theFile
end tell

Funnily enough, it works with the one file on which I tested it this morning before posting, but with none of the others in the same folder. :confused: Now you mention it, I do remember reading about paths alone no longer being kosher. I like the idea of having to use proper specifiers too. It’s the way things were in days of yore.

Presumably you’d opened that file some other way before.

Yeah, who needs more than 32Kb of text… :wink:

Well. It seems that ‘POSIX file outputPath’, ‘outputPath as «class furl»’, and ‘outputPath as POSIX file’ all produce objects of «class furl». The specifier tends to slightly faster than the coercions and doesn’t use chevron syntax, so it would be my preferred choice ” in vanilla AppleScript, as least. (Edit: However, it doesn’t like being used inside application ‘tell’ statements unless preceded by ‘my’ or ‘tell me to’.) ‘as POSIX file’ is the slowest of the three, but you’d have to be doing over 20,000 such conversions before the difference became noticeable.

My old BBC B only had 32K of RAM altogether and it beeped perfectly well. :wink: (Its cassette-tape storage was a pain, though. I wrote an I Ching program for it once as an exercise and if you got Hexagram 64, it would take half an hour to retrieve the corresponding text for display. Time enough to go out and get run over by a bus while waiting to learn your fortune! Luckily, the buses to my village only ran every couple of hours in those days.)

It’s confusing because a «class furl» object will appear in logs as a file or even »class file» sometimes. Another one of those drawn-out AS transitions.

Those were the days. I had a 64K computer – which meant the cassettes could take even longer…

Hi Guys,

Nigel given me the below script to combine multiple pdfs into single pdf.

It works fine. But it removing all the comments in the combined pdf file.

Can anyone fix it?

set topFolder to (choose folder with prompt "Please choose a folder which pdfs to be combined..." default location "/Work/")


-- Get the POSIX paths to all the PDFs in folder aaa/bbb./ of the chosen folder and derive an output path (name of top folder & ".pdf" in the bbb. 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)

-- Grab the output path for the return at the end.
set outputPath to paragraph 1 of pdfPaths
-- Make a single line of the output path and input paths, all individually quoted and separated by spaces.
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "' '"
set pdfPaths to (paragraphs of quoted form of pdfPaths) as text
set AppleScript's text item delimiters to astid

do shell script "/System/Library/Automator/Combine\\ PDF\\ Pages.action/Contents/Resources/join.py " & "-o " & pdfPaths

tell application "Adobe Acrobat Pro"
	activate
	open outputPath
end tell

Thanks,
John