Convert org-babel Markdown Blocks to HTML

During app development, I track the tasks in an org-mode task list. And I track the stuff I finished and want to highlight in the release notes in a Markdown block right there.

A list of tasks for the latest update, and the running list of relese note changes

When I release an update, I’ll copy & paste the Markdown part to the “Release Notes” of the app and push the changes to the server online.

I also convert the Markdown to HTML and paste the HTML in the app’s updater feed. The result will be rendered by the app when people are notified of a new update.

Until now, I opened my update.xml feed in TextMate, pasted the Markdown, then converted it via a macOS system service into HTML. Today, it occured to me that since I do everything in Emacs up until this point, why not also convert the Markdown to HTML? That should be 100% possible and I don’t need to switch the app for that.

The Markdown block in my task list is wrapped in #+begin_src#+end_src. This is an org-babel block. The name’s “Babel” because you can get syntax highlighting and execution of code in various (programming) languages. You can put the cursor anywhere inside the block, hit the idiomatic “execute” shortcut (C-c C-c), and confirm the execution of the code block.

By default, a Markdown source block does nothing. You need to install functions for org-babel to understand Markdown. For some reason, nobody pushed this as a downloadable package to the common package repositories, so all I found is Takahiro Noda’s ob-markdown.el code. You have to save the file and include it manually during the Emacs startup sequence.

The default output format is kind of disappointingly useless

The default output is not that helpful, though: each line is prepended by a colon (:). So copying the result is a pain. This is influenced by the variable org-babel-min-lines-for-block-output – the default value is 10, and this is less than 10 lines of output, so it doesn’t get wrapped in a #+begin_src-block but instead each line is marked as a result output line. (This behavior is the default to make replacing of the output possible by default.)

So you could lower org-babel-min-lines-for-block-output to, say, 3 and that’s great.

But you also can customize the code block’s header arguments to affect the output format. There’s a ton of options. But when you add :results output html, the output is always wrapped in a #+begin_src html block. That makes sense for Markdown conversion.

You can also make this the default for all Markdown code blocks so you don’t have to type these settings all the time.

This can be set as the default for the Markdown format, too:

;; By default, the header arguments for Markdown are empty:
;; (setq org-babel-default-header-args:markdown '())
(add-to-list 'org-babel-default-header-args:markdown
             '(:results . "output verbatim html"))

When you evaluate a Markdown code block now, these settings are applied by default and you get much nicer output.

The Markdown code is converted to an HTML block with beautiful (?) syntax highlighting!

Now it’s ready for copying and pasting into the Update feed.