[nolan@nprescott.com] $  cat weblog archive feed

Why Bother With Markdown?

2020-05-14

The more I pare down this site into the sort of unfussy, maintainable thing that interests me, the more I come to reconsider my choices about the design and implementation.

While I previously slimmed the templates and styles down into a more coherent, semantic HTML document, before even that I threw out a third-party templating in favor of my own as part of an experiment in the kind of maintenance I want for software I write. Almost inevitably, there is little left of the software that builds this site.

How Complicated Could Markdown Really Be?

I recently sat down and seriously considered writing or modifying my own markdown or markdown-like parser for converting these posts into their web-presentable HTML. I was initially drawn to the idea because it sounds like an interesting problem — how much does it take to parse markdown if you strip out all of the extension modules and supported flavors and everything else that gets bundled in? The longer I spent looking at different implementations the more disinterested I found myself getting; the more I learned, the less I liked markdown.

In my own use I think I've managed to overlook the crazy amounts of complexity in markdown and I never realized the number of different ways each implementation might differ (and hence, the need for so many flavors and extensions I guess). In most cases the implementation ends up being a pile of regular expressions, ho-hum. While I think markdown is okay, I don't know that it is valuable for the kind of writing I do. My most used features are probably:

It was about this point that I considered "doing it right" and designing a markup syntax that did only what I needed, with little more than what I've outlined above. Thankfully, I spent another minute thinking about it before realizing what I was envisioning was basically HTML. Which leads to the question of the hour:

Why Not Write HTML?

My list of nice-to-haves is so small I was able to come up with an answer for each, either in the format of HTML or in how I already do all of my writing. Of the three I thought fenced code blocks would present the most friction, due to the automatic escaping that markdown handles in the case of special entities like <>&.

It turns out simulating something like a fenced code block isn't too hard, perhaps due to the way I normally use them. Typically I am copying code from a program I've already written, or copying and lightly editing. As a result, I really just need a way to quickly insert the block sequence for preformatted code and a way to escape HTML entities within. I accomplish the first part with a feature built into Emacs, skeletons:

(define-skeleton np-skel-pre-code
  "HTML pre-code block template"
  ?\n "<pre><code>" _ "</code></pre>")

A skeleton is a barebones template with about two features. In the above I'm only using one of them. The underscore represents where the cursor lands after the template runs, so it's just a function to save me from typing out the two opening and closing tags. The second piece of functionality is a small bit of Emacs Lisp to take a selected region and replace troublesome characters within using the corresponding HTML entities:

(defun np-escape-html ()
  (interactive)
  (let ((replacer (lambda (search replace)
                    (goto-char 1)
                    (while (search-forward search nil t) 
                      (replace-match replace nil t)))))
    (save-excursion
      (narrow-to-region (region-beginning) (region-end))
      (funcall replacer "&" "&amp;")
      (funcall replacer "<" "&lt;")
      (funcall replacer ">" "&gt;")
      (widen))))

With that done I can copy a piece of code (like the function above), call my skeleton via a keybinding, paste at the cursor, and finally call np-escape-html on the region (via a keybinding in all likelihood).

skeletons are neat

I was so pleased to find skeletons easy to use that I went ahead and wrote two more, the first for inline-code blocks (<code></code>):

(define-skeleton np-skel-code
  "HTML code block skeleton"
  ?\n "<code>" _ 
  "</code>")

The second template demonstrates another piece of functionality available (or maybe two), I use it to create the stub of a new post:

(define-skeleton np-skel-new-post
  "new weblog post skeleton header"
  "Title: "
  "<h1>" str "</h1>"
  ?\n "<span>" (format-time-string "%Y-%m-%d") "</span>"
  ?\n "<p>"
  ?\n _)

Invoking the skeleton results in a prompt for a "Title:", the date is automatically included, and lastly the first paragraph tag which becomes the "leader" (included on the main page). These three pieces constitute a well-formed post in the generation process.

That's Nearly All Of It

So far, this has been sufficient to feel like I've matched the ergonomics of writing markdown I'm accustomed to. I'm already using a number of helpful utilities built into Emacs, things like html-paragraph (C-c RET) to create new paragraph tags, html-href-anchor (C-c C-c h) to insert links. I bothered reading up on some of the HTML spec and found that in the case of some tags, like <p> and <li> including the closing tag is optional, which further cements some of my ideas about markdown, I'm not even stuck slavishly chasing down a missing closing tag amidst the process of writing.

And before anyone else mentions it, yes, I've come full circle and my website looks not unlike something from the 90's which is fitting given how it is now authored.

Software Longevity

Having finally made the choice to quit writing in markdown my static site generator requires zero dependencies and a couple hundred lines of code. I can't really guess at how long this will last, but it does feel a bit like I've reached a local optimum for my own writing workflow. I don't really expect anyone else to use my tools because they're built for exactly one person — I also think that might mean they last longer.