Apple Event: May 7th at 7 am PT

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Is it possible to set the colour of text with Applescript

I have script with searches text with a search argument and if found I would like to highlight that text by changing it's colour. Have tried the following (and other variants) but nothing works, any help greatly appreciated.


set searchItem to "04/07/2014 Mrs Brenda Bird 27 Somewhere Street Somewhere Town"


set the color of every word of text 23 thru 26 of searchItem to {0, 0, 65535}


error "Can’t set color of {\"Bird\"} to {0, 0, 65535}." number -10006 from color of {"Bird"}


Running OS X 10.9.4

Posted on Jul 15, 2014 9:32 AM

Reply
25 replies

Jul 20, 2014 11:29 AM in response to Frank Caggiano

I don't think you need to set up anything specific, you can use an attributed string instead of a regular string in any text field. In my example, I just showed how to create the attributed string, and how to apply attributes by coloring each word. You can apply attributes to individual characters in the same way - I was going to do that in my example, but the colors were about to give me seizures 😝.


You would just need to get the offsets for the search results (the beginning offset and the length), then apply an attribute to that character range. If you are dealing with plain text to begin with you can easily create an attributed string from it, and if you already have an attributed string you can just apply new attributes where needed.




MacBook Pro / OS X Mavericks (10.9.3) / Xcode 5.1.1 / RubyMotion FTW

Jul 20, 2014 2:32 PM in response to red_menace

Most of my comment were in regards to Phil's suggestion to look at the set color methods in TextFieldCell. As I mentioned those would only be good for coloring the entire field, not individual chars in the field.


As for my comments regarding designing this in from the start; trying to merge your code for setting attributes on a string into Frinton's code, while doable, isn't something I'd want to do. I'd much rather start from scratch knowing how I was going to color the search terms in the output going in. Just seems like it would make for a much more pleasant experience.


So while nothing specific needs to be done it is still a good idea, at least from my standpoint, to have an idea of where you are tying to get to before starting the actual coding process. Doesn;t mean things can;t evolve as you code, in fact step-wise development is an old tried and true method for coding. Just means if in the middle of the stream you need to make a sharp left you might want to get back to the back and start over,


Finally as far as doing this with Applescript-Objective-C, I wonder if at some point you don;t just reach a limit as to what is reasonable to do this way. At a certain level of complexity would it just be better to drop the Applescript part and code the whole thing up in Objective-C? Something to think about.


regards

Jul 20, 2014 3:14 PM in response to Frank Caggiano

It was looking to me like the OP already had a string and some indexes to highlight the search term(s), so to just throw that into a text field is fairly straightforward. More complex setups would involve text storage or whatever, but a regular text field dragged in from the object library will let you use an attributed string. It isn't too complicated, as far as AppleScriptObjC goes, although this forum's formatting is about to give me an aneurism - the ASObjC-ified snippet from the OP would look something like:

set searchItem to "04/07/2014 Mrs Brenda Bird 27 Somewhere Street Somewhere Town"
set attributeRange to {22, 4} -- starting index and length - attributed string starts at 0
set attributedSearchItem to current application's NSMutableAttributedString's alloc's initWithString:searchItem -- mutable so that we can modify the attributes
attributedSearchItem's addAttribute:(current application's NSForegroundColorAttributeName) value:(current application's NSColor's redColor) range:attributeRange -- set color
attributedSearchItem's applyFontTraits:((current application's NSBoldFontMask as integer) + (current application's NSItalicFontMask as integer)) range:attributeRange -- bold + italic
textField's setAttributedStringValue:attributedSearchItem


You are right though, AppleScriptObjC does tend to get a bit unwieldy, especially with a larger project or when trying to use the framework constants and enumerations. As far as complexity goes, I've moved on to Ruby these days - I definitely stay away from Objective-C.




MacBook Pro / OS X Mavericks (10.9.3) / Xcode 5.1.1 / RubyMotion FTW

Jul 21, 2014 4:49 AM in response to Frank Caggiano

Frank said: Most of my comment were in regards to Phil's suggestion to look at the set color methods in TextFieldCell. As I mentioned those would only be good for coloring the entire field, not individual chars in the field.


That was the point of my suggestion. I don't know how the OP is displaying his results, but (as I also said), you'd use NSAttributedString if they were in a textview. It's not difficult or low-level, you just define a dictionary with your colours in. Basically, you do something like this:


NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:

[NSColor colorWithSRGBRed:0.7 green:0 blue:0.7 alpha:1.0], NSForegroundColorAttributeName, [NSFont fontWithName:@"Verdana" size:13.0],NSFontAttributeName, nil];

NSAttributedString *coloredString = [[NSAttributedString alloc] initWithString:@"hello world" attributes:d];

[[_textView textStorage] setAttributedString:coloredString];


where _textView is an IBOutlet property for the textview in Interface Builder.


Again, I don't know how to translate this into ASObjC, but its fairly straightforward Cocoa.

Jul 21, 2014 6:17 AM in response to red_menace

Thanks red_menace for the suggested code but I must admit I'm floundering now, tried the code and got the error "Unrecognized function setAttributedStringValue_. (error -10000), no idea what that means. All I wanted to do was highlight a piece of text, had no idea how complex it would become. Thanks to everyone who tried to help, it seems to have exercised a few grey cells!!

Jul 21, 2014 9:55 AM in response to Frinton Fogey

I'm sure RM will be along to fix it, but in the meantime, see if this helps. Change the line near the top that says


