Change color of character in selection

Hi there,

I found this script to set the color of characters that works in Pages 09 and Pages 5.

tell application "Pages"
	activate
	tell the front document
		tell body text
			set the color of ¬
				(every character of every paragraph where it is "U") to {37890, 0, 35421}
		end tell
	end tell
end tell

In Pages: how can I set the color of one or several characters of selected text? E.g., set all hyphens in selected text mhjk----frgz—g-hj------qw-r to color orange?

Thanks for your help.

Here is an awful script which does the job in Pages 5.x.
It assumes that TextEdit default to rtf format.

set colorRed to {64638, 4079, 6844}

tell application "Pages"
	activate
end tell
tell application "System Events" to tell process "Pages"
	set frontmost to true
	set mt to 10
	tell menu bar 1 to tell menu bar item mt to tell menu 1
		set theMenuItems to reverse of (get name of menu items)
	end tell
	set theDocsNames to {}
	repeat with anItem in theMenuItems
		if class of anItem is not text then exit repeat # exit when we found missing value
		copy contents of anItem to end of theDocsNames
	end repeat
	
	if (count theDocsNames) = 1 then
		set theOrigName to item 1 of theDocsNames as text
	else
		tell menu bar 1 to tell menu bar item mt to tell menu 1
			repeat with aName in theDocsNames
				if value of attribute "AXMenuItemMarkChar" of menu item aName = "✓" then
					set theOrigName to aName as text
					exit repeat
				end if
			end repeat
		end tell
	end if
	keystroke "c" using {command down} # Grabs the selected text
end tell

tell application "TextEdit"
	set newDoc to make new document
end tell

tell application "System Events" to tell process "TextEdit"
	set frontmost to true
	keystroke "v" using {command down} # Paste it in TextEdit document
end tell

tell application "TextEdit"
	activate
	tell newDoc
		tell its text
			set the color of (every character where it is "-") to colorRed
		end tell
	end tell
end tell
tell application "System Events" to tell process "TextEdit"
	set frontmost to true
	keystroke "a" using {command down}
	keystroke "c" using {command down} # Grab the text modified text
end tell

set {mt, mi} to {10, theOrigName}
tell application "System Events" to tell process "Pages"
	set frontmost to true
	tell menu bar 1 to tell menu bar item mt to ¬
		tell menu 1 to click menu item mi # Brings the original document to front
	
	keystroke "v" using {command down} # Paste the modified text
end tell

tell application "TextEdit"
	close newDoc without saving # Drops the temp document
end tell

I don’t paste in a new Pages 5.x document because pasting creates a text box and I don’t know how to work with such object.

Edited to take care of possible difference between the document’s name and the name available in the windows menu.

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) lundi 16 mai 2016 19:08:47

For Pages 09 I found a simpler scheme using a loop.

set colorRed to {64638, 4079, 6844}

tell application "Pages 09"
	tell document 1
		set begSel to character offset of (get properties of the selection)
		set selectedText to contents of the selection
		set offsetsFound to {}
		repeat with i from 1 to count selectedText
			if text item i of selectedText is "-" then set end of offsetsFound to i
		end repeat
		if offsetsFound is not {} then
			tell body text
				repeat with i in offsetsFound
					set color of character (begSel - 1 + i) to colorRed
				end repeat
			end tell
		end if
	end tell
end tell

Yvan KOENIG running El Capitan 10.11.5 in French (VALLAURIS, France) mardi 17 mai 2016 12:30:36

Hi Yvan,

thanks again for your fantastic help.

I tried your first script with Pages 5. On my computer with El Capitan and Pages 5 and Pages 09 I get the red character in TextEdit but it doesn’t copy to Pages.
Your second script from today is so great. It works very nice with Pages 09. I had to change tell application “Pages 09” to “Pages”.

Thanks so much for your help.

set colorRed to {64638, 4079, 6844}

tell application "Pages"
   tell document 1
       set begSel to character offset of (get properties of the selection)
       set selectedText to contents of the selection
       set offsetsFound to {}
       repeat with i from 1 to count selectedText
           if text item i of selectedText is "-" then set end of offsetsFound to i
       end repeat
       if offsetsFound is not {} then
           tell body text
               repeat with i in offsetsFound
                   set color of character (begSel - 1 + i) to colorRed
               end repeat
           end tell
       end if
   end tell
end tell

Thanks for the feedback.
Right, I forgot to edit the name of the application which I customized when iPlay’13 was delivered so that it was quite easy to make the difference between applications from iWork '09 and games from iPlay '13.

About the script dedicated to Pages 5, I have a track.
Most of the time the name of the Pages document in the window’s title bar and the name available in the Window menu are the same but if the Pages document was created using cmd + shift + S they may be different.

I edited the script above to take care of that.

Here is an all in a single script version.

(*
Put hyphens in red in the selection in Pages body text.
Forces the temporary TextEdit document to Rtf if needed.

KOENIG Yvan
VALLAURIS, France
2016/05/17
*)

