Append text to a string in Applescript - applescript

It seems that the concatenation in AppleScript doesn't let you easily append text to a string variable. I have the following line that would work in most other languages:
repeat with thisRecpt in recipients of eachMessage
set recp to recp & "," & address of thisRecpt
end repeat
From what I can tell, this doesn't seem to work in AppleScript, as you cannot use the recp variable within the same line apparently. Is there any easier way of adding text to the end of a variable without having to use two variables within the loop?
Thanks!

The code you posted works fine as long as recp is set to something first, say "". However, you'll then get a , as the first character in your string, which is probably not what you want.
Instead, you can do this:
set _delimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set recp to eachMessage's recipient's address as string
set AppleScript's text item delimiters to _delimiters
Yes, it's ugly, but it's more efficient and you'll only get "," between addresses.

Related

Removing a word from a variable in Applescript

I'm pretty newbie at Applescript and I can't work out how to remove a word from a variable if the word contains a “#” in it.
My script gets this error -> "Can’t make word into type integer." number -1700 from word to integer
Here's my script so far:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set Description to the clipboard
if any word in Description contains "#" then delete that word
return Description
end tell
Any pointers?
Cheers,
Chris
To get text out of the clipboard, use (clipboard as text). The clipboard can contain almost anything, even multiple objects, in multiple formats, so as text gives you a string to work with.
And watch out: 'Description' appears to be part of some existing appleScript 'terminology', at least on the Mac I have right here, so I am changing your identifier to desc here:
activate application "Grids"
delay 2
tell application "System Events"
keystroke "a" using command down
delay 0.25
keystroke "c" using command down
delay 0.25
set desc to the clipboard as text
end tell
set out to {}
set tids to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
repeat with anItem in (text items of desc)
set str to (anItem as string)
if (str does not contain "#") then
set end of out to str
end if
end repeat
set outStr to out as string
set AppleScript's text item delimiters to tids
return outStr
This code just returns the text you are looking for. It does not re-insert the groomed string, or do anything else interesting.
I assume you're going to tell System Events to paste it via cmd-v. (Remember to set the clipboard to outStr before you paste!)
AppleScript's text item delimiters allows the string to be split and reassembled using a space (or any other token you wish). For code hygiene reasons, it's wise practice to store it before changing it, then reset it to its original value afterwards, as shown here, otherwise odd things might happen in scripts which expect it to have the default value.

Mac OS Script is supposed to paste a UNC path as SMB, but it keeps converting the colon to a semicolon and converts the capital letters to lower-case

I have a Script that was supposed to convert Windows UNC path to Mac SMB, but keep converting the colon to a semicolon and Upper case to lower case. Here is code. Help is appreciated.
set myClip to the clipboard
set mytext to searchReplace(myClip, "<", "")
set mytext to searchReplace(mytext, ">.", "")
set mytext to searchReplace(mytext, ">", "")
set findIt to "\\"
set replaceIt to "/"
set mylocation to searchReplace(mytext, findIt, replaceIt)
set mylocation to "smb:" & mylocation
set the clipboard to mylocation
do shell script "pbpaste |textutil -convert txt -stdin -stdout -encoding 30 |pbcopy"
tell application "System Events" to keystroke (the clipboard)
on searchReplace(theText, SearchString, ReplaceString)
set OldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to SearchString
set newText to text items of theText
set AppleScript's text item delimiters to ReplaceString
set newText to newText as text
set AppleScript's text item delimiters to OldDelims
return newText
end searchReplace
This line:
tell application "System Events" to keystroke (the clipboard)
simulates key presses. The characters in the string are converted to the corresponding key and "pressed" without modifiers like Shift (by default). You can specify a using <modifiers> phrase on the command to specify which modifiers to use, but then those are used for all of the simulated key presses. You can't cause it to simulate the Shift for some key presses (for the upper-case letters and colon) and not others based on the characters in the string.
This seems like a good candidate for a Service rather than a stand-alone script. A service will automatically receive the selected text in the active app and its output will automatically replace that selected text, without having to use the clipboard or simulating key presses. Use Automator.app to create a service, enable "Output replaces selected text", add the Run AppleScript action, and put the guts of your script into the handler.

Applescript find, replace and style

