Customizing Pages ’09: Scripts for text inside table cells

Posted by Pierre Igot in: Pages
May 3rd, 2010 • 6:21 pm

Over the past few weeks, I have been working on customizing my work environment in Pages ’09 using a combination of AppleScript scripts and Keyboard Maestro.

In particular, I have been using this approach to define custom keyboard shortcuts for applying specific character styles and paragraph styles.

But in the process of customizing Pages ’09, I also have encountered significant road blocks caused by the limitations of Pages ’09’s AppleScript support. In particular, I have discovered that the standard commands for changing character styles and paragraph styles (and all kinds of other properties) do not work for text inside table cells, because Pages ’09’s AppleScript support does not allow you to read or set the properties of the selection when the selection is a range of text inside a table cell.

My conclusion based on this was that it was simply impossible to use my custom keyboard shortcuts and scripts when editing text inside table cells and that, in such a context, I would be forced to revert to the mouse-only approach provided by the Pages ’09 interface.

However, I also posted a query on the AppleScript forum at Apple Discussions, just to confirm with more experienced AppleScript experts that my conclusion was correct.

Once again, fellow Canadian Pierre L. answered my query, but, while he confirmed that Pages ’09’s AppleScript commands for manipulating text were unusable inside table cells, he also pointed out that there was a way to work around that limitation using something called Graphic User Interface (GUI) Scripting, which works with any Mac OS X application that follows Mac OS X’s basic user interface guidelines, even if it does not support AppleScript or, as is the case with Pages ’09, only offers partial AppleScript support.

Pierre L. was kind enough to provide sample scripts. After a bit of to-and-fro, he was able to establish that it was possible to script the Pages ’09 GUI in order to apply character styles. However, we had to work around further limitations, namely the inability to click on a specific style in the styles drawer of a Pages ’09 document window using GUI scripting and the inability to select a menu item by name in the character styles pop-up menu in Pages ’09’s Format Bar.

Instead, Pierre L. figured out a clever approach where he uses the styles drawer to get the position of the desired character style in the list of character styles and then clicks the corresponding menu item in the same position in the character styles pop-up menu in Pages ’09’s Format Bar.

It is hard to believe the loops that one has to jump through in order to get things to work!

There was one further snag when we found that Pierre L.’s initial version of the script was not executing smoothly on my machine. I was able to figure out that it was the presence of one or more inspector windows open next to the document window that was causing a stall and a failure of the script to proceed with the application of the style (until I switched away to another application, which would cause the inspectors to disappear).

Finally, Pierre L. produced a script that worked well even when inspector windows were visible in Pages ’09:

tell application "Pages"
	activate
	try
		tell front document
			if selection = "" then set selection to "|"
			set character style of (get selection) to "Strong Emphasis"
		end tell
	on error
		my setCharacterSyle("Strong Emphasis")
	end try
end tell

on setCharacterSyle(myStyle)
	tell application "System Events" to tell process "Pages"
		set theWindow to (window 1 whose role description is "standard window")
		my showCharacterStyles(theWindow)
		tell theWindow
			set characterStyles to value of static text 1 of rows of outline 1 of scroll area 2 of splitter group 1 of group 1 of drawer 1
			set k to 0
			repeat with thisStyle in the characterStyles
				set k to k + 1
				if thisStyle as text is myStyle then exit repeat
			end repeat
			if k > 1 then set k to k - 1
			click menu button 2
			click menu item k of menu 1 of menu button 2
		end tell
	end tell
end setCharacterSyle

on showCharacterStyles(theWindow)
	tell application "System Events" to tell process "Pages"
		if not (pop up button 1 of theWindow exists) then click menu item "Show Format Bar" of menu 1 of menu bar item "View" of menu bar 1
		if menu item "Show Styles Drawer" of menu 1 of menu bar item "View" of menu bar 1 exists then keystroke "t" using {shift down, command down}
		tell theWindow
			tell checkbox 1 of group 1 of drawer 1
				repeat until it exists
					delay 0.1
				end repeat
				if description is "show character style" then click
			end tell
		end tell
	end tell
end showCharacterStyles

This sample script is able to apply the “Strong Emphasis” style to any selected text in a Pages ’09 document, including selected text in a table cell. When the selected text is part of the body text of the document, it just uses the standard approach using Pages ’09’s proper AppleScript commands.

When that fails with an error, the script switches to the GUI-based approach and applies the style to the selection using the character styles pop-up menu in the Format Bar. You can actually see the script pulling down the menu and selecting the menu item. On my machine, it is fast enough that it does not interfere with my work.

Of course, ideally we should not have to go through all this and we should be able to use the standard approach for any selection. But in the real world, Pages ’09’s AppleScript support is limited and we have to work around those limitations to get something that works everywhere.

Incidentally, I should note that there are more contexts in Pages ’09 other than a table cell where proper AppleScript commands do not work either. The other day, I discovered that they also failed to work on a selection made inside a footnote.

Here again, just like in table cells, when you try to get the selection in a script, you get something like this:

text from character 11 to character 15 of some «class » of document id 24819922 of application "Pages"

In this case, the footnote class is not even defined! But even if it were, the fact that Pages ’09 is only able to refer to “some” footnote and not to a specific one indicates that things would break anyway. Thankfully, Pierre L.’s approach works for any kind of error and so it works for both table cells and footnote, as well as any other context where the standard approach causes an error.

Finally, since I have a number of different character styles that I want to have shortcuts for using the same approach, I figured out how to avoid having to include a copy of the two subroutines (“handlers” in AppleScript parlance) called setCharacterSyle() and showCharacterStyles() in each and every script.

I now have a script file that I have called “Pages Library.scpt” and that contains the two handlers as they appear above. And then the script for applying the “Strong Emphasis” character style itself looks like this:

set s to load script file "xxx:Users:yyy:Library:Scripts:Pages:Pages Library.scpt"
tell application "Pages"
	activate
	try
		tell front document
			if selection = "" then set selection to "|"
			set character style of (get selection) to "Strong Emphasis"
		end tell
	on error
		s's setCharacterSyle("Strong Emphasis")
	end try
end tell

where “xxx” is the name of my startup volume and “yyy” is the name of my home folder. (You can of course store that file anywhere you like.)

This loads my script library at the beginning of the script and then refer to the handlers stored in that library using the “s's” syntax. It works well as far as I can tell.

Many thanks to Pierre L. again for all his help!


Comments are closed.