Monday, February 1, 2016

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 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.


Noteworthy versions


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], [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], [Strikethrough]



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.


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: CommonMark, Github Flavored Markdown, Kramdown, Markdown-it, Marked, Maruku, Multi-Markdown, 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 and

 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: Github Flavored Markdown, Kramdown*, Marked, Maruku, Multi-Markdown, 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: Github Flavored Markdown, Kramdown, Markdown-it, Marked, Maruku, Multi-Markdown, 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


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


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



Footnotes & Other Link types


Footnotes allows 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)

There are a couple of other alternate link methods in Multi-Markdown, but they have virtually no support outside that specification. This includes Cross References and Citations. Chances are, the way that the individual parsers handle links is something you’ll want to explore.


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



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: 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 tag. However for a more comprehensive implementation of editor notes, you might want to check out the related format called CriticMarkup.


Available with: Github Flavored Markdown, Markdown-it, Marked, Multi-Markdown, 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 markdown implementations, namely Multi-Markdown. 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 versions says it support tables, doesn't mean that there's a standard way of defining the tables. Furthermore, some versions will generate HTML that is extremely verbose and some will be very minimalist. There’s also wide 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 behind the OpenMark. The best way to identify 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.




Choosing the Right Markdown Parser is a post from CSS-Tricks

No comments:

Post a Comment