textField's setAttributedStringValue:rainbowize("red orange yellow green blue purple gray - colors start again")


to


textField's setAttributedStringValue_rainbowize("red orange yellow green blue purple gray - colors start again")


(in other words, replace the colon before 'rainbowize' with an underscore). If that doesn't help, we'll all have to wait on RM's return.

Jul 21, 2014 3:30 PM in response to Frinton Fogey

All I wanted to do was highlight a piece of text, had no idea how complex it would become.

As Phil posted, it really isn't too complicated, you just need to replace the regular (plain) text string with one that you can add attributes to. The attributed string can be manipulated by specifying the range of characters (starting index and length) and the attribute(s) you want to use. A bit verbose yes, but that is Cocoa/Objective-C for you. The AppleScript Editor in Mavericks converts the older style selectors that use underscores into the newer style that more closely matches the Objective-C method selectors, but either should work in an Xcode project.


As for the unrecognized function, that sounds like the property is not connected to the text field. In my last example, which was a conversion of your original code to highlight the last name, textField is an Interface Builder outlet property that is connected to the text field you are using. Just to double-check, I pasted the example into a test project and it highlights "Bird" in red, using bold and italics. If you are not getting the font traits, you can try setting the text field to allow Rich Text, but I didn't have any issues with the default text field dragged in from the object library.


If you are still having issues, post back with the code you are using and any error messages.




MacBook Pro / OS X Mavericks (10.9.3) / Xcode 5.1.1 / RubyMotion FTW

Jul 21, 2014 7:43 PM in response to Frinton Fogey

Working with ideas from red_menace and using a search routine in Applescript I found at http://applescript.bratis-lover.net/library/string/ I cobbled together this as a test bed for you to try out some ideas.

Basically the important parts are on searchText(itemToSearchFor, stringToSearch,colorToSet) and on findAll(str, findString)

you call searchText with the string to search for, the string to search and the color (as an NSColor) you want the matches colored. It returns an attributed string with the matches colored. The search is case sensitve but that could be easily changed.

If no match is found the original string is returned.

This test bed has tge sting to search hard coded in. You enter the search term in a text filed in the applications window.


Thank's to red_menace for pointing out the attributed string. This wasn't as bad to do as I first thought (finding the search rountine really helped speed things up) and adding it to your code should not require to many changes.


regards


Complete project at:

https://www.dropbox.com/sh/2oolboxo1ckhyut/AAALgW5dwh2ji1BcBiwCQ-6Sa




--

-- TMAppDelegate.applescript

-- testMAt

--

-- Created by Frank Caggiano on 7/17/14.

-- Copyright (c) 2014 Frank Caggiano. All rights reserved.

--


script TMAppDelegate


propertyparent : class"NSObject"



-- IBOutlets

property window : missing value

property searchField : missing value

property textField : missing value

property noMatch : missing value


property ss : "04/07/2014 Mrs Brenda Bird 27 Somewhere Street Somewhere Town"


on applicationWillFinishLaunching_(aNotification)


-- Insert code here to initialize your application before any files are opened

textField's setStringValue:ss

noMatch's setHidden:true

end applicationWillFinishLaunching_


on applicationShouldTerminate_(sender)


-- Insert code here to do any housekeeping before your application quits

return current application's NSTerminateNow

end applicationShouldTerminate_


on applicationShouldTerminateAfterLastWindowClosed_(sender)

returntrue

end applicationShouldTerminateAfterLastWindowClosed_


on buttonClicked_(sender)

noMatch's setHidden:true

set searchForItem to searchField's stringValue() as text

set displayString to searchText(searchForItem, ss, current application's NSColor's redColor)

textField's setAttributedStringValue:displayString

end buttonClicked_



on searchText(itemToSearchFor, stringToSearch,colorToSet)

set lenOfSearch to count of itemToSearchFor

--set searchItem to "04/07/2014 Mrs Brenda Bird 27 Somewhere Street Somewhere Town"

set foundPositions to findAll(stringToSearch, itemToSearchFor)

if foundPositions is {} then

noMatch's setHidden:false

return stringToSearch

end if

set attributedSearchItem to current application's NSMutableAttributedString's alloc's initWithString:stringToSearch

repeat with i in foundPositions

set attributeRange to {i - 1 , lenOfSearch}

attributedSearchItem's addAttribute:(current application's NSForegroundColorAttributeName) value: colorToSet range:attributeRange

end

return attributedSearchItem

end searchText_


--

-- Wonderful search rountine found at the URL listed

--

on findAll(str, findString)

-- ljr (http://applescript.bratis-lover.net/library/string/)

local ASTID, str, findString, tmp, len, len2, pos, res

set ASTID to AppleScript's text item delimiters

try

set AppleScript's text item delimiters to findString

if str does not contain findString then return {}

consideringcase

script k

property res : {}

property tmp : str's text items


endscript


endconsidering

set len to count k's tmp

set len2 to count findString

set pos to 0


repeatwith i from1to len - 1

set thisPos to (count k's tmp's item i)

set thisPos to thisPos + pos

set pos to thisPos + len2

set end of k's res to (thisPos + 1)


endrepeat

set AppleScript's text item delimiters to ASTID

return k's res

on error eMsg number eNum

set AppleScript's text item delimiters to ASTID

error "Can't findAll: " & eMsg number eNum

end try

end findAll



endscript

Is it possible to set the colour of text with Applescript

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.