Hardscrabble 🍫

By Max Jacobson

See also: the archives and an RSS feed

Multi-paragraph footnotes in Markdown

October 1, 2023

It can be challenging to write about Markdown in Markdown, but I’m going to try. The hard part is showing examples of the syntax without that syntax getting converted into HTML. For example, did you know that if you want to bold some text, you do it like this? Shit, that got bolded. Let me try again. You can do it **like this**. OK, great.

So what about footnotes? Adding a simple footnote is fairly straightforward: you put [^1] in the main flow of your prose to indicate that there is a footnote. Then you can add your footnote like this:

[^1]: My great footnote

Here’s how that looks1.

John Gruber, the inventor of Markdown, recently published a recap of Apple’s recent iPhone 15 event which contained three footnotes. When I saw that one of them is three whole paragraphs, my eyes widened. You can do that???

If we look at the generated HTML, it looks like this:

<li id="fn2-2023-09-15">
<p>On the eve...</p>

<blockquote>
  <p>Apple has also...</p>
</blockquote>

<p>Huawei’s geopolitical travails...</p>
</li>

Nothing magical going on at all. Just some normal-looking HTML.

But, I wondered, how the hell do you represent that in Markdown? When I generate footnotes with Markdown, as soon as I finish the first paragraph, the footnote is done.

I happen to know that Daring Fireball has a trick, where you can append .text to any URL and see the Markdown source code for that article. So I took a look at that article’s source Markdown, and here’s what I saw:

<li id="fn2-2023-09-15">
<p>On the eve...</p>

<blockquote>
  <p>Apple has also...</p>
</blockquote>

<p>Huawei’s geopolitical travails...</p>
</li>

Yep: the exact same thing. He’s not using any special Markdown syntax to generate the footnotes, he’s doing it manually by writing HTML. And that’s fair enough; it’s totally valid to include bits of HTML in your Markdown source.

But… does that mean that it’s not possible to have multi-paragraph footnotes in HTML-free Markdown? Well… unfortunately, it’s time that we start to get into some nuance (and a bit of drama).

I should note that I’m referring to “Markdown” as though Markdown is one thing. It’s not. Gruber’s original version of Markdown doesn’t support footnotes at all (so it’s not a surprise that his blog implements them without any non-HTML syntax). There are many, many different implementations of Markdown. The one that I tend to use is called GitHub Flavored Markdown, which is the version of Markdown used in GitHub text fields. It’s also the version of Markdown that I use to build this blog. So that’s the one I’ll focus on today.

This diaspora of implementations can make it hard to find good information about what features you should expect to have access to. GitHub publishes a spec for GitHub flavored Markdown but it doesn’t describe their implementation of footnotes. Elsewhere, they publish a doc on “Basic writing and formatting syntax” and its section on footnotes includes these two examples:

Here is a simple footnote[^1].

A footnote can also have multiple lines[^2].

[^1]: My reference.
[^2]: To add line breaks within a footnote, prefix new lines with 2 spaces.
  This is a second line.

Oh God, is that the best we can do? That seems to generate one paragraph, with <br /> tags breaking it up into multiple lines. That’s not really what I want.

But, clicking around, I found some reason for hope. The 2021 changelog post that introduced footnotes to GitHub embeds a gif that, hooray, includes a multi-paragraph footnote example, which looks like this:

Some text.[^bignote]

[^bignote]: Here's one with multiple paragraphs and code.

    Indent paragraphs to include them in the footnote.

    `{ my code }`

    Add as many paragraphs as you like

As the gif looped and this little miracle flashed on the screen momentarily before flickering away again, I did my best to see what was there, and eventually the carousel looped around enough times that I got it. So that’s easy enough: you can add more paragraphs to your footnote as long as you indent them (with four spaces). Easy.2 And hopefully this will actually continue to work, even though it’s barely documented.