I've been trying to get this simple script to work, it's supposed to search for a string, replace it while applying some styling, e.g. setting the text bold and red.
Here's what I have so far:
tell application "Finder"
set fl to files of folder POSIX file "/Users/Sc/Desktop/app/" as alias list
end tell
repeat with f in fl
tell application "TextEdit"
open f
set text of front document to replace_chars(text of front document, "a", "0000") of me
end tell
end repeat
on replace_chars(this_text, search_string, replacement_string)
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set the size of replacement_string to 14
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
return this_text
end replace_chars
However this produces an error, I understand why, but not sure how to go about styling it before replacement, any help would be appreciated.
TextEdit uses Cocoa Scripting's standard Text Suite implementation, which is pretty naff at the best of times. If you're doing whole-word replacement, the following should work:
tell application "TextEdit"
set aRef to a reference to (every word of document 1 where it is "OLDWORD")
set aRef's color to {65535, 0, 0}
set aRef's contents to "NEWWORD"
end tell
The same approach should also work for single-character or whole-paragraph replacement; just modify the every word of... query appropriately. In each case though, you must match exactly one word/character/paragraph and replace it with exactly one word/character/paragraph, otherwise you'll get hilarious off-by-N errors throughout subsequent matches[1] due to Cocoa Scripting being made of dumb and incompetent[2] (e.g. try changing a recurring word to two new words, e.g. "foo" -> "boo boo" to see what I mean).
Also, unlike Text Suite implementations found in better written apps, Cocoa Scripting's Text Suite provides no way to describe to text ranges (e.g. text (character i) thru (character j) of.../text i thru j of...), so it's impossible to tell TextEdit to match, say, "oo" in "baboon", "fool", "spitoon", etc. If you need to match arbitrary character ranges, you'll have to get the text into AppleScript and calculate the start and end of each match yourself.
[1] When making multiple replacements, CS's Text Suite first calculates the positions of all of the text ranges that need changed, and then performs each substitution starting at the first match and finishing at the last. Thus, any differences in the length of the new vs old text mean all of the remaining match indexes it already calculated are no longer correct because the characters previously at that position have now shifted to the left or right. To do the job right, CS should've calculated all the positions from first to last, and then replaced them starting at the last and working backwards to the first.
[2] (CocoaScripting.framework was originally designed by Cocoa developers who didn't understand how AppleScript works, and since then has been maintained by AppleScript developers who don't understand either. So it goes.)
TextEdit is not the best tool to search and replace styled text, for example the free TextWrangler has more powerful skills to do that.
Anyway, try this, it affects only one opened document in TextEdit
The "algorithm" is to calculate the offset of the search string, replace it with the replace string and keeps the location in a repeat loop. At the end reassign the changed text to the text object of TextEdit and change the style at the stored locations to {font: Helvetica Bold, size: 24 and color: red}.
property searchString : "a"
property replaceString : "0000"
tell application "TextEdit"
set completed to false
set ranges to {}
set theText to text of front document
set theSize to size of text of front document
repeat while completed is false
tell current application to set o to offset of searchString in theText
if o is 0 then
set completed to true
else
tell theText to set newText to text 1 thru (o - 1) & replaceString & text (o + (length of searchString)) thru -1
set end of ranges to o
copy newText to theText
end if
end repeat
set text of front document to theText
set size of text of front document to theSize
repeat with aRange in ranges
tell characters aRange thru (aRange + (length of replaceString) - 1) of front document
set size to 24
set its color to {65535, 0, 0}
set font to "Helvetica Bold"
end tell
end repeat
end tell
Since the other posters both noted how poorly suited TextEdit is for this task, allow me to make an "out of the box" suggestion: Use MS Word
The Find and Replace tool in Word can easily handle this task, and much more complicated replacements.
If you have a lot of source documents in RTF format, you could open them in Word, make the changes, and save back to the same (or different) RTF file. It would be very easy to create a Word VBA macro to do this.
You could then either write an AppleScript to open each RTF file in Word and run the macro, or you could do all of the processing using a master Word VBA. You could do it in either way, but I would choose the all VBA route since, IMO, it is a much better language for processing MS documents than AppleScript.
Of course, this requires that you have MS Word installed. I'm still running MS Office 2011 on all of my Macs, and don't plan to upgrade to Office 2016 for a while. Word 2011 works very well.
Good luck.

Unable to manipulate text from Clipboard in Applescript

