tentacled gardener

February 9th, 2013  |  Published in etc

Yesterday at work I demoed some things I’ve been doing to make dealing with a Jekyll/Markdown-based workflow easier. It was all about knowing how to use existing stuff better, not inventing new stuff. Two things are thanks to BBEdit being so goddamn awesome, and took just a little time to discover then apply to our own environment:

  1. Custom HTML preview templates (so you can see your Markdown looking like rendered HTML in the same templates in use on your live site)
  2. Custom Markdown interpreters, so if you’ve strayed from vanilla Gruber Markdown, you can preview things like table markup rendered correctly.

Those two things make day-to-day Markdown authoring in Jekyll 90 percent livable.

Jekyll also has a preview server and filesystem watcher that’s supposed to give you the ability to run a little Webrick instance and have your site automatically regenerate when changes are made. That would address a pain point we have when we’re writing docs or trying to deal with a bit of Liquid and need to see how things will look for real rather than in Markdown and code. The problem is that our docs site is pretty big and there’s a lot for the filesystem watcher to keep track of, and it takes forever (o.k., 3 minutes) to build the site. So I tested Jekyll’s preview server and found myself making a change to a file and waiting as long for Jekyll to redraw that one page as I would have anyhow just to preview the whole site.

Last week, with the release of Puppet 3.1, I had to work with the Liquid in the templates to selectively show or hide links to the newly incorporated YARD developer documentation we’re maintaining. Being new to writing Liquid, I was doing a lot of stumbling around and experimenting, and it was driving me nuts. The immediate solution to the problem was actually to just make the minimum viable bit of Ruby needed to parse and render a here doc with Liquid markup in it. That would be something like this:

Both BBEdit and Textmate will run code with ⌘r, so it just takes a second to paste that into a window and run it and see what Liquid will make of it.

So that got me over the hump of not wanting to wait to regenerate our site just to make sure I was handling a few little conditionals correctly, but there are a other places where practically live rendering of Liquid would come in handy. For instance, our syntax highlighting doesn’t preview well.

So as I was fiddling with Octopress last week, I noticed one of its Rake tasks was isolate, which allows you to specify a specific file (or a fragment of its name). Rake moves all the files in the _posts directory to a stash directory except for the named file, then the little preview server spins up and the file is watched for changes. It makes previewing changes exactly as they’d be rendered almost instantaneous.

The Octopress solution wasn’t exactly right for us because it assumes a flat collection of files: No directories. And it also wasn’t exactly right for us because I think we tend to work on groups of files that may or may not share names but will probably be in a common directory.

So I took Octopress’s isolate and turned it into preview: Instead of specifying a file, you specify a directory, e.g. rake preview[hiera], and then let the little Webrick/fswatcher bits of Jekyll run. While I was in there, I added a here doc that provides an index of files available for preview/edit at the docroot of the preview server (so you don’t need to guess URLs to find what’s available). Even with a dozen or so files to watch and re-render, it only takes Jekyll about a second to catch on that something has changed and spit out an updated version. I modified Octopress’s isolate workflow a little further by automatically restoring the stashed files when the server is shut down, so there’s no need to run isolate‘s companion integrate task. It also invokes the Webrick preview automatically. So what Octopress does in three commands we can do in one.

An optional extra touch for the whole thing involves the LiveReload browser plugin, which makes it possible to monitor a given URL for changes to the associated file and automatically reload it. So I can stick Safari in my second monitor, make edits in BBEdit, and each time I save the file Jekyll re-renders it and LiveReload updates Safari without me having to reach over and refresh. That’s handy.

But really, learning about Octopress’s isolate task gave me a small nudge in the direction of just pulling the trigger on using Octopress for real, bringing me to a small list of things I’ve got to do to make the 1,865 (1,866 once this post is live) posts work o.k.:

  1. Scrubbing as much block-level HTML as makes sense. Mostly that means dropping naked paragraph tags because stuff just goes wrong with them in Markdown parsers. Hey … it’s version controlled, so I can even pass that stuff through kramdown’s html-to-Markdown function and see what I get.
  2. Scrubbing a bunch of poorly encoded characters that made their way through the several generations of software and operating systems involved with writing for the site. Fortunately, there are some fairly consistent ones, and BBEdit’s project search/replace will work fine for this.
  3. Getting the 301s proper. I wrote just enough Ruby to reassure me that the filenames Jekyll’s WordPress extractor created matched the SEF URLs WordPress was using, so it looks like I’ll be able to get away with a single 301 built on a regexp instead of some greater number of individual 301s.
  4. Straightening out syntax highlighting: I’ve got three or four different kinds of code markup on the blog, and since it isn’t even really a “code blog,” that’s sort of sad. I’ve got gists, <code> and <pre>, plus one or two false starts with WordPress plugins. Octopress has some plugins to support gists, which I’ve come to favor, but I think the more future-thinking approach is to convert non-gist code blocks to Jekyll/Liquid’s native method or CodeRay and leave existing gists embedded with JS alone.
  5. Images.

Wow. Images. What a mess. The WordPress part of the blog legacy won’t be terrible to sort out because they’re in consistent places, so no big deal to move them somewhere appropriate and either write a generic redirect or do a BBEdit mass replace. The Movable Type part of the blog’s heritage is sort of concerning, because I think I picked some of MT’s busier image display options and there’ll be some markup to find, parse, consider and rework.

Why’s it even matter? Mostly just the reasons for the ongoing trickle of traffic the site sees:

  1. org-mode In Your Pocket Is a GNU-Shaped Devil
  2. Put the current Chrome URL in your Safari reading list
  3. Import Mail.app “Notes” Into Evernote
  4. Scripting iWork Numbers ’09 With Appscript
  5. Back to BBEdit with a Unix Accent
  6. Dumping Your Safari History With Ruby (Apple’s Curious Epoch)
  7. Evernote and Repeatable Checklists

Those are the posts out of the top 10 for the past year that aren’t either the front page or an index page of some kind. Out of the top 20 or more, a small proportion of “personal” entries creep in. So, I look at the list and think that I’m responsible for information people are at least hoping will be useful. If I scope in on the date, the list is made up of pretty much the same items. There isn’t a ton of traffic coming through, but it’s not nothing. So I’d like the information to be accessible and halfway pleasant to look at; and I’d like it to continue to be discoverable. Making that effort feels like it’s just part of the social contract. Especially since I feel privileged to do the sort of work I do, and that having that privilege is a direct result of other information gardeners keeping up their own plots.

Leave a Response

© Michael Hall, licensed under a Creative Commons Attribution-ShareAlike 3.0 United States license.