Customizing Pages ’09: How to work around the AppleScript bug with documents containing an automatic table of contents (Part 2)Posted by Pierre Igot in: Pages
March 31st, 2011 • 9:22 am
Last year, I wrote a series of articles on customizing Pages ’09 with a combination of AppleScript and Keyboard Maestro.
At the time, I noted that AppleScript support in Pages ’09 suffered from a bug causing it to fail to compute the offset of the current selection in a document if that selection comes after a section of the document that contains an automatic table of contents.
A few months later, I wrote about a workaround that I had found (with the help of a contributor to the AppleScript forum at Apple Discussions). It involved testing the list of styles of the document to see if it included a style called “TOC Heading 1” (the default style name used by Pages ’09 for the top-level TOC style).
If the test is positive, then instead of using a routine that relies on computing the offset of the current selection in the document, your AppleScript script must rely on GUI scripting to accomplish whatever it needs to accomplish.
The example that I gave back then was an AppleScript script for toggling the “All Caps” formatting option on and off. (The default behaviour of the “ ” menu item in the “ ” menu in Pages ’09’s menu bar is not a toggling behaviour. The menu item can only be used to turn the option on. To turn it off, you need to use the “ ” menu item. It’s a pain.)
To control such a formatting option via GUI scripting, you can use an attribute called “
AXMenuItemMarkChar” to test the “ ” menu item in the “ ” menu. The attribute value tells you whether the menu item is checked or unchecked. If it’s unchecked, you can check it using GUI scripting. If it’s checked, you can check the “ ” menu item using GUI scripting.
So that works fine for a menu-based formatting option. (For similar reasons, it also works fine for character and paragraph styles, because they are available via menu controls in the Format Bar and so can similarly be accessed via GUI scripting.)
But what about a formatting option that is not available via a menu? I had such a problem for another formatting option that I use all the time: the “Keep with following paragraph” formatting option. This option is only available via a tab in the Text inspector:
This means that you cannot use Mac OS X’s system-wide Keyboard Shortcuts feature (in System Preferences) to assign a keyboard shortcut to it.
You can, however, toggle the formatting option on and off via AppleScript, using the “
keep with next paragraph” property of the selection. I provide a sample script in this post. Then you can use a third-party utility such as Keyboard Maestro to assign a Pages-specific keyboard shortcut to it. (My choice is command-option-shift-K.)
However, as noted above, the script does not work when the current Pages document contains a table of contents. Instead of applying the formatting option to the selection, the script causes Pages ’09 to apply it somewhere higher up in your document, because its computation of the offset of the current selection is off by so many characters.
It’s the same problem as with the script for toggling all caps on and off mentioned above. For that script, I was able to work around the problem by using GUI scripting, when the current document contains a table of contents, to test the actual menu item and toggle it, instead of relying on Pages-specific AppleScript properties that can no longer be used reliably.
But what about doing the same thing for the “Keep with following paragraph” option. It’s not accessible through a menu item. It’s only available via the Text inspector. Is there a way to control this inspector via GUI scripting?
Yes, there is. With the help of this post on the AppleScript forum at Apple Discussions and a demo version of the third-party UI Browser utility, I was able to use GUI scripting to mimic a series of clicks on the Text inspector that can toggle the option on and off. Fortunately, for this particular formatting option, there is no need to test the current status of the option. If you click on it when it’s checked, it becomes unchecked, and vice versa. So a single click will always toggle it on or off.
Here’s the script I ended up using for my “improved” AppleScript script for toggling the “Keep with following paragraph” option on and off:
tell application "Pages" tell front document set myStyles to name of paragraph style of paragraphs end tell if myStyles does not contain "TOC Heading 1" then set mySel to (get selection of document 1) if (keep with next paragraph of mySel) is false then set (keep with next paragraph of mySel) to true else set (keep with next paragraph of mySel) to false end if else tell application "Pages" to activate tell application "System Events" tell process "Pages" click radio button 4 of radio group 1 of window 1 click radio button 4 of tab group 1 of group 1 of window 1 click checkbox 2 of tab group 1 of group 1 of window 1 end tell end tell end if end tell
And I use Keyboard Maestro to assign the command-option-shift-K shortcut to this script.
It now works reliably in all circumstances. If the document contains no automatic TOC, it relies on the standard AppleScript property. If the document contains a TOC, which would cause the “
get selection” part of the script to fail, then it uses GUI scripting instead (controlling Pages ’09 via System Events) to click on the checkbox in the Text inspector.
Please note that this script does not provide for cases where there is no inspector window open. I always have at least one inspector open in Pages ’09, so I don’t feel the need to add to the complexity of the script.
Of course, the same technique can be used to control other formatting options that are only accessible via an inspector. You just need to find the exact way to refer to the specific control that you want to access via GUI scripting. As indicated, I used a demo version of the third-party UI Browser utility for this, and more specifically its “Screen Reader” feature.
UI Browser is not cheap, but I might end up buying it, because it really does help you to control all kinds of things via GUI scripting. (Based on my research, there used to be a utility called UI Scripting in Apple’s own Xcode, but I cannot find it, and people say it was not as good as UI Browser anyway.) It is particularly useful in cases where the reference to the control is not what you’d expect. For example, in the Text inspector, the checkbox for the “Keep with following paragraph” option is checkbox 2 of tab group 1 of group 1 of window 1, but the checkbox for the “Keep lines together” option, which appears right above it in the Text inspector, is actually… checkbox 5 of the same group.
So there we are. Thanks to GUI scripting of the inspector in Pages ’09, we now have a way to work around the bug in Pages ’09’s AppleScript support for documents with automatic TOCs even for features that are not accessible via a menu and can only be controlled via the inspector.
Of course, I am still hoping that Apple will eventually fix this bug, which will eliminate the need to resort to GUI scripting. But I am not holding my breath, and in the meantime, this improved script will help me avoid accidentally applying formatting options such as “Keep with following paragraph” and “”Keep lines together” to the wrong paragraph in my documents with TOCs!