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.
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:
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 "&" "&")
(funcall replacer "<" "<")
(funcall replacer ">" ">")
(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).
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.
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.
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.