Writing a reStructuredText plugin for Nikola

In the previous post I wrote about how and why I changed the engine behind my website to Nikola. There was just one thing which got lost in migration: support for ASCII Box reStructuredText compiler extension, which provides asciibox reStructuredText directive. With asciibox directive, one can compose ASCII text diagrams which then get rendered as images by reStructuredText compiler.

I decided to share the responsibility of rendering ASCII text diagrams as images in Nikola's output between the following three components:

  • A tool for rendering image files from ASCII text diagrams. (Renderer)
  • An extension to reStructuredText compiler for rendering images from ASCII text diagrams defined within the body of asciibox directive. (reST extension)
  • A Nikola plugin for integrating the reStructuredText extension with Nikola's build system. (Nikola reST plugin)

Their mutual relationships are illustrated in the following diagram (which is actually defined with asciibox directive, see the page source):

components.png

Renderer and reST extension had already been implemented in ASCII Box as I had used asciibox directive also with my previous site generator. So, I only had to figure out how to integrate the reST extension with Nikola's build system.

Luckily, the plugin API of Nikola seemed straightforward and there was also a suitable builtin plugin, rest_media, which I used as a reference (media.py and media.plugin).

Because the actual rendering work and reStructuredText integration was already been taken care by asciibox, the implementation of Nikola reST plugin required just the following two files:

plugins/rest_asciibox.plugin:

[Core]
Name = rest_asciibox
Module = rest_asciibox

plugins/rest_asciibox.py:

import asciibox

import nikola.plugin_categories

class Plugin(nikola.plugin_categories.RestExtension):

    name = "rest_asciibox"

    def set_site(self, site):
        self.site = site
        asciibox.register_rst_directive()
        return super(Plugin, self).set_site(site)

By default, Nikola includes all plugins from the plugins/ directory, so no configuration changes had to be made. I only had to ensure asciibox was somewhere in Python's module search path for the plugin to be able to import it.

Now it's all working and I'm a happy user of Nikola!

Comments

Comments powered by Disqus