I did tease a little drama, but I’m actually not super invested in it. So, suffice it to say that Gruber is occasionally a bit salty about the various takes on Markdown that exist.

  1. My great footnote 

  2. Just to show it off here, I’m doing another footnote, and this is the first paragraph of it.

    and wow here’s a blockquote and it’s still in the same footnote

    And here’s another paragraph that’s still, magically, in the same footnote.

    The blank lines between the paragraphs can just be blank, they don’t need to have four spaces in them for no reason, don’t worry. 

The Apple Studio Display's Missing Volume Knob

October 1, 2023

I’ve been using the Apple Studio Display as a computer monitor for over a year now and here’s my review: it’s pretty good, but it’s missing a volume knob.

I use the built-in speakers, which are pretty good. And, of course, it’s possible to adjust the volume. My goofy mechanical keyboard1 has a row of function keys, and maybe one of them is supposed to control the volume, but I can’t figure it out (I’ve tried for like two whole minutes). So for the first year or so of using this monitor, any time I wanted to adjust the volume, I moused up to the little Control Center icon in the menu bar, clicked, and dragged the little slider.

Adjusting volume with Control Center

And reader, forgive me, maybe this is intuitively obvious to you, but it must be said: this experience sucks!

If I’m “feeling myself” and want to turn up the tunes, that should be as easy as possible to do. I don’t want to scan through a mess of tiny monochromatic icons and have to think. If I’m in the middle of a tense chess position and I want to turn down the music and concentrate, again, that needs to be so easy to do without even taking my eyes off the chess.com chess board.

This sucky experience was kind of simmering below the threshold of conscious annoyance for a while, but a few months ago I finally put my finger on it and had the thought: damn, I wish I had a little volume knob I could turn right now, I wonder if that exists somewhere? So I started doing some google queries like “standalone volume knob” that yielded some very interesting products.

Some products are literally what I imagined: a standalone volume knob. For example this handmade walnut one from Etsy seller ZiddyMakes that I came very close to ordering:

Walnut knob

A bunch more of them were small knobs that are not usable standalone electronics, but meant to be somehow fastened to a mechanical keyboard. An appealing idea! If my keyboard had a little knob, I’d be thrilled. But my keyboard doesn’t, and I do not dare attempt to give it one.

Eventually, in this research, I found my way to the term “macropad”, which is basically like a little standalone keyboard with a few keys on it that you can program to do whatever you want, like kick off some automation, or act as simple media controls to pause your music or adjust your volume. Some of them even have knobs on them.

I ordered this one: DOIO KB04-01 Macro Keyboard 4 Keys + 1 Knob Macro Pad

DOIO macropad

Hot yellow! Nice.

When it arrived, it basically worked out of the box. The knob controlled the volume. The first button worked like a play/pause button. The second button like a previous track button. The third one like a next track button. The fourth one, uh, didn’t seem to do anything.

I spent a few minutes trying to figure out how to customize what those buttons would do, but nothing seemed to work. Then I remembered the classic Mitch Hedberg joke:

I write jokes for a living, I sit at my hotel at night, I think of something that’s funny, then I go get a pen and I write it down. Or if the pen is too far away, I have to convince myself that what I thought of ain’t funny.

And so I convinced myself that actually having play/pause, previous track, next track, and a no-op button was what I wanted.

I did order some media keycaps from WASD to replace the blank keycaps that came with it, so I could remember what each key does. I was planning to leave the fourth key blank, but the WASD keycaps were a bit taller than the keycaps that came with the macropad, and it felt weird for them not to all be the same height, so I just put the square “stop” keycap there, even though it doesn’t actually stop anything.

I’ve had this little guy on my desk for a few months now and I really love it. I almost never press the keys, but I turn the volume knob all the time. It has a nice uh, knob feel. It isn’t an entirely smooth spin; it sort of turns in notches. As you turn it, you can feel exactly how many notches you’re turning it, and each notch is equivalent to pressing the “volume up” or “volume down” key on a keyboard that has those buttons.

