A few weeks ago GitHub introduced a markdown toolbar to their textarea interface in pretty much the style I've been wanting to add to our Project Management Tool for a while. I had been putting off this task because I didn't want to try and solve what I saw as a complicated problem myself when I knew other people were working on it. I was waiting for the perfect "Markdown Toolbar" library to present itself.
There's been lots of activity in the past few years in this space of creating "smart" WYSIWYG editing interfaces. Basically, web developers who like flexible text-based formats like Markdown have their own take on the aging ideas of CKEditor and TinyMCE (which in turn drew inspiration from word processing software like Microsoft Word). In fact, there's now even markdown-compatible interfaces to these WYSIWYG editors, for example: http://ckeditor.com/addon/markdown. But there's plenty of fresh starts as well. My friends at 201-created put together the well thought-out Mobiledoc-kit.
Since working on the CommonMark python library, I've learned the value and ease of developing against a well-defined test specification when dealing with text i/o. (That's also why I think CommonMark is such an important project in the sea of unspecified Markdown libraries). I learned that there's really no theoretical knowledge required: although I know the terms, I couldn't tell you the difference between parsing "top-down", "bottom-up", "recursive descent", etc.
I've always appreciated the ideals of reverse engineering, "black box" design. And to me, it sort of takes the boring parts out of developing something: project planning and writing specifications. If you have well-defined inputs and outputs, all you're left with is the fun part of writing the code. Now I understand why there are so many SNES emulators out there.
The first step is copy-and-paste the DOM elements:
markdown_toolbar.html.
Looking at the HTML gave me some intriguing clues into how this works:
The buttons use the
data-prefix
, data-suffix
,
data-block-prefix
, and data-block-suffix
variables to define what sort of text is added around the cursor.
With this piece of info, I put the heart of this re-implementation
in
markdown_toolbar_controller.js using the unit tests at
markdown_toolbar.spec.js.
The controller is connected to the DOM with
markdown_toolbar.js.
The code now works for basic use cases. It doesn't behave in the
exact same way as GitHub's toolbar yet, and there are minor bugs.
But the path ahead is straightforward: I just need to add more
unit tests (with use cases taken from GitHub's toolbar), and I
need to expand the breadth of my unit testing. For example,
there are parts of markdown_toolbar.js
that should
be tested,
like the lastHotkey
and lastText
functionality that records what happens when you click the same
button twice.
After development is complete, it would be nice to package markdown-toolbar into a separate library that can be integrated anywhere.
Update (March 15, 2017):
You can now use this package as a jQuery plugin: https://github.com/nikolas/markdown-toolbar