Keynote's Connections

In his article that compares OS X's presentation programs, Ian F. Darwin illustrates how Keynote has what it takes to compete with PowerPoint, both in terms of its ease of use and feature set. However, Keynote goes one step further than PowerPoint by making it easy to dynamically create presentations from within other applications. Traditionally this would fall into the realm of AppleScript. But with Keynote, Apple has gone down a different path.

Opening Tag

AppleScripts and Oranges

AppleScript serves as the glue between applications on the Mac by providing a channel to transfer information from one application to another (ex: take information out of a FileMaker database and insert it into an HTML document via BBEdit). In order to take advantage of AppleScript, an application must provide a dictionary that tells the scriptable architecture of OS X what commands are supported by the application (for example, a web browser will use the getURL command to open a web page). However, if an application doesn't provide a dictionary, then it can't be scripted.

In a similar vein, XML serves as the glue between applications that run on a variety of platforms: everything from high-end web and application servers to hand-held PDAs. However, there is a large difference between the two: AppleScript is a programming language that is used in scripts that are interpreted by the operating system and then executed, while XML defines how information is stored in a file. This XML file can then be passed between applications to transfer the information from one system to another. For a more detailed introduction to the basics of XML, refer to Learning XML, 2nd Edition by Erik T. Ray (O'Reilly & Associates, 2003).

En Vogue

There are a variety of reasons why XML has become so popular in recent years, the biggest being that it provides standard methods to store and retrieve information, no matter what that information may be. XML can be used to describe almost any type of information imaginable, including:

But how are we to understand the difference in structure between an XML document that holds data for a vector graphics image, and one that is used to describe a web page? Documents that are simple in nature can be understood by inspecting them. Anyone with a basic familiarity with XHTML can inspect the source of a webpage to understand how it is built. However, how are we to understand how more complicated documents, such as Keynote presentations, are structured? The answer to that question lies in XML Schema. A schema is simply an XML document that describes how another XML document can be structured. Since the information required to describe a vector image is different from the information required to describe a hypertext document, the two documents will require unique structures for their information, and hence, they will also require unique schema. Any document that conforms to its schema is considered valid, while any XML document that doesn't validate against its schema is pretty much useless (it's like having a CSV file with commas in the wrong places).

To Infinity And Beyond

In addition to the abbreviated list of XML applications given above, developers are free to create their own XML syntax to suit their needs. In order for anyone else to understand how the document can be structured, the schema must be made available. Let's say developer X wants to create an XML representation for his recipe collection. In order for developer Y to understand the structure that X has settled on, he/she will need the schema for the document.

And this is what precisely what Apple has done with Keynote's presentations: they've created an XML syntax, APXL (short for Apple Presentation XmL), and made its schema publicly available on the Apple Developer Connection site. So with Keynote's release, Apple is making waves for two reasons:

The second point has long been considered the Holy Grail for XML. While XML has gained momentum in web and enterprise applications, it's not widely used as the file format for documents in mainstream desktop applications. Why? Possibly the biggest reason is that by using a plain-text file format for documents, people are free to edit the document without using the original application. While this may seem insignificant, it also means that other applications can also read and write the files, and this is exactly what Apple has chosen to do with Keynote presentations. Contrast this situation with MS Office, where Microsoft wants you to use its applications and only its applications to edit Office documents.

Brave New World

