April 15th, 2010 • 9:52 am
A couple of weeks ago, I wrote my first post about using a combination of AppleScript and a third-party utility such as Keyboard Maestro or FastScript to customize Pages ’09 and more specifically to assign shortcuts other than F1–F8 to paragraph and character styles.
In that post, I indicated that my script for applying the paragraph style called “Body” was the following:
tell application "Pages" set mySel to (get selection of document 1) set paragraph style of mySel to "Body" end tell
and that my script for applying the character style called “None” is the following:
tell application "Pages" set mySel to (get selection of document 1) set character style of mySel to "None" end tell
In Pages ’09, things work as expected for the former script, i.e. for paragraph styles. Regardless of whether your current selection is a string of text or just the blinking insertion point, in both cases the script correctly switches the style of the underlying paragraph(s) to the desired paragraph styles.
For character styles, on the other hand, things don’t quite work as expected. The script above works fine when the selection is a string of text, i.e. a range of characters.
But if the selection is an insertion point, the command
set character style fails. Or at least it does not do what one would expect, i.e. change the current character style to the desired style and apply it to anything that’s inserted after the insertion point.
This is problematic, because this behaviour what happens when you select a character style in the styles drawer. So in that respect the
set character style does not work the way that the corresponding action in the Pages ’09 user interface works. Whether it’s a bug or an intrinsic limitation of the AppleScript implementation in Pages ’09, I do not know.
But in order to be able to assign keyboard shortcuts to specific character styles, I definitely needed to work around this limitation.
As per usual with my limited scripting skills, I soon encountered what seemed to be unfathomable problems. So I ended up asking for help in the AppleScript forum at Apple Discussions. And a kind fellow Canadian soon provided me with the answer.
It does look like the problem with switching character styles when the selection is an insertion point is a limitation of Pages ’09′s AppleScript support. But Pierre L. of Québec suggests a workaround where you change the selection from an insertion point to a character and then change the character style of that character.
Since, after changing the selection from an insertion point to a character and changing the character style of that character, the character in question remains selected, as soon as you resume typing, Pages ’09 replaces the selection (i.e. that character) with what you are typing, and this time it is in the right character style, i.e. the character style of the character that your typing is replacing.
Although it is somewhat inelegant, it works fine, and I am starting to get used to using somewhat inelegant solutions to problems that don’t seem to have elegant solutions in AppleScript. Fortunately, today’s machines are fast enough that even inelegant solutions work so effectively as to make them equivalent to more elegant solutions.
The last hurdle that I had to overcome was that I obviously only wanted my script to change the selection to that character when the selection was an insertion point to begin with. Otherwise, in cases where the current selection was an existing range of characters, it would have changed that existing range of characters to the new character, and that was definitely not a desirable behaviour.
How do you test the current selection in AppleScript to see if it’s an insertion point or a range of text? Pierre L. came to my rescue again, suggesting using
if selection = "" then… I would have expected something more intuitive in AppleScript’s pseudo-natural language, like
if the selection is an insertion point then… But I’ve also learned not to expect the more intuitive stuff to work with AppleScript. AppleScript might look like English, but it definitely is not English and is nowhere near intuitive in that respect.
And so finally, for applying/switching character styles in Pages ’09, I ended up using a script like this:
tell application "Pages" if selection is "" then set selection to "|" end if set character style of (get selection) to "None" end tell
As indicated, this script tests the current selection. If it’s a range of text, it simply applies the character style “None” to it. If it’s an insertion point, it changes the selection from that insertion point to the character “|” (but it could be any character, really) and then applies the character style “None” to that character.
After the script is executed, if the selection was an insertion point, it is now that “|” character at the insertion point, and if I resume typing it will simply replace that selection with what I am typing, in the desired character style.
And that, in effect, is a behaviour that mimics the behaviour you get when your select the character style manually in the styles drawer or in the Format Bar in Pages ’09.
Once this script is saved, all that remains to do is to use Keyboard Maestro to define a trigger for the script. In my case, the trigger is command-control-Space. And the same system can be used for as many character styles as you like.
Thanks again to Pierre L. for his help.