Nice little gizmo.

  1. FWIW, I’ve been very happily using the REALFORCE R2 KEYBOARD MID SIZE (IVORY) keyboard for almost two years and it’s my favorite keyboard I’ve ever used. It has the excellent topre switches from the iconic Happy Hacker Keyboard, but in a normal keyboard layout that asks very little of you. 

Streaming sites and their bad URLs

October 1, 2023

Why do streaming sites have such poor URLs?

Here’s a quick survey of the field:

Site Example series URL
Amazon Prime Gen V https://www.amazon.com/gp/video/detail/B0CBFTRGPZ/
Apple TV+ Ted Lasso https://tv.apple.com/us/show/ted-lasso/umc.cmc.vtoh0mn0xn7t3c643xqonfzy
Disney+ Bluey https://www.disneyplus.com/series/bluey/1xy9TAOQ0M3r
Hulu Only Murders in the Building https://www.hulu.com/series/ef31c7e1-cd0f-4e07-848d-1cbfedb50ddf
Max Friends https://play.max.com/show/52dae4c7-2ab1-4bb9-ab1c-8100fd54e2f9
Netflix One Piece https://www.netflix.com/title/80217863
Paramount+ Star Trek: The Original Series (Remastered) https://www.paramountplus.com/shows/star_trek/
Peacock Killing It https://www.peacocktv.com/watch/asset/tv/killing-it/5156438808822262112
Tubi Hannibal https://tubitv.com/series/300000159/hannibal

Of these, the best one is clearly Paramount+, because it’s human-readable and free of any junk. If I were feeling uncharitable, I might ding it for using snake case rather than kebab case, but I’m willing to concede that’s a matter of taste.

In the second tier are Apple TV+, Disney+, Peacock, and Tubi which all contain the series name somewhere in their URL. They don’t make it easy for you to read them, because there’s some amount of junk mixed in there too, but it’s possible.

When I see a URL like that, I want to test if they actually validate the human-readable bit. Let’s see:

Site Example series Fake URL
Apple TV+ Ted Lasso https://tv.apple.com/us/show/sad-soccer-show/umc.cmc.vtoh0mn0xn7t3c643xqonfzy
Disney+ Bluey https://www.disneyplus.com/series/sad-dog-show/1xy9TAOQ0M3r
Peacock Killing It https://www.peacocktv.com/watch/asset/tv/silly-snake-scenarios/5156438808822262112

And indeed, two out of those three work. Good for Peacock going that extra mile.

In a distant last place, of course, are Hulu, Netflix, Max, and Amazon Prime, which don’t make an effort to be human-readable at all. Boo.

Michael in the Bathroom

September 3, 2023

Here’s some more musical theatre. I think a lot of people’s introduction to the musical Be More Chill is this song, because it’s a real powerhouse performance.

I wonder how many of them, like me, were disappointed to learn that Michael is not the main character of the musical. He’s the best friend of the main character, Jeremy.

Jeremy is being a kind of shitty friend, and Michael feels abandoned. That’s all you need to know to enjoy this song.

George Salazar performs this song again at the Tiny Desk Concert performance the production did:

C’mon, what a voice!

Be More Chill is based on a young adult novel by Ned Vizzini which I haven’t read. When I was a young adult I recall enjoying his memoir Teen Angst? Naaah…, which he published in 2000 while still a teenager. He died, apparently by suicide, in 2013. The reference to suicide in this song hits harder knowing that.

On a related note, perhaps the other great example of a musical theatre piece about debilitating anxiety in recent years is Surface Pressure from Encanto:

Fair warning to readers with siblings that this one might fuck you up a little, depending on whatever dynamics y’all are working with.

On another tangentically related note, here’s one more terrific George Salazar performance, this one a duet with Michaela Jaé Rodriguez performing Suddenly Seymour:

Tautology Supercut

September 3, 2023

The Wire (famously good TV show) had this weird tic: practically half of it’s dialogue is tautologies like “it is what it is”.

And it works.

I saw this video years ago and I think about it constantly. Enjoy.

My baby teeth

May 24, 2023

Wye Oak’s Civilian is one of my favorite songs.