At this point, you might be wondering how it all ties together: AppleScript, XML, and Keynote. Traditionally, if you want to create an automated workflow on the Mac (such as the one documented in this article by MacDevCenter's editor, Derrick Story), you'll need at least one application that can be controlled with AppleScript. Well, guess what. If you try opening Keynote's AppleScript dictionary in Script Editor, you'll find out that there is no dictionary, which makes it pretty much impossible to create a presentation via AppleScript. But don't lose all hope yet: Keynote's XML file format fills the hole. By editing an XML document, you can actually work with a Keynote presentation from your own application. Try working with a PowerPoint document in something other than PowerPoint, and you'll see what a difference Keynote's method of document storage makes.

Integrating Keynote With Applications

FileMaker Pro

The Mac's friendly neighbourhood database, FileMaker includes XML support in the latest version. By doing so, it is now possible to transform the information stored in a database into a variety of XML flavours. And yes, Keynote presentations is now included in that list. The tool can be downloaded from here.

A sample Keynote presentation created by FileMaker Pro

4-D Keynote Builder

A perfect example of how Keynote can be used as a presentation medium for other applications is 4th Dimension's Keynote Builder. By querying a database based on a client's preferences for a house, the application produces a presentation that will contain one slide for each house that matches the necessary criteria. In turn, each slide will contain a photo of the house along with other pertinent information. From this point, the realtor can export the presentation (to PDF, QuickTime, or PowerPoint) or present the slideshow to the client. A sample slide is shown below:

A sample slide from 4D's Keynote Builder

A Custom Solution

However, we are not limited to using existing solutions to dynamically generate Keynote presentations. The tools necessary to create your own workflow are freely available:

  1. A compiler and run-time system (or an interpreter for the scripters in the audience) for your language of choice,
  2. an XML parser,
  3. and an understanding of Apple's APXL schema, which is documented here.

You'll notice that an actual copy of the Keynote application is not in the above list; you can create a Keynote presentation on virtually any computer, since essentially all that you are doing is working with a bunch of files. However, you'll need a copy of Keynote in order to work with the resulting presentations in any useful matter, whether that be printing, viewing, or presenting them to an audience.

What You'll Need to Know

Keynote documents are actually stored as directories that contain all of the files require by the presentation; these directories are called "bundles", and the Finder treats each bundle as a single file (this is identical to Cocoa applications, which wrap directories around all of the necessary components for an application). By right-clicking on a document and then selecting "Show Package Contents", the Finder will show all of the files that make up the presentation. Alternatively, you can use Terminal and ls to view the files, since OS X's BSD foundation treats Keynote documents as regular directories).

Inspecting the contents of a Keynote presentation

The presentation.apxl file is the XML document that stores all of the information for a presentation, including all the slides, bullets, headings, charts and graphs, while the other files are media that is used in the presentation, such as images, movies, or other multimedia elements. If you open the presentation.apxl file in a text editor, you'll notice that it's more than a little unwieldy. Generating all of that mark-up from scratch is not practical for the purposes of this tutorial, so we'll take a shortcut and create a template presentation to create the bulk of the XML, and simply fill in the necessary blanks with our code.

The Problem

So now that I've gone ahead and stated how easy it is to create a Keynote presentation purely through code, I'll walk through the process of doing so. As a bit of a music buff, I like to keep tabs on what kinds of music I'm listening to at a glance. But doing so through the iTunes interface requires too much effort. Instead, I want to automatically generate the information so I can spend my time in other ways. Luckily, most of the work is already done: using MyTunes, I've already placed my music library into a MySQL database. We'll supply the information to Keynote, and let the application do the heavy lifting to produce the result.

The Boring Part

As usual, the first thing we have to do is make sure we have the tools required for the job. For this tutorial, I'll use Java and the Apache Software Foundation's Xerces XML parser, which is freely available here, in addition to MySQL's JDBC driver, available here. You'll also need your iTunes music library information to be stored in a MySQL database (which can be done with MyTunes, available here). Refer to my previous article "Using Java to Expand iTunes Functionality" to get it up and running. The final step is to download the template presentation file and the Java class that will fill in the blanks for us, both of which are available here.

The Solution

Expand the archive, and open up the presentation.apxl in a text editor, and scroll down to the part of the file that appears as follows:

The template that we'll use for our own presentation

The highlighted tag is the needle that we'll look for in the haystack, while the tags that are commented-out illustrate how we'll have to format our data so that it will be presented in the graph. To make this easy, we'll parse the information using SAX. Whereas DOM makes the information in the document available in a hierarchical tree structure, SAX provides it on an as it becomes available basis, as the parser works through the document from beginning to end. So when we're parsing the document and come across the <mytunesChart /> tag, we'll replace it with the information for the columns in our graph. For all other tags, we'll simply echo them to the stream to be printed. The following snippet of code does exactly what we want:

// invoked when the parser encounters an
// opening tag; we're looking for the tag
// whose name local name is "mytunesChart"
public void startElement(String uri, String loc,
  String q, Attributes atts)
  throws SAXException {

  buffer = new StringBuffer();

  // if this tag is NOT what we're looking for...
  if (! localName.equals("mytunesChart")) {

    // open the tag
    buffer.append("<").append(qName);

    // add all the attributes of the tag
    for (int i = 0; i < atts.getLength(); i++) {
      buffer.append(" ");
      buffer.append(atts.getQName(i));
      buffer.append("=").append("\"");
      buffer.append(atts.getValue(i));
      buffer.append("\"");
    } 

    // add the namespace info, if any exists
    if (! ns.toString().equals("")) {
      buffer.append(ns.toString());
    } 

    // close the tag, and print to the stream
    buffer.append(">");
    this.writer.print(buffer.toString());

  // this is the key that we're looking for,
  // so we'll spit out our column info
  } else {

    // change the items in [] to match your
    // database connection parameters
    Connection con = DriverManager.getConnection(
      "jdbc:mysql://" + [host] + "/" + [db name]
      + "?user=" + [username] + "&password=" +
      [password]);

    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(
      "select DISTINCT(trackGenre), COUNT(*) " +
      "as trackCount FROM Tracks " +
      "GROUP BY " + trackGenre");

    // while there's another genre...
    while (rs.next()) {

      String genre = rs.getString("trackGenre");
      int count = rs.getInt("trackCount");

      // make sure the genre has been specified
      // note: you will have to encode an "&"
      // to "&amp;" if any of your genres
      // contain an ampersand
      if (genre != null) {
        buffer.append("<array>\n");
        buffer.append("<string>");
        buffer.append(genre);
        buffer.append("</string>\n");
        buffer.append("<number>");
        buffer.append(count);
        buffer.append("</number>\n");
        buffer.append("</array>\n");
      }
    }

    this.writer.println(buffer.toString());
  }
}

Run the class with the command

javac MyTunesChart; java MyTunesChart template.key

Upon the class' completion, there should be a new Keynote document in the directory named mytunes.key. Open it in Keynote, and you should see something similar to the following:

The result of our work

It is important to note that the template file itself can not be opened in Keynote. While this seems a bit odd, remember that by inserting the key in the APXL file, the document no longer validates against the schema. However, once our Java class processes the template, this tag will be replaced with data that will make the output file validate.

Closing Tag

One of the major attractions in using applications on the Mac is in creating an automated workflow, in which one or more applications are glued together to pass information and commands between themselves. We've now seen how it is possible to accomplish the feat with XML, in the absence of AppleScript. And since XML bindings are available for almost high-level languages, you are free to use whichever language that you are most comfortable with, whether it's Java, Objective-C, C/C++, Ruby, Perl, PHP, or another.

Apple is actively promoting Keynote to developers as a tool to serve as the presentation medium for applications. If you are interested in finding out more information, there are several resources on the ADC site to assist developers who are considering integrating Keynote with their applications:

While there currently aren't any standard applications that incorporate Keynote presentation capabilities, it should be interesting to see what happens in the near future now that the application has established its audience.