On this past sunny, long Memorial Day weekend, I decided to play around with static site generation for a new blogging platform.

I’ve used a self-hosted Wordpress site for a while now, but I don’t use it enough to justify the resources. Plus, I found its new “blocks” WYSIWYG editor wasn’t great with links and code.

When dealing with links and code in prose, what better choice than a markup language? I’d love to use some form of markup, and avoid spending tons of time styling.

Those requirements lead me to Jekyll.

Jekyll and Org?

I’ve been an Emacs user for the better part of 4 years, and still use Org mode for a handful of tasks. I love the Emacs-native code snippet styling, simple LaTeX, and ease of exporting to other formats. `org-latex-export-to-pdf` was incredibly useful in college: I know enough about LaTeX to write math, but when organizing responses on an assignment, I’d prefer to let Org handle it.

I set out with a simple goal:

This should not be a challenging problem: Org has been around for a while, Jekyll has been around for a while. Surely a plugin exists to tackle this exact task. Or at worst, go from Org->Markdown (even Org->HTML), and let Jekyll take it from there.

A breeze through Jekyll

If you’ve heard of/used Jekyll before, here’s a brief intro, relative to what I’ll be touching.

Jekyll generates a cohesive, static site from various markup templates. I’m using it for a blog, but it offers colections, several templating/layout options, and more.

For my use case, markup goes in _posts, and is added to a list of posts on the home page. Example:

// _posts/2020-05-24-Hello-world.md
---
title:  "Welcome to Jekyll!"
date:   2020-05-24 17:33:51 -0400
categories:
  - category1 
  - category2
tags: 
  - tag1
  - tag2
---

Hello world!

On example.com, this will generate http://example.com/2020-05-24-Hello-world with the requested tags + content.

The state of Org+Jekyll support, and Org in general

In traditional Emacs fashion, you have your pick of solutions. Worg lists a majority of popular ones. Many looked out of date or unmaintained, but some looked promising.

Using that list + some searching, I had a handful of projects to try out.

All of them fell short for one reason or another, which surprised me. It changed my view of this ecosystem a bit, and I’d like to explore each potential solution a bit to identify sources of shortcomings.

jekyll-org

jekyll-org is a Jekyll plugin, allowing Jekyll to treat .org files as any other markup file, and auto-generate pages from it.

This means Jekyll handles everything: no exporting through Emacs necessary. Sounds great! Less I need to worry about.

I tried adding a code snippet. Org indicates a code block using the following format.

##+BEGIN_SRC python
import pprint
pprint.pprint("Hello world!")
##+END_SRC

With only one # on each line.

In my editor, syntax highlighting is all honky dory. Syntax highlighting is borderline essential for a tech blog: I post various code snippets so folks can follow along, so it’s a must-for the rendered output.

For one blog entry, this snippet gave me some hassle (ARM assembly):

// A ==> B
MOV R3, #0x2 // R3 Button mask
MOV R4, #0x3 // R4 EOR mask
AND R5, R6, R3 // Extract desired values

This rendered as:

<div class="highlight"><pre><span></span><span class="err">//</span> <span class="nf">A</span> <span class="err">==&gt;</span> <span class="no">B</span>
<span class="nf">MOV</span> <span class="no">R3</span><span class="p">,</span> <span class="c">#0x2 // R3 Button mask</span>
<span class="no">MOV</span> <span class="no">R4</span><span class="p">,</span> <span class="c">#0x3 // R4 EOR mask</span>
<span class="no">AND</span> <span class="no">R5</span><span class="p">,</span> <span class="no">R6</span><span class="p">,</span> <span class="no">R3</span> <span class="err">//</span> <span class="no">Extract</span> <span class="no">desired</span> <span class="no">values</span>

Notice how each token is given a span tag, so it can be identified and highlighted individually.

…Why does the second MOV instruction have a different class than the first? Why is a comment (//) given an err class, but the first “token” in the comment (A) is a seemingly valid nf?

Clearly something under the hood was weird. This begs the question: if it’s not using Emacs, what does it use?

org-ruby

To avoid running Emacs every time Jekyll publishes, jekyll-org uses org-ruby. This library + standalone program handles conversion from Org to a handful of popular formats. It’s used by GitHub and GitLab to render .org files, too.

org-ruby isn’t feature complete, which isn’t a surprise. The Org manual is big, and it’s the closest thing Org has to a specification. This makes the two interoperable implementations rule tough, much less a modest subset such as org-ruby.

jekyll-org supports syntax highlighting with pygments.rb, a Ruby library. (Note: Jekyll no longer uses it under the hood, and instead uses Rouge. I’m not sure if this will stop working in a newer version of Jekyll.)

Under the hood, syntax highlighting + exporting to HTML is a tricky problem. You need to know something about the target language in order to highlight it properly. You can’t get away with the horrible regexp hack Emacs uses to accomplish syntax highlighting, when you’re only working with HTML+CSS.

Since I’m essentially using two Org implementations, there will be discrepancies between what I see & what’s actually rendered. And you can forget about Evaluating Code Blocks to show code output alongside source. So I can’t use any advanced Org features with this library.

Not a deal breaker, but certainly disappointing.

Using Emacs to export Org as HTML

Jekyll supports a handful of markup formats: one Emacs-compatabile approach is to export Org as another markup format, and hand that off to Jekyll.

Off the bat, I’m not that fond of this approach.

Going from source->target to source->inbetween->target I can accept, since the inbetween is essentially just an HTML body that Jekyll will drop into a new page.

What I don’t like is the placement of the burden: myself. I need to remember to export Org as HTML before I commit, or even when I want to test something.

This is partially mitigated by git hooks, but git hooks are hard to manage.

Configuring an Org project

Org supports “publishing” configured projects for situations such as these. Worg has a segment on setting up such a project: https://orgmode.org/worg/org-tutorials/org-jekyll.html#org14785a7.

/(The #org14785a7 at the end bothers me more than it should. A Markdown-rendered page would link that header tag as configuring-org-html-export, or the like. But, I digress.)/

That example works, and you can change the hardlink to the writer’s directory if you like. But I hate that there’s a hardlink in the first place. This took me down my first rabbit hole: how to I make that a dynamic configuration?

Digging myself into a plist hole

Using Emacs to export Org as Markdown