How do you format text between search char - translate VB to Applescri

I am new to apple scripting and have not been able to figure out how I can search for all characters between quotations, or parenthesis. e.g. “text” or (text) - and then format the text, for example, make it bold and uppercase.

I’ve accomplished this in Microsoft word Macro VB - and here is the code. Can anyone translate this into applescript?

sub setbolduppercase

Application.ScreenUpdating = False
Dim Rng As Range
Set Rng = Selection.Range
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = “(?)”
.Replacement.Text = “”
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = True
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
End With
Do While .Find.Found
.Select
With Selection
.EndKey Unit:=wdLine, Extend:=wdExtend
'MsgBox .Text
.EndKey
.Font.AllCaps = True
.Font.Bold = True

  '.Font.Color = RGB(0, 0, 0)
End With
.End = Selection.End
.Collapse wdCollapseEnd
.Find.Execute

Loop
End With
Rng.Select
Set Rng = Nothing
Application.ScreenUpdating = True

end sub

Hi dlaurentny,

Are you searching for the text in a certain application?

gl,
kel

He’s reiterating this unanswered post.

The original question was about Pages. Alas it didn’t said which version so I assume that it’s the late one : 5.2

In this toy Applescript can’t get/set style of text.
If a piece of text is set to Italic thru cmd + i, it’s given an italic font, for instance TrebuchetMS-Italic
If a piece of text is set to italic using the clean way ” applying the style Italic ” AppleScript can’t tell us that and returns only the fact that the font in use is also TrebuchetMS-Italic.

So, with this version we can’t do clean job which means : apply a style.
We may just change the font from TrebuchetMS to TrebuchetMS-Italic or TrebuchetMS-Bold

I really dislike this way to set font attributes but as we have no alternative, here is a draft doing that.

