Svenv.nl

Home notebook with code

Adding CSS classes to images with markdown

I use markdown in my blogposts to apply some basic formatting to my content. I chose markdown over HTML because it's far more readable and much less cumbersome.

The downside of markdown however, is that because of it's simple nature, sometimes it can be quite limited. I encountered this problem when I needed to apply formatting to an image. A simple CSS class on the image was al I needed but markdown doesn't support this. I fixed this by extending markdown.

Since I use Django, and markdown is called as a custom template filter. I could easily extend it to make it support CSS classes. I can now use an alternative image syntax like this:

![Alt text](/path/to/img.jpg "Title" "Class")

as well as the original:

![Alt text](/path/to/img.jpg "Optional title")

The snippet below contains the code to make it work:

from django import template
from re import sub
from markdown2 import Markdown


@register.filter
def markdown(value):
    """
    Runs "svenv flavored markdown" on value
    """
    md = svenv_flavored_markdown(extras=['fenced-code-blocks'])
    return md.convert(value)


class svenv_flavored_markdown(Markdown):
    def _do_links(self, value):
        """
        Extends markdown image syntax with additional class parameter
        Syntax: ![Alt text](/path/to/img.jpg "Title" "Class")
        """
        value = sub(r'!\[(.+?)]\((.+?)\s+?["\'](.+?)["\']\s*?(?:["\'](.+?)["\'])?\)',
                      self.parse_markdown_class_image, value)

        return super(svenv_flavored_markdown, self)._do_links(value)


    def parse_markdown_class_image(self, match):
        """
        Replaces the match with correct image tag
        """
        alt = match.group(1)
        src = match.group(2)
        title = match.group(3)
        classname = match.group(4)

        if classname != None:
            html = '<img alt="%s" src="%s" title="%s" class="%s" />' % (alt, src, title, classname)
        else:
            html = '<img alt="%s" src="%s" title="%s" />' % (alt, src, title)

        return self._escape_special_chars(html)

Regular markdown isn't matched by the regex and is passed to the original (markdown2) library, so this change has only minimal impact on the original behavior.

Regards,

Sven van de Scheur

Published on July 5, 2015, 12:48 p.m.