Gems in the rough #2

More geeky hints for SSG fans.


For those of you who haven’t read the first “Gems in the rough,” initially posted just a few weeks ago, it contained a variety of what I hoped were useful hints and tips for those of you who, as do I, love playing around with websites built by static site generators (SSGs). In that one, I offered the opinion that “this might end up being a series.”

Well, looks like we’re there, because I’ve already accumulated some more of this stuff to pass along. (Fortunately for you, I doubt seriously that future such instances will be quite this closely spaced. No promises, though.) So, without further ado . . .

Straight cache, homey

[Fans of U.S. professional football likely will “get” the pun in that headline without much help, but here’s a brief explainer for the rest of you.]

I spent three entire posts in recent weeks talking about how to handle cache-busting your CSS in Eleventy. Now, don’t worry: I’m not going over all that again, I promise. Still, for those of you who did read those posts, especially the last two (in which I proposed a solution that actually works with my recommended CSS setup), please be aware that I recently added one more notable bit of related info. So here it is once again (including a later update):

Important: Note that the process completes itself only during actual site builds, and not in the dev or testbuild scripts — which means that, for version control purposes (i.e., changes you can commit in Git), actual site builds are the only times that all the applicable changes will occur. Thus, you may want to gitignore the top-level file csshash (but not csshash.js) and the files /_data/csshash.json and /_data/year.json.

While this means your builds online are always okay, it occurred to me that you might (as I did) become concerned that, during your local development, your version-controlled CSS edits weren’t triggering concomitant version-controlled edits for the corresponding files handling the cache-busting. (If that sentence doesn’t quite make sense to you, please review those aforementioned three posts, especially the last two.)


Each SSG has its own way of parsing the plain text, usually Markdown, that constitutes a typical static website’s main content. The Hugo SSG’s default parser is goldmark. While it’s faster than its predecessor, Blackfriday, goldmark currently has a bug — or, to be more specific, one of its built-in extensions has a bug — that will matter to you if you care about good typography.

The Typographer extension is supposed to make sure text has the proper “smart” punctuation:

Here’s some nice-lookin’ “punctuation.”

However, as of this writing, the goldmark version “shipping” with Hugo has a problem with plural possessives. As I noted in an issue I filed concerning the problem, if you include the following text in a Markdown file . . .

John's dog is named Sam. The Smiths' dog is named Rover.

. . . you’d expect to get:

John’s dog is named Sam. The Smiths’ dog is named Rover.

But what you actually get right now is:

John’s dog is named Sam. The Smiths' dog is named Rover.

So, if you’re a Hugo user right now, you have two options where it comes to good typography and plural possessives:

  • Make sure you manually (or, if your text editor app handles it for you, automatically) take care of “smart” punctuation in your Markdown source files rather than relying on Hugo/goldmark to do it.

  • Use your Hugo project’s config file to opt instead for Blackfriday, which Hugo does still support. It’s unknown how long that support will continue; so, if you go this route, you may want to start periodically checking the Hugo community forum and relevant Hugo docs, just so a deprecation doesn’t catch you by surprise.

Update, 2022-03-02: This issue was resolved on February 28, 2022, with the release of Hugo 0.93.0. It included the first goldmark version, 1.4.7, with the code from a pull request that fixed all the cases I’d reported.

Check your brackets

Those who have inflicted upon themselves the curse of reading any significant number of my posts are all too aware that I have a thing about using footnotes. Often, lots of ’em. So it kinda griped my cookies (as the technical term is used) that Eleventy — when properly set up for footnotes in the first place through use of the markdown-it-footnote plugin for Eleventy’s usual markdown-it parser — always encased the footnote numbers in brackets. Brackets!! Argh.

Here’s an example, using a screen capture of a paragraph from last year’s “YouTube TV and the RSNs flap”:

Paragraph ending in a footnote whose number is bracketed

But it turns out there’s been an answer out there for months, in the form of Mark Llobrera’s “Eleventy: Markdown and Footnotes,” in which he prescribed adding the following code within the part of the .eleventy.js config file that specifies how markdown-it and its various plugins will work with Eleventy:

markdownLibrary.renderer.rules.footnote_caption = (tokens, idx) => {
	let n = Number(tokens[idx] + 1).toString();

	if (tokens[idx].meta.subId > 0) {
		n += ":" + tokens[idx].meta.subId;

	return n;

After a brief and successful test on a repo branch, I gleefully incorporated his fix1 on each of my Eleventy repos (the one for this site and my two Eleventy-based starter repos); and, now, that earlier paragraph looks like this, as it should:

Paragraph ending in a footnote whose number is not bracketed

Yay. Thanks and nice going, Mark. (By the way, Eleventy fans: he’s got a lot of other neat Eleventy-related posts on his site — and they’re considerably more concise than my bloated blatherings — so I highly recommend checking them out.)

AVIF: Cloudi forecast?

It appears the next hot image format on the website front is going to be AVIF. It offers even tighter compression than Google’s WebP (and, thus, ’waaay more than the comparatively ancient JPEG), and is quickly gaining support among the most popular browsers.

I bring this up only to note that, so far, Cloudinary — which I began using last year to offload the increasing headaches of my site’s image-handling — has yet to support AVIF except in an experimental way mentioned in a blog post from a few months back. Moreover, that same post says that, “due to AVIF’s extreme encode times, usage is currently limited.” For now, I’m taking this to mean that little cheapo free-tier users such as I won’t get to see AVIF be one of the formats provided by that otherwise amazing f_auto parameter in Cloudinary image URLs. I hope I’m wrong; the final outcome is TBD.

And that’ll do it for this descent into the geeky, SSG-loving recesses of my cranium. Let me know if you have questions or thoughts about any of this stuff.

  1. Well, all but the semicolons at lines’ ends. I’m one of those who choose to avoid them in their JS. Sorry, pro-semicolon partisans↩︎