Choosing the Right Markdown Parser

The following is a guest post by Ray Villalobos. Ray is going to explore many of the different varietals of Markdown. All of them offer features beyond what the original Markdown can do, but they offer different features amongst themselves. If you're choosing a version to use (or a version you're offering to users on your web product), it pays to know what you are getting into, as it's difficult to switch once you've chosen and there is content out there that depends on those features. Ray, who has a course on Markdown, is going to share which versions have which features to help you make an informed choice.

Markdown has changed the way professionals in many fields write. The language uses simple text with minimal markup and can convert it to a growing number of formats. However, not all markdown parsers are created equally. Because the original spec hasn't evolved with the times, alternate versions like Multi-Markdown, GFM (Github Flavored Markdown), Markdown Extra and others have expanded the language.

The original parser was written in Perl. The core features include parsing block elements (such as paragraphs, line breaks, headers, blockquotes, lists, code blocks and horizontal rules) and span elements (links, emphasis, code snippets and images). Since then, the language hasn't been expanded by its creator John Gruber, so a number of additions and implementations have surfaced with different parsers adding support for different implementations as they see fit, or interpreting how certain elements are parsed.

Choosing a version

There's a lot to consider when thinking about implementing Markdown into a project, including the language you'll be developing with as well as the features you want to support. The original implementation was written in Perl, but that's not a practical option for every project. There are implementations in most popular languages including: PHP, Ruby and JavaScript. Which language you choose will have repercussions as to which features you'll be able to support and what libraries will be available. Let's take a look at some of the options:

Language Library (download project)
Perl Original version
JavaScript CommonMark, Marked, Markdown-it, Remarkable, Showdown
Ruby Github Flavored Markup, Kramdown, Maruku, Redcarpet
PHP Cebe Markdown, Ciconia, Parsedown, PHP Markdown Extended
Python Python Markdown

There are additional implementations in many other languages, just in case you're looking to implement Markdown in other languages.

Core features

The core markdown language supports a number of default features that are quite useful. Although different implementations support a range of extended features, they should all support at least the following core syntax: Inline HTML, Automatic paragraphs, headers, blockquotes, lists, code blocks, horizontal rules, links, emphasis, inline code and images.

Noteworthy Extensions

With the many versions of markdown available, a few have had a substantial impact on other versions. So much so that you'll often see them quoted as part of other versions. For example, libraries will mention support of CommonMark, GFM or Multi-Markdown. Let's take a look at what those mean.

GFM

One of the reason Markdown became so popular with developers is because Github, the open source sharing platform accepted and extended the language with a version called Github Flavored Markup (GFM) to include Fenced Codeblocks, URL Autolinking, Strikethrough, Tables and even the ability to create to-dos within repos. So, when a version mentions support of GFM, look for those extensions to be implemented.

Supports: Fenced Codeblocks, Syntax Highlighting, Tables, URL AutoLinking, To-dos, Strikethrough.

CommonMark

Recently there has been a move to standardize markdown. A group of Markdown developers joined to create a version, tests and documentation for the language that resulted in a more robust specification for the language called CommonMark. At this time, the implementation added fenced codeblocks, but mostly detailed the specifics of how certain features were to be implemented for consistent output and conversion. A lot more extensions that would bring this more in line with what's available in other languages have been proposed for the future.

This format is relatively new and doesn't support a lot of features, but it is actively being developed and there are plans to add many Multi-Markdown features.

Supports: Fenced Codeblocks, URL AutoLinking

Multi-markdown

The first serious projects that extended the language is Multi-Markdown. It added a number of features to the language that is supported by other versions. It was originally written in Perl, like Markdown, but then moved onto C. So, if you see that a project has Multi-Markdown support, then it probably has most of these features.

Supports: Fenced Codeblocks, Syntax Highlighting, Tables, Metadata, Fragments/Cross References Links, Footnotes, Strikethrough, Definition Lists, Math.

Optional Features

Let's take a look at the features that are available through different implementations.