set theColor to {64638, 4079, 6844} # Here it's red
set charToChange to "-"

tell application id "com.apple.iWork.Pages"
	activate
	set theVersion to version
end tell

if theVersion starts with "5" then
	# Here if Pages 5.x
	tell application "System Events" to tell process "Pages"
		set frontmost to true
		set mt to 10 # CAUTION. If we have to trigger the menu in Pages '09, mt would be 9 !
		# Grab the reversed list of menu items in the menu Window.
		tell menu bar 1 to tell menu bar item mt to tell menu 1
			set theMenuItems to reverse of (get name of menu items)
		end tell
		# Build the list of menu items pointing to an open document
		set theDocsNames to {}
		repeat with anItem in theMenuItems
			if class of anItem is not text then exit repeat # exit when we found missing value
			copy contents of anItem to end of theDocsNames
		end repeat
		
		if (count theDocsNames) = 1 then
			# There is a single document, no need to use a loop
			set theOrigName to item 1 of theDocsNames as text
		else
			tell menu bar 1 to tell menu bar item mt to tell menu 1
				repeat with aName in theDocsNames
					if value of attribute "AXMenuItemMarkChar" of menu item aName = "✓" then exit repeat
				end repeat
				set theOrigName to aName as text # It's the name of the active document
			end tell
		end if
		
		keystroke "c" using {command down} # Grabs the selected text
	end tell
	
	tell application "TextEdit"
		set newDoc to make new document
	end tell
	
	tell application "System Events" to tell process "TextEdit"
		set frontmost to true
		tell menu bar 1 to tell menu bar item 5 to tell menu 1 to tell menu item -1
			set isRtfMode to enabled is true # Test last item of menu Format
		end tell
		if not isRtfMode then keystroke "t" using {command down, shift down} # Force mode Rtf
		keystroke "v" using {command down} # Paste it in TextEdit Rtf document
	end tell
	
	tell application "TextEdit" to tell newDoc to tell its text
		set (color of every character where it is charToChange) to theColor
	end tell
	tell application "System Events" to tell process "TextEdit"
		set frontmost to true
		keystroke "a" using {command down} # Select All
		keystroke "c" using {command down} # Grabs the modified text
	end tell
	
	tell application "System Events" to tell process "Pages"
		set frontmost to true
		tell menu bar 1 to tell menu bar item mt to tell menu 1
			click menu item theOrigName # Brings the original document to front
		end tell
		keystroke "v" using {command down} # Paste the modified text
	end tell
	
	tell application "TextEdit"
		close newDoc without saving # Drops the temp document
	end tell
	
else if theVersion starts with "4" then
	# Here if Pages '09
	# Replaced YK's code by Nigel Garvey's one posted at http://macscripter.net/viewtopic.php?id=44895
	tell application id "com.apple.iWork.Pages"
		tell front document
			set theSelection to the selection
			-- If only one chunk of text is selected, put the reference in a list for convenience.
			if (theSelection's class is text) then set theSelection to {theSelection}
			-- Deal with each chunk in turn.
			repeat with thisChunk in theSelection
				set (color of characters of thisChunk where it is charToChange) to theColor
			end repeat
		end tell
	end tell
else
	error "Pages version : " & theVersion & " isn't supported !"
end if

Yvan KOENIG running El Capitan 10.11.5 in French (VALLAURIS, France) mardi 17 mai 2016 15:53:26

CAUTION

Pages '09 accept a selection made of non continuous blocks, but the given script is unable to treat such case.

When the selection is not continuous, when AppleScript grabs its properties, it returns something like :

{property list item:0.0, class:{text, text}, contents:{“TextEdit’s scripting dictionary doesn’t offer a sel”, “Open this Scriplet in your Editor”}}

As you may see, there is no property named character offset.

Yvan KOENIG running El Capitan 10.11.5 in French (VALLAURIS, France) mercredi 18 mai 2016 11:04:25

Hi.

For what it’s worth, I’ve had some success with this in Pages '09:

set orange to {65535, 32896, 0}
set toBeRecoloured to "-"

-- This assumes that the front document cursor's in body text.
tell application "Pages"
	tell front document
		set theSelection to the selection
		-- If only one chunk of text is selected, put the reference in a list for convenience.
		if (theSelection's class is text) then set theSelection to {theSelection}
		-- Deal with each chunk in turn.
		repeat with i from 1 to (count theSelection)
			set thisChunk to item i of theSelection
			set (color of characters of thisChunk where it is toBeRecoloured) to orange
		end repeat
	end tell
end tell

When I tried this a couple of days ago, I kept getting a spinning beach ball. I suspect it may have been connected with the Versions autosave system, but I don’t know. Anyway, it’s been working here perfectly so far today.

Thank you Nigel and Ivan, that works perfectly for me.

Thanks Nigel.
I edited the combined script with your code.

Yvan KOENIG running El Capitan 10.11.5 in French (VALLAURIS, France) mercredi 18 mai 2016 19:43:51