Removing a word from a variable in Applescript - 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.

Related

AppleScript: How to extract numbers from a string?

I am writing a script to go to the NYT website on Corona, get the US data, extract numbers (total, death), and to send me a notification. I am close, but when I extract numbers and display them, they are put together (ie 700021 instead of 7000,21). My question is:
How do I extract the numbers so that they are delineated?
Here is the code:
set theURL to "https://www.nytimes.com/interactive/2020/world/coronavirus-maps.html?action=click&pgtype=Article&state=default&module=styln-coronavirus&variant=show&region=TOP_BANNER&context=storyline_menu"
tell application "Safari" to make new document with properties {URL:theURL}
tell application "System Events"
repeat until exists (UI elements of groups of toolbar 1 of window 1 of application process "Safari" whose name = "Reload this page")
delay 0.5
end repeat
end tell
to getInputByClass(theClass, num)
tell application "Safari"
set input to do JavaScript "
document.getElementsByClassName('" & theClass & "')[" & num & "].innerText;" in document 1
end tell
return input
end getInputByClass
set myVar to getInputByClass("g-body ", 5)
on returnNumbersInString(inputString)
set s to quoted form of inputString
do shell script "sed s/[a-zA-Z\\']//g <<< " & s
set dx to the result
set numlist to {}
repeat with i from 1 to count of words in dx
set this_item to word i of dx
try
set this_item to this_item as number
set the end of numlist to this_item
end try
end repeat
return numlist
end returnNumbersInString
set theNums to returnNumbersInString(myVar) as text
display notification "COVID-19 UPDATE" subtitle theNums sound name "glass"
tell application "Safari"
close its front window
end tell
You are getting a list of numbers from the returnNumbersInString handler, but just coercing the list to text doesn't normally provide any kind of formatting. One solution would be to use text item delimiters to specify the text to use when joining the list items. For example, when converting to text for the notification you could do something like:
set tempTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ", "
set theNums to returnNumbersInString(myVar) as text
set AppleScript's text item delimiters to tempTID
Similar to your other question I helped you with, the target data is already in a table and as such I'd use the table data to get the information as its structure layout is not likely to change where target 'g-body ' of 5 may not always be the United States.
I get my data a little different way:
set theURL to "https://www.nytimes.com/interactive/2020/world/coronavirus-maps.html?action=click&pgtype=Article&state=default&module=styln-coronavirus&variant=show&region=TOP_BANNER&context=storyline_menu"
tell application "Safari" to make new document with properties {URL:theURL}
tell application "System Events"
repeat until exists ¬
(UI elements of groups of toolbar 1 of window 1 of ¬
application process "Safari" whose name = "Reload this page")
delay 0.5
end repeat
end tell
tell application "Safari" to tell document 1 to set CountriesTable to ¬
do JavaScript "document.getElementsByClassName('svelte-f9sygj')[0].innerText;"
tell application "Safari" to close its front window
set awkCommand to ¬
"awk '/United States/{print $3,\"Cases &\",$4,\"Deaths\"}'"
set notificationMessage to ¬
do shell script awkCommand & "<<<" & CountriesTable's quoted form
display notification notificationMessage subtitle "US COVID-19 UPDATE" sound name "glass"
NOTE: The code used to determine when the page in Safari has finished loading works in macOS Mojave and later, however, for macOS High Sierra and some earlier versions, add the words buttons of in front of UI elements ... in the repeat until exists ¬ ... code.
Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

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 inserts string into application inbetween double quotes

I just purchased Alfred App for my Mac and I want to use this script I found online:
---------------------------------------------------
--Modified by: Pontus Sundén, http://psu.se
--Icon from: http://findicons.com/pack/1362/private_eye_act_1
---------------------------------------------------
on alfred_script(strQuery)
--Get the parameters passed to the script - this is the search query
set strSearchCriteria to SpaceList(strQuery)
--Try to populated an existing window with the search query
tell application "Evernote"
try
set query string of window 1 to strSearchCriteria
on error
--No existing window, open an new one
open collection window with query string strSearchCriteria
end try
end tell
tell application "System Events" to set frontmost of process "Evernote" to true
end alfred_script
--Take a list of text items and retrun them as a string with a space between each item
on SpaceList(astrItems)
--Store what the current list delimiter is
set tmpDelimiters to AppleScript's text item delimiters
--Set the list delimiter to a space and build the string we want to pass back
set AppleScript's text item delimiters to " "
set strReturn to astrItems as string
--Set the list delimiter back to what it was previously
set AppleScript's text item delimiters to tmpDelimiters
--Return the string we built
return strReturn
end SpaceList
which should open up evernote and search for something. It works fine, but instead of searching for, say the word boat, it will search for "boat" with the double quotes and obviously this yields no matches.
Your script is perfectly correct – the spurious quoting of search terms passed via AppleScript is a known Evernote bug in version 3 of the client (well, “known” as in “I opened a support ticket for it a while ago, and Evernote acknowledged it”; I’d add a link to the ticket, but these are private to the user who opened it … will update on progress, though).
Until they get around to fix it, you will have to either use the suggested GUI Scripting solution as a workaround, or correct the search strings manually.
You can use UI scripting to populate the search field like this:
set xxx to "boat"
activate application "Evernote"
tell application "System Events" to tell process "Evernote"
set value of text field 1 of group 4 of tool bar 1 of window 1 to xxx
end tell

