The open-source community has pretty much standardized on Markdown for documentation which is a great choice because it's easy to read, write, and understand. That said, Markdown has a syntax, so there are "right" and "wrong" ways to do things - and not all parsers handle nuances the same way (though the CommonMark effort is trying to standardize). In particular, there are constructs that can lead to missing/broken text in some parsers but which are not obviously wrong in the original Markdown.
To show what I mean, I created a Gist of common Markdown mistakes. If you're not a Markdown expert, you might learn something by comparing the source and output. :)
Aside: The Markdown parser used by GitHub is quite good - but many issues are user error and it can't (yet) read your mind.
You shouldn't need to be a Markdown expert to avoid silly mistakes - that's what we have computers for. When I looked around for a Node-based linter, I didn't see anything - but I did find a very nice implementation for Ruby by Mark Harrison. I don't tend to have Ruby available in my development environment, but I had an itch to scratch, so I installed it and added a couple of rules to Mark's tool for the checks I wanted. Mark kindly accepted the corresponding pull requests, and all was well.
Except that once I'd tasted of the fruit of Markdown linting, I wanted to integrate it into other workflows - many of which are exclusively Node-based. I briefly entertained the idea of creating a Node package to install Ruby then use it to install and run a Ruby gem - but that made my head hurt...
So I prototyped a Node version of
markdownlint by porting a few rules over and then ran the idea by Mark.
Mark already had a fantastic test infrastructure and great documentation for rules, so I shamelessly reused both in the Node version.
I started with a fully asynchronous API for efficiency, but ended up adding a synchronous version for scenarios where that's more convenient.
I strived to achieve functional parity with the Ruby implementation (and continue to do so as Mark makes updates!), but duplicating the CLI was a non-goal (please have a look at the mdl gem if that's what you need).
If this sounds interesting, please have a look at
markdownlint on GitHub.
As of this writing, it supports the same set of ~40 rules that the Ruby implementation does - you can read all about them in Mark's fantastic Rules.md.
markdownlint exposes a single API which can be called in an asynchronous or synchronous manner and accepts an
options object to identify the files/strings to lint and the set of rules to apply.
It returns a simple object that lists the items that were checked along with the line numbers for any violations.
The documentation shows of all of this and includes examples of calling
markdownlint from both gulp and Grunt.
To make sure
markdownlint works well, I've integrated it into some of my own projects, including this blog which I wrote specifically to allow authoring in Markdown.
That's a nice start, but it doesn't prove
markdownlint can handle larger projects with significant documentation written by different people at different times.
For that you'd need to integrate with a project like ESLint which has extensive documentation that's entirely Markdown-based.
So I did. :)
Supporting ESLint was one of the motivating factors behind porting
markdownlint to Node in the first place: I love the tool and use it in all my projects.
The documentation is excellent, but every now and then I'd come across weird or broken text.
After submitting a couple of pull requests with fixes, I decided adding a Markdown linter to their test script would be a better way to keep typos out of the documentation.
It turns out this was on the team's radar as well, and they - especially project owner Nicholas - were very helpful and accommodating as I introduced
markdownlint and tweaked things to satisfy some of the rules.
At this point, maybe I've convinced you
markdownlint works for my own purposes and that it works for some other purposes, but it's likely you have special requirements or would like to "try before you buy".
(Which seems an ironic thing to say about free software, but there's a cost to everything, so maybe it's not that unreasonable after all.)
Well, I have just the thing for you:
markdownlint demo that runs in the browser!
So it was actually fairly straightforward (with some help from Browserify) to create a standalone, offline-enabled web page that lets anyone use a (modern) browser to experiment with
markdownlint and validate arbitrary content.
To make it super easy to get started, I made some deliberate mistakes in the sample content for the demo - feel free to fix them for me. :)
- Markdown is great
- It's easy to read and write
- Sometimes it doesn't do what you think
- There are tools to help
markdownlintis one of them
- Get it for Ruby or Node
- Or try it in the browser