keynote 4, syntax highlighting, and other monkeying around

I was pretty sure I was going to buy iWork ‘08 before it was announced. Every version of Keynote has had a few improvements that made it worth having, even though I only produce two or three slideshows a year. Keynote 4 adds a feature I’ve often wanted: the ability to make an object on a slide move around. I’ve wanted to use this for code samples: I’d create a text box with code in it, then put a rectangle on top of it, translucent and one line high, and have that move from one important line to the next.

I’ve already tried this, and I think it works pretty well. I’m a little disappointed that I can’t have it grow to twice its height while doing this, but the only action that would come close is scale. I don’t want to scale the box, I want to change one dimesion.

This brings me to the one big issue that I have with Keynote. Its AppleScript support, as far as I can tell, really sucks. Now, this is a big improvement from Keynote 1.0, in which there was no scriptability. There still isn’t much. It focuses mainly on automating the playing of slideshows. It would be nice to have a way to alter the contents of the slide. I can set the “body” property, but setting up the body text area is sort of annoying and stupid. Worse, I can only set the content of the body not, as far as I can tell, its formatting.

I don’t really want to set any formatting except for the coloring, but I can’t do that with AppleScript. I will probably have to resort to generating RTF or (ugh) PDF (via LaTeX) and then putting it on the slide.

See, I want to syntax highlight my code samples, at least some of the time, and probably most of the time. Doing this by hand is problematic and painful, especially if I realize, later, that I need to change a small problem on fifty similar but different slides.

My current best hope is to marry RTF::Writer and Syntax::Highlight::Engine::Kate, which so far looks something like this:

my $str = '';
my $hl  = Syntax::Highlight::Engine::Kate::Perl->new;
my $rtf = RTF::Writer->new_to_string(\$str);

my %color = (
  _default => [ 0, 0, 0 ],
  Keyword  => [ 0, 0, 255 ],
);

my %color_pos;
my @colors;

for (keys %color) {
  my @rgb = @{ $color{ $_ } };

  my $pos = $color_pos{ @rgb };

  unless (defined $pos) {
    push @colors, \@rgb;
    $pos = $color_pos{ @rgb } = $#colors;
  }

  $color_pos{ $_ } = $pos;
}

$rtf->prolog(
  fonts  => [ 'Courier New' ],
  colors => [ sort ],
);

while (my $in = <>) {
  my ($text, $type) = $hl->highlight($in);
  my $pos = $color_pos{ $type } // $color_pos{ _default };

  $rtf->print(
    \"\\cf$pos",
    \'\fs40\b\i',  # 20pt, bold, italic
    $text,
  );
}

$rtf->close;

print $str;

It needs some work, but the big problem I have now is that input that looks like this:

$obj->method

Comes out like this:

$obj>method

There’s some kind of escaping of the dash, turning it into a backslashed underscore. I’ve sent the Sean Burke an email, but I’ll probably have a look at the code and spec myself soon.

Even if I can’t parlay this into a syntax highlighter for Keynote, maybe I’ll end up with a good syntax highlighting engine that outputs to RTF. I guess that might be useful.

Written on September 4, 2007
apple   keynote   macosx   rtf   software   syntax