Renaming Files Sequentially

When I ran this code, it failed because it encountered the hidden file named 'Icon
" which does not contain underscore characters.

So, I made a small change :

set AppleScript's text item delimiters to "_"
tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list
	
	set fileName to anAlias's name
	if fileName ends with ".pdf" then
		tell (get anAlias's name) to if (count text item 4) = 5 then set anAlias's name to text items 1 thru 3 & ("0" & text item 4) as text
	end if
end repeat

set AppleScript's text item delimiters to ""

and got an awful : error “Saturation de la pile.” number -2706

As I am pig-headed I made other attempts and ended with :

set AppleScript's text item delimiters to "_"
tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list
	
	set fileName to anAlias's name
	if fileName ends with ".pdf" then
		set nameItems to text items of fileName
		set nbItems to count nameItems
		if (count (nameItems's item nbItems)) = 5 then
			set anAlias's name to items 1 thru (nbItems - 1) of nameItems & ("0" & nameItems's item nbItems) as text
		end if
	end if
end repeat

set AppleScript's text item delimiters to ""

Which works also with the original names contains more or less than three underscore characters

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mardi 14 juillet 2015 19:14:04

Hi, Yvan. Thanks for testing. After looking at the events, it appears that the first explicit get was preventing the coercion to alias list, making my “anAlias” variable a misnomer. My approach worked in Mavericks, but only because that coercion failed and it defaulted to using a finder reference; that may not be the case in Yosemite.

Hello

I made new tests and got always the same odd behavior.

set AppleScript's text item delimiters to "_"
set theFolder to (path to desktop as text) & "Æ’ sur  Le Terminal:"

--tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list

tell application "Finder" to repeat with anAlias in (theFolder as alias)'s files as alias list --exportPath's files as alias list
	set fileName to anAlias's name
	log result
	if fileName ends with ".pdf" then
		
		tell fileName
			if (count text item 4) = 5 then
				tell me to log "here I am" # never reached
				set anAlias's name to text items 1 thru 3 & ("0" & text item 4) as text
			end if
		end tell
		
	end if
end repeat

set AppleScript's text item delimiters to ""

The events log is :

tell current application
	path to desktop as text
end tell
tell application "Finder"
	get every file of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:"
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:.DS_Store"
	(*.DS_Store*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:Icon
"
	(*Icon
*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_01.pdf"
	(*MacOSX_Terminal_part_01.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_02.pdf"
	(*MacOSX_Terminal_part_02.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_07.pdf"
	(*MacOSX_Terminal_part_07.pdf*)
	get name of alias "SSD 500:Users:<myAccount>:Desktop:Æ’ sur  Le Terminal:MacOSX_Terminal_part_3.pdf"
	(*MacOSX_Terminal_part_3.pdf*)
end tell
(*here I am*)
Résultat :
error "Saturation de la pile." number -2706

As you see, not only the stack is saturated but the important test is behaving wrongly.

To get a running code I had to edit it as :

set AppleScript's text item delimiters to "_"
set theFolder to (path to desktop as text) & "Æ’ sur  Le Terminal:"

--tell application "Finder" to repeat with anAlias in (get (choose folder)'s files) as alias list --exportPath's files as alias list

tell application "Finder" to repeat with anAlias in (theFolder as alias)'s files as alias list --exportPath's files as alias list
	set fileName to anAlias's name
	log result
	if fileName ends with ".pdf" then
		
		set nameItems to text items of fileName
		try # In case a name doesn't contain three undescore characters
			if (count (item 4 of nameItems)) = 5 then
				tell me to log "here I am" # now it's reached reached
				set anAlias's name to ((items 1 thru 3 of nameItems) & ("0" & (item 4 of nameItems))) as text
			end if
		end try
		
	end if
end repeat

set AppleScript's text item delimiters to ""

But I prefer my late version which is not restricted to a given count of underscore characters.

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mercredi 15 juillet 2015 17:44:35

Thanks, but I meant to get across the point that the reason mine initially worked was because my coercion failed. I was under the false impression that I was using an alias, when an alias actually refuses to work with my single-line method. This works (under 10.9) and incorporates your improvements.

set AppleScript's text item delimiters to "_"

tell application "Finder" to repeat with aRef in (get (choose folder)'s files)  --> finder reference(s)
	tell (get aRef's name) to if it ends with ".pdf" and (count text item 4's word 1) = 1 then set aRef's name to text items 1 thru -2 & ("0" & text item -1) as text
end repeat

set AppleScript's text item delimiters to ""

This time it works under 10.10.4.

I introduced three small changes.

(1) No longer work with item 4, work upon item -1 so the script will apply well if names contain variable number of underscore character.
(2) Use (count text item -1) = 5 where you used (count text item 4’s word 1) = 1
because I stay away from word which is language dependant. It’s easier to simply chek that the last item of the list created when we split the name upon underscore is a five character long string : a digit + “.pdf”
(3) I don’t assume that on entry the delimiter in use is “” so I like to save the in use one to restore it on exit.

This said the final code become :

set {oTids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {"_"}}

tell application "Finder" to repeat with aRef in (get (choose folder)'s files) --> finder reference(s)
	tell (get aRef's name) to if it ends with ".pdf" and (count text item -1) = 5 then set aRef's name to text items 1 thru -2 & ("0" & text item -1) as text
end repeat

set AppleScript's text item delimiters to oTids

Yvan KOENIG running Yosemite 10.10.4 (VALLAURIS, France) mercredi 15 juillet 2015 21:27:58

I am trying to do something similar (splitting PDFs and renaming sequentially.) I’ve got automator neatly doing the splitting, but I am having trouble with the renaming, so if I may ask a question about this. I need to rename batches of files and name them sequentially. My problem is that I need to have it capture the first number in the file name (for example the 68 from: SMP_SEPDM_C01EOC_68_75_annos. Then the others increment sequentially. However, I’m just trying to teach myself this, and I am not finding how to tell it to get the starting variable from a filename.

You may try :

set sourceFolder to choose folder
tell application "Finder"
	set theFiles to files of sourceFolder as alias list
end tell

set cntFile to "count_tnuoc.txt"
set p2AS to path to application support from user domain
set p2Count to (p2AS as text) & cntFile

tell application "System Events"
	if not (exists file p2Count) then
		make new file at end of p2AS with properties {name:cntFile}
		set theCnt to 0
	else
		set theCnt to (read file p2Count) as integer
	end if
	
	repeat with aFile in theFiles # aFile is supposed to be an alias
		set oldName to name of aFile
		--> SMP_SEPDM_C01EOC_68_75_annos.pdf # ADDED
		--> SMP_SEPDM_C01EOC_68_98_annos.pdf # ADDED
		if oldName ends with ".pdf" then # ADDED
			set splittedName to my decoupe(oldName, "_")
			--> {"SMP", "SEPDM", "C01EOC", "68", "75", "annos.pdf"} # ADDED
			--> {"SMP", "SEPDM", "C01EOC", "68", "98", "annos.pdf"} # ADDED
			set splittedNewName to {}
			repeat with txt in splittedName
				set txt to txt as text
				set end of splittedNewName to txt
				if character 1 of txt is in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} then exit repeat
			end repeat
			--> {"SMP", "SEPDM", "C01EOC", "68"} # ADDED
			--> {"SMP", "SEPDM", "C01EOC", "68"} # ADDED
			set theCnt to theCnt + 1
			set newName to my recolle(splittedNewName, "_") & "_" & text -2 thru -1 of ((100 + theCnt) as text) & ".pdf"
			--> SMP_SEPDM_C01EOC_68_01.pdf # ADDED
			--> SMP_SEPDM_C01EOC_68_02.pdf # ADDED
			set name of aFile to newName
		end if # ADDED
	end repeat
end tell # System Events
my writeto(p2Count, theCnt, text, false)

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as alias
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access targetFile
		end try
		return false
	end try
end writeto

#=====

(1) added some comments tracing the intermediate results.
(2) added test checking that the passed file is a pdf one.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) lundi 5 décembre 2016 21:27:03

I feel like I should be able to take it from there, but I’m still having issues. So that script should pick up the first numbers in the file name, right? I ask because I ran it as a way to figure out how I wanted to tinker with it, and it is giving me much larger numbers than I expect, so I think it is getting incremented more necessary. I don’t know whether this is related, but isn’t the script just taking the first digit it finds even if the digit is a multi-digit number?

When I tested with these original file names :
SMP_SEPDM_C01EOC_68_75_annos.pdf
SMP_SEPDM_C01EOC_68_98_annos.pdf
it built these names :
SMP_SEPDM_C01EOC_68_01.pdf
SMP_SEPDM_C01EOC_68_02.pdf
which are what was asked by your question if I understood it correctly.

I’m just wondering if it is useful to add a test checking that the renamed files are really pdf ones.
In my test they were but I don’t know the way you fill the folder.
I wait your feedback before making changes.

I added some comments tracing the intermediate results.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mardi 6 décembre 2016 11:27:45

Thank you a lot for your help. Today is the one day I work from a PC, so I can’t test it until tomorrow, but I think I was getting larger numbers when I ran the script.

Also, my end goal is actually names like SMP_SEPDM_C01EOC_69.pdf and SMP_SEPDM_C01EOC_70.pdf. The range 68_98 in the original file name is the page range. Which does mean that doing human spot checks will be easy at least.

Maybe it’s due to the fact that English is not my main language but I don’t understand what you want.

What seems sure at this time is that one file is originally named : SMP_SEPDM_C01EOC_68_75_annos.pdf
I don’t guess what are the original names of other files.
Are the files listed in the correct order so that the script may do :

SMP_SEPDM_C01EOC_68_75_annos.pdf → SMP_SEPDM_C01EOC_68.pdf
listed file #2 → SMP_SEPDM_C01EOC_69.pdf
listed file #3 → SMP_SEPDM_C01EOC_70.pdf
and so on

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mardi 6 décembre 2016 14:28:02

This new one takes a folder containing :
4329ee93a48b50de5d871926b34a5327.jpg
SMP_SEPDM_C01EOC_68_75_annos.pdf
SMP_SEPDM_C01EOC_68_75_annos0.jpg
SMP_SEPDM_C01EOC_68_75_annos02.pdf
SMP_SEPDM_C01EOC_68_75_annos03.pdf

and rename them as:
4329ee93a48b50de5d871926b34a5327.jpg
SMP_SEPDM_C01EOC_68_75_annos0.jpg
SMP_SEPDM_C01EOC_68.pdf
SMP_SEPDM_C01EOC_69.pdf
SMP_SEPDM_C01EOC_70.pdf

set sourceFolder to choose folder
tell application "Finder"
	set theFiles to files of sourceFolder as alias list
end tell

tell application "System Events"
	set beg to 1
	repeat with aFile in theFiles # aFile is supposed to be an alias
		set beg to beg + 1
		set oldName to name of aFile
		if oldName ends with ".pdf" then
			--> SMP_SEPDM_C01EOC_68_75_annos.pdf 
			set splittedName to my decoupe(oldName, "_")
			--> {"SMP", "SEPDM", "C01EOC", "68", "75", "annos.pdf"} # ADDED
			set splittedNewName to {}
			repeat with txt in splittedName
				set txt to txt as text
				if character 1 of txt is in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} then
					exit repeat
				else
					set end of splittedNewName to txt
				end if
			end repeat # with txt.
			set rootName to my recolle(splittedNewName, "_") & "_"
			if rootName starts with space then # ADDED
				set rootName to text 2 thru -1 of rootName # ADDED
			end if # ADDED
			--> SMP_SEPDM_C01EOC
			set name of aFile to rootName & txt & ".pdf"
			set indx to txt as integer
			exit repeat
		end if
	end repeat
	# The first pdf is renamed.
	# Drop the first(s) item(s)
	set theFiles to items beg thru -1 of theFiles
	# Enter the loop renaming remaining files incrementally
	repeat with aFile in theFiles # aFile is supposed to be an alias
		set oldName to name of aFile
		if oldName ends with ".pdf" then
			--> SMP_SEPDM_C01EOC_68_75_annos02.pdf
			--> SMP_SEPDM_C01EOC_68_75_annos03.pdf
			set indx to indx + 1
			set txt to text -2 thru -1 of ((100 + indx) as text)
			set name of aFile to rootName & txt & ".pdf"
			--> SMP_SEPDM_C01EOC_69.pdf
			--> SMP_SEPDM_C01EOC_70.pdf
		end if # ADDED
	end repeat
end tell # System Events

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====

Here is the history
[format]tell application “Script Editor”
choose folder
→ alias “bootVolume:Users:myHome:Desktop: dossier copie:”
end tell
tell application “Finder”
get every file of alias “bootVolume:Users:myHome:Desktop: dossier copie:”
→ {alias “bootVolume:Users:myHome:Desktop: dossier copie:4329ee93a48b50de5d871926b34a5327.jpg”, alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68.pdf”, alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos0.jpg”, alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_69.pdf”, alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_70.pdf”}
end tell
tell application “System Events”
get name of alias “bootVolume:Users:myHome:Desktop: dossier copie:4329ee93a48b50de5d871926b34a5327.jpg”
→ “4329ee93a48b50de5d871926b34a5327.jpg” – not a PDF, skip it
get name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos.pdf”
→ “SMP_SEPDM_C01EOC_68_75_annos.pdf”
set name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos.pdf” to “SMP_SEPDM_C01EOC_68.pdf” – first PDF, rename it
get name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos0.jpg”
→ “SMP_SEPDM_C01EOC_68_75_annos0.jpg” – not a PDF, skip it
get name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos02.pdf”
→ “SMP_SEPDM_C01EOC_68_75_annos02.pdf”
set name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos02.pdf” to “SMP_SEPDM_C01EOC_69.pdf” – 2nd PDF, rename it
get name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos03.pdf”
→ “SMP_SEPDM_C01EOC_68_75_annos03.pdf”
set name of alias “bootVolume:Users:myHome:Desktop: dossier copie:SMP_SEPDM_C01EOC_68_75_annos03.pdf” to “SMP_SEPDM_C01EOC_70.pdf” – 3rd PDF, rename it
end tell[/format]

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mardi 6 décembre 2016 15:10:07

You may split the original PDF in files with the wanted names in a single call.

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

#=====

on findPattern:thePattern inString:theString
	set theNSString to current application's NSString's stringWithString:theString
	set theOptions to ((current application's NSRegularExpressionDotMatchesLineSeparators) as integer) + ((current application's NSRegularExpressionAnchorsMatchLines) as integer)
	set theRegEx to current application's NSRegularExpression's regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value)
	set theFinds to theRegEx's matchesInString:theNSString options:0 range:{location:0, |length|:theNSString's |length|()}
	set theResult to {} -- we will add to this
	repeat with i from 1 to count of theFinds
		set theRange to (item i of theFinds)'s range()
		set end of theResult to (theNSString's substringWithRange:theRange) as string
	end repeat
	return theResult
end findPattern:inString:

#=====

on splitPDF:thePath numberingFrom:theNum basePath:strippedPath
	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:("_" & text -2 thru -1 of ((100 + theNum) as text)) beforeExtensionIn:strippedPath)
		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)
		set theNum to theNum + 1
	end repeat
end splitPDF:numberingFrom:basePath:

-- 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:

#=====

on replace:sourceString existingString:d1 newString:d2
	set sourceString to current application's NSString's stringWithString:sourceString
	return (sourceString's stringByReplacingOccurrencesOfString:d1 withString:d2) as text
end replace:existingString:newString:

#=====

set thePath to POSIX path of (choose file with prompt "Choose a PDF file." of type {"PDF"})
set sourceString to current application's NSString's stringWithString:thePath
set itsName to (sourceString's lastPathComponent()) as text
set itsFirstNumStr to item 1 of (its findPattern:"_[0-9][0-9]_" inString:itsName)
set itsFirstNum to (my replace:itsFirstNumStr existingString:"_" newString:"") as integer
set strippedPath to item 1 of ((sourceString's componentsSeparatedByString:itsFirstNumStr) as list) & ".pdf"
my splitPDF:thePath numberingFrom:itsFirstNum basePath:strippedPath

One more time, most of the code was borrowed from Shane STANLEY’s scripts.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mercredi 7 décembre 2016 11:50:29

I think splitting them at the same time is probably a much better idea–You are amazing, thank you–because my files after being split ended up with the first file last (because it had nothing appended) and then the others sequentially starting from the second (because they had 1, 2, 3, etc stuck onto the end.)

Your script is giving me errors though. Maybe a versioning problem? The useapplescript line at the beginning is giving an error, but if I delete that, I get “expected end of line” errors on the second through fourth lines. The first line below the cut gives the error of "expected “given” “into” “with,” “without” or other parameter line but found “:”

First point, you may use the script posted to split with your “wrongly” ordered files.
Rename the “main file” inserting at its very beginning.
I edited the script so that it will do the job in original case as well as with this new one.

Second point, probably the most important.
Which operating system are you running ?

use AppleScript version “2.4” means that the script requires 10.10 or later OS.

I guess that you are running an old operating system.

If it’s older than 10.9, no hope to use the script.
If it’s 10.9.x you may take benefit of ASObjC features but the dedicated code can’t be in a standard script, it must be in a library package.

This requires some changes to the script.

Part 1

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

#=====

on findPattern:thePattern inString:theString
	set theNSString to current application's NSString's stringWithString:theString
	set theOptions to ((current application's NSRegularExpressionDotMatchesLineSeparators) as integer) + ((current application's NSRegularExpressionAnchorsMatchLines) as integer)
	set theRegEx to current application's NSRegularExpression's regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value)
	set theFinds to theRegEx's matchesInString:theNSString options:0 range:{location:0, |length|:theNSString's |length|()}
	set theResult to {} -- we will add to this
	repeat with i from 1 to count of theFinds
		set theRange to (item i of theFinds)'s range()
		set end of theResult to (theNSString's substringWithRange:theRange) as string
	end repeat
	return theResult
end findPattern:inString:

#=====

on splitPDF:thePath numberingFrom:theNum basePath:strippedPath
	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:("_" & text -2 thru -1 of ((100 + theNum) as text)) beforeExtensionIn:strippedPath)
		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)
		set theNum to theNum + 1
	end repeat
end splitPDF:numberingFrom:basePath:

-- 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:

#=====

on replace:sourceString existingString:d1 newString:d2
	set sourceString to current application's NSString's stringWithString:sourceString
	return (sourceString's stringByReplacingOccurrencesOfString:d1 withString:d2) as text
end replace:existingString:newString:

#=====

on getName:POSIXPath
	local PosixName
	set theURL to current application's |NSURL|'s fileURLWithPath:POSIXPath
	return theURL's lastPathComponent() as text
end getName:

#=====

on split:sourceString usingString:d1
	set sourceString to current application's NSString's stringWithString:sourceString
	return (sourceString's componentsSeparatedByString:d1) as list
end split:usingString:

As you may see, I dropped the calling instructions and added two handlers.

Save this code as a script bundle (.scptd file) which you will store in ~/Library/Script Libraries/
I named it : “4macScripter.scptd”
You will probably have to create the subdirectory Script Libraries by yourself.
Open the bundle in the Script Editor.
At the right-top of its window you will get a button entitled “Bundle Contents”.
Click it to reveal the dedicated drawer.
In it you will see a checkbox entitled “AppleScript/Objective-C Library”
Check it, and re-save the file.
Now you will have an usable library.

Part 2
Contains quite only the calling instructions.

use theLib : script "4macScripter"
use scripting additions

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

set itsName to theLib's getName:thePath
set itsFirstNumStr to item 1 of (theLib's findPattern:"_[0-9][0-9]_" inString:itsName)
set itsFirstNum to (theLib's replace:itsFirstNumStr existingString:"_" newString:"") as integer
set strippedPath to (item 1 of (theLib's split:thePath usingString:itsFirstNumStr)) & ".pdf"
theLib's splitPDF:thePath numberingFrom:itsFirstNum basePath:strippedPath

The very first instruction will inform the script that it’s urged to use features defined in the named bundle.
The second one is required because calling libraries disable scripting additions so we must re-enable them as we are using a feature of StandardAdditions : choose file.

As you may see, all the prefixes (my or its) which were used to call handlers are replaced by the prefix “theLib’s” which tell the script that the called handler belongs to theLib (aka 4macScripter)

Run the caller script.
It will ask you to choose a PDF to split then it will call the handlers : getName, findPattern, replace, split, splitPDF of our library to do the job.

Of course we weren’t forced to use ASObjC for everything here.
It would be easy to replace the handlers getName, replace and split by old fashioned pieces of code but the ObjC version is faster than them.

If you use 10.7 or 10.8, you may perhaps do the job with Shane STANLEY’s ASObjC Runner which was available from https://www.macosxautomation.com/applescript/apps/runner.html.
Alas, the important word in my late sentence is “was” because, as ASObjC Runner can’t be used with Sierra (10.12), it’s deprecated and I don’t know if there is a living link allowing to get it.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mercredi 7 décembre 2016 16:03:00

Hi Yvan,

Ah, well this is a work computer, so I can request updates! Apparently IT can do that in a couple hours, and I will run the program again.

Thank you!

Your message appeared while I was adding some words at the beginning of my late message. Please look at them.

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mercredi 7 décembre 2016 16:34:43

Yvan, you are awesome. I got updated to Sierra and with very slight tinkering that script does everything I could want. Thank you. I am more aware than ever how much applescript I have to learn!

Thanks for the feedback.

Don’t worry, at this time, thanks to ASObjC, AppleScript is more powerful than the one I discovered in year 1995 when I used my first script.
At this time I was unable to write one from my own brain :frowning:

Yvan KOENIG running Sierra 10.12.1 in French (VALLAURIS, France) mercredi 7 décembre 2016 19:22:36

Not sure if this helps…



property kCoreLibX : {}
property kPDFexc : ""
property kGhostScript : ""

on open (kfiles)
	try
		if kLoadLibraries() ≠ true then error "Unable to load coreLibX.library!"
		set kPDFexc to quoted form of POSIX path of ((path to me) & "Contents:PDF_INFO" as string)
		set kGhostScript to quoted form of POSIX path of ((path to me) & "Contents:gs" as string)
		set kfirstFile to (item 1 of kfiles) as string
		set klocation to (kMacPathContainer(kfirstFile) of kCoreLibX as string)
		--set kJobPath to kMacPathContainer(item 1 of kfiles) of kCoreLibX --choose folder with prompt "Choose folder to extract files." default location klocation as alias
		repeat with kfile in kfiles
			
			kprocess(kfile, klocation)
			
		end repeat
		activate
		display dialog "Script finished." buttons {"OK"} default button "OK"
	on error e
		activate
		display dialog e buttons {"Ok"} default button 1 with icon 1
	end try
end open

on run
	
	activate
	display dialog "Drop PDFs on script to set the internal page number….script starts at C2, 1, 2 etc." buttons {"Cancel", "OK"} default button "OK"
	
end run

on kLoadLibraries()
	try
		set kCoreLibXPath to "/Library/Application Support/ScriptingLibraries/coreLibX.library"
		set kCoreLibX to load script (POSIX file kCoreLibXPath)
		return true
	on error
		return false
	end try
end kLoadLibraries

on kprocess(kfile, kJobPath)
	
	set kDelimName to ""
	set kOrigName to kRemoveExtensionFromEnd(kItemNameFromMacPath(kfile) of kCoreLibX, {".pdf"}) of kCoreLibX
	set kExtractFolder to kJobPath & "ExtractedPDFs:" as string
	kCheckPath(kExtractFolder) of kCoreLibX
	
	tell application "Adobe Acrobat"
		close all docs saving no
		open kfile
		set kpageCount to do script "this.numPages;"
		set kitem to 0
		repeat kpageCount times
			if kOrigName = "" then
				---omitted code
			else
				set kgetLabel to do script "this.getPageLabel('" & kitem & "')"
				set kEnd to ".pdf" as string
				set kDestination to POSIX path of ((kExtractFolder & my kpadFolio(kgetLabel as string) & "_" & kOrigName)) as string
				try
					set kDestination to (item 2 of (kDelimitItems(kDestination, "Volumes") of kCoreLibX) as string)
				end try
				try
					do script "var i = " & kitem & "; 
							this.extractPages({
							nStart: i,
							cPath : " & (quoted form of (kDestination & kEnd)) & "
							});"
					set kDelimName to kDelimName + 1
				on error
					display alert "Error, Must be running Acrobat version XI or newer, or possibly check Security setting on PDF. Found under Document Properties."
				end try
				set kitem to kitem + 1 as string
			end if
			
		end repeat
		close all docs saving no
	end tell
	
end kprocess

on kpadFolio(Folio_x)
	if (count of characters of Folio_x) = 1 then
		set Folio_x to "0" & Folio_x as string
	end if
	return Folio_x
end kpadFolio