Fenced Codeblocks

One of the best additions for developers is the ability to easily add code to your markdown. The original implementation automatically considered a block of text as code if it was indented by 4 spaces or a single tab. That's sometimes inconvenient, so several implementations incorporated fenced codeblocks by allowing you to place three tickmarks (`) or in some cases triple tilde (~) characters at the beginning of a block of text to mark it as code:

```
body {
  margin: 0;
  padding: 0;
  color: #222;
  background-color: white;
  font-family: sans-serif;
  font-size: 1.8rem;
  line-height: 160%;
  font-weight: 400;
}
```

Available with:
Cebe Markdown, Ciconia, Github Flavored Markdown, Kramdown, Markdown-it, Marked, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

Syntax Highlighting

Adding code blocks is great but, by default, markdown interpreters will simply wrap the blocks inside <code> and <pre> tags, which makes the text show up as pre-formatted text in a fixed width font. Some implementations can improve on this by allowing you to specify a language next to the tickmarks and may include a parser that automatically lets you choose different color styles and specify which language your code was written so that the colors are more meaningful.

```css
body {
  margin: 0;
  padding: 0;
  color: #222;
  background-color: white;
  font-family: sans-serif;
  font-size: 1.8rem;
  line-height: 160%;
  font-weight: 400;
}
```

Available with:
Ciconia, Github Flavored Markdown, Kramdown*, Marked, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

* Some of this support doesn't come embedded into the parser, but is dependent upon other libraries like highlight.js.

Tables

Writing tables in HTML can be cumbersome. Some versions of markdown can take care of this by letting you add tables with a fairly simple syntax.

Dimensions | Megapixels
---|---
1,920 x 1,080 | 2.1MP
3,264 x 2,448 | 8MP
4,288 x 3,216 | 14MP

Renders like this:

Dimensions Megapixels
1,920 x 1,080 2.1MP
3,264 x 2,448 8MP
4,288 x 3,216 14MP

It takes a few minutes to get the hang of building tables like this, but after you do it a few times, you’ll think of using HTML a bit of a hassle. If you need help creating tables, check out this Markdown Tables Generator.

Markdown Tables Generator

Available with:
Cebe Markdown, Ciconia, Github Flavored Markdown, Kramdown, Markdown-it, Marked, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

Metadata

Some extensions will let you add meta data that you can use to add information that your app can parse like perhaps choosing a template or setting the page title. Some use the Multi-Markdown structure for this metadata, and others like the Jekyll parser use YAML as the format, which lets you express complex data within this metadata section. This can be a really useful handy feature for app developers.

---
Title:  SVG Article
Author: Ray Villalobos
Date:   January 6, 2016
heroimage: "http://i.imgur.com/rBX9z0k.png"
tags:
- data visualization
- bitmap
- raster graphics
- navigation
---

Available with:
Markdown-it, Maruku, Multi-Markdown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

URL Autolinking

This fairly simple extension allows URLs that naturally occur within your text to convert to links via the parser. This is really convenient and useful in an implementation like GFM, where making URLs clickable without additional work makes for building documentation that's easier to write.

Available with:
Cebe Markdown, Ciconia, CommonMark, Github Flavored Markdown, Kramdown, Markdown-it, Marked, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

Fragments/Cross Reference Links

With HTML, you can easily create references to within your document by using a hash mark in your anchor tag with the ID of an element on a page. Some implementations allow you to create a shortcut for this type of reference. That's specially useful because it allows you quickly cross-reference your own document without having to write a bunch of HTML. This feature is implemented in very different ways, so you really need to be careful to read the documentation for the specific version you'll be using.

You can link to a headline called 'myheadline' in your document using this [My Headline][].

## My Headline
The word 'reference' right next to this will get a link that links via an href to the headline above. The headline, in other words, gets an ID that the link points to.

Available with:
Ciconia, Multi-Markdown, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Redcarpet, Showdown

Custom IDs on Headlines

