Change words' color in Pages meeting certain conditions with AppleScript. Words include arithmetic signs

I am writing a programming materials. I would like to highlight some keywords in it meeting certain conditions.


Code block:

int x = 10;
int x = (int) d;
// int, double, float, ...


Would like to change a color of word "int" and equal sign (=), provided that word "int" is followed by a space or is surrounded by brackets. So in line 3 there is no need to change color.


In the case of brackets only the word "int" should change color, not brackets.


The following script does not change the color of any character:

set wordList to {"int ", "=", "<="} 

set theColor to {0, 51 * 257, 179 * 257}

tell application "Pages"
	tell body text of front document
		repeat with aword in wordList
			set color of (words where it is aword) to theColor
		end repeat
	end tell
end tell
```


Is it possible to do the task with AppleScript? Thanks a lot for your help.


2) And a second related question. Is this possible to pass a color in HEX?


set theColor to (HEX)


[Re-Titled by Moderator]

Mac mini

Posted on Apr 14, 2025 9:56 AM

Reply
Question marked as ⚠️ Top-ranking reply

Posted on Apr 14, 2025 12:59 PM

Oh boy, you picked a doozy :)


At first glance, your script doesn't work because of the definition of a 'word' in Pages (well, in AppleScript in general).


Notably, if you ask for 'words of' the document, you get:


{"int", "x", "10", "int", "x", "int", "d", "int", "double", "float"}


Compare that to your wordList and you'll see the first problem:


set wordList to {"int ", "=", "<="}


By definition, 'words' in AppleScript are alphanumeric, do not include spaces, punctuation or other symbols, so you're first checking for 'int ' (note the trailing space), which will never match AppleScript's definition of a 'word' which will always drop the trailing space.

You could change wordList to include 'int' rather than 'int ', but even then you're not out of the woods, because AppleScript's 'words' do not include "=", "<=", etc., so these are excluded.


(side note: there is a little known/used considering/ignoring clause where you can tell AppleScript to consider or ignore white space, diacriticals, and other modifiers, but it still doesn't apply here).


It gets worse, though. Even assuming you could get Numbers to break down the text into space-delimited chunks, the code:


			set color of (words where it is aword) to theColor


is doomed to failure. That's because words where it is aword will return something like:


{"int", "int", "int", "int"}


because those are the literal words that match your search term - you asked for 'words where it is 'int", and that's what you get. There's no reference back to the document at that point, so Numbers has no way to change the text's color.


So, what it comes down to is that Numbers really isn't geared to make this kind of change for you. It is possible to do, but only by walking through the document.


Here's a revision to your script that 'walks' the characters and determines which 'words' to change color:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- 'words' to change color
set wordList to {"int", "=", "<="}

set theColor to {0, 51 * 257, 179 * 257}

-- tokens that break words
set symbolTokens to {" ", ";", return, "(", ")", ","}

tell application "Pages"
	-- get the body text
	tell body text of front document
		-- get all the characters
		set allChars to its characters
		-- start at the beginning
		set startChar to 1
		--iteratate through the characters		
		repeat with i from 1 to count allChars
			-- do we have a word break?
			if item i of allChars is in symbolTokens then
				-- determine the word we have just found
				set checkWord to (characters startChar through (i - 1)) as text
				-- is it one of our keywords?
				if checkWord is in wordList then
					-- then change it
					set color of characters startChar through (i - 1) to theColor
				end if
				-- and move on
				set startChar to i + 1
			end if
		end repeat
	end tell
end tell


You can see the lists at the beginning which identify the words to colorize, as well as the characters that indicate a word break. Amend these as you like.


Additionally challenges I can foresee include comments (different color?), and there are probably others.


> 2) And a second related question. Is this possible to pass a color in HEX?


Sure, but only if you do the decoding of hex to decimal :)


Pages (and AppleScript) define a color as a RGB triplet of three values 0..65535, so if you want to define the color as a Hex triplet (e.g. 0xFFBB00) then you'll have to do the conversion before you pass it to Pages.

16 replies
Sort By: 
Question marked as ⚠️ Top-ranking reply

Apr 14, 2025 12:59 PM in response to кирилл278

Oh boy, you picked a doozy :)


At first glance, your script doesn't work because of the definition of a 'word' in Pages (well, in AppleScript in general).


Notably, if you ask for 'words of' the document, you get:


{"int", "x", "10", "int", "x", "int", "d", "int", "double", "float"}


Compare that to your wordList and you'll see the first problem:


set wordList to {"int ", "=", "<="}


By definition, 'words' in AppleScript are alphanumeric, do not include spaces, punctuation or other symbols, so you're first checking for 'int ' (note the trailing space), which will never match AppleScript's definition of a 'word' which will always drop the trailing space.

You could change wordList to include 'int' rather than 'int ', but even then you're not out of the woods, because AppleScript's 'words' do not include "=", "<=", etc., so these are excluded.


(side note: there is a little known/used considering/ignoring clause where you can tell AppleScript to consider or ignore white space, diacriticals, and other modifiers, but it still doesn't apply here).


It gets worse, though. Even assuming you could get Numbers to break down the text into space-delimited chunks, the code:


			set color of (words where it is aword) to theColor


is doomed to failure. That's because words where it is aword will return something like:


{"int", "int", "int", "int"}


because those are the literal words that match your search term - you asked for 'words where it is 'int", and that's what you get. There's no reference back to the document at that point, so Numbers has no way to change the text's color.


So, what it comes down to is that Numbers really isn't geared to make this kind of change for you. It is possible to do, but only by walking through the document.


Here's a revision to your script that 'walks' the characters and determines which 'words' to change color:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- 'words' to change color
set wordList to {"int", "=", "<="}

set theColor to {0, 51 * 257, 179 * 257}

-- tokens that break words
set symbolTokens to {" ", ";", return, "(", ")", ","}

tell application "Pages"
	-- get the body text
	tell body text of front document
		-- get all the characters
		set allChars to its characters
		-- start at the beginning
		set startChar to 1
		--iteratate through the characters		
		repeat with i from 1 to count allChars
			-- do we have a word break?
			if item i of allChars is in symbolTokens then
				-- determine the word we have just found
				set checkWord to (characters startChar through (i - 1)) as text
				-- is it one of our keywords?
				if checkWord is in wordList then
					-- then change it
					set color of characters startChar through (i - 1) to theColor
				end if
				-- and move on
				set startChar to i + 1
			end if
		end repeat
	end tell
end tell


You can see the lists at the beginning which identify the words to colorize, as well as the characters that indicate a word break. Amend these as you like.


Additionally challenges I can foresee include comments (different color?), and there are probably others.


> 2) And a second related question. Is this possible to pass a color in HEX?


Sure, but only if you do the decoding of hex to decimal :)


Pages (and AppleScript) define a color as a RGB triplet of three values 0..65535, so if you want to define the color as a Hex triplet (e.g. 0xFFBB00) then you'll have to do the conversion before you pass it to Pages.

Reply

Apr 15, 2025 11:56 AM in response to кирилл278

Reading a little further into your question...


> there is no need to change the color of the sign in comments that have grey color.


I'd probably take a slightly different approach and check for the comments start '//' and change everything up to the next return. Here's a revised script that does that:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set commentColor to {140 * 256, 140 * 256, 140 * 256}

-- 'words' to change color
set wordList to {"int", "=", "<="}

set theColor to {0, 51 * 257, 179 * 257}

-- tokens that break words
set symbolTokens to {" ", ";", return, linefeed, "(", ")", ","}

tell application "Pages"
	-- get the body text
	tell body text of front document
		-- get all the characters
		set allChars to its characters
		-- start at the beginning
		set startChar to 1
		--iteratate through the characters		
		repeat with i from 1 to count allChars
			-- do we have a word break?
			if item i of allChars is in symbolTokens then
				-- determine the word we have just found
				set checkWord to (characters startChar through (i - 1)) as text
				-- is this a comment marker"
				if checkWord is "//" then
					-- we have a comment marker, so find the end of line
					repeat until item i of allChars is in {linefeed, return}
						set i to i + 1
					end repeat
					-- and set this text to the comment color
					set color of characters startChar through (i - 1) to commentColor
				else
					-- is it one of our keywords?
					if checkWord is in wordList then
						-- then change it
						set color of characters startChar through (i - 1) to theColor
					end if
					-- and move on
				end if
				set startChar to i + 1
			end if
		end repeat
	end tell
end tell


Note this doesn't necessarily handle block comments that span multiple lines, but an additional check could be added for whatever that marker is (e.g. "/*") up to its corresponding end marker (e.g. "*/")

Reply

Apr 18, 2025 11:37 AM in response to кирилл278

You're absolutely right - I guess I don't spend enough time colorizing text in Pages :)

I'd never noticed the RGB sliders are limited to the 0..255 range. Probably because a 2" slider covering 0...65535 would be too much? :)


This is kind of borne out by the (...)alongside the color space menu, which gives you options for how to specify the color, as well as the color profile to use - options include 8-bit and floating point.



Floating point gives you 3 decimal places to point to, which is 1,000 options. Still far less than the actual internal representation.


Ultimately, while Pages does offer a number of ways to choose a color (RGB, CMYK, HLB, etc.), that's just the interface... internally, the color is stored as quad 64-bit floating point values (RGBA), and RGB16 is how AppleScript deals with it. If you're using AppleScript, you kinda have to play by it's rules :)


At least now you know how to use AppleScript to find out what RGB16 value Pages is using.

Reply

Apr 14, 2025 12:26 PM in response to VikingOSX

Pages is a word-processing application, not a programmer's editor, and syntax awareness and color scheme coding are not within its purpose.


The AppleScript scripting dictionary that supports Pages does not treat mathematical operators in body text as words. Since they are not addressable as words or text items (if using text item delimiters), you have no means to colorize them in the body text unless painstakingly doing so manually with the color chooser.


This code works. Note that I have changed "int " to "int" because the former is not a word either. Now every occurrence of "int" is changed to RGB16 {0, 13107, 46003} or darker blue. The AppleScript color chooser returns RGB16 colors only, and one cannot convert from hex to RGB or hex to RGB16 without writing a conversion routine.


use scripting additions

set wordList to {"int", "=", "<="}

set theColor to {0, 51 * 257, 179 * 257}

tell application "Pages"
	activate
	tell body text of front document
		repeat with aword in wordList
			set color of (its words where it is aword) to theColor
		end repeat
	end tell
end tell





Reply

Apr 15, 2025 10:47 AM in response to кирилл278

> Is it possible to define in AppleScript the style of the paragraph in which the word is located? For example, the style of the paragraph called "Code block".


Unfortunately not.


In theory, to do what you ask shouldn't be too hard. A simple amendment to first extract the paragraphs of the document (rather than the entire character list of the body text) will give you sufficient context (i.e. you know the paragraph you're working on), so you should be able to iterate each paragraph in turn rather than than the entire document at once.


Where it falls short, though, is that Pages has zero support for Styles in its AppleScript dictionary. You can neither get nor set the paragraph style applied to a specific piece of text. I admit I was surprised when I found this, but it's not in the dictionary, and therefore out of reach.

Reply

Apr 15, 2025 11:32 AM in response to кирилл278

> I understand that "color of ..." is not a string. However can not find any information how to compare colors.


Colors are defined as a triple of integers 0..65535 representing Red, Blue and Green.


For example, solid red would be:


set colorRed to {65535,0,0}


and a shade of brown might be:


set colorBrown to {32888,28672,16384}


where each integer represents the amount of red, green and blue to mix, in order.


So to do what you want, you first have to find the RGB values for the color you're looking for, and the color you want to set, then the rest is easy:


set searchColor to {59149, 6, 3483} -- Pages standard red
set destColor to {35980, 28672, 16384} -- yummy brown

tell application "Pages"
	tell body text of document 1
		repeat with i from 1 to (count characters)
			if c is searchColor then
				set color of character i to destColor
			end if
		end repeat
	end tell
end tell


> Also I can not find how to print information in console of ScriptEditor.


What do you mean by 'print information in console'? Do you mean logging? If so, just use the log command:


...
		repeat with i from 1 to (count characters)
			set c to color of character i
			log "Got character '" & character i & "', and its color is R:" & (item 1 of c) & ", G:" & (item 2 of c) & ", B:" & (item 3 of c)
			if color of character i is searchColor then
				set color of character i to destColor
			end if
		end repeat


and use Script Editor's Window -> Log History to view.

Reply

Apr 18, 2025 1:36 AM in response to Camelot

I see. :) As I am not an actual user of AppleScript, I started using it a week ago - so when I said "Pages" I meant the actual Pages app.


Example. I have document in Pages and I see colors from its Interface:


Now I want to use AppleScript for some operations with the text. To ignore all words in blocks of comments I decided to compare colors.


I look at my Pages document and see that the color of comments is RGB(140,140,140). AppleScript does not understand this value so it needs some manipulations to tell AppleScript what color needs to ignore.


After some testing in code were found that the color of RGB(140,140,140) defines by AppleScript as {31155, 31155, 31155}. Ok.


It would be comfortable if these last numbers {31155, 31155, 31155} could be obtained in Pages interface without testing in code.


In Pages interface there are lots of other systems if press 3 dots - 8-bit, floating point, CMYK, ... I do not see that any gives that numbers.

Reply

Apr 14, 2025 12:09 PM in response to кирилл278

The AppleScript scripting dictionary that supports Pages does not treat mathematical operators in body text as words. Since they are not addressable as words or text items (if using text item delimiters), you have no means to colorize them in the body text.


AppleScript uses 16-bit RGB colors (e.g. {0, 65535, 0} for blue). It does not support hex colors without a conversion routine from hex to RGB16 to do that for you.




Reply

Apr 15, 2025 6:04 AM in response to кирилл278

As I and Camelot have explained: arithmetic signs are not words in AppleScript context, so they would not get changed without the much more specialized code that Camelot has provided. I decided to not take the extra time to write an example character inspection code.

Reply

Apr 15, 2025 10:55 AM in response to Camelot

Camelot, good day! I went to color comparison in AppleScript. :)


If take an example of changing color for equal sign (=), there is no need to change the color of the sign in comments that have grey color. In the following script the color "commentGreyColor" is specified exactly as in the Pages document: RGB (140, 140, 140). However, color comparison does not define this and "color of character i" changes.


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set wordList to {"=", "."}

set theColor to "red"
set commentGreyColor to {140 * 257, 140 * 257, 140 * 257}

tell application "Pages"
	tell body text of front document
		set allChars to its characters
		repeat with i from 1 to count allChars
			if item i of allChars is in wordList then
				if color of character i is not commentGreyColor then 
					set color of character i to theColor
				end if
			end if
		end repeat
	end tell
end tell


Can not find any information how to compare colors.


Also I can not find how to print information in console of ScriptEditor.

Reply

Apr 17, 2025 3:18 AM in response to Camelot

Camelot, I see an "elephant" in a question of colors here. :)


If a script paints all text in yummy brown color:

set destColor to {35980, 28672, 16384} -- yummy brown


in Pages this color has RGB(158, 130, 81) and it is not easy to convert this back in exact. I tried several solutions and scripts, no one gives exact result, even Apple ColorSync does not.


So if in Pages a comment color is RGB(140, 140, 140), Display P3 and sRGB, then ColorSync gives {35980, 35980, 35980} RGB 16 bit, DisplayP3 and sRGB.


If paints a text with this color:


use AppleScript version "2.4" 
use scripting additions

set commentColor to {35980, 35980, 35980} 

tell application "Pages"
	tell body text of document 1
		repeat with i from 1 to (count characters)
			set color of character i to commentColor
		end repeat
	end tell
end tell


in Pages this color has RGB(158, 158, 158).


It would be helpful if there was a way to get the color in Pages in RGB 16-bit. However, I don't see it.


---


However, if log a color:


repeat with i from 1 to (count characters)
	set c to color of character i
	log "Got character '" & character i & "', and its color is R:" & (item 1 of c) & ", G:" & (item 2 of c) & ", B:" & (item 3 of c)
end repeat


then the color in Pages RGB (140, 140, 140) defined by AppleScript as {31155, 31155, 31155} and it gives an ability to manipulate inside comments, just an example:


set redPagesColor to {59149, 6, 3483} -- Pages standard red
set commentGreyColor to {31155, 31155, 31155} 

tell application "Pages"
	tell body text of document 1
		repeat with i from 1 to (count characters)
			set c to color of character i
			if c is commentGreyColor then
				set color of character i to redPagesColor
			end if
		end repeat
	end tell
end tell


Thanks! 🙂

Reply

Apr 17, 2025 11:35 AM in response to кирилл278

I think the whole color system is a bit of a mess, thanks to numerous different 'standards' that have evolved over time, and inconsistencies as to which model to use, when.


I do think it's gotten better over time, and recent OS versions have generally migrated to using a NSColor object with inherent Alpha channel and automatic conversion between formats, but to use that in AppleScript giving into AppleScript ObjC, which is a whole other level of complexity for what should be a simple task.


That said...


> in Pages this color has RGB(158, 158, 158).

> It would be helpful if there was a way to get the color in Pages in RGB 16-bit. However, I don't see it.


I don't understand this. Pages always seems to use 16-bit for me:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "Pages"
	tell document 1
		tell body text
			color of item 1 of its characters
		end tell
	end tell
end tell

--> {59149, 6, 3483}


Unless the value you're getting back is in 16-bit - 158 looks the same in 8-bit and 16-bit, and means you're using slightly off-black rather than true black {0,0,0} color.

Reply

Change words' color in Pages meeting certain conditions with AppleScript. Words include arithmetic signs

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