The misery of exporting Org files to S5

In my last post, I mentioned that exporting from Org was a big reason for using it to present. I personally feel like video content is a complete waste of time, so I definitely want my presentation to be available in a format other than video. Because it’s been around for a while, I had read in a few places about slideshows using S5. And I knew that it was possible to export to S5 from Org (note: old info). Surely this would be easy and the output would be perfect on the first try! That turned out to be the exact opposite of what happened. In the end, it took at least five or six hours of fiddling in order to get everything working. Admittedly, if I knew more about HTML and CSS - in other words, if I were the sort of person S5 seems to be designed for - it would likely have been much easier. Likewise, the most up-to-date export tool, ox-s5, seems to be aimed at people who already know a lot about S5. Maybe you can see where this is going.

Rather than rant about how I stayed up until 2am the night before (or the morning of?) my 21st birthday messing with HTML in a text editor, I’m just going to list off a bunch of lessons I learned, to hopefully save future users a bit of pain.

Getting the basics to work

The first issue is the customization variables that ox-s5 offers. Don’t use ‘em. I know, we wouldn’t use Emacs if we didn’t want to change settings - but no. You don’t want to change these settings. The only one you’ll want to change is to specify your theme file, and while there are many wrong ways to do this (and I tried them all), the right way is to specify a CSS file. The exact filename depends on the theme you’re using. For me, I used (setq org-s5-theme-file "railscast/pretty.css") . That’s a relative link, which were the only kind I could get to work, to the railscast theme from the org-s5 repository.

The setting that really messed with me was org-s5-ui-url . It doesn’t seem to do anything other than break your slideshow. I tried settings a direct link to the ui folder, as in C:/Users/Matt/s5/ui - didn’t work. Perhaps it was being interpreted as a relative link, I don’t know. Given that I had no idea what I was doing, I spent a while re-exporting my slideshow, opening it in one folder, moving it and opening it in another folder, over and over in a pitiful attempt to make things work.

When I stopped customizing this variable and reset its value to ui , all of a sudden I had a semi-working presentation! The HTML file has to be kept beside the S5 ui directory in order to work, but whatever. Also note that the ui directory has to contain both the theme you want to use and the default theme, as most themes seem to reference the default theme.

Once I had something being exported, the first thing I changed was to tag parts of my Org file as :noexport: . Just write that beside a heading, and it won’t appear in exported documents. Useful for embedded code blocks that you use to process results and such.

After this, I needed to tweak exported HTML file, which is unfortunate. Most of the changes I made could be automated, if I knew enough Emacs Lisp; for now, perhaps some kind soul will incorporate them into ox-s5. So, what did I change?

Simple HTML changes

I deleted the table of contents. org-present considers every top-level heading as a slide, and nothing else (this is kind of annoying). ox-s5 exports a table of contents containing every heading in your file. These two facts don’t play well together, because org-present encourages having a lot of headings, which then gives you a TOC that’s too large to display on one screen. Aside from that, the table of contents doesnt’ even provide links to specific slides, and S5 advances slides when you click, so it’s useless twice-over. Would be nice if there were an option in ox-s5 to turn off the TOC.

The next issue is that some part of the exporting toolchain considers the underscore character as a marker for subscripting. So if I mention, in plain text, a function called waste_time , I get waste time in the HTML output. It’s hard to say if this is a bug, a misfeature, or what - at any rate, I had to regex replace <sub>(.+?)</sub> with _\1 .

I didn’t like the section numbers being beside my headings, so I removed those. Regex replace <span class="section-number.+?</span> " with nothing (trailing quote mark intentional, I think). Unsure if this can be customized already, but it would be nice to have a choice.

Aesthetic changes

In a few cases, when a slide got too long to show on my (admittedly small) laptop screen, I had to add an extra <div> around half the content, and specify class="slide" . For a few of my headings, I also deleted the slide class, so that S5 would skip over them. If you know as little about HTML as I did at the time, that’s probably hard to visualize - so check out the source to see what I mean.