tell application "Pages" to tell document 1
	set bodyText to body text
	# Set text enclosed between straight double quotes ” named quotes by AppleScript ” in "TrebuchetMS-Italic"
	set enListe to my decoupe(bodyText, quote)
	if (count enListe) > 1 then
		set off7 to 0
		repeat with j from 2 to count enListe by 2
			set off7 to off7 + (count item (j - 1) of enListe) + 2
			set off7end to off7 + (count item j of enListe) - 1
			set font of characters off7 thru off7end of body text to "TrebuchetMS-Italic"
			set off7 to off7end + 1
		end repeat
	end if
	# Set text enclosed between parentheses in "TrebuchetMS-Bold"
	# This piece of code may be used if the text to set in italic is enclosed between localized quotes
	# like "curly" ones or « chevrons » used in French.
	set enListe to my decoupe(bodyText, "(")
	if (count enListe) > 1 then
		set off7 to (count item 1 of enListe) + 2
		repeat with j from 2 to count enListe
			set off7end to off7 + (offset of ")" in enListe's item j) - 2
			set font of characters off7 thru off7end of body text to "TrebuchetMS-Bold"
			set off7 to off7 + (count item j of enListe) + 1
		end repeat
	end if
end tell

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

Yvan KOENIG (VALLAURIS, France) dimanche 20 juillet 2014 16:18:15

Thanks Yvan - I was unavailable last week, I am getting some errors and playing with it. I will post my findings soon

What kind of error ?
Here, with a document whose text was the main body text, I ran the script with no real problem.

I made a single change to get rid of non fatal error issued when calling offset ( I forgot that it’s a function from the OSAX Standard Additions ) inside a tell application “Pages” block.

set off7end to off7 + (offset of ")" in enListe's item j) - 2

becomes

tell me to set off7end to off7 + (offset of ")" in enListe's item j) - 2

With this single change, the event log was :

tell application "Pages"
	get body text of document 1
		--> "
2014-07-18 06:21:41 pm
I am new to apple scripting and have not been able to figure out how I can search for all characters between quotations, or parenthesis.  e.g. \"text\" or (text) - and then format the text, for example, make it bold and uppercase.¨¨¨I've accomplished this in Microsoft word Macro VB - and here is the code.  Can anyone translate this into applescript?¨¨>>>¨sub setbolduppercase¨¨Application.ScreenUpdating = False¨(Dim Rng As Range)¨Set Rng = Selection.Range¨With ActiveDocument.Range¨  With .Find¨    .ClearFormatting¨    .Replacement.ClearFormatting¨    .Text = \"(?)\"¨    .Replacement.Text = \"\"¨    .Forward = True¨    .Wrap = wdFindStop¨    .Format = False¨    .MatchCase = False¨    .MatchWholeWord = False¨    .MatchWildcards = True¨    .MatchSoundsLike = False¨    .MatchAllWordForms = False¨    .Execute¨  End With
\" enclosed with quotes \"¨  Do While .Find.Found¨    .Select¨    With Selection¨      .EndKey Unit:=wdLine, Extend:=wdExtend¨      'MsgBox .Text¨      .EndKey¨      .Font.AllCaps = True¨      .Font.Bold = True¨      ¨      '.Font.Color = RGB(0, 0, 0)¨    End With¨    .End = Selection.End¨    .Collapse wdCollapseEnd¨    .Find.Execute¨  Loop¨End With
\" One more text enclosed with quotes \"¨Rng.Select¨Set Rng = Nothing¨Application.ScreenUpdating = True¨¨end sub"
	set font of characters 169 thru 172 of body text of document 1 to "TrebuchetMS-Italic"
	set font of characters 588 thru 590 of body text of document 1 to "TrebuchetMS-Italic"
	set font of characters 618 thru 617 of body text of document 1 to "TrebuchetMS-Italic"
	set font of characters 846 thru 867 of body text of document 1 to "TrebuchetMS-Italic"
	set font of characters 1196 thru 1231 of body text of document 1 to "TrebuchetMS-Italic"
end tell
tell current application
	offset of ")" in "text) - and then format the text, for example, make it bold and uppercase.¨¨¨I've accomplished this in Microsoft word Macro VB - and here is the code.  Can anyone translate this into applescript?¨¨>>>¨sub setbolduppercase¨¨Application.ScreenUpdating = False¨"
		--> 5
end tell
tell application "Pages"
	set font of characters 179 thru 182 of body text of document 1 to "TrebuchetMS-Bold"
end tell
tell current application
	offset of ")" in "Dim Rng As Range)¨Set Rng = Selection.Range¨With ActiveDocument.Range¨  With .Find¨    .ClearFormatting¨    .Replacement.ClearFormatting¨    .Text = \""
		--> 17
end tell
tell application "Pages"
	set font of characters 438 thru 453 of body text of document 1 to "TrebuchetMS-Bold"
end tell
tell current application
	offset of ")" in "?)\"¨    .Replacement.Text = \"\"¨    .Forward = True¨    .Wrap = wdFindStop¨    .Format = False¨    .MatchCase = False¨    .MatchWholeWord = False¨    .MatchWildcards = True¨    .MatchSoundsLike = False¨    .MatchAllWordForms = False¨    .Execute¨  End With
\" enclosed with quotes \"¨  Do While .Find.Found¨    .Select¨    With Selection¨      .EndKey Unit:=wdLine, Extend:=wdExtend¨      'MsgBox .Text¨      .EndKey¨      .Font.AllCaps = True¨      .Font.Bold = True¨      ¨      '.Font.Color = RGB"
		--> 2
end tell
tell application "Pages"
	set font of characters 589 thru 589 of body text of document 1 to "TrebuchetMS-Bold"
end tell
tell current application
	offset of ")" in "0, 0, 0)¨    End With¨    .End = Selection.End¨    .Collapse wdCollapseEnd¨    .Find.Execute¨  Loop¨End With
\" One more text enclosed with quotes \"¨Rng.Select¨Set Rng = Nothing¨Application.ScreenUpdating = True¨¨end sub"
		--> 8
end tell
tell application "Pages"
	set font of characters 1086 thru 1092 of body text of document 1 to "TrebuchetMS-Bold"
end tell
Résultat :
1306

Yvan KOENIG (VALLAURIS, France) mardi 29 juillet 2014 19:33:46

I forgot to say that the treated text was the content of your original message plus two strings enclosed in quotes.

Of course, I’m not sure that the font Trebuchet is available on your machine (if I remember well it was delivered with the original Pages '09).

Maybe using Helvetica-Bold and Helvetica-Oblique would have be a better choice but I was not sure that the name is Helvetica-Oblique everywhere (I was afraid that it may be spelled Helvetica-Italic).

Here is a modified version of the script you sent to me. The oriingal error is because I have no body text I am in layout mode. I have at least 10 to 12 Text Box in this pages document, but for some reason, in this code, it’s only formatting the first 4. ??? I can email you actual pages doc if you want to take a look to duplicate error.

tell application "Pages"
	tell the front document
		set allTextItems to every text item
		
		repeat with c from 1 to the count of allTextItems
			set thisTextItem to item c of allTextItems
			
			set bodyText to the object text of thisTextItem
			
			tell thisTextItem
				tell its object text
					# set bodyText to sector headlines
					# Set text enclosed between straight double quotes ” named quotes by AppleScript ” in "TrebuchetMS-Italic"
					set enListe to my decoupe(bodyText, quote)
					if (count enListe) > 1 then
						set off7 to 0
						repeat with j from 2 to count enListe by 2
							set off7 to off7 + (count item (j - 1) of enListe) + 2
							set off7end to off7 + (count item j of enListe) - 1
							
							set (font of characters off7 thru off7end) to "Helvetica-Oblique"
							
							set off7 to off7end + 1
						end repeat
					end if
					# Set text enclosed between parentheses in "TrebuchetMS-Bold"
					# This piece of code may be used if the text to set in italic is enclosed between localized quotes
					# like "curly" ones or « chevrons » used in French.
					set enListe to my decoupe(bodyText, "(")
					if (count enListe) > 1 then
						set off7 to (count item 1 of enListe) + 2
						repeat with j from 2 to count enListe
							set off7end to off7 + (offset of ")" in enListe's item j) - 2
							
							set (font of characters off7 thru off7end) to "Helvetica-Bold"
							set (color of characters off7 thru off7end) to "green"
							
							set off7 to off7 + (count item j of enListe) + 1
						end repeat
					end if
				end tell
			end tell
		end repeat
	end tell
end tell

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#===== 

I applied your edited script to a document with 12 text boxes with a perfect result.

My address is :
koenig yvan @ sfr fr

Here is a version applying to text boxes and body text.
It also treat text enclosed between French chevrons and offer a scheme to convert them to UPPERcase using Shane STANLEY’s ASObjC Runner. Of course we may choose to use a Maverick’s library to achieve the same goal.

tell application "Pages"
	tell front document
		set allTextItems to every text item
		if allTextItems is not {} then
			repeat with thisTextItem in allTextItems
				my handleIt(a reference to object text of thisTextItem)
			end repeat
		end if
		if document body then
			my handleIt(a reference to body text)
		end if
	end tell # front document
end tell # Pages

#=====

on handleIt(target_object)
	tell application "Pages" to tell document 1
		tell target_object
			set body_text to its contents
			# Set text enclosed between parentheses in "Helvetica-Bold"
			set enListe to my decoupe(body_text, "(")
			if (count enListe) > 1 then
				set off7 to (count item 1 of enListe) + 2
				repeat with j from 2 to count enListe
					tell me to set off7end to off7 + (offset of ")" in enListe's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-Bold"
					set (color of characters off7 thru off7end) to "green"
					
					set off7 to off7 + (count item j of enListe) + 1
				end repeat
			end if
			
			# Use quite the same code to treat text enclosed into French chevrons
			set enListe to my decoupe(body_text, "«")
			if (count enListe) > 1 then
				set off7 to (count item 1 of enListe) + 2
				repeat with j from 2 to count enListe
					tell me to set off7end to off7 + (offset of "»" in enListe's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-BoldOblique"
					set (color of characters off7 thru off7end) to "red"
					repeat with k from off7 to off7end
						set character k to my change_case(character k, "upper")
					end repeat
					set off7 to off7 + (count item j of enListe) + 1
				end repeat
			end if
			# Set text enclosed between straight double quotes ” named quotes by AppleScript ” in "Helvetica-Oblique"
			set enListe to my decoupe(body_text, quote)
			if (count enListe) > 1 then
				set off7 to 0
				repeat with j from 2 to count enListe by 2
					set off7 to off7 + (count item (j - 1) of enListe) + 2
					set off7end to off7 + (count item j of enListe) - 1
					set (font of characters off7 thru off7end) to "Helvetica-Oblique"
					set off7 to off7end + 1
				end repeat
			end if
		end tell
	end tell
end handleIt

#=====
(*
Le second argument peut être: "upper", "lower", "capitalize"
*)

on change_case(txt, mode)
	tell application "ASObjC Runner"
		if mode is "upper" then
			return modify string txt so it is caps
		else if mode is "lower" then
			return modify string txt so it is lower
		else if mode is "capitalize" then
			return modify string txt so it is cap words
		end if
	end tell
end change_case

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#===== 

Yvan KOENIG (VALLAURIS, France) mercredi 30 juillet 2014 11:51:43

Your modified script is excellent. Thank you for the assistance. I am still however having issues with the pages doc. I will send it to you.

DL

To all of you.
The original document contain in fact, numerous objects embedding text items.
Four of them are text box, three with short contents without quotes or parenthesis and one with a long text with quotes and parenthesis.
The nine other long pieces of text aren’t in text boxes but in shapes.

To see that, I used :

tell application "Pages"
	tell document 1
		set iworkItems to every iWork item
		repeat with anItem in iworkItems
			try
				get properties of anItem
			end try
		end repeat
	end tell
end tell

Of course, using :

tell application "Pages"
	tell document 1
		get properties of iWork items
	end tell
end tell

was my first attempt but I faced what smells like a bug.
The dictionary claims :
image‚n [inh. iWork item] : An image container
elements
contained by documents.
properties
description (text) : Text associated with the image, read aloud by VoiceOver.
file (file, r/o) : The image file.
file name (file or text) : The name of the image file.
opacity (integer) : The opacity of the object, in percent.
reflection showing (boolean) : Is the iWork item displaying a reflection?
reflection value (integer) : The percentage of reflection of the iWork item, from 0 (none) to 100 (full).
rotation (integer) : The rotation of the iWork item, in degrees from 0 to 359.

but trying to get image’s properties issue an error number -10000.

For the OP’s problem there are two possible schemes :
(1) replace the shapes containing long texts by text boxes.
(2) no longer work upon text items but upon iWork items.

tell application "Pages"
	tell front document
		set allTextItems to every iWork item
		if allTextItems is not {} then
			repeat with thisTextItem in allTextItems
				try
					set textContents to object text of thisTextItem
					my handleIt(a reference to object text of thisTextItem)
				end try
			end repeat
		end if
		if document body then
			my handleIt(a reference to body text)
		end if
	end tell # front document
end tell # Pages

#=====

on handleIt(target_object)
	tell application "Pages" to tell document 1
		tell target_object
			set body_text to its contents
			# Set text enclosed between parentheses in "Helvetica-Bold"
			set enListe to my decoupe(body_text, "(")
			if (count enListe) > 1 then
				set off7 to (count item 1 of enListe) + 2
				repeat with j from 2 to count enListe
					tell me to set off7end to off7 + (offset of ")" in enListe's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-Bold"
					set (color of characters off7 thru off7end) to "green"
					
					set off7 to off7 + (count item j of enListe) + 1
				end repeat
			end if
			
			# Use quite the same code to treat text enclosed into French chevrons
			set enListe to my decoupe(body_text, "«")
			if (count enListe) > 1 then
				set off7 to (count item 1 of enListe) + 2
				repeat with j from 2 to count enListe
					tell me to set off7end to off7 + (offset of "»" in enListe's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-BoldOblique"
					set (color of characters off7 thru off7end) to "red"
					repeat with k from off7 to off7end
						set character k to my change_case(character k, "upper")
					end repeat
					set off7 to off7 + (count item j of enListe) + 1
				end repeat
			end if
			# Set text enclosed between straight double quotes ” named quotes by AppleScript ” in "Helvetica-Oblique"
			set enListe to my decoupe(body_text, quote)
			if (count enListe) > 1 then
				set off7 to 0
				repeat with j from 2 to count enListe by 2
					set off7 to off7 + (count item (j - 1) of enListe) + 2
					set off7end to off7 + (count item j of enListe) - 1
					set (font of characters off7 thru off7end) to "Helvetica-Oblique"
					set off7 to off7end + 1
				end repeat
			end if
		end tell
	end tell
end handleIt

#=====
(*
Le second argument peut être: "upper", "lower", "capitalize"
*)

on change_case(txt, mode)
	tell application "ASObjC Runner"
		if mode is "upper" then
			return modify string txt so it is caps
		else if mode is "lower" then
			return modify string txt so it is lower
		else if mode is "capitalize" then
			return modify string txt so it is cap words
		end if
	end tell
end change_case

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#===== 

The try . end try block get rid of two problems :
(a) the bug striking images
(b) the fact that some objects are locked so that changing their contents is not allowed.

Yvan KOENIG (VALLAURIS, France) jeudi 31 juillet 2014 10:57:41

A very big THANK YOU to Yvan Koenig - with some collaboration (although Yvan did most of the work) we found a final solution.

The final script allows user to change font, color, case, etc for string between quotes, parenthesis or another character you wish to replace or add into the script.

It also does a word search and allows to format based on certain words.

The big bug/problem we had was dealing with the fact some way Pages converted Text Box into Shapes. (I never use shape!!!) However, it was solved with a simple solution in the end:

 set allShapes to every shape
		if allShapes is not {} then
			repeat with thisShape in allShapes
				my handleIt(a reference to object text of thisShape)
			end repeat
		end if
 

Here is the Final Script/solution.

If anyone knows how to compare text inside a text object while ignoring case - Please post solution or email me… For now I am using a list with a repeat loop to check words in various case.

 tell application "Pages"
	tell front document
		set allTextItems to every text item
		if allTextItems is not {} then
			repeat with thisTextItem in allTextItems
				my handleIt(a reference to object text of thisTextItem)
			end repeat
		end if
		
		set allShapes to every shape
		if allShapes is not {} then
			repeat with thisShape in allShapes
				my handleIt(a reference to object text of thisShape)
			end repeat
		end if
		
		if document body then
			my handleIt(a reference to body text)
		end if
	end tell # front document
end tell # Pages

#=====

on handleIt(target_object)
	tell application "Pages" to tell front document
		tell target_object
			set body_text to its contents
			
			# Set text enclosed between parentheses in "Helvetica-Bold" and color black
			set theList to my Divide(body_text, "(")
			if (count theList) > 1 then
				set off7 to (count item 1 of theList) + 2
				repeat with j from 2 to count theList
					tell me to set off7end to off7 + (offset of ")" in theList's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-Bold"
					set (color of characters off7 thru off7end) to "black"
					
					set off7 to off7 + (count item j of theList) + 1
				end repeat
			end if
			
			# Use the same code to treat text enclosed into brackets
			set theList to my Divide(body_text, "[")
			if (count theList) > 1 then
				set off7 to (count item 1 of theList) + 2
				repeat with j from 2 to count theList
					tell me to set off7end to off7 + (offset of "]" in theList's item j) - 2
					
					set (font of characters off7 thru off7end) to "Helvetica-BoldOblique"
					set (color of characters off7 thru off7end) to {0, 10 * 256, 85 * 256}
					
					set off7 to off7 + (count item j of theList) + 1
				end repeat
			end if
			
			# Set text enclosed between straight double quotes ” named quote by AppleScript ”
			set theList to my Divide(body_text, quote)
			if (count theList) > 1 then
				set off7 to 0
				#set off7 to (count item 1 of theList) + 2
				repeat with j from 2 to count theList by 2
					set off7 to off7 + (count item (j - 1) of theList) + 2
					set off7end to off7 + (count item j of theList) - 1
					
					set (font of characters off7 thru off7end) to "Helvetica-Oblique"
					
					set off7 to off7end + 1
				end repeat
			end if
			
			# set specific words to some color - Check by paragraph to avoid locking application
			
			set wordlist to {"Missed", "missed"} # Still trying to figure out how to ignore case / use unicode in Object Text
			repeat with ct from 1 to count of wordlist
				set MyWord to item ct of wordlist
				set (color of every word of every paragraph where it is MyWord) to "red"
				set (font of every word of every paragraph where it is MyWord) to "Helvetica-BoldOblique"
			end repeat
			
			set wordlist to {"beat", "Beat"}
			repeat with ct from 1 to count of wordlist
				set MyWord to item ct of wordlist
				set (color of every word of every paragraph where it contains MyWord) to {0, 100 * 256, 0}
				set (font of every word of every paragraph where it contains MyWord) to "Helvetica-BoldOblique"
			end repeat
			
			
		end tell
	end tell
end handleIt

#===== 2

on Divide(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end Divide

#===== 3