I am forced to use a piece of software that requires a lot of data entry into simple web forms, so I have designed an AppleScript to take a text file as input and then keystroke out the contents into Safari, so that tabs in the text file are used to advance to the next field in the web form. I am doing some string replacement so I can treat newlines in the text file as tabs, for readability of the text file.
I want to streamline this by keystroking from the clipboard, which works, but the string replacement is not happening the way it should, and I am unable to determine why. My workaround at this point is to manually find/replace newlines with tabs before copying, but that's basically just as slow as saving the file and pointing the script at it.
tell application "Safari"
activate
end tell
set sourceString to (the clipboard) as text
set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "\n"
set the lineList to every text item of sourceString
set AppleScript's text item delimiters to "\t"
set keystrokeString to the lineList as string
set AppleScript's text item delimiters to ASTID
tell application "System Events"
keystroke keystrokeString as text
end tell
\t and \n will compile down to invisibles if you put this into AppleScript Editor. The string editing (middle) part works as advertised when I read from a file using:
set theFile to (choose file with prompt "Select a file to read:" of type {"txt"})
open for access theFile
set fileContents to (read theFile)
close access theFile
Any ideas why the string replacement might not be working when I get the text from the clipboard?
Using the ASCII Character function when setting the delimiters should work. A linefeed is ASCII character 10. So i.e.: set AppleScript's text item delimiters to ASCII character 10
Should work.
Tabbing through forms on a page is often error prone. You should identify each form by id and populate the form with javascript.
tell application "Safari"
set URL of document 1 to "http://www.google.com/"
delay 3
do JavaScript "document.getElementById('gbqfq').value = 'My Text'" in document 1
end tell
It appears as though linefeeds are translated into carriage returns upon copying text to the clipboard, and \n will not match them.
\r will, however, and they both compile down to invisible characters, which is a bit of an annoyance.
After a little bit of testing, it looks like when you save a text file to disk and then read it with AppleScript, you must match the line endings used in the file, LF or CR with \n or \r. However, when reading text copied to the clipboard, you must always match \r.
Edit:
Many of these characters have AppleScript keywords. tab, linefeed, and return can all be used as is. My script now looks like this:
set backspace to ASCII character 8
get the clipboard
set keystrokeString to (replacement of return by tab for the result)
set keystrokeString to (replacement of linefeed by tab for the result)
set keystrokeString to (replacement of tab by tab & backspace for the result)
tell application "System Events"
keystroke keystrokeString as text
end tell
on replacement of oldDelim by newDelim for sourceString
set oldTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to oldDelim
set strtoks to text items of sourceString
set text item delimiters of AppleScript to newDelim
set joinedString to strtoks as string
set text item delimiters of AppleScript to oldTIDs
joinedString
end replacement
It also now includes backspace characters that are hit after every tab, so if text is not entered into an already filled field, it is deleted after being advanced to.

Edit clipboard content with applescript in os x

I'm copying a lot of source code from different projects to others and I always have to change the same terms. Is it possible to use an applescript which checks the text-content of the clipboard and replaces several keyword? I'm new to applescript so I'm not aware of how powerful applescript can be...
This is possible using get clipboard, set clipboard, and the text item delimiters.
get the clipboard
set the clipboard to (replacement of "this text" by "that text" for the result)
on replacement of oldDelim by newDelim for sourceString
set oldTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to oldDelim
set strtoks to text items of sourceString
set text item delimiters of AppleScript to newDelim
set joinedString to strtoks as string
set text item delimiters of AppleScript to oldTIDs
joinedString
end replacement
For more sophisticated text manipulation, I'd just call out to a shell script. The above becomes:
do shell script "pbpaste | sed 's/this text/that text/g' | pbcopy"
Not sure that I understood what you want to do. I reckon you want to replace multiple strings within the clipboard content, for example: "PS3 costs 200 dollars at Wallmart" to "XBox costs 180 dollars at Wallmart". The following code achieves this:
get the clipboard
set the clipboard to (replacement of "PS3" by "XBox" for the result)
on replacement of oldDelim by newDelim for sourceString
set oldTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to oldDelim
set strtoks to text items of sourceString
set text item delimiters of AppleScript to newDelim
set joinedString to strtoks as string
set text item delimiters of AppleScript to oldTIDs
joinedString
end replacement
get the clipboard
set the clipboard to (replacement of "200" by "180" for the result)
Kudos to Michael J. Barber for the original code. I know virtually nothing about coding. I just tried this modification it worked.

Resources