There’s a cinematic, epic yearning here, and it’s no surprise it’s been used in a ton of movies and TV shows.

I don’t need another friend

When most of them I can barely keep up with them

I’m perfectly able to hold my own hand

But I still can’t kiss my own neck

The studio version benefits from a driving drum beat and a ripping guitar solo to help build up its intensity, but this acoustic rendition doesn’t need them.

Jenn Wasner is the coolest. Outside of her work in Wye Oak, she’s also toured with Bon Iver and contributed to their most recent album I, I.

Sweet like Fanta

May 22, 2023

This track by Rema and Selena Gomez from last summer is so good:

You can sing along to it if you want to.

The world is so vast. This song is a massive hit featuring a pop star I’m a fan of1 and I almost never heard about it.

I came across it in a kind of fun way that I want to recommend. I’m big into the Apple ecosystem, including Apple TV and Apple Music. Recently I was clicking around the Apple Music app on my Apple TV and I found a section dedicated to music videos. I put on a playlist of music videos called The A-List: Pop Videos and let it play on shuffle on the TV while I worked on other things. Lots of good, fun stuff came through, but this was the stand out. The experience was great: not cluttered with ads or other non-music segments. They have other playlists for other genres and moods too.

I love music videos. The track opens with Selena Gomez murmuring the word “Vibes” and then Rema declaring that the track is “Another banger”, and it’s hard to disagree when you watch this.

  1. Not only is Selena Gomez a very talented singer (my favorite solo song of hers is the frosty Hands To Myself) but she’s also very funny in Only Murders In The Building 

How and why to use an SSH passphrase

May 1, 2023

While writing about git commit signatures earlier today, a related memory came to mind.

A few months in to my working at Code Climate, back in mid 2016, I confessed to a colleague that I didn’t have a passphrase associated with my SSH key. His eyes filled with horror, and he said “For God’s sake, use a passphrase, man!”1

SSH Keys are used as an authentication mechanism for some very sensitive things like read/write access to remote git repositories and for managing access to remote servers.

But, anecdotally, I feel like a lot of people don’t use passphrases with their SSH keys… So let’s talk about it.

When you generate an SSH Key, you get a pair of text files on your computer. On my computer, I have these two files:

$ ls ~/.ssh
id_ed25519
id_ed25519.pub

The first one is the private key and the second one is the public key. The public key is the one I give out, and the private one is really important for me not to share with anyone at all.

(Yours might be named id_rsa and id_rsa.pub, or something else, but it will come in a pair of a public key and a private key.)

When I add my public key to my github.com account, and that lets me clone private repositories as long as I have the corresponding private key.

We can imagine a scenario where my private key is compromised. Maybe I’m at a coffee shop and I run to the bathroom and forget to lock my laptop. The snoop sitting next to me might quickly run cat ~/.ssh/id_ed25519, take a photo, and then close the terminal window. Now they have my private key, and they can use it from their computer to access whatever I can access.

Eep.

When generating an SSH key, the ssh-keygen command will ask you whether you would like your key to have a passphrase. If you say no, you’re vulnerable to the cafe snoopers of the world2.

If, however, you do provide a passphrase, your private key will be useless to the snooper, because they will need to type in the passphrase when they try to use the key.

Of course, that means that you will also need to type in the passphrase when you try to use the key. That’s super annoying! You probably push and pull several times throughout the day, and if your passphrase is convenient to type, it’s probably not that strong of a passphrase.

To mitigate that annoyance, I have this line in my ~/.zshrc:

ssh-add -q --apple-use-keychain

The effect of this is that I only need to enter the passphrase once, and it will remember it forever. I guess it stores it in the keychain, some secure thing that the Mac manages. I don’t really get how the keychain works to be honest.

But the user experience is pretty great: I have a passphrase, so I can sleep easy at night, but I don’t need to deal with the hassle of entering it all the time.

  1. I paraphrase from memory 😅. 

  2. perhaps a more likely scenario is an attacker stealing your laptop, unscrewing the bottom, yanking the hard drive out, and rummaging around in your files. But if your disk is encrypted, you shouldn’t need to worry about this. 