The exported HTML has some CSS embedded in it, and I tweaked things there rather than modifying the theme file (at least, originally - some things are in the theme file now). First thing: When you have code blocks in your source, ox-s5 will show the programming language name when you mouse over them. Only for a few predefined languages, though - and it should really decide what languages to use based on org-babel-load-languages . I added this rule: pre.src-python:before { content: 'Python'; } to handle Python blocks. Also, the language name doesn’t show up very well on dark backgrounds, so I added color: black; in the existing pre.src:before block.

Another issue I was having was that using the arrow keys to change slides was attempting to scroll the page. So the scroll bars would show up, sometimes content would go off screen in certain browsers if you pressed left/right too much, and it just looked dumb. Adding body { overflow: hidden; } fixed that. This probably deserves to go in the theme file itself, but perhaps ox-s5 could specify it anyway - I can’t imagine why you’d want the scroll bars visible.

Lastly, for aesthetic reasons, I decided to center my headings. So: h1 { text-align: center; } and h2 { text-align: center; } handled that. However, that made my title slide look weird - apparently my theme added some padding to headings. Solution: #slide0 h1 { padding-right: 0; } . This isn’t useful for anyone not using the railscast theme, but since it’s the only good looking theme I could find, I figure it’s worth mentioning.

Indirectly fixing bad behaviour

S5 also has some funky JavaScript code, pre-jQuery, which attempts to hide slides other than the one you’re currently looking at. For my presentation (which had some short slides), and with the theme I was using (which didn’t have large a large header or footer like the default theme), this wasn’t working all the time. Oddly enough, sometimes it would work, for a little while. Anyway, there was no need to fix the JavaScript portion - adding .slide { margin-bottom: 1400px; } solved the issue.

As a bonus, it also fixed the problem I was having where slides at the bottom of the page couldn’t be shown correctly. Presumably, this won’t work perfectly on screens taller than 1400 pixels + length of my content, but I don’t know how big of a number I’d need to use to satisfy people with vertical monitors. This might be worth including in ox-s5’s output by default - I have no idea if it has any adverse effects, though.

Edit: Turns out adding this bottom margin globally messes up the print stylesheet, which would have allowed me to easily convert the slideshow into a PDF using Chrome’s print to PDF option (and presumably other browsers can do it too) - without the pain of exporting from Org to LaTeX. With the margin, each slide winds up being on one page when you try to print (if that’s what you want). Normally, the settings for printing are in a file called print.css. If you put the margin-bottom thing in your main theme file, in my case railscast/pretty.css, it works out fine..

Edit 2: If you scroll using the mouse with the margin active, you wind up in empty space. And the arrow keys stop working. So, uh… don’t do that.

Aftermath

And after all that, I finally had a working slideshow. You can see it here, if you want. I realize that these instructions are probably fairly specific to me, but, if I want to make another slideshow in a few months I’ll be happy I wrote them down. And I guess I did learn a bunch about CSS and HTML from a supa pro web dev friend. It was painful at the time, because nothing worked and I had no idea why, but I’m happy with the end result and happy with what I learned.

…However, while preparing this post, I found org-reveal. Which kind of sucks because it looks amazing. Probably because Reveal.js is more modern, org-reveal offers more control over the structure of the exported presentation, to say nothing of the options for visuals and other fancy junk. I mean, I like the look of my presentation - I’m a minimalist. Which is to say I have no sense of design whatsoever and the less design involved, the better. But the setup of S5 means that nice things require editing HTML and CSS, and I know neither. I have no idea how I’d add transitions between slides, for instance. And I can’t specify those things in my Org buffer, like I could with org-reveal.

In other words, this is probably the only time I’ll ever use ox-s5. But I’m glad it exists. The one downside to Reveal.js is that I think it’s what everyone else uses for their presentations at EdmontonPy, and it likewise only has one good colour theme (the default), so if I had used org-reveal there would have been three nearly-identical slideshows in a row. That just seems weird to me.

For the more visually inclined (not me), impress.js exists, and there’s an older package for using it from within Org. It hasn’t been updated for Org 8’s new export engine, though, and since it’s 3000 lines of code, an update could be non-trivial.