Customizing Pages ’09: How to work around the AppleScript bug with documents containing an automatic table of contents

Posted by Pierre Igot in: Pages
August 5th, 2010 • 4:49 pm

A few months ago, I wrote about a bug in Pages ’09’s AppleScript functionality that causes all kinds of problems when working on documents that contain an automatic table of contents.

In essence, the presence of the table of contents renders many scripts unusable, because, when a table of contents is present, AppleScript fails to compute the offset of the current selection in a document if that selection is located anywhere after the automatic table of contents. This means that, if you attempt to manipulate the selection in any way via AppleScript, your script ends up manipulating some range of text somewhere higher up in your document.

Needless to say, it is a rather irritating and dangerous bug, because if you forget about it, you might not notice that your scripts are doing stuff to sections of your text outside the current (visible) selection.

Back then, I wrote that, typically, in my workflow, I insert the automatic table of contents near the end of my work on a document, so it’s not a huge problem. But it still causes me grief, because once I have inserted the table of contents, I have to remember that I must refrain from using any of the many scripts that I use (via Keyboard Maestro) to customize the Pages ’09 user interface and make it more efficient. I have to remember to switch from a keyboard-based approach (which relies on my scripts) to a mouse-based approach (which is quite tedious and repetitive).

So today I decided to see if I couldn’t devise a way to work around this bug.

After all, I have already had to alter my AppleScript scripts for Pages ’09 to work around another limitation in Pages ’09’s AppleScript support, namely the fact that many AppleScript commands and properties do not work when the current selection is text inside a table or in a footnote.

There, the solution was to resort to GUI scripting. Could I use the same kind of workaround when the selection was text coming after an automatic table of contents?

The answer was yes, but only if there was a way to test the Pages ’09 document to see if it contained an automatic table of contents. My idea was that I would test for this, and if the document did contain a TOC, then I would switch to the GUI scripting-based approach in my script.

But of course, it was not immediately obvious to me that there was a way to test for this. On the contrary, when I explored the AppleScript dictionary for Pages ’09, all I found was a command for inserting a TOC. And that was it.

So I posted a query on the AppleScript forum at Apple Discussions, and I soon received an excellent suggestion from regular contributor Pierre L., which was to test the paragraph styles currently in use in the document to see if any of them was a TOC style.

By default, Pages ’09 uses styles called “TOC Heading 1,” “TOC Heading 2,” and so on. I always use these default styles (customized to my liking), so all I had to do was to test to see if the paragraph styles currently in use in the document included, say, “TOC Heading 1.”

And here is what I eventually came up with as an improved script for toggling the “All Caps” formatting option on and off, for instance:

tell application "Pages"
	tell front document
		set myStyles to name of paragraph style of paragraphs
		if myStyles contains "TOC Heading 1" then
			my toggleAllCaps()
		else
			try
				set mySel to (get selection)
				if capitalization type of mySel is all caps then
					set capitalization type of mySel to normal capitalization
				else
					set capitalization type of mySel to all caps
				end if
			on error
				my toggleAllCaps()
			end try
		end if
	end tell
end tell

on toggleAllCaps()
	tell application "System Events" to tell process "Pages"
		tell menu bar 1
			tell menu bar item "Format"
				tell menu "Format"
					tell menu item "Font"
						tell menu "Font"
							tell menu item "Capitalization"
								tell menu "Capitalization"
									try
										set myMark to value of attribute "AXMenuItemMarkChar" of menu item "All Caps"
										if myMark is "?" then
											click menu item "None"
										end if
									on error
										click menu item "All Caps"
									end try
								end tell
							end tell
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell
end toggleAllCaps

As you can see if you compare this script to my previous version, I had to make the following changes:

I moved the GUI scripting-based approach to toggle “All Caps” from the main script to a separate toggleAllCaps() subroutine, because I would now have to be able to call it in two different places in the main script.

Then I started the main script by inserting a test to see if the paragraph styles currently in use in the document includes the “TOC Heading 1” style.

If the document does, then my script switches to the GUI scripting-based approach and calls the subroutine.

If not, then the script attempts to use the approach based on Pages ’09’s built-in AppleScript support. If that fails (because the selection is inside a table cell or a footnote), then the script also switches to the GUI scripting-based approach and calls the same subroutine.

Et voilà.

Now all I have to do is update all my other scripts (for applying paragraph and character styles, etc.) using the same approach. After that, my scripts will no longer apply the desired formatting changes to the wrong text in documents that contain an automatic TOC.

Thanks to Pierre L. for his help.


Comments are closed.