Problem with pasting

I'm trying to write an apple scrip to search Sparrow (mail client for Mac)
Here is the script:
on run argv
tell application "Sparrow"
activate
end tell
tell application "System Events"
key code 3 using {option down, command down}
keystroke argv
end tell
end run
The problem is that I want the script to take an argument on run so that I can supply it with what to search for, but I can't get it to pastet it out.
argv is always initialized to a list.
You cannot keystroke a list (you have to coerce each item to a string first).
You can never tell the exact number of parameters that will be sent to the script, so a better route would be to iterate through the list and do whatever needs to be done, as shown below:
tell application "System Events"
tell process "Sparrow"
key code 3 using {command down, option down}
repeat with this_item in argv
keystroke (this_item as string)
end repeat
end tell
end tell
#Runar
The script is implying that Sparrow is already activated.
You can't do this as written (the result of every text item of argv is still a list). However, if you coerce the result into a string, this will work, but it will squash everything together (assuming AppleScript's text item delimiters is ""). If you set AppleScript's text item delimiters to space, then this would actually be better than the previous script...
on run argv
tell application "Sparrow" to activate
tell application "System Events"
tell process "Sparrow" --implying Sparrow is already activated
set prevTIDs to AppleScript's text item delimiters
key code 3 using {command down, option down}
set AppleScript's text item delimiters to space
keystroke (every text item of argv) as string
set AppleScript's text item delimiters to prevTIDs
end tell
end tell
end run

Get message in compose window from Mail.app

I am trying to make a script that will get the contents of an email message that I'm composing in Mail, do something with the data, and then send the message. I know how to make and send a new message from scratch with AppleScript, but I can't find a way to get a message that I'm already writing. I don't care what language is used, and I would be open to trying a different email client. Thanks for your help!
Mail has huge limitations with regards to Applescript and dealing with its content area is a major one. The best bet is to use GUI scripting to tab to the content area, type cmd-C, and then work off the data in the clipboard.
Sadly from what I can see Applescript has not been improved at all in Lion.
It's actually pretty easy to do what you need.
If you want to run some kind of an inline processing (assigned to, say, a hotkey (in Mail, e.g. Cmd+D is not occupied), or "just" listed in the Services menu, accessible after selecting something), you can simply use Automator. A demo Automator script reading the current selection, making some changes (here, converting some ASCII char+number combinations to some accented characters) and, finally, returning the modified text is as follows:
on run {input, parameters}
set myText to replaceText("a1", "á", (input as text))
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
return myText
end run
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
Make sure you enable the "Replaces selected text", should you want to overwrite the original content with the returned one.
if you want to write an external script not invoked from the local Services menu (or via a hotkey), you'll also need to add clipboard handling. A solution similar to the above with additional clipboard copy/paste:
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Select All" of menu "Edit" of menu bar 1
click menu item "Copy" of menu "Edit" of menu bar 1
end tell
end tell
end tell
tell application "Mail"
set textclip to (the clipboard)
end tell
set myText to replaceText("a1", "á", textclip)
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
set the clipboard to myText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Paste" of menu "Edit" of menu bar 1
end tell
end tell
end tell
Note that the latter script selects (and, then, overwrites) the entire window contents. It should be easy to work on the current selection only.
It's possible, but painful. Painful enough that I'm still trying to work out exactly how to do something similar but in Safari. I've gotten to the point where I can find the textarea, but the documentation I've found for getting the content isn't working. (Unfortunately, that's pretty much par for the course for AppleScript; every program does stuff just a little bit differently from the next program.)
EDIT: ok, have some horrible evil which hopefully can be adapted to work with Mail: http://www.ece.cmu.edu/~allbery/edit_textarea.script
This is striaghtforward if we make two reasonably weak assumptions: that the message you're working on is frontmost, and that the subject of all draft messages is unique. Then, before running the script, save the message you're working on; this will place it in the drafts mailbox. Then, since the subject of the message is the name of the window, we can easily access it; and since we can easily access the drafts mailbox, we can combine the two. This gives us:
tell application "Mail"
set msgs to messages of drafts mailbox ¬
whose subject is (name of window 1 as string)
if (count of msgs) = 1 then
-- Do whatever
else
-- Error, disambiguate, whatever
end if
end tell
It's probably possible to make the script save the frontmost window, and it wouldn't surprise me if a freshly-saved message is always the first item of the drafts mailbox, but these are left as an exercise for the reader :-)
So I came across this in 2020 and with this Apple Script it is (now?) possible (whenever its still a bit hacky since I have to use the clipboard for this):
activate application "Mail"
tell application "System Events"
tell process "Mail"
set initialClipboardContent to (the clipboard as text)
set composeWindow to (first window whose title does not contain "Inbox")
set value of attribute "AXFocused" of UI element 1 of scroll area 1 of composeWindow to true
delay 0.05
# CMD + A
key code 0 using command down
delay 0.1
# CMD + C
key code 8 using command down
delay 0.1
set message to (the clipboard as text) as string
log message
set the clipboard to initialClipboardContent
end tell
end tell
Here a proof of concept:

Resources