Keynote and XML

acme on 2003-01-17T14:29:22

Keynote, Apple's new presentation software for MacOS X is an interesting piece of software. On one hand, it's a very very light layer over Quartz and should have been a doddle to knock up. On the other hand, a lot of people will be comparing it to Powerpoint, so it has to have lots of knobs to turn.

Overall, I'm quite impressed with it. It makes it very easy to build simple presentations, and comes with better themes than Powerpoint does (although I bet you they'll start getting annoying as people overuse them). The alignment guide thing is neat. It is, however, a little slow on my iBook. It takes about a fifth of a second to flick from slide to slide, which only involves blitting 100 or so characters to the screen. That's slow. And it gets very slow when dealing with hundreds of slides... but I'm getting ahead of myself.

Take these two facts: Keynote's presentation format is XML, and I'm doing a tech talk next week entitled "Core Perl Modules You Might Not Know About". Clearly, the only sane thing to do would be to autogenerate slides for each core module, with each slide having the module name as title, the module description, and the synopsis. So I hack up some code with File::Find::Rule and Pod::POM, build a small presentation which displays a module how I want, dig into the XML code produced, and glue it all together with Template Toolkit. The TT stuff in question is fairly simple, and I know you all love angle brackets, so here we go:

[% # 4909 lines of boring theme-describing XML above here %]
[% count = 3 %]
[% FOREACH module = modules %]

  
    
    
  </drawables>
  <transition-style type="inherited"/>
  <thumbnails>
    <thumbnail file="thumbs/st[% count %].tiff" byte-size="3108" size="60 45"/>
[% count = count + 1 %]
  </thumbnails>
  <bullets>
    <bullet marker-type="inherited" level="0">
      <content tab-stops="L 96" font-size="84" font-name="MyriadPro-Semibold" paragraph-alignment="center">[% module.name %]</content>
    </bullet>
      <content tab-stops="L 96" font-size="84" font-name="MyriadPro-Semibold" paragraph-alignment="center">[% module.name %]</content>
    </bullet>
    <bullet marker-type="inherited" level="1">
      <content paragraph-head-indent="7" tab-stops="L 58" font-size="42" font-name="AJensonPro-Subh" paragraph-first-line-indent="7">\342\200\234[% module.description %]\342\200\235</content>
    </bullet>
    <bullet marker-type="none" level="1">
      <content paragraph-head-indent="7" tab-stops="L 58" font-size="36" font-name="Courier" paragraph-first-line-indent="7">
<![CDATA[[% module.synopsis %]]]>
      </content>
    </bullet>
    <bullet marker-type="character" level="1">
      <content paragraph-head-indent="7" tab-stops="L 58" font-size="36" font-name="Courier" paragraph-first-line-indent="7">
        <span font-size="42" font-name="AJensonPro-Subh">Tip</span>
<![CDATA[
]]>
      </content>
      <character-bullet-style size-technique="relative" offset="5" size="1.71429">
        <bullet-characters tab-stops="L 84" font-size="11" font-color="1 0.498039 0" font-name="GillSans">\342\200\242</bullet-characters>
      </character-bullet-style>
    </bullet>
    <bullet marker-type="inherited" level="1">
      <content paragraph-head-indent="7" tab-stops="L 58" font-size="42" font-name="AJensonPro-Subh" paragraph-first-line-indent="7"/>
    </bullet>
  </bullets>
</slide>
[% END %]
[% # 16 lines of boring UI-describing XML below here %]
</pre>
<p>

Icky XML. Some of that is definitely silly (the thumbnail image
probably shouldn't be in the presentation XML, for one thing), and the
fact that they use <a
href="http://www.xmlhack.com/read.php?item=1865">SVG-like-but-not-quite-SVG</a>. But
to be honest, I can ignore all that, all I want to do is autogenerate
my presentation. Which I do. And it all works, especially when I remember to use
&gt; etc. ;-) All in all, a cute little hack, and quite fun.
I'll post the presentation after I've given it.

<p>

<i>Now can I be bothered to do an AxPoint -> Keynote converter...</i></p>


<hr/>



<h2>Module!</h2>
<h3><a href="/user/pudge/">pudge</a> on 2003-01-17T14:47:51</h3>
Where's the Keynote perl module?



<blockquote>

<h2>Re:Module!</h2>
<h3><a href="/user/acme/">acme</a> on 2003-01-17T16:08:53</h3>
Unfortunately there's a lot more to a presentation than just the bullet points. How are you going to add your company logo in the background or a rotating transparent butterfly?<nobr> <wbr></nobr>;-)
<p>
More seriously, there's so much XML in there I don't know where to start. Or if I should do it at all...</p>



<blockquote>

<h2>Re:Module!</h2>
<h3><a href="/user/pudge/">pudge</a> on 2003-01-17T16:18:15</h3>
Wuss!<br> <br>My vision is to create a "template" that sets up the basic look of a slide (or slides), and then use Perl to generate all the individual slides.  Right now I use a custom program called makeslides to take a text (YAML-ish) outline and creates pretty HTML with CSS etc.  It'd be sweet if I could make it generate Keynote presentations too.<br> <br>But I'll probably just end up doing as you've apparently done, create a few slides, then pull out the XML I want, and use that as a template.<br>



<blockquote>

<h2>Re:Module!</h2>
<h3><a href="/user/darobin/">darobin</a> on 2003-01-21T16:30:14</h3>
<p>
  I'd guess that if you're using HTML+CSS, the HTML must be very semantically structured and it'd be trivial to output XML instead. Starting from that, a YourML-to-KeynoteML XSLT should be trivial.
</p>





</blockquote>

</blockquote>

</blockquote>


<h2>html filters, SAX</h2>
<h3><a href="/user/2shortplanks/">2shortplanks</a> on 2003-01-17T14:51:26</h3>
<code>[% thingy | html %]</code>
<p>
Will automatically do the &gt; for you, but you knew that.
</p>
Cool hack.  Shouldn't you be doing this with SAX though?  Just place <acmepresentation:tagname/> in the right place and using a nice filter...



<blockquote>

<h2>Re:html filters, SAX</h2>
<h3><a href="/user/acme/">acme</a> on 2003-01-17T16:12:08</h3>
Oh, thanks. I'd forgotten about that. I could be using SAX, except SAX is horribly complicated when you're passing things around[1]. Template Toolkit is a tool I know well and I bet you dealing with XML in text blocks is faster than dealing with 500,000 XML events too.
<p>
[1] Stop complaining that I complain about SAX too. It may be simple, but isn't practical.</p>



<blockquote>

<h2>Re:html filters, SAX</h2>
<h3><a href="/user/2shortplanks/">2shortplanks</a> on 2003-01-17T16:41:41</h3>
Okay, then you could extract out the text with a XPath statement (using Template::Plugin::XML::LibXML, natch) then rerender it through a VIEW.  At least this way you won't be screwed when apple decide to put a [% in their template<nobr> <wbr></nobr>;-).
<p>
Hmm, you could do a presentation on that itself.  "How I created this presentation: A fully recursive talk".</p>





</blockquote>


<h2>Re:html filters, SAX</h2>
<h3><a href="/user/darobin/">darobin</a> on 2003-01-21T16:27:33</h3>
<p>
  TBH I'm not sure that SAX would be a good idea to do that. SAX is meant to be low-level, and works marvels at that. It's as close as you can get to XML without going lexical. Anyone using it for higher-level things will find it impractical, and rightly so.
</p>

<p>
  Other XML-orientated options that would be fit here could be XSLT (which acme also hates) or a number of modules from Barrie Slaymaker that deal with SAX at higher levels (eg XML::Essex or XML::Filter::Dispatcher).
</p>





</blockquote>


<h2>Hrrmm...</h2>
<h3><a href="/user/pdcawley/">pdcawley</a> on 2003-01-18T17:28:19</h3>
I'm finding Keynote to be something of a pain to drive. It looks lovely and everthing, and once you've got things how you want them it presents them well, but I've yet to find a way, short of editing the XML directly of adding text with linebreaks (vital when you're, say, explaining program listings). Ah well, at least linebreaks are preserved when you edit the XML.<br> <br>Which is probably down to the fact that Keynote was written for Steve, and when was the last time Steve explained any code?





</div> <!-- /span8 -->

</div> <!-- row -->
</div> <!-- /container -->



    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->

  </body>
</html>