AppleScript: Select a substring of currently selected text - applescript

Say if I selected some text in an app like Notes.
I can get the text delimited by a colon by the following code with Automator.
on run {input, parameters}
set lineSubject to text 1 thru ((offset of ":" in input)-1) of item 1 of input
Display Dialog lineSubject
return input
end run
However, what if, after finding the substring, I want to modify the current selection range so that this substring I got is now selected by the application instead, or what if I even change the font of the substring, e.g., making it bold?

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.

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.

Change the color of text by using applescript

I am writing some text in to word file i want to change the color of that text any one can help on that one plz.
I want to print the 'message' from following script in red color.
Here is the Script:
set message to "mostly these windows are popup in application"
on ResultCreationFuction(message)
try
set text_to_save to message as text
tell application "System Events"
tell application "Finder"
set sortedList to sort (get files of folder "SofTestAutomationResult" of desktop) by modification date
set FileCount to get count of sortedList
set theFile to (item FileCount of sortedList) as alias
end tell
set file_ref to open for access theFile with write permission
write (text_to_save & return) to the file_ref starting at eof
close access file_ref
delay 2
end tell
end try
end ResultCreationFuction
Some Details:
The file is word which is all ready present on above location having name "10.012.2014_17_4_20.doc" (the name of .doc file is not fix)
What you are attempting is the wrong way to do it.
To manipulate content like that, including formatted text (not plain
text), you need to work within, ideally, a well-scriptable app, like
Pages (or Word, perhaps, but I don't have that on the machine I'm
writing this from).
Don't use System Events if you don't need to. Use the apps with the appropriate AppleEvents/dictionary, etc. If you don't know what I'm talking about, you need to take advantage of the infinite resource known as the web.
"Fuction" is just bad form.
I would suggest doing a lot more reading up on how AppleScript works (or scripting in general), but to start you out, here is a script I just wrote in pages which sets the color of a specific word of the open document after putting text in there:
tell application "Pages"
set body text of document 1 to "hello there mister fancy pants"
set color of word 3 of body text of page 1 of document 1 to {64614, 0, 111}
end tell
If you have Pages, try this by starting with a blank page and running this script. Obviously, you could get rid of "word 3 of" in the 2nd line, and the whole body text will be red.
I hope this makes sense and is of help.
[edit]
I should mention that even TextEdit is scriptable and can open Word documents. Here's an example using TextEdit:
tell application "TextEdit"
set text of document 1 to "hello mister fancy pants"
set color of words 2 thru 3 of text of document 1 to {65535, 0, 0}
end tell
There is a little danger of non-Word apps losing formatting of Word files. But it just seems you are attempting something very simple, and I'm not sure if Word is really necessary here.
You can't add color using the write to eof. You should open the document in Word and then insert the line and add the color. Here's a script that should demonstrate how:
set text_to_add to "mostly these windows are popup in application"
set theFile to ((path to desktop folder) & "10.012.2014_17_4_20.doc") as string
tell application "Microsoft Word"
set theFile to theFile as string -- assuming theFile is an alias or :: path
open file theFile
tell active document
set endOfDoc to end of content of text object -- insert the text to end of document
set theRange to create range start (endOfDoc - 1) end endOfDoc
insert text text_to_add at theRange
set myRange to create range start endOfDoc end (endOfDoc + (length of text_to_add))
set color index of font object of myRange to red
save
end tell
end tell

AppleScript to get the active list in Reminders?

Can anyone help me to get the active list on display in the Reminders app on OS X?
According to the applescript dictionary for reminders, the application has a "default list" property which is "the list currently active in the Reminders application."
However, this property always seems to return the first list in order in the lists sidebar, not the list which is actually being displayed and is active. I have found that if I rearrange the order of the lists in the sidebar, I will always get whichever I have made the first list, regardless of which is actually being viewed and worked with.
My application is to create a Keyboard Maestro trigger to run an AppleScript to print the list I am currently working on, but it does not appear that the Reminders app functions as is documented in its dictionary. (I have temporarily used a workaround of having the script pop up a chooser listing all the lists so I can select the one i want to print, but that's inefficient and inelegant).
Thanks!
Yes, you can, but you will have to use the bad GUI scripting. And in a bad way. Look:
--Do some GUI scripting to get the decription of a specific group
tell application "Reminders" to activate
tell application "System Events"
tell process "Reminders"
tell window "Reminders"
tell splitter group 1
tell group 1
set des to get description
end tell
end tell
end tell
end tell
end tell
--This description is in the format "Viewing MyList, 1 reminder" so get the part to the "," from des.
set text item delimiters to ","
set texitems to text items of des
set firstPart to get text item 1 of texitems
--Setting the delimiters back
set text item delimiters to ""
--Jump to charcter 9 of firstPart then converting to text
set listname to characters 9 thru end of firstPart as text
--Now we know the name of the current list, so do whatever you want:
tell application "Reminders" to get list listname
This works. But only if Reminders is open. And if Apple changes Reminders structure...

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

Resources