The 10 second elevator pitch
A free alpha markdown editor for OS X 10.6 that lets you preview your document as you write it, according to Markdown syntax
No, really, what is it?
A Markdown editor that formats your Markdown document as you write it. It’s not quite a WYSIWYG editor, as the markup is still visible in the editor. It’s more of a preview so you get an idea how your document will be processed by Markdown.pl, or any of the plethora of Markdown variants.
It’s free, it’s on Github and any feedback, bug reports, or code/patches are most welcome. To build it, you need a copy of OgreKit.
And of course, this document was written with it.
Features
Syntax highlighting for most Markdown formatting including:
- ATX & Setex style headers
- Inline formatting: italic/emphasis; bold/strong; and
code spans - Links – including reference-style – with automatic linking of text
- Inline display of images (for local images)
- Blockquotes
- Lists
- Horizontal rules
- Code blocks
- Default app icon ;)
What does it look like?
The same document in TextEdit, for reference.
A screenshot of a draft of this page.
What’s missing/broken?
An automated tests suite! My excuse is that this started life as an experimental project, so I haven’t done it yet.
Editing around inline images was very buggy, but it seems I’ve ironed out most of the bugs with it.
Strong spans ’**’ nested in emphasis spans ’*’ aren’t picked up. Syntax such as:
*outer **inner** outer*
is effectively interpreted as
*outer * *inner* * outer*
**outer * inner* outer** works correctly.
However, nesting the other way round is correctly highlighted. Also, switching characters – ’*’ vs ’_’ works fine too.
This bug is a dilemma for me as the editor works one way, but Maruku has the opposite problem: It marks up explicit lists incorrectly. Maruku also won’t accept a <hr> without a leading blank line.
Implicitly nested lists aren’t highlighted correctly:
* List
* Sublist
Is a no go, whereas
* List
* * Sublist
works fine.
Top: Correct. Bottom: Incorrect.
Lists with multiple paragraphs aren’t always picked up properly:
* Paragraph 1
Paragraph 2
Will be interpreted as
* Paragraph 1
Code block
due to the parser looking only at the paragraph you edited, instead of the whole document.
The second line of each of the top two isn’t indented correctly.
Automatic indentation doesn’t work well on hard-wrapped paragraphs, the indentation of a block-quote such as
> Line 1
Line 2
or
> Line 1
Line 2
doesn’t align as nicely as one like
> Line 1
> Line 2
or a block with soft-wrapped lines.
The cursor sometimes gets drawn in the wrong place when deleting text. I think this has something to do with me making the wrong sequence of calls to manage the NSTextView system.
Doubtless there are more problems lurking in there. As I said, it’s alpha. Generally I look at a copy of the Markdown reference to see what’s good and what’s not.
What’s next?
Of course I’d like to fix the bugs mentioned above, and I have a pet list of features that I’d like to get to:
-
A good name! I’m thinking of “Rug”. The name should be a pun on markdown, it’s an exercise for the reader to find the pun here.
-
An application icon would be nice… If you’re a designer with some free time, I’d love to pimp your icon-making skills! Also, A design-eye to layout the document, make-this-beautiful-type would be nice too.
-
Fix the file extension/file type stuff so that it will open the right kind of files, and not have weird formats in the save dialog.
-
Highlight missing image references in the same way as missing link references.
-
Highlight hard breaks at the end of lines – Simply
/\s{2}$/for those that know their regular expressions. -
Make the typography customisable.
-
I’d like
<hr>s to rule across document, but this needs work with NSLayoutManager/NSTextView. -
A menu option to… This part of the document is where the earlier implicit list item nesting bug bites me
- toggle inline images.
- show/hide Markdown syntax.
- format selected text.
-
It would be nice to disable spell-checking on code blocks.
-
I’d like to tweak the margins, simply to make the code-block background bleed off the edge.
-
Syntax colouring for code would be nice.
How does it work?
It’s basically an NSTextView with a delegate that, when the document is edited, parses it – The last edited paragraph, to be exact – and adds text attributes to the text at appropriate places. It does it line-by-line for the block elements, and then runs a check across the ‘content’ part of each line to mark the links, images and other inline markup. The line/block processor keeps a stack of the block types to enable nesting.
I use the great Ogre Kit for regular expressions. I should put together an English overview of the API as most of the documentation is in Japanese.
The original version tried to do the work with “smart” regular expressions that could deal with nesting and so on, but quickly became unwieldy – The joke “start with a problem, try to solve it with regular expressions, now you have two problems” felt quite apt. I built a prototype of the current line-by-line-with-stack parser in Ruby, and tried to port the algorithm directly into Objective C, which was quite painful. If you’re a programmer you can probably imagine…
Interestingly, trying to put this together really drove home how ambiguous Markdown can be. I’ve generally taken the behaviour of the Markdown dingus to be canonical, and in writing this document, I’ve discovered some discrepancies between the dingus and Maruku – the library I use to generate this site.
There are existing Markdown parsers…
I looked into using one of the existing parsers, but I couldn’t find one that would give me back the parse-tree with character offsets, rather than just spit out HTML. If you know of one that I could use or adapt to get character offsets, I’d really like to know.
Why not in Emacs?*
*Or your editor of choice.
Good question, I’m not sure why not. It probably would have been easier to customise the faces in Emacs than write this, but my love-hate relationship with Emacs on OS X encouraged me to make it a Cocoa program. Also, my initial inspiration for this was as a widget in a journaling program.
That said, it seems I have an old version of markdown-mode.el, the new one makes it even easier to make redundant my hard work writing this application.
Why build it in the first place?
Why not?
Less flippantly: On an injury-enforced break from work, I stumbled across the journaling application Mémoires, and thought about moving my work log – written in Markdown – into it. Turns out Mémoires doesn’t work quite how I’d like, so I thought about making a similar application. Thinking of how my dream journal app would work, of course I thought it would be nice if it supported Markdown natively. This tweaked my interest, so I put this editor together. The journal app still remains an idea.
Why not give it a try?