Another useful feature is the ability to have IDs within your headlines so that you can more easily target them through CSS. Some parsers will automatically place IDs on all headlines (specially if they support fragments/cross references), so this feature is not always necessary. However, it's nice that some versions allow you to customize how the parser names the IDs, which is sometimes more convenient than auto naming things.

### Custom IDs {#custom-id}
The headline above, when rendered by the parser, will have a custom ID that you specify in the curly braces.

Available with:
Cebe Markdown, Kramdown

Footnotes & Other Link types

Footnotes allow you to create links within your document to references that are placed at the bottom of the markdown page. This is different than normal links, which are placed inline within your content. This allows users to view all of the related links within a document in a single section, which is nice sometimes.

You can find a demo of a site[^Demo] built with PostCSS in our footnotes, or you can checkout the [^Github Repo] for the project.

#### Footnotes
[Demo](http://iviewsource.com/exercises/postcsslayouts)
[Github Repo](https://github.com/planetoftheweb/postcsslayouts)

Available with:
Cebe Markdown, Kramdown, Markdown-it, Maruku, Multi-Markdown, Parsedown, PHP Markdown Extended, Python Markdown, Redcarpet, Remarkable, Showdown

**Note**: There are many alternate link methods in parsers like Multi-Markdown. Support for these is very spotty in the individual versions. That means that even though the parser touts 'multi-markdown' compatibility, different parsers will implement different types of link references. This includes things like Citations, auto-generated ids in headlines, the ability to create custom IDs, cross-reference links and others. Some parsers will even invent their own link features.

To-dos

This is a Github Flavored Markdown feature that has caught on in some implementations. It adds to-do list markup so that you can create checkboxes next to content to simulate a to do list.

- [ ] Run `> npm-install` to install the project dependencies
- [X] Install gulp.js via the Mac terminal or Gitbash on a PC `> npm install -g gulp`
- [ ] Run the Gulp command `> gulp`

Available with:
Ciconia, Github Flavored Markdown, Markdown-it, Marked, Python Markdown, Redcarpet, Showdown

Strikethrough

If you want to mark text with a Strikethrough, you can use a notation in a lot of versions that wraps the text with the &lt;s&gt; tag. However for a more comprehensive implementation of editor notes, you might want to check out the related format called CriticMarkup.

Available with:
Ciconia, Markdown-it, Marked, Multi-Markdown, Parsedown, Remarkable, Redcarpet, Showdown

Definition Lists

Although definitions lists are not as common as other types of lists, it's a great way of coding certain types of elements in HTML, some implementations add a way to create these in a much simpler way. There are two ways of defining them, depending on the language, using a colon (`:`) or a tilde (`~`), although the implementation with the colons are more common.

ES6/ES2015
:   The new version of the popular JavaScript language

TypeScript
  ~ TypeScript is a language that is a superset of JavaScript that can be compiled through a transpiler to JavaScript that will work with most browsers.

Available with:
Kramdown, Markdown-it*, Maruku, Multi-Markdown, PHP Markdown Extended, Python Markdown, Remarkable

* requires an extension

Math

The ability to create mathematical formulas can be useful to some users, so a language for creating them has appeared within some implementations like Multi-Markdown. Although some languages claim to Support in other languages is available, sometimes through an extension.

Available with:
Kramdown*, Maruku, Multi-Markdown, Markdown-it, Python Markdown*

* requires an extension

Oh that sweet I/O

One thing that you have to be careful about is how different versions handle input and output. Just because a version says it supports tables, it doesn't mean that there's a standard way of creating the code for the tables. Some versions will generate HTML that is verbose and some will render minimalist code.

There’s also variations of how things like white space are handled. Some versions will place IDs within each headline and some won’t. This has been one of the concerns that the OpenMark platform tries to address, how to generate consistent output. The best way to figure out how the version you’ve chosen handles this is to use the Babelmark 2 test. Paste some code and it will show you how different parsers take care of the output as well as a preview of what that looks like on a browser.