Tricking Markdown to let me use ![]() syntax within HTML tags

This is a short post on a technique I discovered to trick Markdown (at least the brand of Markdown that I’ve been using that comes with Pelican) to let you stick Markdown-style syntax inside of HTML tags and have it still be parsed.

My particular use-case here was images.

TL;DR

Though normally Markdown doesn’t parse anything inside of HTML tags, you can use Markdown syntax inside of HTML tags in a Markdown file by tricking the Markdown using fake HTML closing tags within a comment. Example below, using Markdown image syntax along with Pelican’s internal content linking syntax:

<center><!-- </center> -->![My Image!]({filename}/images/myimage.png)</center>

This should render a centered image in the HTML, properly rendering the Markdown image syntax, like so:

<center><!-- </center> --><img alt="My Image!" src="https://myblogurl.com/images/myimage.png."></center>

Background

You can always stick arbitrary HTML inside a Markdown document, and it will pass through into the final rendered HTML document unchanged. This is often done for images, because even though Markdown has an image syntax:

![Image-alt-text](http://image-URL/)

Most flavors of Markdown don’t allow you to set the width and height, so people tend to use straight-up HTML instead.

<img alt="alt-text" src="http://image-URL" />

Because of difficulties with centering, as long as you’re using HTML, it’s also easy to center the image using <center> tags or by using styling, whether in-line styling or adding a class to your image. Vertical styling can be a pain though, and what I tended to need to do was stick everything inside a <div> in order to center it:

<div style="text-align: center;"><img alt="" src="path/to/image"></div>
<!-- or -->
<center><img alt="" src="/path/to/image"></center>

The Problem: Relative URLs and other Markdown syntax

The problem that arose in my particular case was trying to center an image while using relative URLs in the Markdown to specify the image source. In the Pelican docs, there’s a section on linking to internal content which specifies the following syntax for linking to any internal content within Markdown:

![My Image]({filename}/images/myimage.png)

Unfortunately, the {filename}/file/path syntax only works within a Markdown-style image or link tag, and so I couldn’t use that syntax within an <img> tag. However, if I wanted to center the image, I needed to have my image appear within manually-specified <center> tags or a <div>. This posed an issue, as Markdown does not process anything within manually specified HTML tags, so you would run across the following issue:

<!-- Markdown: -->
<center>![My Image](http://image/path)</center>

<!-- will be rendered in HTML as: -->
<center>![My Image](http://image/path)</center>

The Solution: Trick Markdown

I took a guess and figured that the Markdown parser was relatively lazy and didn’t take great care when refusing to parse anything within HTML tags—my bet was that when it encountered an opening HTML tag, it simply stopped parsing until it encountered the close of that tag. If I was right, that meant I could trick the parser like so:

<center><!-- </center> -->![My Image!]({filename}/images/myimage.png)</center>

And sure enough, it works! This creates a centered image in the HTML, properly rendering the Markdown image syntax, like so:

<center><!-- </center> --><img alt="My Image!" src="https://myblogurl.com/images/myimage.png."></center>

A Better Solution for Pelican

If you’re using Pelican, the better solution ultimately is to use the Liquid-style tags plugin, which should not only let you specify the width and height but also let you stick it inside a <center> tag. (Note that as far as I can tell, this will not work with <div> tags.) You still get to use the relative filename Pelican syntax, as well:

<center>{% img {filename}/images/Screenshot_2014-02-20-17-51-27.png 361 643 "Example image" %}</center>

However, what I’ve discovered above should remain useful to those using straight Markdown without access to plugins and who don’t want to have to get creative with their blog theme or Javascript.