Hello.
Some of the scripts we write, are scripts that does something on the Finder selection, or lets us do something on files we select. I have tried to merge those two cases into one; if nothing is selected, or valid, by filetype, or other parameters, then choose files, (or folders).
When we do have something, to work on, then do the work on the items, one, or many, and do any postprocessing too.
I have chosen to split the work above into an algorithm, and a script object, with several mandatory handlers, that you must fill in with your details. It may seem daunting at first, but when you have finished off your first implementation, then you have a good grasp, and you can just copy your previous object as a “blue-print” for the next script.
The algorithm, that controls the selection, and what is to be done, is totally transparent, to the type of file reference you elect to work with, and what you do with the files in the script, so it is highly reusable, which has the advantage, that you or others will have a much higher degree of confidence in your file-handling scripts, since they all behave alike.
The code below, is working, but it is all mocked up into a single file for simplicity, so, I have a working demo. Feel free to organize it as you please, if you think that this is something for you, after having played with it. (I have it all arranged in different AS 2.3 Libraries.)
Enjoy.
-- Copyright © 2015 McUsr, you are free to use, and share per email, but not to publish on a webpage or in a book please refer to the link below
-- http://www.macscripter.net/viewtopic.php?pid=179364#p179364
-- You are free to derive the algorithm, and modify it to suit your own needs, but you are not free to publish them as is, as your own work, or any derivations, as your own idea.
property TopLevel : me
property scripttitle : "Make ul>li Listing of selected Files."
script fileListObj
property nameExts : {} -- Contains any extensison , {} means "Anything goes"
property fileUti : {"public.item"}
on obtainFileList(scripttitle)
-- Wrapper for getting the selection from Finder
return TopLevel's selectionListMaybeIncludingFoldersAsPxPath(scripttitle)
end obtainFileList
on preparateFileList(theList)
-- use this handler, to convert the alias list into something different.
-- if you choose to use theAlias list, let this handler be empty!
script o
property l : theList
end script
-- We'll have to create the list of aliases into a list of posix path
repeat with i from 1 to (count theList)
set item i of o's l to POSIX path of item i of o's l
end repeat
end preparateFileList
on okToProcessFile(aFile)
-- A wrapper for writing a test if the file is something we'll process
-- This works in tandem with obtainfileList and preparateFileList, alias-alias, posix-posix, and so on.
return TopLevel's validFileExtOfPxPath(aFile, my nameExts)
end okToProcessFile
on processOneFile(theList, aFile)
processManyFiles(theList, aFile, 0)
return 1 -- mandatory
end processOneFile
on processManyFiles(theList, aFile, theItemNUmber)
if theItemNUmber is 0 then set end of theList to "<ul>"
-- To keep the "Algorithm" clean from implementation details
set end of theList to (tab & "<li>" & (tildeContractPxPath of TopLevel for aFile) & "</li>")
set theItemNUmber to theItemNUmber + 1
return theItemNUmber
end processManyFiles
on postProcess(theList, numberOfItems)
set end of theList to "</ul>"
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, linefeed}
set the clipboard to theList as text
set AppleScript's text item delimiters to tids
end postProcess
on aliasOfFolder(aFile)
-- this mandatory handler, is for returning an alias to a parent folder,
-- that is to be the default location for the choose file dialog, for the case that nothing
-- that was selected was valid for processing,, so that we have a connection to where we were,
-- either from te Finder window, or from the choose file dialog.
tell application id "MACS"
return (container of (POSIX file (aFile) as alias) as alias)
end tell
end aliasOfFolder
end script
selectAndProcessFiles(scripttitle, fileListObj, "Putting ul>li list onto Clipboard")
(* the main library, consisiting of "the Algorithm", and any handlers that returns the selection *)
on selectAndProcessFiles(scripttitle, jobObject, doneMessage)
set fileListReceived to {}
set defLoc to missing value
-- initial selection of files, from a finder window or the desktop
set fileListReceived to jobObject's obtainFileList(scripttitle)
repeat
if length of fileListReceived = 0 then
if defLoc is missing value then tell application id "MACS" to set defLoc to (insertion location as alias)
-- http://macscripter.net/viewtopic.php?id=43732 juanfal
try
tell application (path to frontmost application as text)
set fileListReceived to (choose file with prompt scripttitle & ":
Choose the file(s) you want to make an ul>li listing of:" of type jobObject's fileUti default location defLoc with multiple selections allowed)
end tell
jobObject's preparateFileList(fileListReceived)
on error e number n
return
end try
end if
set resultList to {}
if length of fileListReceived = 1 then
set workFile to item 1 of fileListReceived
if jobObject's okToProcessFile(workFile) then
set numProcessed to jobObject's processOneFile(resultList, workFile)
exit repeat
end if
else
set numProcessed to 0
repeat with workFile in fileListReceived
if jobObject's okToProcessFile(workFile) then
set numProcessed to jobObject's processManyFiles(resultList, workFile, numProcessed)
end if
end repeat
if numProcessed > 0 then exit repeat
-- else, we are going back and finding something.
end if
-- if we end up here, then it seems we may have to choose some objects to work on
-- after all, or cancel the whole thing as the finder selection didn't do the trick
-- for us, so, below we prepare to receive something.
set defLoc to jobObject's aliasOfFolder(item 1 of fileListReceived)
set fileListReceived to {}
end repeat
display notification doneMessage with title scripttitle
jobObject's postProcess(resultList, numProcessed)
end selectAndProcessFiles
(*the handlers below are necessary for "the Algorithm" *)
(* Two different handlers that gets file lists without, or with folder/contents *)
on selectionListingAsPxPath() -- not in use in this demo.
-- returns the current selection as a text-list of px paths
local itemList, tids
script o
property l : missing value
end script
-- fetch the selected items
tell application id "MACS" to set o's l to selection as alias list
-- make a list of posix paths
set itemList to {}
repeat with i from 1 to (count o's l)
set end of itemList to POSIX path of item i of o's l
end repeat
return itemList
end selectionListingAsPxPath
on selectionListMaybeIncludingFoldersAsPxPath(scripttitle)
-- returns the current selection as a text-list of px paths
local itemList, tids
script o
property l : missing value
end script
script p
property l : missing value
end script
-- fetch the selected items
tell application id "MACS" to set o's l to selection as alias list
-- make a list of posix paths
set itemList to {}
repeat with i from 1 to (count o's l)
tell application id "sevs" to set wasFolder to (class of disk item ((item i of o's l) as text) is folder)
if wasFolder then
try
tell application (path to frontmost application as text)
display dialog "One of the selected items was a folder, do you want to include any Contents of the Folder, or to include the Folder itself?" buttons {"Cancel", "Contents", "Folder"} default button "Folder" cancel button 1 giving up after 300 with icon 1 with title scripttitle
end tell
copy {button returned, gave up} of result to {whatToList, gaveUp}
if gaveUp then return {}
on error
return {}
end try
if whatToList is "Contents" then
tell application "Finder"
set probe to folder (item i of o's l as text)
set p's l to (items of folder (item i of o's l as text)) as alias list
end tell
repeat with j from 1 to (count p's l)
set end of itemList to POSIX path of item j of p's l
end repeat
else
set end of itemList to POSIX path of item i of o's l
end if
else
set end of itemList to POSIX path of item i of o's l
end if
end repeat
return itemList
end selectionListMaybeIncludingFoldersAsPxPath
on validFileExtOfPxPath(fileNm, extList)
local fileExt
if extList is {} then return true
set fileExt to my fileExtOfPxPath(fileNm)
ignoring case
if fileExt is in extList then
return true
else
return false
end if
end ignoring
end validFileExtOfPxPath
on fileExtOfPxPath(pxPath)
local astid, basicFn, fileExt
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "/"
set basicFn to (item -1 of text items of pxPath)
set AppleScript's text item delimiters to "."
set fileExt to (item -1 of text items of basicFn) as Unicode text
set AppleScript's text item delimiters to astid
return fileExt
end fileExtOfPxPath
(* ======================================================== *)
(* Handlers that really belong to other libraries, but are included here for demo purposes *)
-- This handler is here, just for this particular job.
on tildeContractPxPath for aPxPath
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, POSIX path of (path to home folder)}
set aPxPath to text items of aPxPath
set AppleScript's text item delimiters to "~/"
set aPxPath to aPxPath as text
set AppleScript's text item delimiters to tids
return aPxPath
end tildeContractPxPath
Edit
Removed two typos, in the description.
Added credit to juanfal for the insertion location.
Moved the comment about necessary handlers to a more logical place than the bottom.