I get Marked Down, but I get up again

When I first decided to start writing this blog I wanted to do it using Markdown, however the default HTML it generated didn’t align with what I needed. One example is my block code <pre> tags need the prettyprint class(es). So I resorted to manually typing everything as HTML.

It was only recently that I had the brain wave that Markdown can be rendered in any way you want. I suppose it might have come to me sooner if I had more frustration with how I had been writing articles, but as someone who writes a lot of HTML, writing a bit more to do a blog post never seemed like that much of a chore.

This post talks about how I used to write my posts, how I do it now, and what advantages there were to changing.

The Old Way

There’s not much to say here — I used to write all my posts manually directly into HTML. I would have to:

  • Convert all HTML entities manually, including straight to curly quotes (e.g. &rsquo; or &ldquo;), em-dashes (&mdash;) ellipses (&hellip;) and so on
  • Add target="_blank" rel="noopener" attributes to links
  • Remember what classes were needed in my <pre> code blocks
  • Remember which heading tags to use
  • And probably more that I’ve forgotten

Enter Markdown

The main advantage I’ve found with markdown is that I can stay in the writing “flow” much more easily. I no longer have to refer back to previous posts to remember how something has to be done. Probably the number one thing I’ve noticed is how disturbing it is to keep stopping your train of thought to add <p></p> tags when you get to the end of a paragraph.

I’m sure that I’ve missed, in previous articles, the conversion of a ' to &rsquo; a few times.

Also it has allowed me (although this might be just a mindset change) to start writing articles on my iPhone while I’m out — most of my previous post was written in a Doctor’s waiting room.

There’s no real reason why I couldn’t have done this before: since I still had to add code examples when I was back on a real computer anyway, I would also use that opportunity to add tags and HTML entities. But something about not needing a computer to add the <p>s and <h3>s in the right place feels so liberating.

How It’s Done

I decided to use Mistune as the Markdown-to-HTML converter, because it’s pure Python and supports custom renderers. You can subclass the Renderer that performs the conversion process and only override the parts you need to customise.

It also supports custom lexers, although I don’t need them yet it’s nice to know they’re there.

I also threw in smartypants which takes care of educating (curling) quote marks, converting characters to entities, and other typographical niceties.

I don’t think it’s worth putting in on Github, so here’s my converter. It’s licensed under the (spins Wheel-O-License) Unlicense

from sys import argv

import mistune
import smartypants


class BbitBlogRenderer(mistune.Renderer):
    def block_code(self, code, lang):
        lang_class = " lang-{}".format(lang) if lang else ""
        return """<pre class="prettyprint linenums{}">\n{}\n</pre>""".format(lang_class,
            mistune.escape(code))

    def paragraph(self, text):
        return super().paragraph(smartypants.smartypants(text))

    def header(self, text, level, raw=None):
        return super().header(smartypants.smartypants(text), level, raw)

    def link(self, link, title, text):
        title = """ title="{}""".format(title) if title else ""
        return """<a href="{}" target="_blank" rel="noopener"{}>{}</a>""".format(link, title, text)


def main():
    renderer = BbitBlogRenderer()
    markdown = mistune.Markdown(renderer=renderer)
    with open(argv[1], 'r') as f:
        print(markdown.render(f.read()))


if __name__ == '__main__':
    main()

This code is probably my most time per line ever, since I guess it took me some four-and-a-half years to come up with it.

Future Improvements

Right now the script just reads the Markdown and outputs to the console. In future I’d be able to put the Markdown straight into the DB and have it rendered in real time. Or at least on save of the post. Maybe I’ll do that in a few years’ time.

Conclusion

Anyone who writes blogs probably already has a process that works for them but I thought I’d share mine. I guess it’s just a reminder that when working on improving a system, it’s not always necessary to overhaul the whole thing, sometimes good improvements can be made just by optimising a part of it.

Blogging about blogging?

Blogception.

Previous entry

Next entry