Pelicorg: A Pelican Plugin for Emacs Org

Click here to skip the backstory and get to the code.

Back in 2011, this website was published as a set of extensions to Emacs’ popular Org mode. As the years went by, I used Emacs less and less for everything. I started another blog which I deployed using Pelican, which allowed me to quickly dash off posts in Markdown, and publish them without much of a fuss at all. Pelican isn’t perfect—no static site generator is—but for a few manic weeks I was able to almost completely ignore the publishing aspect of things and concentrate on writing.

Still, I had three problems:

  • Org 8 had finally arrived, with a complete rewrite of the publishing backend, and I couldn’t publish my old site with it.
  • I was now maintaining two blogs, with two separate sets of credentials, publishing systems, and authoring tools.
  • I liked both of them: the lightweight structure of Markdown for more prose-centric posts, and the insanely powerful Org mode for more technically focused essays with a lot of code.

I don’t know why it took me so long to cut the Gordian knot, but it finally occurred to me a week or so ago: Why not just… use Pelican to publish the Org files? Then I can give up on my (insanely too janky) Org mode publishing scheme, and have the best of both worlds.

Introducing Pelicorg

How does it work? It’s simple. For every Org file in your content directory, the plugin will launch Emacs on the command line, process the Elisp you give it, and spit out the completed HTML.

Yes, you have to launch Emacs for each file. You can’t run an Emacs server and pass off the requests to it, the behavior of princ is fundamentally broken with emacsclient.

It also requires Org 8. So, keep that in mind.

There are three variables for your pelicanconf.py:

  • ORG_READER_EMACS_LOCATION is a required, absolute path to your Emacs binary. If you use Homebrew, it’s probably /usr/local/Cellar/emacs/<version>/bin/emacs.
  • ORG_READER_EMACS_SETTINGS is an optional, absolute path to an Elisp file you want run on every invocation. This is a good place to (require 'package) and (package-initialize) if that’s where your Org comes from.
  • ORG_READER_BACKEND is an optional string with the name of an alternate backend in it. If you don’t know what this means, simply ignore it.

Well, what are you waiting for? Grab the source on GitHub and use Org to write some awesome technical essays!