A Table of Contents for Keynote

Note: This article applies to Keynote ’08 (version 4.x)

Sometimes in life you have to use the wrong tool to get the job done. Recently I had to use Apple’s Keynote to make documents containing a lot of graphic artefacts. Being a presentation tool, Keynote has no concept of generating an index of its contents, but from a user’s perspective a table of contents (TOC) is pretty much essential. Here’s a hack, using AppleScript, to make one.

And it is a hack: it relies on the presenter’s notes fields being populated with whatever you want to appear in the TOC. This means that prior to running the script, someone needs to ensure that the correct information is held in the notes.

The Keynote dictionary only exposes a few properties to AppleScript. Of these one could use title or evenĀ body but I used notes because, well, it was all an afterthought.

Here’s an example of a Keynote document ready to be processed. Note that the presenter’s notes pane is showing at the bottom, populated with the information that I want to appear in the TOC:

To generate the TOC, paste the following script into AppleScript Editor and edit mypath to point to your Keynote file.

set mypath to (path to home folder as text) & "Documents:Guitars.key"
set mynotes to ""
tell application "Keynote"
   open mypath
      tell slideshow 1
         set countslides to count of slides
         repeat with i from 1 to countslides by 1
            -- Only consider those slides with notes
            if (notes of slide i) is not "" then
               -- Get the notes
               set mynotes to mynotes & notes of slide i & "\t" & i & "\n"
            end if
         end repeat
      end tell
      -- Write to the Result pane
      get mynotes
end tell

The script builds a string of each slide’s presenter’s notes (if present) plus the corresponding slide number, separated by the newline character. The result is written to AppleScript Editor’s results pane:

And then it’s simply a case of copying, pasting and formatting however you wish. Pasting into Keynote via Numbers, for example, will insert the TOC as a two-column table.

Disclaimer: I’m an AppleScript newbie so what’s in the script may not be best practice. But I’ve been learning from the great resource that is MacScripter. Check it out for more info.

Edit: As noted above it’s possible to read the title and body properties of a slide using AppleScript. In the default Keynote slide (see below), the upper box is title and the lower body. To target these, replace “notes” in the script with “title” or “body” as appropriate.

4 thoughts on “A Table of Contents for Keynote

  1. I think this was a great idea for you to put this on google it helped me learn how to do table of contents for keynote thanks a lot _ Alyssa Nicole Neighbors on Facebook

  2. Unfortunately this no longer works in Keynote 6. In this version notes are not an accessible attribute.

  3. Thank you for sharing this. I got this working as expected with slide titles. To make it work with titles, change the following:

    Change Line from 09:
    if (notes of slide i) is not “” then

    if (title of slide i) is not “” then

    Change Line 11 from:
    set mynotes to mynotes & notes of slide i & “\t” & i & “\n”

    set mynotes to mynotes & title of slide i & “\t” & i & “\n”

    This script would be even more useful if it could wrap each line in the table of contents with a link to the slide. For example “Slide 1″ would link to Slide 01 so it can be used to navigate the presentation.

  4. I’ve done some digging but cannot find out how to create hyperlinks programmatically.

    It’s easy enough to create a new slide and put the TOC on it, but I think you’re stuck with then manually selecting each item and doing Insert > Text Hyperlink.

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">