How to sign your git commits with the SSH key you already use

May 1, 2023

It’s surprisingly easy to impersonate other people in git and GitHub. All you need to know is their name and email address, and then you can configure git with that information and start committing. When you push those commits to GitHub, it looks up the user by email address and attributes the commit to that user, whether or not they actually made it.

For example, if you want to impersonate dhh on GitHub, all you have to do is:

git config --global user.name "David Heinemeier Hansson"
git config --global user.email "dhh@hey.com"

And then start committing and pushing.

impersonating DHH

But, uh, please don’t actually do that, I don’t want to get in trouble.

Being impersonated is not likely to be a big problem for you, but if it’s something you’re worried about, you should start signing your commits. Honestly, you should probably just start signing your commits anyway, because it’s kind of neat and just got way, way easier1.

Here’s what you do:

git config --global commit.gpgSign true
git config --global gpg.format ssh
git config --global user.signingKey "~/.ssh/id_ed25519"

The user.signingKey config should be a path to your private SSH key. It’s possible that your private SSH key has a different path, such as ~/.ssh/id_rsa, so you may need to tweak that.

This bit is optional, but if you use tags, you can also sign those:

git config --global tag.gpgSign true
git config --global tag.forceSignAnnotated true

If you’re following along, now’s a good time to try making a commit and confirm that it works. If anything doesn’t work, you can always undo those configuration changes by editing ~/.gitconfig. But hopefully it does!

When you push these commits to GitHub, you will see an “Unverified” badge next to them until you let GitHub know that you’re using this SSH Key to sign commits now. You can do that by copying your public key to your clipboard (cat ~/.ssh/id_ed25519.pub | pbcopy) and then adding it, taking care to select “Signing Key” as the key type.

If you’re actually worried about being impersonated, you can also turn on vigilant mode which will display that “Unverified” badge on any commits that aren’t signed by one of your registered signing keys.

Note that this signature only exists for commits that are authored locally on your machine. What about commits you author through GitHub’s web interface? For example when you merge a PR, or edit a file on the web. Actions like those will create commits on GitHub’s servers, which don’t have access to your private key for signing. You might be surprised to see that those commits also have a “Verified” badge on them. What gives? If you look a little closer (by clicking on the badge to reveal some details) you’ll see that those commits are signed by GitHub, not by you.

This commit was created on GitHub.com and signed with GitHub’s verified signature.

GitHub is basically saying that they created the commit on behalf of a particular GitHub user. They know who clicked the big green merge button, and they’re vouching for you.

  1. it used to be that you would sign your commits with gpg, but gpg is kind of confusing and finicky to set up. For a while I used a tool called bpb which makes it a little easier, but it was still finicky. Recently GitHub added support for signing commits with the SSH key you already have and I was thrilled to ditch that bpb setup. 

Natasha Beats The Devil

April 21, 2023

In 2004, Natasha Bedingfield released a track called These Words. In 2006, 65daysofstatic released a remix called Natasha Beats The Devil:

I would have found this via Jerome Holeyman’s blog charlatan, which I was a religious reader of back in the Google Reader days, which covered the hard-to-define genre called Post-Rock.

I can’t really imagine listening to this without watching the video. The video is inseparable, remixing the original music video.

In just a few short minutes, this video reliably restarts my brain. The remix starts out humble, not varying too much from the original song (which is also great). But at some point, when it’s supposed to segue from that perfect chorus (“I love you, I love you”) into a bridge and then wind down, it just… doesn’t. It just stays there, like a glitch happened. Like she was supposed to take a turn, drove off a cliff, and her car started flying. “I love you, I love you” becomes IloveyouIloveyouIloveyouIloloveyouIIloveyou. Natasha beats the devil. A new glitchy beat comes in, and some simple chords, and she keeps going, for what feels like long enough that you kind of forget where you are.

Now I’m reminded of this classic Nathan For You moment: