return expand("")
on ReplaceText(theString, fString, rString)
set current_Delimiters to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to every text item of theString
set AppleScript's text item delimiters to rString
set newString to sList as string
set AppleScript's text item delimiters to current_Delimiters
return newString
end ReplaceText
on expand(separator)
tell application "Finder"
set theSelection to get selection as list
set theResult to ""
if length of separator = 0 then set separator to linefeed
repeat with theItem in theSelection
if length of theResult > 0 then set theResult to theResult & separator
set theResult to theResult & POSIX path of (theItem as alias)
set theResult to ReplaceText(theResult, "/Volumes/DISK_A", "https://download.url.com") of me
end repeat
return theResult
end tell
end expand
I found a script here, but it is not clear how to add this to the script above and if this is the right one?
replaceChars("/Volumes/A Hard Drive", space, "%20")
on replaceChars(aString, charToReplace, newChar)
set {TID, text item delimiters} to {text item delimiters, charToReplace}
set aString to text items of aString
set text item delimiters to newChar
set aString to aString as text
set text item delimiters to TID
return aString
end replaceChars
Vanwoods. The ReplaceText and replaceChars handlers are functionally the same, and both work for me. Just as a matter of personal preference, I would use the replaceChars handler. However, I don’t understand their use in the expand handler. Instead of line 1 below shouldn’t it be line 2 below. I don’t understand the purpose of the expand handler, so perhaps there’s some reason for this?
set theResult to ReplaceText(theResult, "/Volumes/DISK_A", "https://download.url.com") of me
set theResult to ReplaceText(theResult, space, "%20") of me
It’s in an expand handler because I use it for text expansion in email. We are selecting the file in the finder and then expand the script when typing a text string. It gives a download link which can be send to the client.
The below script works now but I don’t know if this is the best setup. To copy the line multiple times?
return expand("")
on ReplaceText(theString, fString, rString)
set current_Delimiters to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to every text item of theString
set AppleScript's text item delimiters to rString
set newString to sList as string
set AppleScript's text item delimiters to current_Delimiters
return newString
end ReplaceText
on expand(separator)
tell application "Finder"
set theSelection to get selection as list
set theResult to ""
if length of separator = 0 then set separator to linefeed
repeat with theItem in theSelection
if length of theResult > 0 then set theResult to theResult & separator
set theResult to theResult & POSIX path of (theItem as alias)
set theResult to ReplaceText(theResult, "/Volumes/DISK_A", "https://download.url.com") of me
set theResult to ReplaceText(theResult, space, "%20") of me
set theResult to ReplaceText(theResult, "/Volumes/DISK_B", "https://download.url.com") of me
set theResult to ReplaceText(theResult, space, "%20") of me
set theResult to ReplaceText(theResult, "/Volumes/DISK_C", "https://download.url.com") of me
set theResult to ReplaceText(theResult, space, "%20") of me
end repeat
return theResult
end tell
end expand
Here is a slightly cleaned up version
I moved most of the routine ‘expand’ outside of the tell “Finder” block.
return expand("")
on ReplaceText(theString, fString, rString)
local tid, newString
set tid to text item delimiters
set text item delimiters to fString
set sList to every text item of theString
set text item delimiters to rString
set newString to sList as string
set text item delimiters to tid
return newString
end ReplaceText
on expand(separator)
local tid, theSelection, theResult
set tid to text item delimiters
tell application "Finder" to set theSelection to selection
if length of separator = 0 then set separator to linefeed
repeat with theItem in theSelection
set contents of theItem to POSIX path of (theItem as alias)
end repeat
set text item delimiters to linefeed
-- uncomment end of line below to have trailing linefeed
set theResult to (theSelection as text) -- & linefeed
set theResult to ReplaceText(theResult, "/Volumes/DISK_A", "https://download.url.com")
set theResult to ReplaceText(theResult, "/Volumes/DISK_B", "https://download.url.com")
set theResult to ReplaceText(theResult, "/Volumes/DISK_C", "https://download.url.com")
set theResult to ReplaceText(theResult, space, "%20") -- only needs to be done once
set text item delimiters to tid
return theResult
end expand
And here is another one with using URL property of selection.
It makes it so we don’t have to replace spaces with %20
return expand("")
on ReplaceText(theString, fString, rString)
local tid, newString
set tid to text item delimiters
set text item delimiters to fString
set sList to every text item of theString
set text item delimiters to rString
set newString to sList as string
set text item delimiters to tid
return newString
end ReplaceText
on expand(separator)
local tid, theSelection, theResult
set tid to text item delimiters
if length of separator = 0 then set separator to linefeed
tell application "Finder"
set theSelection to selection
repeat with theItem in theSelection
set contents of theItem to URL of theItem
end repeat
end tell
set text item delimiters to linefeed
-- uncomment end of line below to have trailing linefeed
set theResult to (theSelection as text) -- & linefeed
set theResult to ReplaceText(theResult, "file:///Volumes/", "https://download.url.com/")
set text item delimiters to tid
return theResult
end expand
The process of replacing special characters in a URL string is called URL encoding. In my experience, AsObjC and ruby handle this most successfully and consistently. The correct AsObjC-handler provided by @Fredrik71 above.
I prefer the ruby solution in cases where AsObjC is not needed by the rest of the script. Because bootstrapping the AsObjC frameworks kills. Note: I commented taking the finder selection and hardcoded the selected file in my example. You can use commented code line instead.
-- tell application "Finder" to set posixPath to POSIX path of ((item 1 of (get selection)) as text)
set posixPath to "/Volumes/DISK_A/folder1/best practises"
set newPath to ReplaceText(posixPath, "/Volumes/DISK_A/", "https://download.url.com/")
set theURL to encodeURL_ruby(newPath)
on ReplaceText(theString, fString, rString)
set current_Delimiters to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to every text item of theString
set AppleScript's text item delimiters to rString
set newString to sList as string
set AppleScript's text item delimiters to current_Delimiters
return newString
end ReplaceText
on encodeURL_ruby(theURL)
do shell script "ruby -e 'require \"uri\";puts URI.escape(\"" & theURL & "\")'"
end encodeURL_ruby
If you do not take into account the bootstrap time of frameworks, then the AsObjC solution is the fastest of all. The second fastest is the perl solution.
I did not include it from the very beginning only because it also encodes the characters “:” and “/”, and as I understand it, the OP do not want this. Although it is this URL encoding that is the standard.
set posixPath to "/Volumes/DISK_A/folder1/best practises"
set newPath to ReplaceText(posixPath, "/Volumes/DISK_A/", "https://download.url.com/")
set theURL to encodeURL_perl(newPath)
on ReplaceText(theString, fString, rString)
set current_Delimiters to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to every text item of theString
set AppleScript's text item delimiters to rString
set newString to sList as string
set AppleScript's text item delimiters to current_Delimiters
return newString
end ReplaceText
on encodeURL_perl(theURL) -- the fastest Plain AppleScript method
do shell script "/usr/bin/perl -e 'use URI::Escape; print uri_escape(\"" & theURL & "\")';"
end encodeURL_perl
Here is very nice AppleScript-solution which doesn’t use shell commands and AsObjC frameworks at all. It is very very fast and allows user defined character sets to encode (see standard_characters, URL_A_chars and URL_A_chars lists in the handler).
You can see the the symbol “:” in URL_B_chars and symbol “/” in URL_A_chars. So, I put to not encode both lists when calling the handler (parameters false, false).
set posixPath to "/Volumes/DISK_A/folder1/best practises"
set newPath to ReplaceText(posixPath, "/Volumes/DISK_A/", "https://download.url.com/")
encode_text(newPath, false, false)
on ReplaceText(theString, fString, rString)
set current_Delimiters to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to every text item of theString
set AppleScript's text item delimiters to rString
set newString to sList as string
set AppleScript's text item delimiters to current_Delimiters
return newString
end ReplaceText
on encode_text(this_text, encode_URL_A, encode_URL_B)
set the standard_characters to "abcdefghijklmnopqrstuvwxyz0123456789"
set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*"
set the URL_B_chars to ".-_:"
set the acceptable_characters to the standard_characters
if encode_URL_A is false then set the acceptable_characters to the acceptable_characters & the URL_A_chars
if encode_URL_B is false then set the acceptable_characters to the acceptable_characters & the URL_B_chars
set the encoded_text to ""
repeat with this_char in this_text
if this_char is in the acceptable_characters then
set the encoded_text to (the encoded_text & this_char)
else
set the encoded_text to (the encoded_text & encode_char(this_char)) as string
end if
end repeat
return the encoded_text
end encode_text
on encode_char(this_char)
set the ASCII_num to (the ASCII number this_char)
set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
set x to item ((ASCII_num div 16) + 1) of the hex_list
set y to item ((ASCII_num mod 16) + 1) of the hex_list
return ("%" & x & y) as string
end encode_char
Finally, I should note that the original problem can be solved even more efficiently. To do this, you need to use the fact that the Finder itself provides the URL-encoded form “file:///”. You just need to stupidly replace “file:///” with “https://”.
set URLs to {}
tell application "Finder"
repeat with anItem in (get selection)
set end of URLs to my replaceText(URL of anItem, "file:///", "https://")
end repeat
end tell
return URLs
on replaceText(theString, fString, rString)
set ATID to text item delimiters of AppleScript
set AppleScript's text item delimiters to fString
set sList to text items of theString
set AppleScript's text item delimiters to rString
set newString to sList as text
set AppleScript's text item delimiters to ATID
return newString
end replaceText
Thanks, I tried al the above scripts and they work like a charm!
Only one more question, is it possible to have to the second part after /VOLUMES/DISK_A or DISK_B or DISK_C be replaced no matter how the disk (or share) is called? Copying the lines like below is resulting in normal posixPaths and not the url (https://download.url.com/)
set newPath to ReplaceText(posixPath, "/Volumes/DISK_A/", "https://download.url.com/")
set newPath to ReplaceText(posixPath, "/Volumes/DISK_B/", "https://download.url.com/")
set newPath to ReplaceText(posixPath, "/Volumes/DISK_C/", "https://download.url.com/")